2012-11-26 18:58:24 +00:00
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Doom 3 BFG Edition GPL Source Code
2012-11-28 15:47:07 +00:00
Copyright ( C ) 1993 - 2012 id Software LLC , a ZeniMax Media company .
2012-11-26 18:58:24 +00:00
2012-11-28 15:47:07 +00:00
This file is part of the Doom 3 BFG Edition GPL Source Code ( " Doom 3 BFG Edition Source Code " ) .
2012-11-26 18:58:24 +00:00
Doom 3 BFG Edition Source Code is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with Doom 3 BFG Edition Source Code . If not , see < http : //www.gnu.org/licenses/>.
In addition , the Doom 3 BFG Edition Source Code is also subject to certain additional terms . You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code . If not , please request a copy in writing from id Software at the address below .
If you have questions concerning this license or the applicable additional terms , you may contact in writing id Software LLC , c / o ZeniMax Media Inc . , Suite 120 , Rockville , Maryland 20850 USA .
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
/*
sys_event . cpp
Event are used for scheduling tasks and for linking script commands .
*/
# pragma hdrstop
# include "../../idlib/precompiled.h"
# include "../Game_local.h"
# define MAX_EVENTSPERFRAME 4096
//#define CREATE_EVENT_CODE
/***********************************************************************
idEventDef
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2012-11-28 15:47:07 +00:00
idEventDef * idEventDef : : eventDefList [ MAX_EVENTS ] ;
2012-11-26 18:58:24 +00:00
int idEventDef : : numEventDefs = 0 ;
static bool eventError = false ;
static char eventErrorMsg [ 128 ] ;
/*
= = = = = = = = = = = = = = = =
idEventDef : : idEventDef
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
idEventDef : : idEventDef ( const char * command , const char * formatspec , char returnType )
{
idEventDef * ev ;
2012-11-26 18:58:24 +00:00
int i ;
unsigned int bits ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
assert ( command ) ;
assert ( ! idEvent : : initialized ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// Allow NULL to indicate no args, but always store it as ""
// so we don't have to check for it.
2012-11-28 15:47:07 +00:00
if ( ! formatspec )
{
2012-11-26 18:58:24 +00:00
formatspec = " " ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
this - > name = command ;
this - > formatspec = formatspec ;
this - > returnType = returnType ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
numargs = strlen ( formatspec ) ;
assert ( numargs < = D_EVENT_MAXARGS ) ;
2012-11-28 15:47:07 +00:00
if ( numargs > D_EVENT_MAXARGS )
{
2012-11-26 18:58:24 +00:00
eventError = true ;
sprintf ( eventErrorMsg , " idEventDef::idEventDef : Too many args for '%s' event. " , name ) ;
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// make sure the format for the args is valid, calculate the formatspecindex, and the offsets for each arg
bits = 0 ;
argsize = 0 ;
memset ( argOffset , 0 , sizeof ( argOffset ) ) ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < numargs ; i + + )
{
2012-11-26 18:58:24 +00:00
argOffset [ i ] = argsize ;
2012-11-28 15:47:07 +00:00
switch ( formatspec [ i ] )
{
case D_EVENT_FLOAT :
bits | = 1 < < i ;
argsize + = sizeof ( float ) ;
break ;
case D_EVENT_INTEGER :
argsize + = sizeof ( int ) ;
break ;
case D_EVENT_VECTOR :
argsize + = sizeof ( idVec3 ) ;
break ;
case D_EVENT_STRING :
argsize + = MAX_STRING_LEN ;
break ;
case D_EVENT_ENTITY :
argsize + = sizeof ( idEntityPtr < idEntity > ) ;
break ;
case D_EVENT_ENTITY_NULL :
argsize + = sizeof ( idEntityPtr < idEntity > ) ;
break ;
case D_EVENT_TRACE :
argsize + = sizeof ( trace_t ) + MAX_STRING_LEN + sizeof ( bool ) ;
break ;
default :
eventError = true ;
sprintf ( eventErrorMsg , " idEventDef::idEventDef : Invalid arg format '%s' string for '%s' event. " , formatspec , name ) ;
return ;
break ;
2012-11-26 18:58:24 +00:00
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// calculate the formatspecindex
formatspecIndex = ( 1 < < ( numargs + D_EVENT_MAXARGS ) ) | bits ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// go through the list of defined events and check for duplicates
// and mismatched format strings
eventnum = numEventDefs ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < eventnum ; i + + )
{
2012-11-26 18:58:24 +00:00
ev = eventDefList [ i ] ;
2012-11-28 15:47:07 +00:00
if ( strcmp ( command , ev - > name ) = = 0 )
{
if ( strcmp ( formatspec , ev - > formatspec ) ! = 0 )
{
2012-11-26 18:58:24 +00:00
eventError = true ;
sprintf ( eventErrorMsg , " idEvent '%s' defined twice with same name but differing format strings ('%s'!='%s'). " ,
2012-11-28 15:47:07 +00:00
command , formatspec , ev - > formatspec ) ;
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
if ( ev - > returnType ! = returnType )
{
2012-11-26 18:58:24 +00:00
eventError = true ;
sprintf ( eventErrorMsg , " idEvent '%s' defined twice with same name but differing return types ('%c'!='%c'). " ,
2012-11-28 15:47:07 +00:00
command , returnType , ev - > returnType ) ;
2012-11-26 18:58:24 +00:00
return ;
}
// Don't bother putting the duplicate event in list.
eventnum = ev - > eventnum ;
return ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
ev = this ;
2012-11-28 15:47:07 +00:00
if ( numEventDefs > = MAX_EVENTS )
{
2012-11-26 18:58:24 +00:00
eventError = true ;
sprintf ( eventErrorMsg , " numEventDefs >= MAX_EVENTS " ) ;
return ;
}
eventDefList [ numEventDefs ] = ev ;
numEventDefs + + ;
}
/*
= = = = = = = = = = = = = = = =
idEventDef : : NumEventCommands
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idEventDef : : NumEventCommands ( )
{
2012-11-26 18:58:24 +00:00
return numEventDefs ;
}
/*
= = = = = = = = = = = = = = = =
idEventDef : : GetEventCommand
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const idEventDef * idEventDef : : GetEventCommand ( int eventnum )
{
2012-11-26 18:58:24 +00:00
return eventDefList [ eventnum ] ;
}
/*
= = = = = = = = = = = = = = = =
idEventDef : : FindEvent
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const idEventDef * idEventDef : : FindEvent ( const char * name )
{
idEventDef * ev ;
2012-11-26 18:58:24 +00:00
int num ;
int i ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
assert ( name ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
num = numEventDefs ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < num ; i + + )
{
2012-11-26 18:58:24 +00:00
ev = eventDefList [ i ] ;
2012-11-28 15:47:07 +00:00
if ( strcmp ( name , ev - > name ) = = 0 )
{
2012-11-26 18:58:24 +00:00
return ev ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return NULL ;
}
/***********************************************************************
idEvent
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static idLinkList < idEvent > FreeEvents ;
static idLinkList < idEvent > EventQueue ;
static idLinkList < idEvent > FastEventQueue ;
static idEvent EventPool [ MAX_EVENTS ] ;
bool idEvent : : initialized = false ;
2012-11-28 15:47:07 +00:00
idDynamicBlockAlloc < byte , 16 * 1024 , 256 > idEvent : : eventDataAllocator ;
2012-11-26 18:58:24 +00:00
/*
= = = = = = = = = = = = = = = =
idEvent : : ~ idEvent ( )
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
idEvent : : ~ idEvent ( )
{
2012-11-26 18:58:24 +00:00
Free ( ) ;
}
/*
= = = = = = = = = = = = = = = =
idEvent : : Alloc
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
idEvent * idEvent : : Alloc ( const idEventDef * evdef , int numargs , va_list args )
{
idEvent * ev ;
2012-11-26 18:58:24 +00:00
size_t size ;
2012-11-28 15:47:07 +00:00
const char * format ;
idEventArg * arg ;
byte * dataPtr ;
2012-11-26 18:58:24 +00:00
int i ;
2012-11-28 15:47:07 +00:00
const char * materialName ;
if ( FreeEvents . IsListEmpty ( ) )
{
2012-11-26 18:58:24 +00:00
gameLocal . Error ( " idEvent::Alloc : No more free events " ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
ev = FreeEvents . Next ( ) ;
ev - > eventNode . Remove ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
ev - > eventdef = evdef ;
2012-11-28 15:47:07 +00:00
if ( numargs ! = evdef - > GetNumArgs ( ) )
{
2012-11-26 18:58:24 +00:00
gameLocal . Error ( " idEvent::Alloc : Wrong number of args for '%s' event. " , evdef - > GetName ( ) ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
size = evdef - > GetArgSize ( ) ;
2012-11-28 15:47:07 +00:00
if ( size )
{
2012-11-26 18:58:24 +00:00
ev - > data = eventDataAllocator . Alloc ( size ) ;
memset ( ev - > data , 0 , size ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
ev - > data = NULL ;
return ev ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
format = evdef - > GetArgFormat ( ) ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < numargs ; i + + )
{
arg = va_arg ( args , idEventArg * ) ;
if ( format [ i ] ! = arg - > type )
{
2012-11-26 18:58:24 +00:00
// when NULL is passed in for an entity, it gets cast as an integer 0, so don't give an error when it happens
2012-11-28 15:47:07 +00:00
if ( ! ( ( ( format [ i ] = = D_EVENT_TRACE ) | | ( format [ i ] = = D_EVENT_ENTITY ) ) & & ( arg - > type = = ' d ' ) & & ( arg - > value = = 0 ) ) )
{
2012-11-26 18:58:24 +00:00
gameLocal . Error ( " idEvent::Alloc : Wrong type passed in for arg # %d on '%s' event. " , i , evdef - > GetName ( ) ) ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
dataPtr = & ev - > data [ evdef - > GetArgOffset ( i ) ] ;
2012-11-28 15:47:07 +00:00
switch ( format [ i ] )
{
case D_EVENT_FLOAT :
case D_EVENT_INTEGER :
* reinterpret_cast < int * > ( dataPtr ) = arg - > value ;
break ;
case D_EVENT_VECTOR :
if ( arg - > value )
{
* reinterpret_cast < idVec3 * > ( dataPtr ) = * reinterpret_cast < const idVec3 * > ( arg - > value ) ;
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
break ;
case D_EVENT_STRING :
if ( arg - > value )
{
idStr : : Copynz ( reinterpret_cast < char * > ( dataPtr ) , reinterpret_cast < const char * > ( arg - > value ) , MAX_STRING_LEN ) ;
}
break ;
case D_EVENT_ENTITY :
case D_EVENT_ENTITY_NULL :
* reinterpret_cast < idEntityPtr < idEntity > * > ( dataPtr ) = reinterpret_cast < idEntity * > ( arg - > value ) ;
break ;
case D_EVENT_TRACE :
if ( arg - > value )
{
* reinterpret_cast < bool * > ( dataPtr ) = true ;
* reinterpret_cast < trace_t * > ( dataPtr + sizeof ( bool ) ) = * reinterpret_cast < const trace_t * > ( arg - > value ) ;
// save off the material as a string since the pointer won't be valid in save games.
// since we save off the entire trace_t structure, if the material is NULL here,
// it will be NULL when we process it, so we don't need to save off anything in that case.
if ( reinterpret_cast < const trace_t * > ( arg - > value ) - > c . material )
{
materialName = reinterpret_cast < const trace_t * > ( arg - > value ) - > c . material - > GetName ( ) ;
idStr : : Copynz ( reinterpret_cast < char * > ( dataPtr + sizeof ( bool ) + sizeof ( trace_t ) ) , materialName , MAX_STRING_LEN ) ;
}
}
else
{
* reinterpret_cast < bool * > ( dataPtr ) = false ;
}
break ;
default :
gameLocal . Error ( " idEvent::Alloc : Invalid arg format '%s' string for '%s' event. " , format , evdef - > GetName ( ) ) ;
break ;
2012-11-26 18:58:24 +00:00
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return ev ;
}
/*
= = = = = = = = = = = = = = = =
idEvent : : CopyArgs
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idEvent : : CopyArgs ( const idEventDef * evdef , int numargs , va_list args , int data [ D_EVENT_MAXARGS ] )
{
2012-11-26 18:58:24 +00:00
int i ;
2012-11-28 15:47:07 +00:00
const char * format ;
idEventArg * arg ;
2012-11-26 18:58:24 +00:00
format = evdef - > GetArgFormat ( ) ;
2012-11-28 15:47:07 +00:00
if ( numargs ! = evdef - > GetNumArgs ( ) )
{
2012-11-26 18:58:24 +00:00
gameLocal . Error ( " idEvent::CopyArgs : Wrong number of args for '%s' event. " , evdef - > GetName ( ) ) ;
}
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < numargs ; i + + )
{
arg = va_arg ( args , idEventArg * ) ;
if ( format [ i ] ! = arg - > type )
{
2012-11-26 18:58:24 +00:00
// when NULL is passed in for an entity, it gets cast as an integer 0, so don't give an error when it happens
2012-11-28 15:47:07 +00:00
if ( ! ( ( ( format [ i ] = = D_EVENT_TRACE ) | | ( format [ i ] = = D_EVENT_ENTITY ) ) & & ( arg - > type = = ' d ' ) & & ( arg - > value = = 0 ) ) )
{
2012-11-26 18:58:24 +00:00
gameLocal . Error ( " idEvent::CopyArgs : Wrong type passed in for arg # %d on '%s' event. " , i , evdef - > GetName ( ) ) ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
data [ i ] = arg - > value ;
}
}
/*
= = = = = = = = = = = = = = = =
idEvent : : Free
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idEvent : : Free ( )
{
if ( data )
{
2012-11-26 18:58:24 +00:00
eventDataAllocator . Free ( data ) ;
data = NULL ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
eventdef = NULL ;
time = 0 ;
object = NULL ;
typeinfo = NULL ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
eventNode . SetOwner ( this ) ;
eventNode . AddToEnd ( FreeEvents ) ;
}
/*
= = = = = = = = = = = = = = = =
idEvent : : Schedule
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idEvent : : Schedule ( idClass * obj , const idTypeInfo * type , int time )
{
idEvent * event ;
2012-11-26 18:58:24 +00:00
assert ( initialized ) ;
2012-11-28 15:47:07 +00:00
if ( ! initialized )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
object = obj ;
typeinfo = type ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// wraps after 24 days...like I care. ;)
this - > time = gameLocal . time + time ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
eventNode . Remove ( ) ;
2012-11-28 15:47:07 +00:00
if ( obj - > IsType ( idEntity : : Type ) & & ( ( ( idEntity * ) ( obj ) ) - > timeGroup = = TIME_GROUP2 ) )
{
2012-11-26 18:58:24 +00:00
event = FastEventQueue . Next ( ) ;
2012-11-28 15:47:07 +00:00
while ( ( event ! = NULL ) & & ( this - > time > = event - > time ) )
{
2012-11-26 18:58:24 +00:00
event = event - > eventNode . Next ( ) ;
}
2012-11-28 15:47:07 +00:00
if ( event )
{
2012-11-26 18:58:24 +00:00
eventNode . InsertBefore ( event - > eventNode ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
eventNode . AddToEnd ( FastEventQueue ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
this - > time = gameLocal . slow . time + time ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
event = EventQueue . Next ( ) ;
2012-11-28 15:47:07 +00:00
while ( ( event ! = NULL ) & & ( this - > time > = event - > time ) )
{
2012-11-26 18:58:24 +00:00
event = event - > eventNode . Next ( ) ;
}
2012-11-28 15:47:07 +00:00
if ( event )
{
2012-11-26 18:58:24 +00:00
eventNode . InsertBefore ( event - > eventNode ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
eventNode . AddToEnd ( EventQueue ) ;
}
}
/*
= = = = = = = = = = = = = = = =
idEvent : : CancelEvents
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idEvent : : CancelEvents ( const idClass * obj , const idEventDef * evdef )
{
idEvent * event ;
idEvent * next ;
if ( ! initialized )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
for ( event = EventQueue . Next ( ) ; event ! = NULL ; event = next )
{
2012-11-26 18:58:24 +00:00
next = event - > eventNode . Next ( ) ;
2012-11-28 15:47:07 +00:00
if ( event - > object = = obj )
{
if ( ! evdef | | ( evdef = = event - > eventdef ) )
{
2012-11-26 18:58:24 +00:00
event - > Free ( ) ;
}
}
}
2012-11-28 15:47:07 +00:00
for ( event = FastEventQueue . Next ( ) ; event ! = NULL ; event = next )
{
2012-11-26 18:58:24 +00:00
next = event - > eventNode . Next ( ) ;
2012-11-28 15:47:07 +00:00
if ( event - > object = = obj )
{
if ( ! evdef | | ( evdef = = event - > eventdef ) )
{
2012-11-26 18:58:24 +00:00
event - > Free ( ) ;
}
}
}
}
/*
= = = = = = = = = = = = = = = =
idEvent : : ClearEventList
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idEvent : : ClearEventList ( )
{
2012-11-26 18:58:24 +00:00
int i ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
//
// initialize lists
//
FreeEvents . Clear ( ) ;
EventQueue . Clear ( ) ;
2012-11-28 15:47:07 +00:00
//
2012-11-26 18:58:24 +00:00
// add the events to the free list
//
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < MAX_EVENTS ; i + + )
{
2012-11-26 18:58:24 +00:00
EventPool [ i ] . Free ( ) ;
}
}
/*
= = = = = = = = = = = = = = = =
idEvent : : ServiceEvents
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idEvent : : ServiceEvents ( )
{
idEvent * event ;
2012-11-26 18:58:24 +00:00
int num ;
int args [ D_EVENT_MAXARGS ] ;
int offset ;
int i ;
int numargs ;
2012-11-28 15:47:07 +00:00
const char * formatspec ;
trace_t * * tracePtr ;
const idEventDef * ev ;
byte * data ;
const char * materialName ;
2012-11-26 18:58:24 +00:00
num = 0 ;
2012-11-28 15:47:07 +00:00
while ( ! EventQueue . IsListEmpty ( ) )
{
2012-11-26 18:58:24 +00:00
event = EventQueue . Next ( ) ;
assert ( event ) ;
2012-11-28 15:47:07 +00:00
if ( event - > time > gameLocal . time )
{
2012-11-26 18:58:24 +00:00
break ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
common - > UpdateLevelLoadPacifier ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// copy the data into the local args array and set up pointers
ev = event - > eventdef ;
formatspec = ev - > GetArgFormat ( ) ;
numargs = ev - > GetNumArgs ( ) ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < numargs ; i + + )
{
2012-11-26 18:58:24 +00:00
offset = ev - > GetArgOffset ( i ) ;
data = event - > data ;
2012-11-28 15:47:07 +00:00
switch ( formatspec [ i ] )
{
case D_EVENT_FLOAT :
case D_EVENT_INTEGER :
args [ i ] = * reinterpret_cast < int * > ( & data [ offset ] ) ;
break ;
case D_EVENT_VECTOR :
* reinterpret_cast < idVec3 * * > ( & args [ i ] ) = reinterpret_cast < idVec3 * > ( & data [ offset ] ) ;
break ;
case D_EVENT_STRING :
* reinterpret_cast < const char * * > ( & args [ i ] ) = reinterpret_cast < const char * > ( & data [ offset ] ) ;
break ;
case D_EVENT_ENTITY :
case D_EVENT_ENTITY_NULL :
* reinterpret_cast < idEntity * * > ( & args [ i ] ) = reinterpret_cast < idEntityPtr < idEntity > * > ( & data [ offset ] ) - > GetEntity ( ) ;
break ;
case D_EVENT_TRACE :
tracePtr = reinterpret_cast < trace_t * * > ( & args [ i ] ) ;
if ( * reinterpret_cast < bool * > ( & data [ offset ] ) )
{
* tracePtr = reinterpret_cast < trace_t * > ( & data [ offset + sizeof ( bool ) ] ) ;
if ( ( * tracePtr ) - > c . material ! = NULL )
{
// look up the material name to get the material pointer
materialName = reinterpret_cast < const char * > ( & data [ offset + sizeof ( bool ) + sizeof ( trace_t ) ] ) ;
( * tracePtr ) - > c . material = declManager - > FindMaterial ( materialName , true ) ;
}
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
else
{
* tracePtr = NULL ;
}
break ;
default :
gameLocal . Error ( " idEvent::ServiceEvents : Invalid arg format '%s' string for '%s' event. " , formatspec , ev - > GetName ( ) ) ;
2012-11-26 18:58:24 +00:00
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// the event is removed from its list so that if then object
// is deleted, the event won't be freed twice
event - > eventNode . Remove ( ) ;
assert ( event - > object ) ;
event - > object - > ProcessEventArgPtr ( ev , args ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
#if 0
// event functions may never leave return values on the FPU stack
// enable this code to check if any event call left values on the FPU stack
2012-11-28 15:47:07 +00:00
if ( ! sys - > FPU_StackIsEmpty ( ) )
{
2012-11-26 18:58:24 +00:00
gameLocal . Error ( " idEvent::ServiceEvents %d: %s left a value on the FPU stack \n " , num , ev - > GetName ( ) ) ;
}
# endif
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// return the event to the free list
event - > Free ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// Don't allow ourselves to stay in here too long. An abnormally high number
// of events being processed is evidence of an infinite loop of events.
num + + ;
2012-11-28 15:47:07 +00:00
if ( num > MAX_EVENTSPERFRAME )
{
2012-11-26 18:58:24 +00:00
gameLocal . Error ( " Event overflow. Possible infinite loop in script. " ) ;
}
}
}
/*
= = = = = = = = = = = = = = = =
idEvent : : ServiceFastEvents
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idEvent : : ServiceFastEvents ( )
{
idEvent * event ;
2012-11-26 18:58:24 +00:00
int num ;
int args [ D_EVENT_MAXARGS ] ;
int offset ;
int i ;
int numargs ;
2012-11-28 15:47:07 +00:00
const char * formatspec ;
trace_t * * tracePtr ;
const idEventDef * ev ;
byte * data ;
const char * materialName ;
2012-11-26 18:58:24 +00:00
num = 0 ;
2012-11-28 15:47:07 +00:00
while ( ! FastEventQueue . IsListEmpty ( ) )
{
2012-11-26 18:58:24 +00:00
event = FastEventQueue . Next ( ) ;
assert ( event ) ;
2012-11-28 15:47:07 +00:00
if ( event - > time > gameLocal . fast . time )
{
2012-11-26 18:58:24 +00:00
break ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// copy the data into the local args array and set up pointers
ev = event - > eventdef ;
formatspec = ev - > GetArgFormat ( ) ;
numargs = ev - > GetNumArgs ( ) ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < numargs ; i + + )
{
2012-11-26 18:58:24 +00:00
offset = ev - > GetArgOffset ( i ) ;
data = event - > data ;
2012-11-28 15:47:07 +00:00
switch ( formatspec [ i ] )
{
case D_EVENT_FLOAT :
case D_EVENT_INTEGER :
args [ i ] = * reinterpret_cast < int * > ( & data [ offset ] ) ;
break ;
case D_EVENT_VECTOR :
* reinterpret_cast < idVec3 * * > ( & args [ i ] ) = reinterpret_cast < idVec3 * > ( & data [ offset ] ) ;
break ;
case D_EVENT_STRING :
* reinterpret_cast < const char * * > ( & args [ i ] ) = reinterpret_cast < const char * > ( & data [ offset ] ) ;
break ;
case D_EVENT_ENTITY :
case D_EVENT_ENTITY_NULL :
* reinterpret_cast < idEntity * * > ( & args [ i ] ) = reinterpret_cast < idEntityPtr < idEntity > * > ( & data [ offset ] ) - > GetEntity ( ) ;
break ;
case D_EVENT_TRACE :
tracePtr = reinterpret_cast < trace_t * * > ( & args [ i ] ) ;
if ( * reinterpret_cast < bool * > ( & data [ offset ] ) )
{
* tracePtr = reinterpret_cast < trace_t * > ( & data [ offset + sizeof ( bool ) ] ) ;
if ( ( * tracePtr ) - > c . material ! = NULL )
{
// look up the material name to get the material pointer
materialName = reinterpret_cast < const char * > ( & data [ offset + sizeof ( bool ) + sizeof ( trace_t ) ] ) ;
( * tracePtr ) - > c . material = declManager - > FindMaterial ( materialName , true ) ;
}
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
else
{
* tracePtr = NULL ;
}
break ;
default :
gameLocal . Error ( " idEvent::ServiceFastEvents : Invalid arg format '%s' string for '%s' event. " , formatspec , ev - > GetName ( ) ) ;
2012-11-26 18:58:24 +00:00
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// the event is removed from its list so that if then object
// is deleted, the event won't be freed twice
event - > eventNode . Remove ( ) ;
assert ( event - > object ) ;
event - > object - > ProcessEventArgPtr ( ev , args ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
#if 0
// event functions may never leave return values on the FPU stack
// enable this code to check if any event call left values on the FPU stack
2012-11-28 15:47:07 +00:00
if ( ! sys - > FPU_StackIsEmpty ( ) )
{
2012-11-26 18:58:24 +00:00
gameLocal . Error ( " idEvent::ServiceEvents %d: %s left a value on the FPU stack \n " , num , event - > eventdef - > GetName ( ) ) ;
}
# endif
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// return the event to the free list
event - > Free ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// Don't allow ourselves to stay in here too long. An abnormally high number
// of events being processed is evidence of an infinite loop of events.
num + + ;
2012-11-28 15:47:07 +00:00
if ( num > MAX_EVENTSPERFRAME )
{
2012-11-26 18:58:24 +00:00
gameLocal . Error ( " Event overflow. Possible infinite loop in script. " ) ;
}
}
}
/*
= = = = = = = = = = = = = = = =
idEvent : : Init
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idEvent : : Init ( )
{
2012-11-26 18:58:24 +00:00
gameLocal . Printf ( " Initializing event system \n " ) ;
2012-11-28 15:47:07 +00:00
if ( eventError )
{
2012-11-26 18:58:24 +00:00
gameLocal . Error ( " %s " , eventErrorMsg ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
# ifdef CREATE_EVENT_CODE
void CreateEventCallbackHandler ( ) ;
CreateEventCallbackHandler ( ) ;
gameLocal . Error ( " Wrote event callback handler " ) ;
# endif
2012-11-28 15:47:07 +00:00
if ( initialized )
{
2012-11-26 18:58:24 +00:00
gameLocal . Printf ( " ...already initialized \n " ) ;
ClearEventList ( ) ;
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
ClearEventList ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
eventDataAllocator . Init ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
gameLocal . Printf ( " ...%i event definitions \n " , idEventDef : : NumEventCommands ( ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// the event system has started
initialized = true ;
}
/*
= = = = = = = = = = = = = = = =
idEvent : : Shutdown
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idEvent : : Shutdown ( )
{
2012-11-26 18:58:24 +00:00
gameLocal . Printf ( " Shutdown event system \n " ) ;
2012-11-28 15:47:07 +00:00
if ( ! initialized )
{
2012-11-26 18:58:24 +00:00
gameLocal . Printf ( " ...not started \n " ) ;
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
ClearEventList ( ) ;
eventDataAllocator . Shutdown ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// say it is now shutdown
initialized = false ;
}
/*
= = = = = = = = = = = = = = = =
idEvent : : Save
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idEvent : : Save ( idSaveGame * savefile )
{
char * str ;
2012-11-26 18:58:24 +00:00
int i , size ;
2012-11-28 15:47:07 +00:00
idEvent * event ;
byte * dataPtr ;
2012-11-26 18:58:24 +00:00
bool validTrace ;
2012-11-28 15:47:07 +00:00
const char * format ;
2012-11-26 18:58:24 +00:00
savefile - > WriteInt ( EventQueue . Num ( ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
event = EventQueue . Next ( ) ;
2012-11-28 15:47:07 +00:00
while ( event ! = NULL )
{
2012-11-26 18:58:24 +00:00
savefile - > WriteInt ( event - > time ) ;
savefile - > WriteString ( event - > eventdef - > GetName ( ) ) ;
savefile - > WriteString ( event - > typeinfo - > classname ) ;
savefile - > WriteObject ( event - > object ) ;
savefile - > WriteInt ( event - > eventdef - > GetArgSize ( ) ) ;
format = event - > eventdef - > GetArgFormat ( ) ;
2012-11-28 15:47:07 +00:00
for ( i = 0 , size = 0 ; i < event - > eventdef - > GetNumArgs ( ) ; + + i )
{
2012-11-26 18:58:24 +00:00
dataPtr = & event - > data [ event - > eventdef - > GetArgOffset ( i ) ] ;
2012-11-28 15:47:07 +00:00
switch ( format [ i ] )
{
2012-11-26 18:58:24 +00:00
case D_EVENT_FLOAT :
2012-11-28 15:47:07 +00:00
savefile - > WriteFloat ( * reinterpret_cast < float * > ( dataPtr ) ) ;
2012-11-26 18:58:24 +00:00
size + = sizeof ( float ) ;
break ;
case D_EVENT_INTEGER :
case D_EVENT_ENTITY :
case D_EVENT_ENTITY_NULL :
2012-11-28 15:47:07 +00:00
savefile - > WriteInt ( * reinterpret_cast < int * > ( dataPtr ) ) ;
2012-11-26 18:58:24 +00:00
size + = sizeof ( int ) ;
break ;
case D_EVENT_VECTOR :
2012-11-28 15:47:07 +00:00
savefile - > WriteVec3 ( * reinterpret_cast < idVec3 * > ( dataPtr ) ) ;
2012-11-26 18:58:24 +00:00
size + = sizeof ( idVec3 ) ;
break ;
case D_EVENT_TRACE :
2012-11-28 15:47:07 +00:00
validTrace = * reinterpret_cast < bool * > ( dataPtr ) ;
2012-11-26 18:58:24 +00:00
savefile - > WriteBool ( validTrace ) ;
size + = sizeof ( bool ) ;
2012-11-28 15:47:07 +00:00
if ( validTrace )
{
2012-11-26 18:58:24 +00:00
size + = sizeof ( trace_t ) ;
2012-11-28 15:47:07 +00:00
const trace_t & t = * reinterpret_cast < trace_t * > ( dataPtr + sizeof ( bool ) ) ;
2012-11-26 18:58:24 +00:00
SaveTrace ( savefile , t ) ;
2012-11-28 15:47:07 +00:00
if ( t . c . material )
{
2012-11-26 18:58:24 +00:00
size + = MAX_STRING_LEN ;
2012-11-28 15:47:07 +00:00
str = reinterpret_cast < char * > ( dataPtr + sizeof ( bool ) + sizeof ( trace_t ) ) ;
2012-11-26 18:58:24 +00:00
savefile - > Write ( str , MAX_STRING_LEN ) ;
}
}
break ;
default :
break ;
}
}
2012-11-28 15:47:07 +00:00
assert ( size = = ( int ) event - > eventdef - > GetArgSize ( ) ) ;
2012-11-26 18:58:24 +00:00
event = event - > eventNode . Next ( ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// Save the Fast EventQueue
savefile - > WriteInt ( FastEventQueue . Num ( ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
event = FastEventQueue . Next ( ) ;
2012-11-28 15:47:07 +00:00
while ( event ! = NULL )
{
2012-11-26 18:58:24 +00:00
savefile - > WriteInt ( event - > time ) ;
savefile - > WriteString ( event - > eventdef - > GetName ( ) ) ;
savefile - > WriteString ( event - > typeinfo - > classname ) ;
savefile - > WriteObject ( event - > object ) ;
savefile - > WriteInt ( event - > eventdef - > GetArgSize ( ) ) ;
savefile - > Write ( event - > data , event - > eventdef - > GetArgSize ( ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
event = event - > eventNode . Next ( ) ;
}
}
/*
= = = = = = = = = = = = = = = =
idEvent : : Restore
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idEvent : : Restore ( idRestoreGame * savefile )
{
char * str ;
2012-11-26 18:58:24 +00:00
int num , argsize , i , j , size ;
idStr name ;
2012-11-28 15:47:07 +00:00
byte * dataPtr ;
idEvent * event ;
const char * format ;
2012-11-26 18:58:24 +00:00
savefile - > ReadInt ( num ) ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < num ; i + + )
{
if ( FreeEvents . IsListEmpty ( ) )
{
2012-11-26 18:58:24 +00:00
gameLocal . Error ( " idEvent::Restore : No more free events " ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
event = FreeEvents . Next ( ) ;
event - > eventNode . Remove ( ) ;
event - > eventNode . AddToEnd ( EventQueue ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > ReadInt ( event - > time ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// read the event name
savefile - > ReadString ( name ) ;
event - > eventdef = idEventDef : : FindEvent ( name ) ;
2012-11-28 15:47:07 +00:00
if ( event - > eventdef = = NULL )
{
2012-11-26 18:58:24 +00:00
savefile - > Error ( " idEvent::Restore: unknown event '%s' " , name . c_str ( ) ) ;
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// read the classtype
savefile - > ReadString ( name ) ;
event - > typeinfo = idClass : : GetClass ( name ) ;
2012-11-28 15:47:07 +00:00
if ( event - > typeinfo = = NULL )
{
2012-11-26 18:58:24 +00:00
savefile - > Error ( " idEvent::Restore: unknown class '%s' on event '%s' " , name . c_str ( ) , event - > eventdef - > GetName ( ) ) ;
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > ReadObject ( event - > object ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// read the args
savefile - > ReadInt ( argsize ) ;
2012-11-28 15:47:07 +00:00
if ( argsize ! = ( int ) event - > eventdef - > GetArgSize ( ) )
{
2012-11-26 18:58:24 +00:00
savefile - > Error ( " idEvent::Restore: arg size (%d) doesn't match saved arg size(%d) on event '%s' " , event - > eventdef - > GetArgSize ( ) , argsize , event - > eventdef - > GetName ( ) ) ;
}
2012-11-28 15:47:07 +00:00
if ( argsize )
{
2012-11-26 18:58:24 +00:00
event - > data = eventDataAllocator . Alloc ( argsize ) ;
format = event - > eventdef - > GetArgFormat ( ) ;
assert ( format ) ;
2012-11-28 15:47:07 +00:00
for ( j = 0 , size = 0 ; j < event - > eventdef - > GetNumArgs ( ) ; + + j )
{
2012-11-26 18:58:24 +00:00
dataPtr = & event - > data [ event - > eventdef - > GetArgOffset ( j ) ] ;
2012-11-28 15:47:07 +00:00
switch ( format [ j ] )
{
2012-11-26 18:58:24 +00:00
case D_EVENT_FLOAT :
2012-11-28 15:47:07 +00:00
savefile - > ReadFloat ( * reinterpret_cast < float * > ( dataPtr ) ) ;
2012-11-26 18:58:24 +00:00
size + = sizeof ( float ) ;
break ;
case D_EVENT_INTEGER :
case D_EVENT_ENTITY :
case D_EVENT_ENTITY_NULL :
2012-11-28 15:47:07 +00:00
savefile - > ReadInt ( * reinterpret_cast < int * > ( dataPtr ) ) ;
2012-11-26 18:58:24 +00:00
size + = sizeof ( int ) ;
break ;
case D_EVENT_VECTOR :
2012-11-28 15:47:07 +00:00
savefile - > ReadVec3 ( * reinterpret_cast < idVec3 * > ( dataPtr ) ) ;
2012-11-26 18:58:24 +00:00
size + = sizeof ( idVec3 ) ;
break ;
case D_EVENT_TRACE :
2012-11-28 15:47:07 +00:00
savefile - > ReadBool ( * reinterpret_cast < bool * > ( dataPtr ) ) ;
2012-11-26 18:58:24 +00:00
size + = sizeof ( bool ) ;
2012-11-28 15:47:07 +00:00
if ( * reinterpret_cast < bool * > ( dataPtr ) )
{
2012-11-26 18:58:24 +00:00
size + = sizeof ( trace_t ) ;
2012-11-28 15:47:07 +00:00
trace_t & t = * reinterpret_cast < trace_t * > ( dataPtr + sizeof ( bool ) ) ;
RestoreTrace ( savefile , t ) ;
if ( t . c . material )
{
2012-11-26 18:58:24 +00:00
size + = MAX_STRING_LEN ;
2012-11-28 15:47:07 +00:00
str = reinterpret_cast < char * > ( dataPtr + sizeof ( bool ) + sizeof ( trace_t ) ) ;
2012-11-26 18:58:24 +00:00
savefile - > Read ( str , MAX_STRING_LEN ) ;
}
}
break ;
default :
break ;
}
}
2012-11-28 15:47:07 +00:00
assert ( size = = ( int ) event - > eventdef - > GetArgSize ( ) ) ;
}
else
{
2012-11-26 18:58:24 +00:00
event - > data = NULL ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// Restore the Fast EventQueue
savefile - > ReadInt ( num ) ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < num ; i + + )
{
if ( FreeEvents . IsListEmpty ( ) )
{
2012-11-26 18:58:24 +00:00
gameLocal . Error ( " idEvent::Restore : No more free events " ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
event = FreeEvents . Next ( ) ;
event - > eventNode . Remove ( ) ;
event - > eventNode . AddToEnd ( FastEventQueue ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > ReadInt ( event - > time ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// read the event name
savefile - > ReadString ( name ) ;
event - > eventdef = idEventDef : : FindEvent ( name ) ;
2012-11-28 15:47:07 +00:00
if ( event - > eventdef = = NULL )
{
2012-11-26 18:58:24 +00:00
savefile - > Error ( " idEvent::Restore: unknown event '%s' " , name . c_str ( ) ) ;
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// read the classtype
savefile - > ReadString ( name ) ;
event - > typeinfo = idClass : : GetClass ( name ) ;
2012-11-28 15:47:07 +00:00
if ( event - > typeinfo = = NULL )
{
2012-11-26 18:58:24 +00:00
savefile - > Error ( " idEvent::Restore: unknown class '%s' on event '%s' " , name . c_str ( ) , event - > eventdef - > GetName ( ) ) ;
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > ReadObject ( event - > object ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// read the args
savefile - > ReadInt ( argsize ) ;
2012-11-28 15:47:07 +00:00
if ( argsize ! = ( int ) event - > eventdef - > GetArgSize ( ) )
{
2012-11-26 18:58:24 +00:00
savefile - > Error ( " idEvent::Restore: arg size (%d) doesn't match saved arg size(%d) on event '%s' " , event - > eventdef - > GetArgSize ( ) , argsize , event - > eventdef - > GetName ( ) ) ;
}
2012-11-28 15:47:07 +00:00
if ( argsize )
{
2012-11-26 18:58:24 +00:00
event - > data = eventDataAllocator . Alloc ( argsize ) ;
savefile - > Read ( event - > data , argsize ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
event - > data = NULL ;
}
}
}
/*
= = = = = = = = = = = = = = = =
idEvent : : ReadTrace
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idRestoreGame has a ReadTrace procedure , but unfortunately idEvent wants the material
string name at the of the data structure rather than in the middle
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idEvent : : RestoreTrace ( idRestoreGame * savefile , trace_t & trace )
{
2012-11-26 18:58:24 +00:00
savefile - > ReadFloat ( trace . fraction ) ;
savefile - > ReadVec3 ( trace . endpos ) ;
savefile - > ReadMat3 ( trace . endAxis ) ;
2012-11-28 15:47:07 +00:00
savefile - > ReadInt ( ( int & ) trace . c . type ) ;
2012-11-26 18:58:24 +00:00
savefile - > ReadVec3 ( trace . c . point ) ;
savefile - > ReadVec3 ( trace . c . normal ) ;
savefile - > ReadFloat ( trace . c . dist ) ;
savefile - > ReadInt ( trace . c . contents ) ;
2012-11-28 15:47:07 +00:00
savefile - > ReadInt ( ( int & ) trace . c . material ) ;
2012-11-26 18:58:24 +00:00
savefile - > ReadInt ( trace . c . contents ) ;
savefile - > ReadInt ( trace . c . modelFeature ) ;
savefile - > ReadInt ( trace . c . trmFeature ) ;
savefile - > ReadInt ( trace . c . id ) ;
}
/*
= = = = = = = = = = = = = = = =
idEvent : : WriteTrace
idSaveGame has a WriteTrace procedure , but unfortunately idEvent wants the material
string name at the of the data structure rather than in the middle
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idEvent : : SaveTrace ( idSaveGame * savefile , const trace_t & trace )
{
2012-11-26 18:58:24 +00:00
savefile - > WriteFloat ( trace . fraction ) ;
savefile - > WriteVec3 ( trace . endpos ) ;
savefile - > WriteMat3 ( trace . endAxis ) ;
savefile - > WriteInt ( trace . c . type ) ;
savefile - > WriteVec3 ( trace . c . point ) ;
savefile - > WriteVec3 ( trace . c . normal ) ;
savefile - > WriteFloat ( trace . c . dist ) ;
savefile - > WriteInt ( trace . c . contents ) ;
2012-11-28 15:47:07 +00:00
savefile - > WriteInt ( ( int & ) trace . c . material ) ;
2012-11-26 18:58:24 +00:00
savefile - > WriteInt ( trace . c . contents ) ;
savefile - > WriteInt ( trace . c . modelFeature ) ;
savefile - > WriteInt ( trace . c . trmFeature ) ;
savefile - > WriteInt ( trace . c . id ) ;
}
# ifdef CREATE_EVENT_CODE
/*
= = = = = = = = = = = = = = = =
CreateEventCallbackHandler
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void CreateEventCallbackHandler ( )
{
2012-11-26 18:58:24 +00:00
int i , j , k ;
char argString [ D_EVENT_MAXARGS + 1 ] ;
idStr string1 ;
idStr string2 ;
2012-11-28 15:47:07 +00:00
idFile * file ;
2012-11-26 18:58:24 +00:00
file = fileSystem - > OpenFileWrite ( " Callbacks.cpp " ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
file - > Printf ( " /* \n ================================================================================================ \n CONFIDENTIAL AND PROPRIETARY INFORMATION/NOT FOR DISCLOSURE WITHOUT WRITTEN PERMISSION \n Copyright 1999-2012 id Software LLC, a ZeniMax Media company. All Rights Reserved. \n ================================================================================================ \n */ \n \n " ) ;
2012-11-28 15:47:07 +00:00
for ( i = 1 ; i < = D_EVENT_MAXARGS ; i + + )
{
2012-11-26 18:58:24 +00:00
file - > Printf ( " \t /******************************************************* \n \n \t \t %d args \n \n \t *******************************************************/ \n \n " , i ) ;
2012-11-28 15:47:07 +00:00
for ( j = 0 ; j < ( 1 < < i ) ; j + + )
{
for ( k = 0 ; k < i ; k + + )
{
2012-11-26 18:58:24 +00:00
argString [ k ] = j & ( 1 < < k ) ? ' f ' : ' i ' ;
}
argString [ i ] = ' \0 ' ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
string1 . Empty ( ) ;
string2 . Empty ( ) ;
2012-11-28 15:47:07 +00:00
for ( k = 0 ; k < i ; k + + )
{
if ( j & ( 1 < < k ) )
{
2012-11-26 18:58:24 +00:00
string1 + = " const float " ;
string2 + = va ( " *( float * )&data[ %d ] " , k ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
string1 + = " void * " ;
string2 + = va ( " (void *)data[ %d ] " , k ) ;
}
2012-11-28 15:47:07 +00:00
if ( k < i - 1 )
{
2012-11-26 18:58:24 +00:00
string1 + = " , " ;
string2 + = " , " ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
file - > Printf ( " \t case %d : \n \t \t typedef void ( idClass::*eventCallback_%s_t )( %s ); \n " , ( 1 < < ( i + D_EVENT_MAXARGS ) ) + j , argString , string1 . c_str ( ) ) ;
file - > Printf ( " \t \t ( this->*( eventCallback_%s_t )callback )( %s ); \n \t \t break; \n \n " , argString , string2 . c_str ( ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
fileSystem - > CloseFile ( file ) ;
}
# endif