Initial commit.
This commit is contained in:
586
code/icarus/BlockStream.cpp
Normal file
586
code/icarus/BlockStream.cpp
Normal file
@@ -0,0 +1,586 @@
|
||||
// Interpreted Block Stream Functions
|
||||
//
|
||||
// -- jweier
|
||||
|
||||
// this include must remain at the top of every Icarus CPP file
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "IcarusInterface.h"
|
||||
#include "IcarusImplementation.h"
|
||||
|
||||
#include "BlockStream.h"
|
||||
|
||||
/*
|
||||
===================================================================================================
|
||||
|
||||
CBlockMember
|
||||
|
||||
===================================================================================================
|
||||
*/
|
||||
|
||||
inline CBlockMember::CBlockMember( void )
|
||||
{
|
||||
m_id = -1;
|
||||
m_size = -1;
|
||||
m_data = NULL;
|
||||
}
|
||||
|
||||
inline CBlockMember::~CBlockMember( void )
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
-------------------------
|
||||
Free
|
||||
-------------------------
|
||||
*/
|
||||
|
||||
void CBlockMember::Free(IGameInterface* game)
|
||||
{
|
||||
if ( m_data != NULL )
|
||||
{
|
||||
game->Free ( m_data );
|
||||
m_data = NULL;
|
||||
|
||||
m_id = m_size = -1;
|
||||
}
|
||||
delete this;
|
||||
}
|
||||
|
||||
/*
|
||||
-------------------------
|
||||
GetInfo
|
||||
-------------------------
|
||||
*/
|
||||
|
||||
void CBlockMember::GetInfo( int *id, int *size, void **data )
|
||||
{
|
||||
*id = m_id;
|
||||
*size = m_size;
|
||||
*data = m_data;
|
||||
}
|
||||
|
||||
/*
|
||||
-------------------------
|
||||
SetData overloads
|
||||
-------------------------
|
||||
*/
|
||||
|
||||
void CBlockMember::SetData( const char *data , CIcarus* icarus)
|
||||
{
|
||||
WriteDataPointer( data, strlen(data)+1, icarus );
|
||||
}
|
||||
|
||||
void CBlockMember::SetData( vec3_t data , CIcarus* icarus)
|
||||
{
|
||||
WriteDataPointer( data, 3 , icarus);
|
||||
}
|
||||
|
||||
void CBlockMember::SetData( void *data, int size, CIcarus* icarus)
|
||||
{
|
||||
IGameInterface* game = icarus->GetGame();
|
||||
if ( m_data )
|
||||
game->Free( m_data );
|
||||
|
||||
m_data = game->Malloc( size );
|
||||
memcpy( m_data, data, size );
|
||||
m_size = size;
|
||||
}
|
||||
|
||||
// Member I/O functions
|
||||
|
||||
/*
|
||||
-------------------------
|
||||
ReadMember
|
||||
-------------------------
|
||||
*/
|
||||
|
||||
int CBlockMember::ReadMember( char **stream, long *streamPos, CIcarus* icarus )
|
||||
{
|
||||
IGameInterface* game = icarus->GetGame();
|
||||
m_id = *(int *) (*stream + *streamPos);
|
||||
*streamPos += sizeof( int );
|
||||
|
||||
if ( m_id == CIcarus::ID_RANDOM )
|
||||
{//special case, need to initialize this member's data to Q3_INFINITE so we can randomize the number only the first time random is checked when inside a wait
|
||||
m_size = sizeof( float );
|
||||
*streamPos += sizeof( long );
|
||||
m_data = game->Malloc( m_size );
|
||||
float infinite = game->MaxFloat();
|
||||
memcpy( m_data, &infinite, m_size );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_size = *(long *) (*stream + *streamPos);
|
||||
*streamPos += sizeof( long );
|
||||
m_data = game->Malloc( m_size );
|
||||
memcpy( m_data, (*stream + *streamPos), m_size );
|
||||
}
|
||||
*streamPos += m_size;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
-------------------------
|
||||
WriteMember
|
||||
-------------------------
|
||||
*/
|
||||
|
||||
int CBlockMember::WriteMember( FILE *m_fileHandle )
|
||||
{
|
||||
fwrite( &m_id, sizeof(m_id), 1, m_fileHandle );
|
||||
fwrite( &m_size, sizeof(m_size), 1, m_fileHandle );
|
||||
fwrite( m_data, m_size, 1, m_fileHandle );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
-------------------------
|
||||
Duplicate
|
||||
-------------------------
|
||||
*/
|
||||
|
||||
CBlockMember *CBlockMember::Duplicate( CIcarus* icarus )
|
||||
{
|
||||
CBlockMember *newblock = new CBlockMember;
|
||||
|
||||
if ( newblock == NULL )
|
||||
return NULL;
|
||||
|
||||
newblock->SetData( m_data, m_size, icarus );
|
||||
newblock->SetSize( m_size );
|
||||
newblock->SetID( m_id );
|
||||
|
||||
return newblock;
|
||||
}
|
||||
|
||||
/*
|
||||
===================================================================================================
|
||||
|
||||
CBlock
|
||||
|
||||
===================================================================================================
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
-------------------------
|
||||
Init
|
||||
-------------------------
|
||||
*/
|
||||
|
||||
int CBlock::Init( void )
|
||||
{
|
||||
m_flags = 0;
|
||||
m_id = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
-------------------------
|
||||
Create
|
||||
-------------------------
|
||||
*/
|
||||
|
||||
int CBlock::Create( int block_id )
|
||||
{
|
||||
Init();
|
||||
|
||||
m_id = block_id;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
-------------------------
|
||||
Free
|
||||
-------------------------
|
||||
*/
|
||||
|
||||
int CBlock::Free( CIcarus* icarus )
|
||||
{
|
||||
IGameInterface* game = icarus->GetGame();
|
||||
int numMembers = GetNumMembers();
|
||||
CBlockMember *bMember;
|
||||
|
||||
while ( numMembers-- )
|
||||
{
|
||||
bMember = GetMember( numMembers );
|
||||
|
||||
if (!bMember)
|
||||
return false;
|
||||
|
||||
bMember->Free(game);
|
||||
}
|
||||
|
||||
m_members.clear(); //List of all CBlockMembers owned by this list
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Write overloads
|
||||
|
||||
/*
|
||||
-------------------------
|
||||
Write
|
||||
-------------------------
|
||||
*/
|
||||
|
||||
int CBlock::Write( int member_id, const char *member_data, CIcarus* icarus )
|
||||
{
|
||||
CBlockMember *bMember = new CBlockMember;
|
||||
|
||||
bMember->SetID( member_id );
|
||||
|
||||
bMember->SetData( member_data, icarus );
|
||||
bMember->SetSize( strlen(member_data) + 1 );
|
||||
|
||||
AddMember( bMember );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int CBlock::Write( int member_id, vec3_t member_data, CIcarus* icarus )
|
||||
{
|
||||
CBlockMember *bMember;
|
||||
|
||||
bMember = new CBlockMember;
|
||||
|
||||
bMember->SetID( member_id );
|
||||
bMember->SetData( member_data, icarus );
|
||||
bMember->SetSize( sizeof(vec3_t) );
|
||||
|
||||
AddMember( bMember );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int CBlock::Write( int member_id, float member_data, CIcarus* icarus )
|
||||
{
|
||||
CBlockMember *bMember = new CBlockMember;
|
||||
|
||||
bMember->SetID( member_id );
|
||||
bMember->WriteData( member_data, icarus );
|
||||
bMember->SetSize( sizeof(member_data) );
|
||||
|
||||
AddMember( bMember );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int CBlock::Write( int member_id, int member_data, CIcarus* icarus )
|
||||
{
|
||||
CBlockMember *bMember = new CBlockMember;
|
||||
|
||||
bMember->SetID( member_id );
|
||||
bMember->WriteData( member_data , icarus);
|
||||
bMember->SetSize( sizeof(member_data) );
|
||||
|
||||
AddMember( bMember );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int CBlock::Write( CBlockMember *bMember, CIcarus* )
|
||||
{
|
||||
// findme: this is wrong: bMember->SetSize( sizeof(bMember->GetData()) );
|
||||
|
||||
AddMember( bMember );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Member list functions
|
||||
|
||||
/*
|
||||
-------------------------
|
||||
AddMember
|
||||
-------------------------
|
||||
*/
|
||||
|
||||
int CBlock::AddMember( CBlockMember *member )
|
||||
{
|
||||
m_members.insert( m_members.end(), member );
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
-------------------------
|
||||
GetMember
|
||||
-------------------------
|
||||
*/
|
||||
|
||||
CBlockMember *CBlock::GetMember( int memberNum )
|
||||
{
|
||||
if ( memberNum > GetNumMembers()-1 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return m_members[ memberNum ];
|
||||
}
|
||||
|
||||
/*
|
||||
-------------------------
|
||||
GetMemberData
|
||||
-------------------------
|
||||
*/
|
||||
|
||||
void *CBlock::GetMemberData( int memberNum )
|
||||
{
|
||||
if ( memberNum > GetNumMembers()-1 )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return (void *) ((GetMember( memberNum ))->GetData());
|
||||
}
|
||||
|
||||
/*
|
||||
-------------------------
|
||||
Duplicate
|
||||
-------------------------
|
||||
*/
|
||||
|
||||
CBlock *CBlock::Duplicate( CIcarus* icarus )
|
||||
{
|
||||
blockMember_v::iterator mi;
|
||||
CBlock *newblock;
|
||||
|
||||
newblock = new CBlock;
|
||||
|
||||
if ( newblock == NULL )
|
||||
return false;
|
||||
|
||||
newblock->Create( m_id );
|
||||
|
||||
//Duplicate entire block and return the cc
|
||||
for ( mi = m_members.begin(); mi != m_members.end(); mi++ )
|
||||
{
|
||||
newblock->AddMember( (*mi)->Duplicate(icarus) );
|
||||
}
|
||||
|
||||
return newblock;
|
||||
}
|
||||
|
||||
/*
|
||||
===================================================================================================
|
||||
|
||||
CBlockStream
|
||||
|
||||
===================================================================================================
|
||||
*/
|
||||
|
||||
char* CBlockStream::s_IBI_EXT = ".IBI"; //(I)nterpreted (B)lock (I)nstructions
|
||||
char* CBlockStream::s_IBI_HEADER_ID = "IBI";
|
||||
const float CBlockStream::s_IBI_VERSION = 1.57f;
|
||||
|
||||
/*
|
||||
-------------------------
|
||||
Free
|
||||
-------------------------
|
||||
*/
|
||||
|
||||
int CBlockStream::Free( void )
|
||||
{
|
||||
//NOTENOTE: It is assumed that the user will free the passed memory block (m_stream) immediately after the run call
|
||||
// That's why this doesn't free the memory, it only clears its internal pointer
|
||||
|
||||
m_stream = NULL;
|
||||
m_streamPos = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
-------------------------
|
||||
Create
|
||||
-------------------------
|
||||
*/
|
||||
|
||||
int CBlockStream::Create( char *filename )
|
||||
{
|
||||
// strip extension
|
||||
int extensionloc = strlen(filename);
|
||||
while ( (filename[extensionloc] != '.') && (extensionloc >= 0) )
|
||||
{
|
||||
extensionloc--;
|
||||
}
|
||||
if ( extensionloc < 0 )
|
||||
{
|
||||
strcpy(m_fileName, filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
strncpy(m_fileName, filename, extensionloc);
|
||||
m_fileName[extensionloc] = '\0';
|
||||
}
|
||||
// add extension
|
||||
strcat((char *) m_fileName, s_IBI_EXT);
|
||||
|
||||
if ( ((m_fileHandle = fopen(m_fileName, "wb")) == NULL) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
fwrite( s_IBI_HEADER_ID, 1, sizeof(s_IBI_HEADER_ID), m_fileHandle );
|
||||
fwrite( &s_IBI_VERSION, 1, sizeof(s_IBI_VERSION), m_fileHandle );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
-------------------------
|
||||
Init
|
||||
-------------------------
|
||||
*/
|
||||
|
||||
int CBlockStream::Init( void )
|
||||
{
|
||||
m_fileHandle = NULL;
|
||||
memset(m_fileName, 0, sizeof(m_fileName));
|
||||
|
||||
m_stream = NULL;
|
||||
m_streamPos = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Block I/O functions
|
||||
|
||||
/*
|
||||
-------------------------
|
||||
WriteBlock
|
||||
-------------------------
|
||||
*/
|
||||
|
||||
int CBlockStream::WriteBlock( CBlock *block, CIcarus* icarus )
|
||||
{
|
||||
CBlockMember *bMember;
|
||||
int id = block->GetBlockID();
|
||||
int numMembers = block->GetNumMembers();
|
||||
unsigned char flags = block->GetFlags();
|
||||
|
||||
fwrite ( &id, sizeof(id), 1, m_fileHandle );
|
||||
fwrite ( &numMembers, sizeof(numMembers), 1, m_fileHandle );
|
||||
fwrite ( &flags, sizeof( flags ), 1, m_fileHandle );
|
||||
|
||||
for ( int i = 0; i < numMembers; i++ )
|
||||
{
|
||||
bMember = block->GetMember( i );
|
||||
bMember->WriteMember( m_fileHandle );
|
||||
}
|
||||
|
||||
block->Free(icarus);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
-------------------------
|
||||
BlockAvailable
|
||||
-------------------------
|
||||
*/
|
||||
|
||||
int CBlockStream::BlockAvailable( void )
|
||||
{
|
||||
if ( m_streamPos >= m_fileSize )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
-------------------------
|
||||
ReadBlock
|
||||
-------------------------
|
||||
*/
|
||||
|
||||
int CBlockStream::ReadBlock( CBlock *get, CIcarus* icarus )
|
||||
{
|
||||
CBlockMember *bMember;
|
||||
int b_id, numMembers;
|
||||
unsigned char flags;
|
||||
|
||||
if (!BlockAvailable())
|
||||
return false;
|
||||
|
||||
b_id = *(int *) (m_stream + m_streamPos);
|
||||
m_streamPos += sizeof( b_id );
|
||||
|
||||
numMembers = *(int *) (m_stream + m_streamPos);
|
||||
m_streamPos += sizeof( numMembers );
|
||||
|
||||
flags = *(unsigned char*) (m_stream + m_streamPos);
|
||||
m_streamPos += sizeof( flags );
|
||||
|
||||
if (numMembers < 0)
|
||||
return false;
|
||||
|
||||
get->Create( b_id );
|
||||
get->SetFlags( flags );
|
||||
|
||||
// Stream blocks are generally temporary as they
|
||||
// are just used in an initial parsing phase...
|
||||
#ifdef _XBOX
|
||||
extern void Z_SetNewDeleteTemporary(bool bTemp);
|
||||
Z_SetNewDeleteTemporary(true);
|
||||
#endif
|
||||
|
||||
while ( numMembers-- > 0)
|
||||
{
|
||||
bMember = new CBlockMember;
|
||||
bMember->ReadMember( &m_stream, &m_streamPos, icarus );
|
||||
get->AddMember( bMember );
|
||||
}
|
||||
|
||||
#ifdef _XBOX
|
||||
Z_SetNewDeleteTemporary(false);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
-------------------------
|
||||
Open
|
||||
-------------------------
|
||||
*/
|
||||
|
||||
int CBlockStream::Open( char *buffer, long size )
|
||||
{
|
||||
char id_header[sizeof(s_IBI_HEADER_ID)];
|
||||
float version;
|
||||
|
||||
Init();
|
||||
|
||||
m_fileSize = size;
|
||||
|
||||
m_stream = buffer;
|
||||
|
||||
for ( int i = 0; i < sizeof( id_header ); i++ )
|
||||
{
|
||||
id_header[i] = *(m_stream + m_streamPos++);
|
||||
}
|
||||
|
||||
version = *(float *) (m_stream + m_streamPos);
|
||||
m_streamPos += sizeof( version );
|
||||
|
||||
//Check for valid header
|
||||
if ( strcmp( id_header, s_IBI_HEADER_ID ) )
|
||||
{
|
||||
Free();
|
||||
return false;
|
||||
}
|
||||
|
||||
//Check for valid version
|
||||
if ( version != s_IBI_VERSION )
|
||||
{
|
||||
Free();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
809
code/icarus/IcarusImplementation.cpp
Normal file
809
code/icarus/IcarusImplementation.cpp
Normal file
@@ -0,0 +1,809 @@
|
||||
// IcarusImplementation.cpp
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "IcarusImplementation.h"
|
||||
|
||||
#include "BlockStream.h"
|
||||
#include "Sequence.h"
|
||||
#include "TaskManager.h"
|
||||
#include "Sequencer.h"
|
||||
|
||||
#define STL_ITERATE( a, b ) for ( a = b.begin(); a != b.end(); a++ )
|
||||
#define STL_INSERT( a, b ) a.insert( a.end(), b );
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// required implementation of CIcarusInterface
|
||||
|
||||
IIcarusInterface* IIcarusInterface::GetIcarus(int flavor,bool constructIfNecessary)
|
||||
{
|
||||
if(!CIcarus::s_instances && constructIfNecessary)
|
||||
{
|
||||
CIcarus::s_flavorsAvailable = IGameInterface::s_IcarusFlavorsNeeded;
|
||||
if (!CIcarus::s_flavorsAvailable)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
CIcarus::s_instances = new CIcarus*[CIcarus::s_flavorsAvailable];
|
||||
for (int index = 0; index < CIcarus::s_flavorsAvailable; index++)
|
||||
{
|
||||
CIcarus::s_instances[index] = new CIcarus(index);
|
||||
//OutputDebugString( "ICARUS flavor successfully created\n" );
|
||||
}
|
||||
}
|
||||
|
||||
if(flavor >= CIcarus::s_flavorsAvailable || !CIcarus::s_instances )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return CIcarus::s_instances[flavor];
|
||||
}
|
||||
|
||||
void IIcarusInterface::DestroyIcarus()
|
||||
{
|
||||
for(int index = 0; index < CIcarus::s_flavorsAvailable; index++)
|
||||
{
|
||||
delete CIcarus::s_instances[index];
|
||||
}
|
||||
delete[] CIcarus::s_instances;
|
||||
CIcarus::s_instances = NULL;
|
||||
CIcarus::s_flavorsAvailable = 0;
|
||||
}
|
||||
|
||||
IIcarusInterface::~IIcarusInterface()
|
||||
{
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CIcarus
|
||||
|
||||
double CIcarus::ICARUS_VERSION = 1.40;
|
||||
|
||||
int CIcarus::s_flavorsAvailable = 0;
|
||||
|
||||
CIcarus** CIcarus::s_instances = NULL;
|
||||
|
||||
CIcarus::CIcarus(int flavor) :
|
||||
m_flavor(flavor), m_nextSequencerID(0)
|
||||
{
|
||||
|
||||
m_GUID = 0;
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
||||
m_DEBUG_NumSequencerAlloc = 0;
|
||||
m_DEBUG_NumSequencerFreed = 0;
|
||||
m_DEBUG_NumSequencerResidual = 0;
|
||||
|
||||
m_DEBUG_NumSequenceAlloc = 0;
|
||||
m_DEBUG_NumSequenceFreed = 0;
|
||||
m_DEBUG_NumSequenceResidual = 0;
|
||||
|
||||
#endif
|
||||
|
||||
m_ulBufferCurPos = 0;
|
||||
m_ulBytesRead = 0;
|
||||
m_byBuffer = NULL;
|
||||
}
|
||||
|
||||
CIcarus::~CIcarus()
|
||||
{
|
||||
Delete();
|
||||
}
|
||||
|
||||
#if defined (_DEBUG) && defined (_WIN32)
|
||||
#include "../qcommon/platform.h" // for OutputDebugString
|
||||
#endif
|
||||
|
||||
void CIcarus::Delete( void )
|
||||
{
|
||||
|
||||
Free();
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
||||
char buffer[1024];
|
||||
|
||||
OutputDebugString( "\nICARUS Instance Debug Info:\n---------------------------\n" );
|
||||
|
||||
sprintf( (char *) buffer, "Sequencers Allocated:\t%d\n", m_DEBUG_NumSequencerAlloc );
|
||||
OutputDebugString( (const char *) &buffer );
|
||||
|
||||
sprintf( (char *) buffer, "Sequencers Freed:\t\t%d\n", m_DEBUG_NumSequencerFreed );
|
||||
OutputDebugString( (const char *) &buffer );
|
||||
|
||||
sprintf( (char *) buffer, "Sequencers Residual:\t%d\n\n", m_DEBUG_NumSequencerResidual );
|
||||
OutputDebugString( (const char *) &buffer );
|
||||
|
||||
sprintf( (char *) buffer, "Sequences Allocated:\t%d\n", m_DEBUG_NumSequenceAlloc );
|
||||
OutputDebugString( (const char *) &buffer );
|
||||
|
||||
sprintf( (char *) buffer, "Sequences Freed:\t\t%d\n", m_DEBUG_NumSequenceFreed );
|
||||
OutputDebugString( (const char *) &buffer );
|
||||
|
||||
sprintf( (char *) buffer, "Sequences Residual:\t\t%d\n\n", m_DEBUG_NumSequenceResidual );
|
||||
OutputDebugString( (const char *) &buffer );
|
||||
|
||||
OutputDebugString( "\n" );
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void CIcarus::Signal( const char *identifier )
|
||||
{
|
||||
m_signals[ identifier ] = 1;
|
||||
}
|
||||
|
||||
bool CIcarus::CheckSignal( const char *identifier )
|
||||
{
|
||||
signal_m::iterator smi;
|
||||
|
||||
smi = m_signals.find( identifier );
|
||||
|
||||
if ( smi == m_signals.end() )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CIcarus::ClearSignal( const char *identifier )
|
||||
{
|
||||
m_signals.erase( identifier );
|
||||
}
|
||||
|
||||
void CIcarus::Free( void )
|
||||
{
|
||||
sequencer_l::iterator sri;
|
||||
|
||||
//Delete any residual sequencers
|
||||
STL_ITERATE( sri, m_sequencers )
|
||||
{
|
||||
(*sri)->Free(this);
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
||||
m_DEBUG_NumSequencerResidual++;
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
m_sequencers.clear();
|
||||
m_signals.clear();
|
||||
|
||||
sequence_l::iterator si;
|
||||
|
||||
//Delete any residual sequences
|
||||
STL_ITERATE( si, m_sequences )
|
||||
{
|
||||
(*si)->Delete(this);
|
||||
delete (*si);
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
||||
m_DEBUG_NumSequenceResidual++;
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
m_sequences.clear();
|
||||
|
||||
m_sequencerMap.clear();
|
||||
}
|
||||
|
||||
int CIcarus::GetIcarusID( int gameID )
|
||||
{
|
||||
CSequencer *sequencer = CSequencer::Create();
|
||||
CTaskManager *taskManager = CTaskManager::Create();
|
||||
|
||||
sequencer->Init( gameID, taskManager );
|
||||
|
||||
taskManager->Init( sequencer );
|
||||
|
||||
STL_INSERT( m_sequencers, sequencer );
|
||||
|
||||
m_sequencerMap[sequencer->GetID()] = sequencer;
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
||||
m_DEBUG_NumSequencerAlloc++;
|
||||
|
||||
#endif
|
||||
|
||||
return sequencer->GetID();
|
||||
}
|
||||
|
||||
void CIcarus::DeleteIcarusID( int& icarusID )
|
||||
{
|
||||
CSequencer* sequencer = FindSequencer(icarusID);
|
||||
if(!sequencer)
|
||||
{
|
||||
icarusID = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
CTaskManager *taskManager = sequencer->GetTaskManager();
|
||||
if (taskManager->IsResident())
|
||||
{
|
||||
IGameInterface::GetGame()->DebugPrint( IGameInterface::WL_ERROR, "Refusing DeleteIcarusID(%d) because it is running!\n", icarusID);
|
||||
assert(0);
|
||||
return;
|
||||
}
|
||||
|
||||
m_sequencerMap.erase(icarusID);
|
||||
|
||||
// added 2/12/2 to properly delete blocks that were passed to the task manager
|
||||
sequencer->Recall(this);
|
||||
|
||||
|
||||
if ( taskManager )
|
||||
{
|
||||
taskManager->Free();
|
||||
delete taskManager;
|
||||
}
|
||||
|
||||
m_sequencers.remove( sequencer );
|
||||
|
||||
sequencer->Free(this);
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
||||
m_DEBUG_NumSequencerFreed++;
|
||||
|
||||
#endif
|
||||
icarusID = -1;
|
||||
}
|
||||
|
||||
CSequence *CIcarus::GetSequence( void )
|
||||
{
|
||||
CSequence *sequence = CSequence::Create();
|
||||
|
||||
//Assign the GUID
|
||||
sequence->SetID( m_GUID++ );
|
||||
|
||||
STL_INSERT( m_sequences, sequence );
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
||||
m_DEBUG_NumSequenceAlloc++;
|
||||
|
||||
#endif
|
||||
|
||||
return sequence;
|
||||
}
|
||||
|
||||
CSequence *CIcarus::GetSequence( int id )
|
||||
{
|
||||
sequence_l::iterator si;
|
||||
STL_ITERATE( si, m_sequences )
|
||||
{
|
||||
if ( (*si)->GetID() == id )
|
||||
return (*si);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CIcarus::DeleteSequence( CSequence *sequence )
|
||||
{
|
||||
m_sequences.remove( sequence );
|
||||
|
||||
sequence->Delete(this);
|
||||
delete sequence;
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
||||
m_DEBUG_NumSequenceFreed++;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
int CIcarus::AllocateSequences( int numSequences, int *idTable )
|
||||
{
|
||||
CSequence *sequence;
|
||||
|
||||
for ( int i = 0; i < numSequences; i++ )
|
||||
{
|
||||
//If the GUID of this sequence is higher than the current, take this a the "current" GUID
|
||||
if ( idTable[i] > m_GUID )
|
||||
m_GUID = idTable[i];
|
||||
|
||||
//Allocate the container sequence
|
||||
if ( ( sequence = GetSequence() ) == NULL )
|
||||
return false;
|
||||
|
||||
//Override the given GUID with the real one
|
||||
sequence->SetID( idTable[i] );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CIcarus::Precache(char* buffer, long length)
|
||||
{
|
||||
IGameInterface* game = IGameInterface::GetGame(m_flavor);
|
||||
CBlockStream stream;
|
||||
CBlockMember *blockMember;
|
||||
CBlock block;
|
||||
|
||||
if ( stream.Open( buffer, length ) == 0 )
|
||||
return;
|
||||
|
||||
const char *sVal1, *sVal2;
|
||||
|
||||
//Now iterate through all blocks of the script, searching for keywords
|
||||
while ( stream.BlockAvailable() )
|
||||
{
|
||||
//Get a block
|
||||
if ( stream.ReadBlock( &block, this ) == 0 )
|
||||
return;
|
||||
|
||||
//Determine what type of block this is
|
||||
switch( block.GetBlockID() )
|
||||
{
|
||||
case ID_CAMERA: // to cache ROFF files
|
||||
{
|
||||
float f = *(float *) block.GetMemberData( 0 );
|
||||
|
||||
if (f == TYPE_PATH)
|
||||
{
|
||||
sVal1 = (const char *) block.GetMemberData( 1 );
|
||||
|
||||
game->PrecacheRoff(sVal1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ID_PLAY: // to cache ROFF files
|
||||
|
||||
sVal1 = (const char *) block.GetMemberData( 0 );
|
||||
|
||||
if (!stricmp(sVal1,"PLAY_ROFF"))
|
||||
{
|
||||
sVal1 = (const char *) block.GetMemberData( 1 );
|
||||
|
||||
game->PrecacheRoff(sVal1);
|
||||
}
|
||||
break;
|
||||
|
||||
//Run commands
|
||||
case ID_RUN:
|
||||
sVal1 = (const char *) block.GetMemberData( 0 );
|
||||
game->PrecacheScript( sVal1 );
|
||||
break;
|
||||
|
||||
case ID_SOUND:
|
||||
sVal1 = (const char *) block.GetMemberData( 1 ); //0 is channel, 1 is filename
|
||||
game->PrecacheSound(sVal1);
|
||||
break;
|
||||
|
||||
case ID_SET:
|
||||
blockMember = block.GetMember( 0 );
|
||||
|
||||
//NOTENOTE: This will not catch special case get() inlines! (There's not really a good way to do that)
|
||||
|
||||
//Make sure we're testing against strings
|
||||
if ( blockMember->GetID() == TK_STRING )
|
||||
{
|
||||
sVal1 = (const char *) block.GetMemberData( 0 );
|
||||
sVal2 = (const char *) block.GetMemberData( 1 );
|
||||
|
||||
game->PrecacheFromSet( sVal1 , sVal2);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
//Clean out the block for the next pass
|
||||
block.Free(this);
|
||||
}
|
||||
|
||||
//All done
|
||||
stream.Free();
|
||||
}
|
||||
|
||||
CSequencer* CIcarus::FindSequencer(int sequencerID)
|
||||
{
|
||||
sequencer_m::iterator mi = m_sequencerMap.find( sequencerID );
|
||||
|
||||
if ( mi == m_sequencerMap.end() )
|
||||
return NULL;
|
||||
|
||||
return (*mi).second;
|
||||
}
|
||||
|
||||
int CIcarus::Run(int icarusID, char* buffer, long length)
|
||||
{
|
||||
CSequencer* sequencer = FindSequencer(icarusID);
|
||||
if(sequencer)
|
||||
{
|
||||
return sequencer->Run(buffer, length, this);
|
||||
}
|
||||
return ICARUS_INVALID;
|
||||
}
|
||||
|
||||
int CIcarus::SaveSequenceIDTable()
|
||||
{
|
||||
//Save out the number of sequences to follow
|
||||
int numSequences = m_sequences.size();
|
||||
|
||||
BufferWrite( &numSequences, sizeof( numSequences ) );
|
||||
|
||||
//Sequences are saved first, by ID and information
|
||||
sequence_l::iterator sqi;
|
||||
|
||||
//First pass, save all sequences ID for reconstruction
|
||||
int *idTable = new int[ numSequences ];
|
||||
int itr = 0;
|
||||
|
||||
if ( idTable == NULL )
|
||||
return false;
|
||||
|
||||
STL_ITERATE( sqi, m_sequences )
|
||||
{
|
||||
idTable[itr++] = (*sqi)->GetID();
|
||||
}
|
||||
|
||||
//game->WriteSaveData( 'SQTB', idTable, sizeof( int ) * numSequences );
|
||||
BufferWrite( idTable, sizeof( int ) * numSequences );
|
||||
|
||||
delete[] idTable;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int CIcarus::SaveSequences()
|
||||
{
|
||||
//Save out a listing of all the used sequences by ID
|
||||
SaveSequenceIDTable();
|
||||
|
||||
//Save all the information in order
|
||||
sequence_l::iterator sqi;
|
||||
STL_ITERATE( sqi, m_sequences )
|
||||
{
|
||||
(*sqi)->Save();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int CIcarus::SaveSequencers()
|
||||
{
|
||||
//Save out the number of sequences to follow
|
||||
int numSequencers = m_sequencers.size();
|
||||
BufferWrite( &numSequencers, sizeof( numSequencers ) );
|
||||
|
||||
//The sequencers are then saved
|
||||
int sequencessaved = 0;
|
||||
sequencer_l::iterator si;
|
||||
STL_ITERATE( si, m_sequencers )
|
||||
{
|
||||
(*si)->Save();
|
||||
sequencessaved++;
|
||||
}
|
||||
|
||||
assert( sequencessaved == numSequencers );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int CIcarus::SaveSignals()
|
||||
{
|
||||
int numSignals = m_signals.size();
|
||||
|
||||
//game->WriteSaveData( 'ISIG', &numSignals, sizeof( numSignals ) );
|
||||
BufferWrite( &numSignals, sizeof( numSignals ) );
|
||||
|
||||
signal_m::iterator si;
|
||||
STL_ITERATE( si, m_signals )
|
||||
{
|
||||
//game->WriteSaveData( 'ISIG', &numSignals, sizeof( numSignals ) );
|
||||
const char *name = ((*si).first).c_str();
|
||||
|
||||
int length = strlen( name ) + 1;
|
||||
|
||||
//Save out the string size
|
||||
BufferWrite( &length, sizeof( length ) );
|
||||
|
||||
//Write out the string
|
||||
BufferWrite( (void *) name, length );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Get the current Game flavor.
|
||||
int CIcarus::GetFlavor()
|
||||
{
|
||||
return m_flavor;
|
||||
}
|
||||
|
||||
int CIcarus::Save()
|
||||
{
|
||||
// Allocate the temporary buffer.
|
||||
CreateBuffer();
|
||||
|
||||
IGameInterface* game = IGameInterface::GetGame(m_flavor);
|
||||
|
||||
//Save out a ICARUS save block header with the ICARUS version
|
||||
double version = ICARUS_VERSION;
|
||||
game->WriteSaveData( 'ICAR', &version, sizeof( version ) );
|
||||
|
||||
//Save out the signals
|
||||
if ( SaveSignals() == false )
|
||||
{
|
||||
DestroyBuffer();
|
||||
return false;
|
||||
}
|
||||
|
||||
//Save out the sequences
|
||||
if ( SaveSequences() == false )
|
||||
{
|
||||
DestroyBuffer();
|
||||
return false;
|
||||
}
|
||||
|
||||
//Save out the sequencers
|
||||
if ( SaveSequencers() == false )
|
||||
{
|
||||
DestroyBuffer();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Write out the buffer with all our collected data.
|
||||
game->WriteSaveData( 'ISEQ', m_byBuffer, m_ulBufferCurPos );
|
||||
|
||||
// De-allocate the temporary buffer.
|
||||
DestroyBuffer();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int CIcarus::LoadSignals()
|
||||
{
|
||||
int numSignals;
|
||||
|
||||
BufferRead( &numSignals, sizeof( numSignals ) );
|
||||
|
||||
for ( int i = 0; i < numSignals; i++ )
|
||||
{
|
||||
char buffer[1024];
|
||||
int length;
|
||||
|
||||
//Get the size of the string
|
||||
BufferRead( &length, sizeof( length ) );
|
||||
|
||||
//Get the string
|
||||
BufferRead( &buffer, length );
|
||||
|
||||
//Turn it on and add it to the system
|
||||
Signal( (const char *) &buffer );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int CIcarus::LoadSequence()
|
||||
{
|
||||
CSequence *sequence = GetSequence();
|
||||
|
||||
//Load the sequence back in
|
||||
sequence->Load(this);
|
||||
|
||||
//If this sequence had a higher GUID than the current, save it
|
||||
if ( sequence->GetID() > m_GUID )
|
||||
m_GUID = sequence->GetID();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int CIcarus::LoadSequences()
|
||||
{
|
||||
CSequence *sequence;
|
||||
int numSequences;
|
||||
|
||||
//Get the number of sequences to read in
|
||||
BufferRead( &numSequences, sizeof( numSequences ) );
|
||||
|
||||
int *idTable = new int[ numSequences ];
|
||||
|
||||
if ( idTable == NULL )
|
||||
return false;
|
||||
|
||||
//Load the sequencer ID table
|
||||
BufferRead( idTable, sizeof( int ) * numSequences );
|
||||
|
||||
//First pass, allocate all container sequences and give them their proper IDs
|
||||
if ( AllocateSequences( numSequences, idTable ) == false )
|
||||
return false;
|
||||
|
||||
//Second pass, load all sequences
|
||||
for ( int i = 0; i < numSequences; i++ )
|
||||
{
|
||||
//Get the proper sequence for this load
|
||||
if ( ( sequence = GetSequence( idTable[i] ) ) == NULL )
|
||||
return false;
|
||||
|
||||
//Load the sequence
|
||||
if ( ( sequence->Load(this) ) == false )
|
||||
return false;
|
||||
}
|
||||
|
||||
//Free the idTable
|
||||
delete[] idTable;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int CIcarus::LoadSequencers()
|
||||
{
|
||||
CSequencer *sequencer;
|
||||
int numSequencers;
|
||||
IGameInterface* game = IGameInterface::GetGame(m_flavor);
|
||||
|
||||
//Get the number of sequencers to load
|
||||
BufferRead( &numSequencers, sizeof( numSequencers ) );
|
||||
|
||||
//Load all sequencers
|
||||
for ( int i = 0; i < numSequencers; i++ )
|
||||
{
|
||||
//NOTENOTE: The ownerID will be replaced in the loading process
|
||||
int sequencerID = GetIcarusID(-1);
|
||||
if ( ( sequencer = FindSequencer(sequencerID) ) == NULL )
|
||||
return false;
|
||||
|
||||
if ( sequencer->Load(this, game) == false )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int CIcarus::Load()
|
||||
{
|
||||
CreateBuffer();
|
||||
|
||||
IGameInterface* game = IGameInterface::GetGame(m_flavor);
|
||||
|
||||
//Clear out any old information
|
||||
Free();
|
||||
|
||||
//Check to make sure we're at the ICARUS save block
|
||||
double version;
|
||||
game->ReadSaveData( 'ICAR', &version, sizeof( version ) );
|
||||
|
||||
//Versions must match!
|
||||
if ( version != ICARUS_VERSION )
|
||||
{
|
||||
DestroyBuffer();
|
||||
game->DebugPrint( IGameInterface::WL_ERROR, "save game data contains outdated ICARUS version information!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read into the buffer all our data.
|
||||
/*m_ulBytesAvailable = */game->ReadSaveData( 'ISEQ', m_byBuffer, 0 ); //fixme, use real buff size
|
||||
|
||||
//Load all signals
|
||||
if ( LoadSignals() == false )
|
||||
{
|
||||
DestroyBuffer();
|
||||
game->DebugPrint( IGameInterface::WL_ERROR, "failed to load signals from save game!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
//Load in all sequences
|
||||
if ( LoadSequences() == false )
|
||||
{
|
||||
DestroyBuffer();
|
||||
game->DebugPrint( IGameInterface::WL_ERROR, "failed to load sequences from save game!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
//Load in all sequencers
|
||||
if ( LoadSequencers() == false )
|
||||
{
|
||||
DestroyBuffer();
|
||||
game->DebugPrint( IGameInterface::WL_ERROR, "failed to load sequencers from save game!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
DestroyBuffer();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int CIcarus::Update(int icarusID)
|
||||
{
|
||||
CSequencer* sequencer = FindSequencer(icarusID);
|
||||
if(sequencer)
|
||||
{
|
||||
return sequencer->GetTaskManager()->Update(this);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int CIcarus::IsRunning(int icarusID)
|
||||
{
|
||||
CSequencer* sequencer = FindSequencer(icarusID);
|
||||
if(sequencer)
|
||||
{
|
||||
return sequencer->GetTaskManager()->IsRunning();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CIcarus::Completed( int icarusID, int taskID )
|
||||
{
|
||||
CSequencer* sequencer = FindSequencer(icarusID);
|
||||
if(sequencer)
|
||||
{
|
||||
sequencer->GetTaskManager()->Completed(taskID);
|
||||
}
|
||||
}
|
||||
|
||||
// Destroy the File Buffer.
|
||||
void CIcarus::DestroyBuffer()
|
||||
{
|
||||
if ( m_byBuffer )
|
||||
{
|
||||
IGameInterface::GetGame()->Free( m_byBuffer );
|
||||
m_byBuffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Create the File Buffer.
|
||||
void CIcarus::CreateBuffer()
|
||||
{
|
||||
DestroyBuffer();
|
||||
m_byBuffer = (unsigned char *)IGameInterface::GetGame()->Malloc( MAX_BUFFER_SIZE );
|
||||
m_ulBufferCurPos = 0;
|
||||
}
|
||||
|
||||
// Write to a buffer.
|
||||
void CIcarus::BufferWrite( void *pSrcData, unsigned long ulNumBytesToWrite )
|
||||
{
|
||||
if ( !pSrcData )
|
||||
return;
|
||||
|
||||
// Make sure we have enough space in the buffer to write to.
|
||||
if ( MAX_BUFFER_SIZE - m_ulBufferCurPos < ulNumBytesToWrite )
|
||||
{ // Write out the buffer with all our collected data so far...
|
||||
IGameInterface::GetGame()->DebugPrint( IGameInterface::WL_ERROR, "BufferWrite: Out of buffer space, Flushing." );
|
||||
IGameInterface::GetGame()->WriteSaveData( 'ISEQ', m_byBuffer, m_ulBufferCurPos );
|
||||
m_ulBufferCurPos = 0; //reset buffer
|
||||
}
|
||||
|
||||
assert( MAX_BUFFER_SIZE - m_ulBufferCurPos >= ulNumBytesToWrite );
|
||||
{
|
||||
memcpy( m_byBuffer + m_ulBufferCurPos, pSrcData, ulNumBytesToWrite );
|
||||
m_ulBufferCurPos += ulNumBytesToWrite;
|
||||
}
|
||||
}
|
||||
|
||||
// Read from a buffer.
|
||||
void CIcarus::BufferRead( void *pDstBuff, unsigned long ulNumBytesToRead )
|
||||
{
|
||||
if ( !pDstBuff )
|
||||
return;
|
||||
|
||||
// If we can read this data...
|
||||
if ( m_ulBytesRead + ulNumBytesToRead > MAX_BUFFER_SIZE )
|
||||
{// We've tried to read past the buffer...
|
||||
IGameInterface::GetGame()->DebugPrint( IGameInterface::WL_ERROR, "BufferRead: Buffer underflow, Looking for new block." );
|
||||
// Read in the next block.
|
||||
/*m_ulBytesAvailable = */IGameInterface::GetGame()->ReadSaveData( 'ISEQ', m_byBuffer, 0 ); //FIXME, to actually check underflows, use real buff size
|
||||
m_ulBytesRead = 0; //reset buffer
|
||||
}
|
||||
|
||||
assert(m_ulBytesRead + ulNumBytesToRead <= MAX_BUFFER_SIZE);
|
||||
{
|
||||
memcpy( pDstBuff, m_byBuffer + m_ulBytesRead, ulNumBytesToRead );
|
||||
m_ulBytesRead += ulNumBytesToRead;
|
||||
}
|
||||
}
|
||||
253
code/icarus/IcarusImplementation.h
Normal file
253
code/icarus/IcarusImplementation.h
Normal file
@@ -0,0 +1,253 @@
|
||||
// IcarusImplementation.h
|
||||
#ifndef ICARUSIMPLEMENTATION_DEFINED
|
||||
#define ICARUSIMPLEMENTATION_DEFINED
|
||||
|
||||
#ifndef ICARUSINTERFACE_DEFINED
|
||||
#include "IcarusInterface.h"
|
||||
#endif
|
||||
|
||||
#pragma warning( disable : 4786 ) // identifier was truncated
|
||||
#pragma warning (push, 3) // go back down to 3 for the stl include
|
||||
#pragma warning (disable:4503) // decorated name length xceeded, name was truncated
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <list>
|
||||
#include <algorithm>
|
||||
#pragma warning (pop)
|
||||
#pragma warning (disable:4503) // decorated name length xceeded, name was truncated
|
||||
using namespace std;
|
||||
|
||||
|
||||
class CSequence;
|
||||
class CSequencer;
|
||||
|
||||
class CIcarusSequencer;
|
||||
class CIcarusSequence;
|
||||
|
||||
class CIcarus : public IIcarusInterface
|
||||
{
|
||||
public:
|
||||
CIcarus(int flavor);
|
||||
virtual ~CIcarus();
|
||||
|
||||
inline IGameInterface* GetGame() {return IGameInterface::GetGame(m_flavor);};
|
||||
|
||||
enum
|
||||
{
|
||||
MAX_STRING_SIZE = 256,
|
||||
MAX_FILENAME_LENGTH = 1024,
|
||||
};
|
||||
|
||||
protected:
|
||||
int m_flavor;
|
||||
int m_nextSequencerID;
|
||||
|
||||
int m_GUID;
|
||||
|
||||
typedef list< CSequence * > sequence_l;
|
||||
typedef list< CSequencer * > sequencer_l;
|
||||
typedef map < int, CSequencer* > sequencer_m;
|
||||
|
||||
sequence_l m_sequences;
|
||||
sequencer_l m_sequencers;
|
||||
sequencer_m m_sequencerMap;
|
||||
|
||||
typedef map < string, unsigned char > signal_m;
|
||||
signal_m m_signals;
|
||||
|
||||
static double ICARUS_VERSION;
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
||||
int m_DEBUG_NumSequencerAlloc;
|
||||
int m_DEBUG_NumSequencerFreed;
|
||||
int m_DEBUG_NumSequencerResidual;
|
||||
|
||||
int m_DEBUG_NumSequenceAlloc;
|
||||
int m_DEBUG_NumSequenceFreed;
|
||||
int m_DEBUG_NumSequenceResidual;
|
||||
|
||||
#endif
|
||||
|
||||
public:
|
||||
static int s_flavorsAvailable;
|
||||
static CIcarus** s_instances;
|
||||
|
||||
// mandatory overrides
|
||||
// Get the current Game flavor.
|
||||
int GetFlavor();
|
||||
|
||||
int Save();
|
||||
int Load();
|
||||
int Run(int icarusID, char* buffer, long length);
|
||||
void DeleteIcarusID(int& icarusID);
|
||||
int GetIcarusID(int ownerID);
|
||||
int Update(int icarusID);
|
||||
|
||||
int IsRunning(int icarusID);
|
||||
void Completed( int icarusID, int taskID );
|
||||
void Precache(char* buffer, long length);
|
||||
|
||||
protected:
|
||||
void Delete();
|
||||
void Free();
|
||||
|
||||
public:
|
||||
CSequence* GetSequence(int id);
|
||||
void DeleteSequence( CSequence *sequence );
|
||||
int AllocateSequences( int numSequences, int *idTable );
|
||||
CSequencer* FindSequencer(int sequencerID);
|
||||
CSequence* GetSequence();
|
||||
|
||||
protected:
|
||||
int SaveSequenceIDTable();
|
||||
int SaveSequences();
|
||||
int SaveSequencers();
|
||||
int SaveSignals();
|
||||
|
||||
int LoadSignals();
|
||||
int LoadSequence();
|
||||
int LoadSequences();
|
||||
int LoadSequencers();
|
||||
|
||||
public:
|
||||
void Signal( const char *identifier );
|
||||
bool CheckSignal( const char *identifier );
|
||||
void ClearSignal( const char *identifier );
|
||||
|
||||
// Overloaded new operator.
|
||||
inline void *operator new( size_t size )
|
||||
{
|
||||
return IGameInterface::GetGame()->Malloc( size );
|
||||
}
|
||||
|
||||
// Overloaded delete operator.
|
||||
inline void operator delete( void *pRawData )
|
||||
{
|
||||
// Free the Memory.
|
||||
IGameInterface::GetGame()->Free( pRawData );
|
||||
}
|
||||
|
||||
public:
|
||||
enum
|
||||
{
|
||||
TK_EOF = -1,
|
||||
TK_UNDEFINED,
|
||||
TK_COMMENT,
|
||||
TK_EOL,
|
||||
TK_CHAR,
|
||||
TK_STRING,
|
||||
TK_INT,
|
||||
TK_INTEGER = TK_INT,
|
||||
TK_FLOAT,
|
||||
TK_IDENTIFIER,
|
||||
TK_USERDEF,
|
||||
TK_BLOCK_START = TK_USERDEF,
|
||||
TK_BLOCK_END,
|
||||
TK_VECTOR_START,
|
||||
TK_VECTOR_END,
|
||||
TK_OPEN_PARENTHESIS,
|
||||
TK_CLOSED_PARENTHESIS,
|
||||
TK_VECTOR,
|
||||
TK_GREATER_THAN,
|
||||
TK_LESS_THAN,
|
||||
TK_EQUALS,
|
||||
TK_NOT,
|
||||
|
||||
NUM_USER_TOKENS
|
||||
};
|
||||
|
||||
//ID defines
|
||||
enum
|
||||
{
|
||||
ID_AFFECT = NUM_USER_TOKENS,
|
||||
ID_SOUND,
|
||||
ID_MOVE,
|
||||
ID_ROTATE,
|
||||
ID_WAIT,
|
||||
ID_BLOCK_START,
|
||||
ID_BLOCK_END,
|
||||
ID_SET,
|
||||
ID_LOOP,
|
||||
ID_LOOPEND,
|
||||
ID_PRINT,
|
||||
ID_USE,
|
||||
ID_FLUSH,
|
||||
ID_RUN,
|
||||
ID_KILL,
|
||||
ID_REMOVE,
|
||||
ID_CAMERA,
|
||||
ID_GET,
|
||||
ID_RANDOM,
|
||||
ID_IF,
|
||||
ID_ELSE,
|
||||
ID_REM,
|
||||
ID_TASK,
|
||||
ID_DO,
|
||||
ID_DECLARE,
|
||||
ID_FREE,
|
||||
ID_DOWAIT,
|
||||
ID_SIGNAL,
|
||||
ID_WAITSIGNAL,
|
||||
ID_PLAY,
|
||||
|
||||
ID_TAG,
|
||||
ID_EOF,
|
||||
NUM_IDS
|
||||
};
|
||||
|
||||
//Type defines
|
||||
enum
|
||||
{
|
||||
//Wait types
|
||||
TYPE_WAIT_COMPLETE = NUM_IDS,
|
||||
TYPE_WAIT_TRIGGERED,
|
||||
|
||||
//Set types
|
||||
TYPE_ANGLES,
|
||||
TYPE_ORIGIN,
|
||||
|
||||
//Affect types
|
||||
TYPE_INSERT,
|
||||
TYPE_FLUSH,
|
||||
|
||||
//Camera types
|
||||
TYPE_PAN,
|
||||
TYPE_ZOOM,
|
||||
TYPE_MOVE,
|
||||
TYPE_FADE,
|
||||
TYPE_PATH,
|
||||
TYPE_ENABLE,
|
||||
TYPE_DISABLE,
|
||||
TYPE_SHAKE,
|
||||
TYPE_ROLL,
|
||||
TYPE_TRACK,
|
||||
TYPE_DISTANCE,
|
||||
TYPE_FOLLOW,
|
||||
|
||||
//Variable type
|
||||
TYPE_VARIABLE,
|
||||
|
||||
TYPE_EOF,
|
||||
NUM_TYPES
|
||||
};
|
||||
|
||||
// Used by the new Icarus Save code.
|
||||
enum { MAX_BUFFER_SIZE = 100000 };
|
||||
unsigned long m_ulBufferCurPos;
|
||||
unsigned long m_ulBytesRead;
|
||||
unsigned char *m_byBuffer;
|
||||
// Destroy the File Buffer.
|
||||
void DestroyBuffer();
|
||||
// Create the File Buffer.
|
||||
void CreateBuffer();
|
||||
// Reset the buffer completely.
|
||||
void ResetBuffer();
|
||||
// Write to a buffer.
|
||||
void BufferWrite( void *pSrcData, unsigned long ulNumBytesToWrite );
|
||||
// Read from a buffer.
|
||||
void BufferRead( void *pDstBuff, unsigned long ulNumBytesToRead );
|
||||
};
|
||||
|
||||
#endif
|
||||
143
code/icarus/IcarusInterface.h
Normal file
143
code/icarus/IcarusInterface.h
Normal file
@@ -0,0 +1,143 @@
|
||||
#pragma once
|
||||
#ifndef ICARUSINTERFACE_DEFINED
|
||||
#define ICARUSINTERFACE_DEFINED
|
||||
|
||||
// IcarusInterface.h: ICARUS Interface header file.
|
||||
// -Date: ~October, 2002
|
||||
// -Created by: Mike Crowns and Aurelio Reis.
|
||||
// -Description: The new interface between a Game Engine and the Icarus Scripting Language.
|
||||
// An Interface is an Abstract Base Class with pure virtual members that MUST be implemented
|
||||
// in order for the compile to succeed. Because of this, all needed functionality can be
|
||||
// added without compromising other core systems.
|
||||
// -Usage: To use the new Icarus Interface, two classes must be derived. The first is the
|
||||
// actual Icarus Interface class which contains all relevent functionality to the scripting
|
||||
// system. The second is the Game Interface which is very much more broad and thus implemented
|
||||
// by the user. Icarus functions by calling the Game Interface to do certain tasks for it. This
|
||||
// is why the Game Interface is required to have certain functions implemented.
|
||||
|
||||
|
||||
// The basic Icarus Interface ABC.
|
||||
class IIcarusInterface
|
||||
{
|
||||
public:
|
||||
enum { ICARUS_INVALID = 0 };
|
||||
virtual ~IIcarusInterface();
|
||||
|
||||
// Get a static singleton instance (of a specific flavor).
|
||||
static IIcarusInterface* GetIcarus(int flavor = 0,bool constructIfNecessary=true); // must be implemented along with concrete class
|
||||
static void DestroyIcarus(); // Destroy the static singleton instance.
|
||||
|
||||
virtual int GetFlavor() = 0;
|
||||
|
||||
virtual int Save() = 0; // Save all Icarus states.
|
||||
virtual int Load() = 0; // Load all Icarus states.
|
||||
|
||||
virtual int Run(int icarusID, char* buffer, long length) = 0; // Execute a script.
|
||||
virtual void DeleteIcarusID(int &icarusID) = 0; // Delete an Icarus ID from the list (making the ID Invalid on the other end through reference).
|
||||
virtual int GetIcarusID(int gameID) = 0; // Get an Icarus ID.
|
||||
virtual int Update( int icarusID ) = 0; // Update all internal Icarus structures.
|
||||
virtual int IsRunning( int icarusID ) = 0; // Whether a Icarus is running or not.
|
||||
virtual void Completed( int icarusID, int taskID ) = 0; // Tells Icarus a task is completed.
|
||||
virtual void Precache( char* buffer, long length ) = 0; // Precache a Script in memory.
|
||||
};
|
||||
|
||||
// Description: The Game Interface is used by the Icarus Interface to access specific
|
||||
// data or initiate certain things within the engine being used. It is made to be
|
||||
// as generic as possible to allow any engine to derive it's own interface for use.
|
||||
// Created: 10/08/02 by Aurelio Reis.
|
||||
class IGameInterface
|
||||
{
|
||||
protected:
|
||||
// Pure Virtual Destructor.
|
||||
virtual ~IGameInterface();
|
||||
|
||||
public:
|
||||
//For system-wide prints
|
||||
enum e_DebugPrintLevel { WL_ERROR = 1, WL_WARNING, WL_VERBOSE, WL_DEBUG };
|
||||
|
||||
// How many flavors are needed.
|
||||
static int s_IcarusFlavorsNeeded;
|
||||
|
||||
// Get a static singleton instance (of a specific flavor).
|
||||
static IGameInterface *GetGame( int flavor = 0 );
|
||||
|
||||
// Destroy the static singleton instance (NOTE: Destroy the Game Interface BEFORE the Icarus Interface).
|
||||
static void Destroy();
|
||||
|
||||
// General
|
||||
// Load a script File into the destination buffer. If the script has already been loaded
|
||||
// NOTE: This is what was called before:
|
||||
/*
|
||||
// Description : Reads in a file and attaches the script directory properly
|
||||
extern int ICARUS_GetScript( const char *name, char **buf ); //g_icarus.cpp
|
||||
static int Q3_ReadScript( const char *name, void **buf )
|
||||
{
|
||||
return ICARUS_GetScript( va( "%s/%s", Q3_SCRIPT_DIR, name ), (char**)buf ); //get a (hopefully) cached file
|
||||
}
|
||||
*/
|
||||
virtual int GetFlavor() = 0;
|
||||
|
||||
virtual int LoadFile( const char *name, void **buf ) = 0;
|
||||
virtual void CenterPrint( const char *format, ... ) = 0;
|
||||
virtual void DebugPrint( e_DebugPrintLevel, const char *, ... ) = 0;
|
||||
virtual unsigned int GetTime( void ) = 0; //Gets the current time
|
||||
virtual int PlaySound( int taskID, int gameID, const char *name, const char *channel ) = 0;
|
||||
virtual void Lerp2Pos( int taskID, int gameID, float origin[3], float angles[3], float duration ) = 0;
|
||||
virtual void Lerp2Angles( int taskID, int gameID, float angles[3], float duration ) = 0;
|
||||
virtual int GetTag( int gameID, const char *name, int lookup, float info[3] ) = 0;
|
||||
virtual void Set( int taskID, int gameID, const char *type_name, const char *data ) = 0;
|
||||
virtual void Use( int gameID, const char *name ) = 0;
|
||||
virtual void Activate( int gameID, const char *name ) = 0;
|
||||
virtual void Deactivate( int gameID, const char *name ) = 0;
|
||||
virtual void Kill( int gameID, const char *name ) = 0;
|
||||
virtual void Remove( int gameID, const char *name ) = 0;
|
||||
virtual float Random( float min, float max ) = 0;
|
||||
virtual void Play( int taskID, int gameID, const char *type, const char *name ) = 0;
|
||||
|
||||
// Camera functions
|
||||
virtual void CameraPan( float angles[3], float dir[3], float duration ) = 0;
|
||||
virtual void CameraMove( float origin[3], float duration ) = 0;
|
||||
virtual void CameraZoom( float fov, float duration ) = 0;
|
||||
virtual void CameraRoll( float angle, float duration ) = 0;
|
||||
virtual void CameraFollow( const char *name, float speed, float initLerp ) = 0;
|
||||
virtual void CameraTrack( const char *name, float speed, float initLerp ) = 0;
|
||||
virtual void CameraDistance( float dist, float initLerp ) = 0;
|
||||
virtual void CameraFade( float sr, float sg, float sb, float sa, float dr, float dg, float db, float da, float duration ) = 0;
|
||||
virtual void CameraPath( const char *name ) = 0;
|
||||
virtual void CameraEnable( void ) = 0;
|
||||
virtual void CameraDisable( void ) = 0;
|
||||
virtual void CameraShake( float intensity, int duration ) = 0;
|
||||
|
||||
virtual int GetFloat( int gameID, const char *name, float *value ) = 0;
|
||||
// Should be float return type?
|
||||
virtual int GetVector( int gameID, const char *name, float value[3] ) = 0;
|
||||
virtual int GetString( int gameID, const char *name, char **value ) = 0;
|
||||
|
||||
virtual int Evaluate( int p1Type, const char *p1, int p2Type, const char *p2, int operatorType ) = 0;
|
||||
|
||||
virtual void DeclareVariable( int type, const char *name ) = 0;
|
||||
virtual void FreeVariable( const char *name ) = 0;
|
||||
|
||||
// Save / Load functions
|
||||
|
||||
virtual int WriteSaveData( unsigned long chid, void *data, int length ) = 0;
|
||||
virtual int ReadSaveData( unsigned long chid, void *address, int length, void **addressptr = NULL ) = 0;
|
||||
virtual int LinkGame( int gameID, int icarusID ) = 0;
|
||||
|
||||
// Access functions
|
||||
|
||||
virtual int CreateIcarus( int gameID) = 0;
|
||||
virtual int GetByName( const char *name ) = 0; //Polls the engine for the sequencer of the entity matching the name passed
|
||||
virtual int IsFrozen(int gameID) = 0; // (g_entities[m_ownerID].svFlags&SVF_ICARUS_FREEZE) // return -1 indicates invalid
|
||||
virtual void Free(void* data) = 0;
|
||||
virtual void* Malloc( int size ) = 0;
|
||||
virtual float MaxFloat(void) = 0;
|
||||
|
||||
// Script precache functions.
|
||||
virtual void PrecacheRoff(const char* name) = 0; // G_LoadRoff
|
||||
virtual void PrecacheScript(const char* name) = 0; // must strip extension COM_StripExtension()
|
||||
virtual void PrecacheSound(const char* name) = 0; // G_SoundIndex
|
||||
virtual void PrecacheFromSet(const char* setname, const char* filename) = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
674
code/icarus/Sequence.cpp
Normal file
674
code/icarus/Sequence.cpp
Normal file
@@ -0,0 +1,674 @@
|
||||
// Script Command Sequences
|
||||
//
|
||||
// -- jweier
|
||||
|
||||
// this include must remain at the top of every Icarus CPP file
|
||||
#include "stdafx.h"
|
||||
#include "IcarusImplementation.h"
|
||||
|
||||
#include "BlockStream.h"
|
||||
#include "Sequence.h"
|
||||
|
||||
#define STL_ITERATE( a, b ) for ( a = b.begin(); a != b.end(); a++ )
|
||||
#define STL_INSERT( a, b ) a.insert( a.end(), b );
|
||||
|
||||
|
||||
inline CSequence::CSequence( void )
|
||||
{
|
||||
m_numCommands = 0;
|
||||
// m_numChildren = 0;
|
||||
m_flags = 0;
|
||||
m_iterations = 1;
|
||||
|
||||
m_parent = NULL;
|
||||
m_return = NULL;
|
||||
}
|
||||
|
||||
CSequence::~CSequence( void )
|
||||
{
|
||||
assert(!m_commands.size());
|
||||
//assert(!m_numChildren);
|
||||
}
|
||||
|
||||
/*
|
||||
-------------------------
|
||||
Create
|
||||
-------------------------
|
||||
*/
|
||||
|
||||
CSequence *CSequence::Create( void )
|
||||
{
|
||||
CSequence *seq = new CSequence;
|
||||
|
||||
//TODO: Emit warning
|
||||
assert(seq);
|
||||
if ( seq == NULL )
|
||||
return NULL;
|
||||
|
||||
seq->SetFlag( SQ_COMMON );
|
||||
|
||||
return seq;
|
||||
}
|
||||
|
||||
/*
|
||||
-------------------------
|
||||
Delete
|
||||
-------------------------
|
||||
*/
|
||||
|
||||
void CSequence::Delete( CIcarus* icarus )
|
||||
{
|
||||
block_l::iterator bi;
|
||||
sequence_l::iterator si;
|
||||
|
||||
//Notify the parent of the deletion
|
||||
if ( m_parent )
|
||||
{
|
||||
m_parent->RemoveChild( this );
|
||||
}
|
||||
|
||||
//Clear all children
|
||||
if ( m_children.size() > 0 )
|
||||
{
|
||||
/*for ( iterSeq = m_childrenMap.begin(); iterSeq != m_childrenMap.end(); iterSeq++ )
|
||||
{
|
||||
(*iterSeq).second->SetParent( NULL );
|
||||
}*/
|
||||
|
||||
for ( si = m_children.begin(); si != m_children.end(); si++ )
|
||||
{
|
||||
(*si)->SetParent( NULL );
|
||||
}
|
||||
}
|
||||
m_children.clear();
|
||||
//m_childrenMap.clear();
|
||||
|
||||
//Clear all held commands
|
||||
for ( bi = m_commands.begin(); bi != m_commands.end(); bi++ )
|
||||
{
|
||||
(*bi)->Free(icarus);
|
||||
delete (*bi); //Free() handled internally -- not any more!!
|
||||
}
|
||||
|
||||
m_commands.clear();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
-------------------------
|
||||
AddChild
|
||||
-------------------------
|
||||
*/
|
||||
|
||||
void CSequence::AddChild( CSequence *child )
|
||||
{
|
||||
assert( child );
|
||||
if ( child == NULL )
|
||||
return;
|
||||
|
||||
m_children.insert( m_children.end(), child );
|
||||
// m_childrenMap[ m_numChildren ] = child;
|
||||
// m_numChildren++;
|
||||
}
|
||||
|
||||
/*
|
||||
-------------------------
|
||||
RemoveChild
|
||||
-------------------------
|
||||
*/
|
||||
|
||||
void CSequence::RemoveChild( CSequence *child )
|
||||
{
|
||||
assert( child );
|
||||
if ( child == NULL )
|
||||
return;
|
||||
|
||||
m_children.remove( child );
|
||||
|
||||
//Remove the child
|
||||
/* sequenceID_m::iterator iterSeq = m_childrenMap.find( child->GetID() );
|
||||
if ( iterSeq != m_childrenMap.end() )
|
||||
{
|
||||
m_childrenMap.erase( iterSeq );
|
||||
}
|
||||
|
||||
m_numChildren--;*/
|
||||
}
|
||||
|
||||
/*
|
||||
-------------------------
|
||||
HasChild
|
||||
-------------------------
|
||||
*/
|
||||
|
||||
bool CSequence::HasChild( CSequence *sequence )
|
||||
{
|
||||
sequence_l::iterator ci;
|
||||
|
||||
for ( ci = m_children.begin(); ci != m_children.end(); ci++ )
|
||||
{
|
||||
if ( (*ci) == sequence )
|
||||
return true;
|
||||
|
||||
if ( (*ci)->HasChild( sequence ) )
|
||||
return true;
|
||||
}
|
||||
|
||||
/* sequenceID_m::iterator iterSeq = NULL;
|
||||
for ( iterSeq = m_childrenMap.begin(); iterSeq != m_childrenMap.end(); iterSeq++ )
|
||||
{
|
||||
if ( ((*iterSeq).second) == sequence )
|
||||
return true;
|
||||
|
||||
if ( (*iterSeq).second->HasChild( sequence ) )
|
||||
return true;
|
||||
}*/
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
-------------------------
|
||||
SetParent
|
||||
-------------------------
|
||||
*/
|
||||
|
||||
void CSequence::SetParent( CSequence *parent )
|
||||
{
|
||||
m_parent = parent;
|
||||
|
||||
if ( parent == NULL )
|
||||
return;
|
||||
|
||||
//Inherit the parent's properties (this avoids messy tree walks later on)
|
||||
if ( parent->m_flags & SQ_RETAIN )
|
||||
m_flags |= SQ_RETAIN;
|
||||
|
||||
if ( parent->m_flags & SQ_PENDING )
|
||||
m_flags |= SQ_PENDING;
|
||||
}
|
||||
|
||||
/*
|
||||
-------------------------
|
||||
PopCommand
|
||||
-------------------------
|
||||
*/
|
||||
|
||||
CBlock *CSequence::PopCommand( int type )
|
||||
{
|
||||
CBlock *command = NULL;
|
||||
|
||||
//Make sure everything is ok
|
||||
assert( (type == POP_FRONT) || (type == POP_BACK) );
|
||||
|
||||
if ( m_commands.empty() )
|
||||
return NULL;
|
||||
|
||||
switch ( type )
|
||||
{
|
||||
case POP_FRONT:
|
||||
|
||||
command = m_commands.front();
|
||||
m_commands.pop_front();
|
||||
m_numCommands--;
|
||||
|
||||
return command;
|
||||
break;
|
||||
|
||||
case POP_BACK:
|
||||
|
||||
command = m_commands.back();
|
||||
m_commands.pop_back();
|
||||
m_numCommands--;
|
||||
|
||||
return command;
|
||||
break;
|
||||
}
|
||||
|
||||
//Invalid flag
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
-------------------------
|
||||
PushCommand
|
||||
-------------------------
|
||||
*/
|
||||
|
||||
int CSequence::PushCommand( CBlock *block, int type )
|
||||
{
|
||||
//Make sure everything is ok
|
||||
assert( (type == PUSH_FRONT) || (type == PUSH_BACK) );
|
||||
assert( block );
|
||||
|
||||
switch ( type )
|
||||
{
|
||||
case PUSH_FRONT:
|
||||
|
||||
m_commands.push_front( block );
|
||||
m_numCommands++;
|
||||
|
||||
return true;
|
||||
break;
|
||||
|
||||
case PUSH_BACK:
|
||||
|
||||
m_commands.push_back( block );
|
||||
m_numCommands++;
|
||||
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
|
||||
//Invalid flag
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
-------------------------
|
||||
SetFlag
|
||||
-------------------------
|
||||
*/
|
||||
|
||||
void CSequence::SetFlag( int flag )
|
||||
{
|
||||
m_flags |= flag;
|
||||
}
|
||||
|
||||
/*
|
||||
-------------------------
|
||||
RemoveFlag
|
||||
-------------------------
|
||||
*/
|
||||
|
||||
void CSequence::RemoveFlag( int flag, bool children )
|
||||
{
|
||||
m_flags &= ~flag;
|
||||
|
||||
if ( children )
|
||||
{
|
||||
/* sequenceID_m::iterator iterSeq = NULL;
|
||||
for ( iterSeq = m_childrenMap.begin(); iterSeq != m_childrenMap.end(); iterSeq++ )
|
||||
{
|
||||
(*iterSeq).second->RemoveFlag( flag, true );
|
||||
}*/
|
||||
|
||||
sequence_l::iterator si;
|
||||
for ( si = m_children.begin(); si != m_children.end(); si++ )
|
||||
{
|
||||
(*si)->RemoveFlag( flag, true );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
-------------------------
|
||||
HasFlag
|
||||
-------------------------
|
||||
*/
|
||||
|
||||
int CSequence::HasFlag( int flag )
|
||||
{
|
||||
return (m_flags & flag);
|
||||
}
|
||||
|
||||
/*
|
||||
-------------------------
|
||||
SetReturn
|
||||
-------------------------
|
||||
*/
|
||||
|
||||
void CSequence::SetReturn ( CSequence *sequence )
|
||||
{
|
||||
assert( sequence != this );
|
||||
m_return = sequence;
|
||||
}
|
||||
|
||||
/*
|
||||
-------------------------
|
||||
GetChildByID
|
||||
-------------------------
|
||||
*/
|
||||
|
||||
CSequence *CSequence::GetChildByID( int id )
|
||||
{
|
||||
if ( id < 0 )
|
||||
return NULL;
|
||||
|
||||
//NOTENOTE: Done for safety reasons, I don't know what this template will return on underflow ( sigh... )
|
||||
/* sequenceID_m::iterator mi = m_childrenMap.find( id );
|
||||
|
||||
if ( mi == m_childrenMap.end() )
|
||||
return NULL;
|
||||
|
||||
return (*mi).second;*/
|
||||
|
||||
sequence_l::iterator iterSeq;
|
||||
STL_ITERATE( iterSeq, m_children )
|
||||
{
|
||||
if ( (*iterSeq)->GetID() == id )
|
||||
return (*iterSeq);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
-------------------------
|
||||
GetChildByIndex
|
||||
-------------------------
|
||||
*/
|
||||
|
||||
CSequence *CSequence::GetChildByIndex( int iIndex )
|
||||
{
|
||||
if ( iIndex < 0 || iIndex >= (int)m_children.size() )
|
||||
return NULL;
|
||||
|
||||
sequence_l::iterator iterSeq = m_children.begin();
|
||||
for ( int i = 0; i < iIndex; i++ )
|
||||
{
|
||||
++iterSeq;
|
||||
}
|
||||
return (*iterSeq);
|
||||
}
|
||||
|
||||
/*
|
||||
-------------------------
|
||||
SaveCommand
|
||||
-------------------------
|
||||
*/
|
||||
|
||||
int CSequence::SaveCommand( CBlock *block )
|
||||
{
|
||||
CIcarus *pIcarus = (CIcarus *)IIcarusInterface::GetIcarus();
|
||||
|
||||
unsigned char flags;
|
||||
int numMembers, bID, size;
|
||||
CBlockMember *bm;
|
||||
|
||||
// Data saved here (IBLK):
|
||||
// Block ID.
|
||||
// Block Flags.
|
||||
// Number of Block Members.
|
||||
// Block Members:
|
||||
// - Block Member ID.
|
||||
// - Block Data Size.
|
||||
// - Block (Raw) Data.
|
||||
|
||||
//Save out the block ID
|
||||
bID = block->GetBlockID();
|
||||
pIcarus->BufferWrite( &bID, sizeof ( bID ) );
|
||||
|
||||
//Save out the block's flags
|
||||
flags = block->GetFlags();
|
||||
pIcarus->BufferWrite( &flags, sizeof ( flags ) );
|
||||
|
||||
//Save out the number of members to read
|
||||
numMembers = block->GetNumMembers();
|
||||
pIcarus->BufferWrite( &numMembers, sizeof ( numMembers ) );
|
||||
|
||||
for ( int i = 0; i < numMembers; i++ )
|
||||
{
|
||||
bm = block->GetMember( i );
|
||||
|
||||
//Save the block id
|
||||
bID = bm->GetID();
|
||||
pIcarus->BufferWrite( &bID, sizeof ( bID ) );
|
||||
|
||||
//Save out the data size
|
||||
size = bm->GetSize();
|
||||
pIcarus->BufferWrite( &size, sizeof ( size ) );
|
||||
|
||||
//Save out the raw data
|
||||
pIcarus->BufferWrite( bm->GetData(), size );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int CSequence::LoadCommand( CBlock *block, CIcarus *icarus )
|
||||
{
|
||||
IGameInterface* game = icarus->GetGame();
|
||||
int bID, bSize;
|
||||
void *bData;
|
||||
unsigned char flags;
|
||||
int id, numMembers;
|
||||
|
||||
// Data expected/loaded here (IBLK) (with the size as : 'IBSZ' ).
|
||||
// Block ID.
|
||||
// Block Flags.
|
||||
// Number of Block Members.
|
||||
// Block Members:
|
||||
// - Block Member ID.
|
||||
// - Block Data Size.
|
||||
// - Block (Raw) Data.
|
||||
|
||||
//Get the block ID.
|
||||
icarus->BufferRead( &id, sizeof( id ) );
|
||||
block->Create( id );
|
||||
|
||||
//Read the block's flags
|
||||
icarus->BufferRead( &flags, sizeof( flags ) );
|
||||
block->SetFlags( flags );
|
||||
|
||||
//Get the number of block members
|
||||
icarus->BufferRead( &numMembers, sizeof( numMembers ) );
|
||||
|
||||
for ( int j = 0; j < numMembers; j++ )
|
||||
{
|
||||
//Get the member ID
|
||||
icarus->BufferRead( &bID, sizeof( bID ) );
|
||||
|
||||
//Get the member size
|
||||
icarus->BufferRead( &bSize, sizeof( bSize ) );
|
||||
|
||||
//Get the member's data
|
||||
if ( ( bData = game->Malloc( bSize ) ) == NULL )
|
||||
return false;
|
||||
|
||||
//Get the actual raw data
|
||||
icarus->BufferRead( bData, bSize );
|
||||
|
||||
//Write out the correct type
|
||||
switch ( bID )
|
||||
{
|
||||
case CIcarus::TK_INT:
|
||||
{
|
||||
assert(0);
|
||||
int data = *(int *) bData;
|
||||
block->Write( CIcarus::TK_FLOAT, (float) data, icarus );
|
||||
}
|
||||
break;
|
||||
|
||||
case CIcarus::TK_FLOAT:
|
||||
block->Write( CIcarus::TK_FLOAT, *(float *) bData, icarus );
|
||||
break;
|
||||
|
||||
case CIcarus::TK_STRING:
|
||||
case CIcarus::TK_IDENTIFIER:
|
||||
case CIcarus::TK_CHAR:
|
||||
block->Write( CIcarus::TK_STRING, (char *) bData, icarus );
|
||||
break;
|
||||
|
||||
case CIcarus::TK_VECTOR:
|
||||
case CIcarus::TK_VECTOR_START:
|
||||
block->Write( CIcarus::TK_VECTOR, *(vec3_t *) bData, icarus );
|
||||
break;
|
||||
|
||||
case CIcarus::ID_TAG:
|
||||
block->Write( CIcarus::ID_TAG, (float) CIcarus::ID_TAG, icarus );
|
||||
break;
|
||||
|
||||
case CIcarus::ID_GET:
|
||||
block->Write( CIcarus::ID_GET, (float) CIcarus::ID_GET, icarus );
|
||||
break;
|
||||
|
||||
case CIcarus::ID_RANDOM:
|
||||
block->Write( CIcarus::ID_RANDOM, *(float *) bData, icarus );//(float) ID_RANDOM );
|
||||
break;
|
||||
|
||||
case CIcarus::TK_EQUALS:
|
||||
case CIcarus::TK_GREATER_THAN:
|
||||
case CIcarus::TK_LESS_THAN:
|
||||
case CIcarus::TK_NOT:
|
||||
block->Write( bID, 0, icarus );
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
//Get rid of the temp memory
|
||||
game->Free( bData );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
-------------------------
|
||||
Save
|
||||
-------------------------
|
||||
*/
|
||||
|
||||
int CSequence::Save()
|
||||
{
|
||||
// Data saved here.
|
||||
// Parent ID.
|
||||
// Return ID.
|
||||
// Number of Children.
|
||||
// Children.
|
||||
// - Child ID
|
||||
// Save Flags.
|
||||
// Save Iterations.
|
||||
// Number of Commands
|
||||
// - Commands (raw) data.
|
||||
|
||||
CIcarus *pIcarus = (CIcarus *)IIcarusInterface::GetIcarus();
|
||||
|
||||
block_l::iterator bi;
|
||||
int id;
|
||||
|
||||
// Save the parent (by GUID).
|
||||
id = ( m_parent != NULL ) ? m_parent->GetID() : -1;
|
||||
pIcarus->BufferWrite( &id, sizeof( id ) );
|
||||
|
||||
//Save the return (by GUID)
|
||||
id = ( m_return != NULL ) ? m_return->GetID() : -1;
|
||||
pIcarus->BufferWrite( &id, sizeof( id ) );
|
||||
|
||||
//Save the number of children
|
||||
int iNumChildren = m_children.size();
|
||||
pIcarus->BufferWrite( &iNumChildren, sizeof( iNumChildren ) );
|
||||
|
||||
//Save out the children (only by GUID)
|
||||
/*STL_ITERATE( iterSeq, m_childrenMap )
|
||||
{
|
||||
id = (*iterSeq).second->GetID();
|
||||
pIcarus->BufferWrite( &id, sizeof( id ) );
|
||||
}*/
|
||||
sequence_l::iterator iterSeq;
|
||||
STL_ITERATE( iterSeq, m_children )
|
||||
{
|
||||
id = (*iterSeq)->GetID();
|
||||
pIcarus->BufferWrite( &id, sizeof( id ) );
|
||||
}
|
||||
|
||||
//Save flags
|
||||
pIcarus->BufferWrite( &m_flags, sizeof( m_flags ) );
|
||||
|
||||
//Save iterations
|
||||
pIcarus->BufferWrite( &m_iterations, sizeof( m_iterations ) );
|
||||
|
||||
//Save the number of commands
|
||||
pIcarus->BufferWrite( &m_numCommands, sizeof( m_numCommands ) );
|
||||
|
||||
//Save the commands
|
||||
STL_ITERATE( bi, m_commands )
|
||||
{
|
||||
SaveCommand( (*bi) );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
-------------------------
|
||||
Load
|
||||
-------------------------
|
||||
*/
|
||||
|
||||
int CSequence::Load( CIcarus* icarus )
|
||||
{
|
||||
CSequence *sequence;
|
||||
CBlock *block;
|
||||
int id;
|
||||
|
||||
// Data expected/loaded here (ISEQ) (with the size as : 'ISSZ' ).
|
||||
// Parent ID.
|
||||
// Return ID.
|
||||
// Number of Children.
|
||||
// Children.
|
||||
// - Child ID
|
||||
// Save Flags.
|
||||
// Save Iterations.
|
||||
// Number of Commands
|
||||
// - Commands (raw) data.
|
||||
|
||||
//Get the parent sequence
|
||||
icarus->BufferRead( &id, sizeof( id ) );
|
||||
m_parent = ( id != -1 ) ? icarus->GetSequence( id ) : NULL;
|
||||
|
||||
//Get the return sequence
|
||||
icarus->BufferRead( &id, sizeof( id ) );
|
||||
m_return = ( id != -1 ) ? icarus->GetSequence( id ) : NULL;
|
||||
|
||||
//Get the number of children
|
||||
int iNumChildren = 0;
|
||||
icarus->BufferRead( &iNumChildren, sizeof( iNumChildren ) );
|
||||
|
||||
//Reload all children
|
||||
for ( int i = 0; i < iNumChildren; i++ )
|
||||
{
|
||||
//Get the child sequence ID
|
||||
icarus->BufferRead( &id, sizeof( id ) );
|
||||
|
||||
//Get the desired sequence
|
||||
if ( ( sequence = icarus->GetSequence( id ) ) == NULL )
|
||||
return false;
|
||||
|
||||
//Insert this into the list
|
||||
STL_INSERT( m_children, sequence );
|
||||
|
||||
//Restore the connection in the child / ID map
|
||||
// m_childrenMap[ i ] = sequence;
|
||||
}
|
||||
|
||||
|
||||
//Get the sequence flags
|
||||
icarus->BufferRead( &m_flags, sizeof( m_flags ) );
|
||||
|
||||
//Get the number of iterations
|
||||
icarus->BufferRead( &m_iterations, sizeof( m_iterations ) );
|
||||
|
||||
int numCommands;
|
||||
|
||||
//Get the number of commands
|
||||
icarus->BufferRead( &numCommands, sizeof( numCommands ) );
|
||||
|
||||
//Get all the commands
|
||||
for ( i = 0; i < numCommands; i++ )
|
||||
{
|
||||
block = new CBlock;
|
||||
LoadCommand( block, icarus );
|
||||
|
||||
//Save the block
|
||||
//STL_INSERT( m_commands, block );
|
||||
PushCommand( block, PUSH_BACK );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
2614
code/icarus/Sequencer.cpp
Normal file
2614
code/icarus/Sequencer.cpp
Normal file
File diff suppressed because it is too large
Load Diff
19
code/icarus/StdAfx.h
Normal file
19
code/icarus/StdAfx.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef __ICR_STDAFX__
|
||||
#define __ICR_STDAFX__
|
||||
|
||||
#pragma warning( disable : 4786 ) // identifier was truncated
|
||||
|
||||
#pragma warning (push, 3)
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
#pragma warning (pop)
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define STL_ITERATE( a, b ) for ( a = b.begin(); a != b.end(); a++ )
|
||||
#define STL_INSERT( a, b ) a.insert( a.end(), b );
|
||||
|
||||
#endif
|
||||
2036
code/icarus/TaskManager.cpp
Normal file
2036
code/icarus/TaskManager.cpp
Normal file
File diff suppressed because it is too large
Load Diff
213
code/icarus/blockstream.h
Normal file
213
code/icarus/blockstream.h
Normal file
@@ -0,0 +1,213 @@
|
||||
// BlockStream.h
|
||||
|
||||
#ifndef __INTERPRETED_BLOCK_STREAM__
|
||||
#define __INTERPRETED_BLOCK_STREAM__
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
typedef float vec3_t[3];
|
||||
|
||||
|
||||
// Templates
|
||||
|
||||
// CBlockMember
|
||||
|
||||
class CBlockMember
|
||||
{
|
||||
public:
|
||||
CBlockMember();
|
||||
|
||||
protected:
|
||||
~CBlockMember();
|
||||
|
||||
public:
|
||||
void Free(IGameInterface* game);
|
||||
|
||||
int WriteMember ( FILE * ); //Writes the member's data, in block format, to FILE *
|
||||
int ReadMember( char **, long *, CIcarus* icarus ); //Reads the member's data, in block format, from FILE *
|
||||
|
||||
void SetID( int id ) { m_id = id; } //Set the ID member variable
|
||||
void SetSize( int size ) { m_size = size; } //Set the size member variable
|
||||
|
||||
void GetInfo( int *, int *, void **);
|
||||
|
||||
//SetData overloads
|
||||
void SetData( const char * ,CIcarus* icarus);
|
||||
void SetData( vec3_t , CIcarus* icarus);
|
||||
void SetData( void *data, int size, CIcarus* icarus);
|
||||
|
||||
int GetID( void ) const { return m_id; } //Get ID member variables
|
||||
void *GetData( void ) const { return m_data; } //Get data member variable
|
||||
int GetSize( void ) const { return m_size; } //Get size member variable
|
||||
|
||||
// Overloaded new operator.
|
||||
inline void *operator new( size_t size )
|
||||
{ // Allocate the memory.
|
||||
return IGameInterface::GetGame()->Malloc( size );
|
||||
}
|
||||
|
||||
// Overloaded delete operator.
|
||||
inline void operator delete( void *pRawData )
|
||||
{ // Free the Memory.
|
||||
IGameInterface::GetGame()->Free( pRawData );
|
||||
}
|
||||
|
||||
CBlockMember *Duplicate( CIcarus* icarus );
|
||||
|
||||
template <class T> void WriteData(T &data, CIcarus* icarus)
|
||||
{
|
||||
IGameInterface* game = icarus->GetGame();
|
||||
if ( m_data )
|
||||
{
|
||||
game->Free( m_data );
|
||||
}
|
||||
|
||||
m_data = game->Malloc( sizeof(T) );
|
||||
*((T *) m_data) = data;
|
||||
m_size = sizeof(T);
|
||||
}
|
||||
|
||||
template <class T> void WriteDataPointer(const T *data, int num, CIcarus* icarus)
|
||||
{
|
||||
IGameInterface* game =icarus->GetGame();
|
||||
if ( m_data )
|
||||
{
|
||||
game->Free( m_data );
|
||||
}
|
||||
|
||||
m_data = game->Malloc( num*sizeof(T) );
|
||||
memcpy( m_data, data, num*sizeof(T) );
|
||||
m_size = num*sizeof(T);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
int m_id; //ID of the value contained in data
|
||||
int m_size; //Size of the data member variable
|
||||
void *m_data; //Data for this member
|
||||
|
||||
};
|
||||
|
||||
//CBlock
|
||||
|
||||
class CBlock
|
||||
{
|
||||
typedef vector< CBlockMember * > blockMember_v;
|
||||
|
||||
public:
|
||||
|
||||
CBlock()
|
||||
{
|
||||
m_flags = 0;
|
||||
m_id = 0;
|
||||
}
|
||||
~CBlock() { assert(!GetNumMembers()); }
|
||||
|
||||
int Init( void );
|
||||
|
||||
int Create( int );
|
||||
int Free(CIcarus* icarus);
|
||||
|
||||
//Write Overloads
|
||||
|
||||
int Write( int, vec3_t, CIcarus* icaru );
|
||||
int Write( int, float, CIcarus* icaru );
|
||||
int Write( int, const char *, CIcarus* icaru );
|
||||
int Write( int, int, CIcarus* icaru );
|
||||
int Write( CBlockMember *, CIcarus* icaru );
|
||||
|
||||
//Member push / pop functions
|
||||
|
||||
int AddMember( CBlockMember * );
|
||||
CBlockMember *GetMember( int memberNum );
|
||||
|
||||
void *GetMemberData( int memberNum );
|
||||
|
||||
CBlock *Duplicate( CIcarus* icarus );
|
||||
|
||||
int GetBlockID( void ) const { return m_id; } //Get the ID for the block
|
||||
int GetNumMembers( void ) const { return m_members.size();} //Get the number of member in the block's list
|
||||
|
||||
void SetFlags( unsigned char flags ) { m_flags = flags; }
|
||||
void SetFlag( unsigned char flag ) { m_flags |= flag; }
|
||||
|
||||
int HasFlag( unsigned char flag ) const { return ( m_flags & flag ); }
|
||||
unsigned char GetFlags( void ) const { return m_flags; }
|
||||
|
||||
// Overloaded new operator.
|
||||
inline void *operator new( size_t size )
|
||||
{ // Allocate the memory.
|
||||
return IGameInterface::GetGame()->Malloc( size );
|
||||
}
|
||||
|
||||
// Overloaded delete operator.
|
||||
inline void operator delete( void *pRawData )
|
||||
{ // Validate data.
|
||||
if ( pRawData == 0 )
|
||||
return;
|
||||
|
||||
// Free the Memory.
|
||||
IGameInterface::GetGame()->Free( pRawData );
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
blockMember_v m_members; //List of all CBlockMembers owned by this list
|
||||
int m_id; //ID of the block
|
||||
unsigned char m_flags;
|
||||
};
|
||||
|
||||
// CBlockStream
|
||||
|
||||
class CBlockStream
|
||||
{
|
||||
public:
|
||||
|
||||
CBlockStream()
|
||||
{
|
||||
m_stream = NULL;
|
||||
m_streamPos = 0;
|
||||
}
|
||||
~CBlockStream() {};
|
||||
|
||||
int Init( void );
|
||||
|
||||
int Create( char * );
|
||||
int Free( void );
|
||||
|
||||
// Stream I/O functions
|
||||
|
||||
int BlockAvailable( void );
|
||||
|
||||
int WriteBlock( CBlock *, CIcarus* icarus ); //Write the block out
|
||||
int ReadBlock( CBlock *, CIcarus* icarus ); //Read the block in
|
||||
|
||||
int Open( char *, long ); //Open a stream for reading / writing
|
||||
|
||||
// Overloaded new operator.
|
||||
static void *operator new( size_t size )
|
||||
{ // Allocate the memory.
|
||||
return IGameInterface::GetGame()->Malloc( size );
|
||||
}
|
||||
|
||||
// Overloaded delete operator.
|
||||
static void operator delete( void *pRawData )
|
||||
{ // Free the Memory.
|
||||
IGameInterface::GetGame()->Free( pRawData );
|
||||
}
|
||||
|
||||
protected:
|
||||
long m_fileSize; //Size of the file
|
||||
FILE *m_fileHandle; //Global file handle of current I/O source
|
||||
char m_fileName[CIcarus::MAX_FILENAME_LENGTH]; //Name of the current file
|
||||
|
||||
char *m_stream; //Stream of data to be parsed
|
||||
long m_streamPos;
|
||||
|
||||
static char* s_IBI_EXT;
|
||||
static char* s_IBI_HEADER_ID;
|
||||
static const float s_IBI_VERSION;
|
||||
};
|
||||
|
||||
#endif //__INTERPRETED_BLOCK_STREAM__
|
||||
115
code/icarus/sequence.h
Normal file
115
code/icarus/sequence.h
Normal file
@@ -0,0 +1,115 @@
|
||||
// Sequence Header File
|
||||
|
||||
#ifndef __SEQUENCE__
|
||||
#define __SEQUENCE__
|
||||
|
||||
class CSequence
|
||||
{
|
||||
|
||||
typedef list < CSequence * > sequence_l;
|
||||
// typedef map < int, CSequence *> sequenceID_m;
|
||||
typedef list < CBlock * > block_l;
|
||||
|
||||
public:
|
||||
|
||||
//Constructors / Destructors
|
||||
CSequence( void );
|
||||
~CSequence( void );
|
||||
|
||||
//Creation and deletion
|
||||
static CSequence *Create( void );
|
||||
void Delete( CIcarus* icarus );
|
||||
|
||||
//Organization functions
|
||||
void AddChild( CSequence * );
|
||||
void RemoveChild( CSequence * );
|
||||
|
||||
void SetParent( CSequence * );
|
||||
CSequence *GetParent( void ) const { return m_parent; }
|
||||
|
||||
//Block manipulation
|
||||
CBlock *PopCommand( int );
|
||||
int PushCommand( CBlock *, int );
|
||||
|
||||
//Flag utilties
|
||||
void SetFlag( int );
|
||||
void RemoveFlag( int, bool = false );
|
||||
int HasFlag( int );
|
||||
int GetFlags( void ) const { return m_flags; }
|
||||
void SetFlags( int flags ) { m_flags = flags; }
|
||||
|
||||
//Various encapsulation utilities
|
||||
int GetIterations( void ) const { return m_iterations; }
|
||||
void SetIterations( int it ) { m_iterations = it; }
|
||||
|
||||
int GetID( void ) const { return m_id; }
|
||||
void SetID( int id ) { m_id = id; }
|
||||
|
||||
CSequence *GetReturn( void ) const { return m_return; }
|
||||
|
||||
void SetReturn ( CSequence *sequence );
|
||||
|
||||
int GetNumCommands( void ) const { return m_numCommands; }
|
||||
int GetNumChildren( void ) const { return m_children.size(); }
|
||||
|
||||
CSequence *GetChildByID( int id );
|
||||
CSequence *GetChildByIndex( int iIndex );
|
||||
bool HasChild( CSequence *sequence );
|
||||
|
||||
int Save();
|
||||
int Load( CIcarus* icarus );
|
||||
|
||||
// Overloaded new operator.
|
||||
inline void *operator new( size_t size )
|
||||
{ // Allocate the memory.
|
||||
return IGameInterface::GetGame()->Malloc( size );
|
||||
}
|
||||
|
||||
// Overloaded delete operator.
|
||||
inline void operator delete( void *pRawData )
|
||||
{ // Free the Memory.
|
||||
IGameInterface::GetGame()->Free( pRawData );
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
SQ_COMMON = 0x00000000, //Common one-pass sequence
|
||||
SQ_LOOP = 0x00000001, //Looping sequence
|
||||
SQ_RETAIN = 0x00000002, //Inside a looping sequence list, retain the information
|
||||
SQ_AFFECT = 0x00000004, //Affect sequence
|
||||
SQ_RUN = 0x00000008, //A run block
|
||||
SQ_PENDING = 0x00000010, //Pending use, don't free when flushing the sequences
|
||||
SQ_CONDITIONAL = 0x00000020, //Conditional statement
|
||||
SQ_TASK = 0x00000040, //Task block
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
POP_FRONT,
|
||||
POP_BACK,
|
||||
PUSH_FRONT,
|
||||
PUSH_BACK
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
int SaveCommand( CBlock *block );
|
||||
int LoadCommand( CBlock *block, CIcarus *icarus );
|
||||
|
||||
//Organization information
|
||||
sequence_l m_children;
|
||||
//sequenceID_m m_childrenMap;
|
||||
|
||||
//int m_numChildren;
|
||||
CSequence *m_parent;
|
||||
CSequence *m_return;
|
||||
|
||||
//Data information
|
||||
block_l m_commands;
|
||||
int m_flags;
|
||||
int m_iterations;
|
||||
int m_id;
|
||||
int m_numCommands;
|
||||
};
|
||||
|
||||
#endif //__SEQUENCE__
|
||||
163
code/icarus/sequencer.h
Normal file
163
code/icarus/sequencer.h
Normal file
@@ -0,0 +1,163 @@
|
||||
// Sequencer Header File
|
||||
|
||||
#ifndef __SEQUENCER__
|
||||
#define __SEQUENCER__
|
||||
|
||||
//Defines
|
||||
|
||||
|
||||
//const int MAX_ERROR_LENGTH = 256;
|
||||
|
||||
//Typedefs
|
||||
|
||||
typedef struct bstream_s
|
||||
{
|
||||
CBlockStream *stream;
|
||||
bstream_s *last;
|
||||
} bstream_t;
|
||||
|
||||
// Sequencer
|
||||
|
||||
/*
|
||||
==================================================================================================
|
||||
|
||||
CSequencer
|
||||
|
||||
==================================================================================================
|
||||
*/
|
||||
|
||||
class CSequencer
|
||||
{
|
||||
//typedef map < int, CSequence * > sequenceID_m;
|
||||
typedef list < CSequence * > sequence_l;
|
||||
typedef map < CTaskGroup *, CSequence * > taskSequence_m;
|
||||
|
||||
public:
|
||||
enum
|
||||
{
|
||||
BF_ELSE = 0x00000001, //Block has an else id //FIXME: This was a sloppy fix for a problem that arose from conditionals
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
SEQ_OK, //Command was successfully added
|
||||
SEQ_FAILED, //An error occured while trying to insert the command
|
||||
};
|
||||
|
||||
CSequencer();
|
||||
|
||||
protected:
|
||||
~CSequencer();
|
||||
|
||||
public:
|
||||
int GetID() { return m_id;};
|
||||
|
||||
int Init( int ownerID, CTaskManager *taskManager);
|
||||
static CSequencer *Create ( void );
|
||||
void Free( CIcarus* icarus );
|
||||
|
||||
int Run( char *buffer, long size, CIcarus* icarus);
|
||||
int Callback( CTaskManager *taskManager, CBlock *block, int returnCode, CIcarus* icarus );
|
||||
|
||||
void SetOwnerID( int owner ) { m_ownerID = owner;}
|
||||
|
||||
int GetOwnerID( void ) const { return m_ownerID; }
|
||||
|
||||
CTaskManager *GetTaskManager( void ) const { return m_taskManager; }
|
||||
|
||||
void SetTaskManager( CTaskManager *tm) { if ( tm ) m_taskManager = tm; }
|
||||
|
||||
int Save();
|
||||
int Load( CIcarus* icarus, IGameInterface* game );
|
||||
|
||||
// Overloaded new operator.
|
||||
inline void *operator new( size_t size )
|
||||
{ // Allocate the memory.
|
||||
return IGameInterface::GetGame()->Malloc( size );
|
||||
}
|
||||
|
||||
// Overloaded delete operator.
|
||||
inline void operator delete( void *pRawData )
|
||||
{ // Free the Memory.
|
||||
IGameInterface::GetGame()->Free( pRawData );
|
||||
}
|
||||
|
||||
// moved to public on 2/12/2 to allow calling during shutdown
|
||||
int Recall( CIcarus* icarus );
|
||||
protected:
|
||||
|
||||
int EvaluateConditional( CBlock *block, CIcarus* icarus );
|
||||
|
||||
int Route( CSequence *sequence, bstream_t *bstream , CIcarus* icarus);
|
||||
int Flush( CSequence *owner, CIcarus* icarus );
|
||||
void Interrupt( void );
|
||||
|
||||
bstream_t *AddStream( void );
|
||||
void DeleteStream( bstream_t *bstream );
|
||||
|
||||
int AddAffect( bstream_t *bstream, int retain, int *id, CIcarus* icarus );
|
||||
|
||||
CSequence *AddSequence( CIcarus* icarus );
|
||||
CSequence *AddSequence( CSequence *parent, CSequence *returnSeq, int flags, CIcarus* icarus );
|
||||
|
||||
CSequence *GetSequence( int id );
|
||||
|
||||
//NOTENOTE: This only removes references to the sequence, IT DOES NOT FREE THE ALLOCATED MEMORY!
|
||||
int RemoveSequence( CSequence *sequence, CIcarus* icarus);
|
||||
int DestroySequence( CSequence *sequence, CIcarus* icarus);
|
||||
|
||||
int PushCommand( CBlock *command, int flag );
|
||||
CBlock *PopCommand( int flag );
|
||||
|
||||
inline CSequence *ReturnSequence( CSequence *sequence );
|
||||
|
||||
void CheckRun( CBlock ** , CIcarus* icarus);
|
||||
void CheckLoop( CBlock ** , CIcarus* icarus);
|
||||
void CheckAffect( CBlock ** , CIcarus* icarus);
|
||||
void CheckIf( CBlock ** , CIcarus* icarus);
|
||||
void CheckDo( CBlock ** , CIcarus* icarus);
|
||||
void CheckFlush( CBlock ** , CIcarus* icarus);
|
||||
|
||||
void Prep( CBlock ** , CIcarus* icarus);
|
||||
|
||||
int Prime( CTaskManager *taskManager, CBlock *command, CIcarus* icarus);
|
||||
|
||||
void StripExtension( const char *in, char *out );
|
||||
|
||||
int ParseRun( CBlock *block , CIcarus* icarus);
|
||||
int ParseLoop( CBlock *block, bstream_t *bstream , CIcarus* icarus);
|
||||
int ParseAffect( CBlock *block, bstream_t *bstream, CIcarus* icarus );
|
||||
int ParseIf( CBlock *block, bstream_t *bstream, CIcarus* icarus );
|
||||
int ParseElse( CBlock *block, bstream_t *bstream, CIcarus* icarus );
|
||||
int ParseTask( CBlock *block, bstream_t *bstream , CIcarus* icarus);
|
||||
|
||||
int Affect( int id, int type , CIcarus* icarus);
|
||||
|
||||
void AddTaskSequence( CSequence *sequence, CTaskGroup *group );
|
||||
CSequence *GetTaskSequence( CTaskGroup *group );
|
||||
|
||||
//Member variables
|
||||
|
||||
int m_ownerID;
|
||||
|
||||
CTaskManager *m_taskManager;
|
||||
|
||||
int m_numCommands; //Total number of commands for the sequencer (including all child sequences)
|
||||
|
||||
//sequenceID_m m_sequenceMap;
|
||||
sequence_l m_sequences;
|
||||
taskSequence_m m_taskSequences;
|
||||
|
||||
CSequence *m_curSequence;
|
||||
CTaskGroup *m_curGroup;
|
||||
|
||||
bstream_t *m_curStream;
|
||||
|
||||
int m_elseValid;
|
||||
CBlock *m_elseOwner;
|
||||
vector<bstream_t*> m_streamsCreated;
|
||||
|
||||
int m_id;
|
||||
};
|
||||
|
||||
#endif //__SEQUENCER__
|
||||
227
code/icarus/taskmanager.h
Normal file
227
code/icarus/taskmanager.h
Normal file
@@ -0,0 +1,227 @@
|
||||
// Task Manager header file
|
||||
|
||||
#ifndef __TASK_MANAGER__
|
||||
#define __TASK_MANAGER__
|
||||
|
||||
typedef unsigned long DWORD;
|
||||
|
||||
#define MAX_TASK_NAME 64
|
||||
#define TASKFLAG_NORMAL 0x00000000
|
||||
const int RUNAWAY_LIMIT = 256;
|
||||
|
||||
enum
|
||||
{
|
||||
TASK_RETURN_COMPLETE,
|
||||
TASK_RETURN_FAILED,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
TASK_OK,
|
||||
TASK_FAILED,
|
||||
TASK_START,
|
||||
TASK_END,
|
||||
};
|
||||
|
||||
// CTask
|
||||
|
||||
class CTask
|
||||
{
|
||||
public:
|
||||
|
||||
CTask();
|
||||
~CTask();
|
||||
|
||||
static CTask *Create( int GUID, CBlock *block );
|
||||
|
||||
void Free( void );
|
||||
|
||||
DWORD GetTimeStamp( void ) const { return m_timeStamp; }
|
||||
CBlock *GetBlock( void ) const { return m_block; }
|
||||
int GetGUID( void) const { return m_id; }
|
||||
int GetID( void ) const { return m_block->GetBlockID(); }
|
||||
|
||||
void SetTimeStamp( DWORD timeStamp ) { m_timeStamp = timeStamp; }
|
||||
void SetBlock( CBlock *block ) { m_block = block; }
|
||||
void SetGUID( int id ) { m_id = id; }
|
||||
|
||||
// Overloaded new operator.
|
||||
inline void *operator new( size_t size )
|
||||
{ // Allocate the memory.
|
||||
return IGameInterface::GetGame()->Malloc( size );
|
||||
}
|
||||
|
||||
// Overloaded delete operator.
|
||||
inline void operator delete( void *pRawData )
|
||||
{ // Free the Memory.
|
||||
IGameInterface::GetGame()->Free( pRawData );
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
int m_id;
|
||||
DWORD m_timeStamp;
|
||||
CBlock *m_block;
|
||||
};
|
||||
|
||||
// CTaskGroup
|
||||
|
||||
class CTaskGroup
|
||||
{
|
||||
public:
|
||||
|
||||
typedef map < int, bool > taskCallback_m;
|
||||
|
||||
CTaskGroup( void );
|
||||
~CTaskGroup( void );
|
||||
|
||||
void Init( void );
|
||||
|
||||
int Add( CTask *task );
|
||||
|
||||
void SetGUID( int GUID );
|
||||
void SetParent( CTaskGroup *group ) { m_parent = group; }
|
||||
|
||||
bool Complete(void) const { return ( m_numCompleted == m_completedTasks.size() ); }
|
||||
|
||||
bool MarkTaskComplete( int id );
|
||||
|
||||
CTaskGroup *GetParent( void ) const { return m_parent; }
|
||||
int GetGUID( void ) const { return m_GUID; }
|
||||
|
||||
// Overloaded new operator.
|
||||
static void *operator new( size_t size )
|
||||
{ // Allocate the memory.
|
||||
return IGameInterface::GetGame()->Malloc( size );
|
||||
}
|
||||
// Overloaded delete operator.
|
||||
static void operator delete( void *pRawData )
|
||||
{ // Free the Memory.
|
||||
IGameInterface::GetGame()->Free( pRawData );
|
||||
}
|
||||
|
||||
//protected:
|
||||
|
||||
taskCallback_m m_completedTasks;
|
||||
|
||||
CTaskGroup *m_parent;
|
||||
|
||||
unsigned int m_numCompleted;
|
||||
int m_GUID;
|
||||
};
|
||||
|
||||
// CTaskManager
|
||||
class CSequencer;
|
||||
|
||||
class CTaskManager
|
||||
{
|
||||
|
||||
typedef map < int, CTask * > taskID_m;
|
||||
typedef map < string, CTaskGroup * > taskGroupName_m;
|
||||
typedef map < int, CTaskGroup * > taskGroupID_m;
|
||||
typedef vector < CTaskGroup * > taskGroup_v;
|
||||
typedef list < CTask *> tasks_l;
|
||||
|
||||
public:
|
||||
|
||||
CTaskManager();
|
||||
~CTaskManager();
|
||||
|
||||
int GetID();
|
||||
|
||||
static CTaskManager *Create( void );
|
||||
|
||||
CBlock *GetCurrentTask( void );
|
||||
|
||||
int Init( CSequencer *owner );
|
||||
int Free( void );
|
||||
|
||||
int Flush( void );
|
||||
|
||||
int SetCommand( CBlock *block, int type, CIcarus* icarus );
|
||||
int Completed( int id );
|
||||
|
||||
int Update( CIcarus* icarus );
|
||||
int IsRunning( void ) const { return(!m_tasks.empty()); };
|
||||
bool IsResident( void ) const { return m_resident;};
|
||||
|
||||
CTaskGroup *AddTaskGroup( const char *name , CIcarus* icarus);
|
||||
CTaskGroup *GetTaskGroup( const char *name, CIcarus* icarus);
|
||||
CTaskGroup *GetTaskGroup( int id, CIcarus* icarus );
|
||||
|
||||
int MarkTask( int id, int operation, CIcarus* icarus );
|
||||
CBlock *RecallTask( void );
|
||||
|
||||
void Save();
|
||||
void Load( CIcarus* icarus );
|
||||
|
||||
// Overloaded new operator.
|
||||
inline void* operator new( size_t size )
|
||||
{ // Allocate the memory.
|
||||
return IGameInterface::GetGame()->Malloc( size );
|
||||
}
|
||||
|
||||
// Overloaded delete operator.
|
||||
inline void operator delete( void *pRawData )
|
||||
{ // Free the Memory.
|
||||
IGameInterface::GetGame()->Free( pRawData );
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
int Go( CIcarus* icarus ); //Heartbeat function called once per game frame
|
||||
int CallbackCommand( CTask *task, int returnCode, CIcarus* icarus );
|
||||
|
||||
inline bool Check( int targetID, CBlock *block, int memberNum ) const;
|
||||
|
||||
int GetVector( int entID, CBlock *block, int &memberNum, vec3_t &value, CIcarus* icarus );
|
||||
int GetFloat( int entID, CBlock *block, int &memberNum, float &value, CIcarus* icarus );
|
||||
int Get( int entID, CBlock *block, int &memberNum, char **value, CIcarus* icarus );
|
||||
|
||||
int PushTask( CTask *task, int flag );
|
||||
CTask *PopTask( int flag );
|
||||
|
||||
// Task functions
|
||||
int Rotate( CTask *task, CIcarus* icarus );
|
||||
int Remove( CTask *task , CIcarus* icarus);
|
||||
int Camera( CTask *task, CIcarus* icarus );
|
||||
int Print( CTask *task , CIcarus* icarus);
|
||||
int Sound( CTask *task, CIcarus* icarus );
|
||||
int Move( CTask *task , CIcarus* icarus);
|
||||
int Kill( CTask *task , CIcarus* icarus);
|
||||
int Set( CTask *task, CIcarus* icarus );
|
||||
int Use( CTask *task , CIcarus* icarus);
|
||||
int DeclareVariable( CTask *task , CIcarus* icarus);
|
||||
int FreeVariable( CTask *task, CIcarus* icarus );
|
||||
int Signal( CTask *task , CIcarus* icarus);
|
||||
int Play( CTask *task , CIcarus* icarus);
|
||||
|
||||
int Wait( CTask *task, bool &completed, CIcarus* icarus );
|
||||
int WaitSignal( CTask *task, bool &completed, CIcarus* icarus);
|
||||
|
||||
int SaveCommand( CBlock *block );
|
||||
|
||||
// Variables
|
||||
|
||||
CSequencer *m_owner;
|
||||
int m_ownerID;
|
||||
|
||||
CTaskGroup *m_curGroup;
|
||||
|
||||
taskGroup_v m_taskGroups;
|
||||
tasks_l m_tasks;
|
||||
|
||||
int m_GUID;
|
||||
int m_count;
|
||||
|
||||
taskGroupName_m m_taskGroupNameMap;
|
||||
taskGroupID_m m_taskGroupIDMap;
|
||||
|
||||
bool m_resident;
|
||||
|
||||
int m_id;
|
||||
|
||||
//CTask *m_waitTask; //Global pointer to the current task that is waiting for callback completion
|
||||
};
|
||||
|
||||
#endif //__TASK_MANAGER__
|
||||
Reference in New Issue
Block a user