You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
204 lines
4.5 KiB
204 lines
4.5 KiB
//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======
|
|
//
|
|
// Purpose:
|
|
//
|
|
//=============================================================================
|
|
|
|
#include "../game/shared/choreoscene.h"
|
|
#include "../game/shared/choreoactor.h"
|
|
#include "../game/shared/choreochannel.h"
|
|
#include "../game/shared/choreoevent.h"
|
|
#include "../game/shared/iscenetokenprocessor.h"
|
|
#include "characterset.h"
|
|
|
|
// NOTE: This has to be the last file included!
|
|
#include "tier0/memdbgon.h"
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Helper for parsing scene data file
|
|
//-----------------------------------------------------------------------------
|
|
class CSceneTokenProcessor : public ISceneTokenProcessor
|
|
{
|
|
public:
|
|
CSceneTokenProcessor();
|
|
|
|
const char *CurrentToken( void );
|
|
bool GetToken( bool crossline );
|
|
bool TokenAvailable( void );
|
|
void Error( const char *fmt, ... );
|
|
void SetBuffer( char *buffer );
|
|
private:
|
|
|
|
const char *ParseNextToken (const char *data);
|
|
|
|
const char *m_pBuffer;
|
|
char m_szToken[ 1024 ];
|
|
|
|
characterset_t m_BreakSetIncludingColons;
|
|
};
|
|
|
|
CSceneTokenProcessor::CSceneTokenProcessor()
|
|
{
|
|
CharacterSetBuild( &m_BreakSetIncludingColons, "{}()':" );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Output : const char
|
|
//-----------------------------------------------------------------------------
|
|
const char *CSceneTokenProcessor::CurrentToken( void )
|
|
{
|
|
return m_szToken;
|
|
}
|
|
|
|
const char *CSceneTokenProcessor::ParseNextToken (const char *data)
|
|
{
|
|
unsigned char c;
|
|
int len;
|
|
characterset_t *breaks;
|
|
|
|
breaks = &m_BreakSetIncludingColons;
|
|
|
|
len = 0;
|
|
m_szToken[0] = 0;
|
|
|
|
if (!data)
|
|
return NULL;
|
|
|
|
// skip whitespace
|
|
skipwhite:
|
|
while ( (c = *data) <= ' ')
|
|
{
|
|
if (c == 0)
|
|
return NULL; // end of file;
|
|
data++;
|
|
}
|
|
|
|
// skip // comments
|
|
if (c=='/' && data[1] == '/')
|
|
{
|
|
while (*data && *data != '\n')
|
|
data++;
|
|
goto skipwhite;
|
|
}
|
|
|
|
|
|
// handle quoted strings specially
|
|
if (c == '\"')
|
|
{
|
|
data++;
|
|
while (1)
|
|
{
|
|
c = *data++;
|
|
if (c=='\"' || !c)
|
|
{
|
|
m_szToken[len] = 0;
|
|
return data;
|
|
}
|
|
m_szToken[len] = c;
|
|
len++;
|
|
}
|
|
}
|
|
|
|
// parse single characters
|
|
if ( IN_CHARACTERSET( *breaks, c ) )
|
|
{
|
|
m_szToken[len] = c;
|
|
len++;
|
|
m_szToken[len] = 0;
|
|
return data+1;
|
|
}
|
|
|
|
// parse a regular word
|
|
do
|
|
{
|
|
m_szToken[len] = c;
|
|
data++;
|
|
len++;
|
|
c = *data;
|
|
if ( IN_CHARACTERSET( *breaks, c ) )
|
|
break;
|
|
} while (c>32);
|
|
|
|
m_szToken[len] = 0;
|
|
return data;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : crossline -
|
|
// Output : Returns true on success, false on failure.
|
|
//-----------------------------------------------------------------------------
|
|
bool CSceneTokenProcessor::GetToken( bool crossline )
|
|
{
|
|
// NOTE: crossline is ignored here, may need to implement if needed
|
|
m_pBuffer = ParseNextToken( m_pBuffer );
|
|
if ( Q_strlen( m_szToken ) >= 0 )
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Output : Returns true on success, false on failure.
|
|
//-----------------------------------------------------------------------------
|
|
bool CSceneTokenProcessor::TokenAvailable( void )
|
|
{
|
|
const char *search_p = m_pBuffer;
|
|
|
|
while ( *search_p <= 32)
|
|
{
|
|
if (*search_p == '\n')
|
|
return false;
|
|
search_p++;
|
|
if ( !*search_p )
|
|
return false;
|
|
|
|
}
|
|
|
|
if (*search_p == ';' || *search_p == '#' || // semicolon and # is comment field
|
|
(*search_p == '/' && *((search_p)+1) == '/')) // also make // a comment field
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : *fmt -
|
|
// ... -
|
|
//-----------------------------------------------------------------------------
|
|
void CSceneTokenProcessor::Error( const char *fmt, ... )
|
|
{
|
|
char string[ 2048 ];
|
|
va_list argptr;
|
|
va_start( argptr, fmt );
|
|
Q_vsnprintf( string, sizeof(string), fmt, argptr );
|
|
va_end( argptr );
|
|
|
|
Warning( "%s", string );
|
|
Assert(0);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : *buffer -
|
|
//-----------------------------------------------------------------------------
|
|
void CSceneTokenProcessor::SetBuffer( char *buffer )
|
|
{
|
|
m_pBuffer = buffer;
|
|
}
|
|
|
|
CSceneTokenProcessor g_TokenProcessor;
|
|
|
|
ISceneTokenProcessor *GetTokenProcessor()
|
|
{
|
|
return &g_TokenProcessor;
|
|
}
|
|
|
|
void SetTokenProcessorBuffer( const char *buf )
|
|
{
|
|
g_TokenProcessor.SetBuffer( (char *)buf );
|
|
}
|
|
|