2013-04-22 05:25:59 +00:00
// Interpreted Block Stream Functions
//
// -- jweier
// this include must remain at the top of every Icarus CPP file
2013-04-22 08:08:27 +00:00
# include "../game/g_local.h"
# include "../game/q_shared.h"
2013-04-22 05:25:59 +00:00
# include "icarus.h"
# pragma warning(disable : 4100) //unref formal parm
# pragma warning(disable : 4710) //member not inlined
# include <string.h>
# include "BlockStream.h"
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
CBlockMember
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
CBlockMember : : CBlockMember ( void )
{
m_id = - 1 ;
m_size = - 1 ;
m_data = NULL ;
}
CBlockMember : : ~ CBlockMember ( void )
{
Free ( ) ;
}
/*
- - - - - - - - - - - - - - - - - - - - - - - - -
Free
- - - - - - - - - - - - - - - - - - - - - - - - -
*/
void CBlockMember : : Free ( void )
{
if ( m_data ! = NULL )
{
ICARUS_Free ( m_data ) ;
m_data = NULL ;
m_id = m_size = - 1 ;
}
}
/*
- - - - - - - - - - - - - - - - - - - - - - - - -
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 )
{
WriteDataPointer ( data , strlen ( data ) + 1 ) ;
}
void CBlockMember : : SetData ( vector_t data )
{
WriteDataPointer ( data , 3 ) ;
}
void CBlockMember : : SetData ( void * data , int size )
{
if ( m_data )
ICARUS_Free ( m_data ) ;
m_data = ICARUS_Malloc ( size ) ;
memcpy ( m_data , data , size ) ;
m_size = size ;
}
// Member I/O functions
/*
- - - - - - - - - - - - - - - - - - - - - - - - -
ReadMember
- - - - - - - - - - - - - - - - - - - - - - - - -
*/
2013-04-23 00:25:52 +00:00
int CBlockMember : : ReadMember ( char * * stream , int * streamPos )
2013-04-22 05:25:59 +00:00
{
2013-04-23 00:25:52 +00:00
m_id = * ( int * ) ( * stream + * ( ( int * ) streamPos ) ) ;
2013-04-22 05:25:59 +00:00
* streamPos + = sizeof ( int ) ;
if ( m_id = = 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-23 00:25:52 +00:00
* streamPos + = sizeof ( int ) ;
2013-04-22 05:25:59 +00:00
m_data = ICARUS_Malloc ( m_size ) ;
float infinite = Q3_INFINITE ;
memcpy ( m_data , & infinite , m_size ) ;
}
else
{
2013-04-23 00:25:52 +00:00
m_size = * ( int * ) ( * stream + * streamPos ) ;
* streamPos + = sizeof ( int ) ;
2013-04-22 05:25:59 +00:00
m_data = ICARUS_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 ( void )
{
CBlockMember * newblock = new CBlockMember ;
if ( newblock = = NULL )
return NULL ;
newblock - > SetData ( m_data , m_size ) ;
newblock - > SetSize ( m_size ) ;
newblock - > SetID ( m_id ) ;
return newblock ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
CBlock
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
CBlock : : CBlock ( void )
{
m_flags = 0 ;
m_id = 0 ;
}
CBlock : : ~ CBlock ( void )
{
Free ( ) ;
}
/*
- - - - - - - - - - - - - - - - - - - - - - - - -
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 ( void )
{
int numMembers = GetNumMembers ( ) ;
CBlockMember * bMember ;
while ( numMembers - - )
{
bMember = GetMember ( numMembers ) ;
if ( ! bMember )
return false ;
delete bMember ;
}
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 )
{
CBlockMember * bMember = new CBlockMember ;
bMember - > SetID ( member_id ) ;
bMember - > SetData ( member_data ) ;
bMember - > SetSize ( strlen ( member_data ) + 1 ) ;
AddMember ( bMember ) ;
return true ;
}
int CBlock : : Write ( int member_id , vector_t member_data )
{
CBlockMember * bMember ;
bMember = new CBlockMember ;
bMember - > SetID ( member_id ) ;
bMember - > SetData ( member_data ) ;
bMember - > SetSize ( sizeof ( vector_t ) ) ;
AddMember ( bMember ) ;
return true ;
}
int CBlock : : Write ( int member_id , float member_data )
{
CBlockMember * bMember = new CBlockMember ;
bMember - > SetID ( member_id ) ;
bMember - > WriteData ( member_data ) ;
bMember - > SetSize ( sizeof ( member_data ) ) ;
AddMember ( bMember ) ;
return true ;
}
int CBlock : : Write ( int member_id , int member_data )
{
CBlockMember * bMember = new CBlockMember ;
bMember - > SetID ( member_id ) ;
bMember - > WriteData ( member_data ) ;
bMember - > SetSize ( sizeof ( member_data ) ) ;
AddMember ( bMember ) ;
return true ;
}
int CBlock : : Write ( CBlockMember * bMember )
{
// 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 ( void )
{
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 ( ) ) ;
}
return newblock ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
CBlockStream
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
CBlockStream : : CBlockStream ( void )
{
m_stream = NULL ;
m_streamPos = 0 ;
}
CBlockStream : : ~ CBlockStream ( void )
{
}
/*
- - - - - - - - - - - - - - - - - - - - - - - - -
GetChar
- - - - - - - - - - - - - - - - - - - - - - - - -
*/
char CBlockStream : : GetChar ( void )
{
char data ;
data = * ( char * ) ( m_stream + m_streamPos ) ;
m_streamPos + = sizeof ( data ) ;
return data ;
}
/*
- - - - - - - - - - - - - - - - - - - - - - - - -
GetUnsignedInteger
- - - - - - - - - - - - - - - - - - - - - - - - -
*/
unsigned CBlockStream : : GetUnsignedInteger ( void )
{
unsigned data ;
data = * ( unsigned * ) ( m_stream + m_streamPos ) ;
m_streamPos + = sizeof ( data ) ;
return data ;
}
/*
- - - - - - - - - - - - - - - - - - - - - - - - -
GetInteger
- - - - - - - - - - - - - - - - - - - - - - - - -
*/
int CBlockStream : : GetInteger ( void )
{
int data ;
data = * ( int * ) ( m_stream + m_streamPos ) ;
m_streamPos + = sizeof ( data ) ;
return data ;
}
/*
- - - - - - - - - - - - - - - - - - - - - - - - -
GetLong
- - - - - - - - - - - - - - - - - - - - - - - - -
*/
long CBlockStream : : GetLong ( void )
{
long data ;
2013-04-23 00:25:52 +00:00
data = * ( int * ) ( m_stream + m_streamPos ) ;
2013-04-22 05:25:59 +00:00
m_streamPos + = sizeof ( data ) ;
return data ;
}
/*
- - - - - - - - - - - - - - - - - - - - - - - - -
GetFloat
- - - - - - - - - - - - - - - - - - - - - - - - -
*/
float CBlockStream : : GetFloat ( void )
{
float data ;
data = * ( float * ) ( m_stream + m_streamPos ) ;
m_streamPos + = sizeof ( data ) ;
return data ;
}
// Extension stripping utility
/*
- - - - - - - - - - - - - - - - - - - - - - - - -
StripExtension
- - - - - - - - - - - - - - - - - - - - - - - - -
*/
void CBlockStream : : StripExtension ( const char * in , char * out )
{
int i = strlen ( in ) ;
while ( ( in [ i ] ! = ' . ' ) & & ( i > = 0 ) )
i - - ;
if ( i < 0 )
{
strcpy ( out , in ) ;
return ;
}
strncpy ( out , in , i ) ;
}
/*
- - - - - - - - - - - - - - - - - - - - - - - - -
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 )
{
char newName [ MAX_FILENAME_LENGTH ] , * id_header = IBI_HEADER_ID ;
float version = IBI_VERSION ;
//Clear the temp string
memset ( newName , 0 , sizeof ( newName ) ) ;
//Strip the extension and add the BLOCK_EXT extension
strcpy ( ( char * ) m_fileName , filename ) ;
StripExtension ( ( char * ) m_fileName , ( char * ) & newName ) ;
strcat ( ( char * ) newName , IBI_EXT ) ;
//Recover that as the active filename
strcpy ( m_fileName , newName ) ;
if ( ( ( m_fileHandle = fopen ( m_fileName , " wb " ) ) = = NULL ) )
{
return false ;
}
fwrite ( id_header , 1 , sizeof ( id_header ) , m_fileHandle ) ;
fwrite ( & version , 1 , sizeof ( 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 )
{
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 ( ) ;
return true ;
}
/*
- - - - - - - - - - - - - - - - - - - - - - - - -
BlockAvailable
- - - - - - - - - - - - - - - - - - - - - - - - -
*/
int CBlockStream : : BlockAvailable ( void )
{
if ( m_streamPos > = m_fileSize )
return false ;
return true ;
}
/*
- - - - - - - - - - - - - - - - - - - - - - - - -
ReadBlock
- - - - - - - - - - - - - - - - - - - - - - - - -
*/
int CBlockStream : : ReadBlock ( CBlock * get )
{
CBlockMember * bMember ;
int b_id , numMembers ;
unsigned char flags ;
if ( ! BlockAvailable ( ) )
return false ;
b_id = GetInteger ( ) ;
numMembers = GetInteger ( ) ;
flags = ( unsigned char ) GetChar ( ) ;
if ( numMembers < 0 )
return false ;
get - > Create ( b_id ) ;
get - > SetFlags ( flags ) ;
while ( numMembers - - > 0 )
{
bMember = new CBlockMember ;
bMember - > ReadMember ( & m_stream , & m_streamPos ) ;
get - > AddMember ( bMember ) ;
}
return true ;
}
/*
- - - - - - - - - - - - - - - - - - - - - - - - -
Open
- - - - - - - - - - - - - - - - - - - - - - - - -
*/
int CBlockStream : : Open ( char * buffer , long size )
{
char id_header [ sizeof ( IBI_HEADER_ID ) ] ;
float version ;
Init ( ) ;
m_fileSize = size ;
m_stream = buffer ;
for ( int i = 0 ; i < sizeof ( id_header ) ; i + + )
{
id_header [ i ] = GetChar ( ) ;
}
version = GetFloat ( ) ;
//Check for valid header
if ( strcmp ( id_header , IBI_HEADER_ID ) )
{
Free ( ) ;
return false ;
}
//Check for valid version
if ( version ! = IBI_VERSION )
{
Free ( ) ;
return false ;
}
return true ;
}