2013-04-19 02:52:48 +00:00
// Interpreted Block Stream Functions
//
// -- jweier
// this include must remain at the top of every Icarus CPP file
2013-04-23 07:39:09 +00:00
# include "StdAfx.h"
2013-04-19 02:52:48 +00:00
# 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
- - - - - - - - - - - - - - - - - - - - - - - - -
*/
2013-04-20 06:19:40 +00:00
int CBlockMember : : ReadMember ( char * * stream , int * streamPos , CIcarus * icarus )
2013-04-19 02:52:48 +00:00
{
IGameInterface * game = icarus - > GetGame ( ) ;
2013-04-20 06:19:40 +00:00
m_id = * ( int * ) ( * stream + * ( ( int * ) streamPos ) ) ;
2013-04-19 02:52:48 +00:00
* 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 ) ;
2013-04-20 06:19:40 +00:00
* streamPos + = sizeof ( int ) ;
2013-04-19 02:52:48 +00:00
m_data = game - > Malloc ( m_size ) ;
float infinite = game - > MaxFloat ( ) ;
memcpy ( m_data , & infinite , m_size ) ;
}
else
{
2013-04-20 06:19:40 +00:00
m_size = * ( int * ) ( * stream + * streamPos ) ;
* streamPos + = sizeof ( int ) ;
2013-04-19 02:52:48 +00:00
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 ;
}