mirror of
https://github.com/jmarshall23/DoomRTX.git
synced 2026-08-21 13:10:37 +02:00
Fixed x64 script/class connections and added material flags that are needed.
This commit is contained in:
@@ -60,10 +60,10 @@ typedef enum {
|
||||
} traceModel_t;
|
||||
|
||||
// these are bit cache limits
|
||||
#define MAX_TRACEMODEL_VERTS 32
|
||||
#define MAX_TRACEMODEL_EDGES 32
|
||||
#define MAX_TRACEMODEL_POLYS 16
|
||||
#define MAX_TRACEMODEL_POLYEDGES 16
|
||||
#define MAX_TRACEMODEL_VERTS 64
|
||||
#define MAX_TRACEMODEL_EDGES 64
|
||||
#define MAX_TRACEMODEL_POLYS 32
|
||||
#define MAX_TRACEMODEL_POLYEDGES 32
|
||||
|
||||
typedef idVec3 traceModelVert_t;
|
||||
|
||||
|
||||
+1530
-1531
File diff suppressed because it is too large
Load Diff
@@ -12,7 +12,6 @@ instancing of objects.
|
||||
|
||||
#include "../Game_local.h"
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
|
||||
idTypeInfo
|
||||
@@ -882,7 +881,7 @@ idClass::ProcessEventArgs
|
||||
bool idClass::ProcessEventArgs( const idEventDef *ev, int numargs, ... ) {
|
||||
idTypeInfo *c;
|
||||
int num;
|
||||
int data[ D_EVENT_MAXARGS ];
|
||||
intptr_t data[ D_EVENT_MAXARGS ];
|
||||
va_list args;
|
||||
|
||||
assert( ev );
|
||||
@@ -990,106 +989,89 @@ bool idClass::ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg ar
|
||||
idClass::ProcessEventArgPtr
|
||||
================
|
||||
*/
|
||||
bool idClass::ProcessEventArgPtr( const idEventDef *ev, int *data ) {
|
||||
idTypeInfo *c;
|
||||
bool idClass::ProcessEventArgPtr( const idEventDef *ev, intptr_t*data ) {
|
||||
idTypeInfo* c;
|
||||
int num;
|
||||
eventCallback_t callback;
|
||||
|
||||
assert( ev );
|
||||
assert( idEvent::initialized );
|
||||
|
||||
if ( g_debugTriggers.GetBool() && ( ev == &EV_Activate ) && IsType( idEntity::Type ) ) {
|
||||
const idEntity *ent = *reinterpret_cast<idEntity **>( data );
|
||||
gameLocal.Printf( "%d: '%s' activated by '%s'\n", gameLocal.framenum, static_cast<idEntity *>( this )->GetName(), ent ? ent->GetName() : "NULL" );
|
||||
assert(ev);
|
||||
assert(idEvent::initialized);
|
||||
if (g_debugTriggers.GetBool() && (ev == &EV_Activate) && IsType(idEntity::Type)) {
|
||||
const idEntity* ent = *reinterpret_cast<idEntity**>(data);
|
||||
gameLocal.Printf("%d: '%s' activated by '%s'\n", gameLocal.framenum, static_cast<idEntity*>(this)->GetName(), ent ? ent->GetName() : "NULL");
|
||||
}
|
||||
|
||||
c = GetType();
|
||||
num = ev->GetEventNum();
|
||||
if ( !c->eventMap[ num ] ) {
|
||||
if (!c->eventMap[num]) {
|
||||
// we don't respond to this event, so ignore it
|
||||
return false;
|
||||
}
|
||||
|
||||
callback = c->eventMap[ num ];
|
||||
|
||||
#if !CPU_EASYARGS
|
||||
|
||||
/*
|
||||
on ppc architecture, floats are passed in a seperate set of registers
|
||||
the function prototypes must have matching float declaration
|
||||
|
||||
http://developer.apple.com/documentation/DeveloperTools/Conceptual/MachORuntime/2rt_powerpc_abi/chapter_9_section_5.html
|
||||
*/
|
||||
|
||||
switch( ev->GetFormatspecIndex() ) {
|
||||
case 1 << D_EVENT_MAXARGS :
|
||||
( this->*callback )();
|
||||
callback = c->eventMap[num];
|
||||
// RB: I tried first to get CPU_EASYARGS switch running with x86_64
|
||||
// but it caused many crashes with the Doom scripts.
|
||||
// The new Callbacks.cpp was generated with intptr_t and it works fine.
|
||||
#if CPU_EASYARGS
|
||||
/*
|
||||
on ppc architecture, floats are passed in a separate set of registers
|
||||
the function prototypes must have matching float declaration
|
||||
http://developer.apple.com/documentation/DeveloperTools/Conceptual/MachORuntime/2rt_powerpc_abi/chapter_9_section_5.html
|
||||
*/
|
||||
switch (ev->GetFormatspecIndex())
|
||||
{
|
||||
case 1 << D_EVENT_MAXARGS:
|
||||
(this->*callback)();
|
||||
break;
|
||||
|
||||
// generated file - see CREATE_EVENT_CODE
|
||||
// generated file - see CREATE_EVENT_CODE
|
||||
#include "Callbacks.cpp"
|
||||
|
||||
default:
|
||||
gameLocal.Warning( "Invalid formatspec on event '%s'", ev->GetName() );
|
||||
gameLocal.Warning("Invalid formatspec on event '%s'", ev->GetName());
|
||||
break;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
assert( D_EVENT_MAXARGS == 8 );
|
||||
|
||||
switch( ev->GetNumArgs() ) {
|
||||
case 0 :
|
||||
( this->*callback )();
|
||||
assert(D_EVENT_MAXARGS == 8);
|
||||
// RB: 64 bit fixes, changed int to intptr_t
|
||||
switch (ev->GetNumArgs())
|
||||
{
|
||||
case 0:
|
||||
(this->*callback)();
|
||||
break;
|
||||
|
||||
case 1 :
|
||||
typedef void ( idClass::*eventCallback_1_t )( const int );
|
||||
( this->*( eventCallback_1_t )callback )( data[ 0 ] );
|
||||
case 1:
|
||||
typedef void (idClass::* eventCallback_1_t)(const intptr_t);
|
||||
(this->*(eventCallback_1_t)callback)(data[0]);
|
||||
break;
|
||||
|
||||
case 2 :
|
||||
typedef void ( idClass::*eventCallback_2_t )( const int, const int );
|
||||
( this->*( eventCallback_2_t )callback )( data[ 0 ], data[ 1 ] );
|
||||
case 2:
|
||||
typedef void (idClass::* eventCallback_2_t)(const intptr_t, const intptr_t);
|
||||
(this->*(eventCallback_2_t)callback)(data[0], data[1]);
|
||||
break;
|
||||
|
||||
case 3 :
|
||||
typedef void ( idClass::*eventCallback_3_t )( const int, const int, const int );
|
||||
( this->*( eventCallback_3_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ] );
|
||||
case 3:
|
||||
typedef void (idClass::* eventCallback_3_t)(const intptr_t, const intptr_t, const intptr_t);
|
||||
(this->*(eventCallback_3_t)callback)(data[0], data[1], data[2]);
|
||||
break;
|
||||
|
||||
case 4 :
|
||||
typedef void ( idClass::*eventCallback_4_t )( const int, const int, const int, const int );
|
||||
( this->*( eventCallback_4_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ] );
|
||||
case 4:
|
||||
typedef void (idClass::* eventCallback_4_t)(const intptr_t, const intptr_t, const intptr_t, const intptr_t);
|
||||
(this->*(eventCallback_4_t)callback)(data[0], data[1], data[2], data[3]);
|
||||
break;
|
||||
|
||||
case 5 :
|
||||
typedef void ( idClass::*eventCallback_5_t )( const int, const int, const int, const int, const int );
|
||||
( this->*( eventCallback_5_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ] );
|
||||
case 5:
|
||||
typedef void (idClass::* eventCallback_5_t)(const intptr_t, const intptr_t, const intptr_t, const intptr_t, const intptr_t);
|
||||
(this->*(eventCallback_5_t)callback)(data[0], data[1], data[2], data[3], data[4]);
|
||||
break;
|
||||
|
||||
case 6 :
|
||||
typedef void ( idClass::*eventCallback_6_t )( const int, const int, const int, const int, const int, const int );
|
||||
( this->*( eventCallback_6_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ] );
|
||||
case 6:
|
||||
typedef void (idClass::* eventCallback_6_t)(const intptr_t, const intptr_t, const intptr_t, const intptr_t, const intptr_t, const intptr_t);
|
||||
(this->*(eventCallback_6_t)callback)(data[0], data[1], data[2], data[3], data[4], data[5]);
|
||||
break;
|
||||
|
||||
case 7 :
|
||||
typedef void ( idClass::*eventCallback_7_t )( const int, const int, const int, const int, const int, const int, const int );
|
||||
( this->*( eventCallback_7_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ] );
|
||||
case 7:
|
||||
typedef void (idClass::* eventCallback_7_t)(const intptr_t, const intptr_t, const intptr_t, const intptr_t, const intptr_t, const intptr_t, const intptr_t);
|
||||
(this->*(eventCallback_7_t)callback)(data[0], data[1], data[2], data[3], data[4], data[5], data[6]);
|
||||
break;
|
||||
|
||||
case 8 :
|
||||
typedef void ( idClass::*eventCallback_8_t )( const int, const int, const int, const int, const int, const int, const int, const int );
|
||||
( this->*( eventCallback_8_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] );
|
||||
case 8:
|
||||
typedef void (idClass::* eventCallback_8_t)(const intptr_t, const intptr_t, const intptr_t, const intptr_t, const intptr_t, const intptr_t, const intptr_t, const intptr_t);
|
||||
(this->*(eventCallback_8_t)callback)(data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]);
|
||||
break;
|
||||
|
||||
default:
|
||||
gameLocal.Warning( "Invalid formatspec on event '%s'", ev->GetName() );
|
||||
gameLocal.Warning("Invalid formatspec on event '%s'", ev->GetName());
|
||||
break;
|
||||
}
|
||||
|
||||
// RB end
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,17 +32,17 @@ struct idEventFunc {
|
||||
class idEventArg {
|
||||
public:
|
||||
int type;
|
||||
int value;
|
||||
intptr_t value;
|
||||
|
||||
idEventArg() { type = D_EVENT_INTEGER; value = 0; };
|
||||
idEventArg( int data ) { type = D_EVENT_INTEGER; value = data; };
|
||||
idEventArg( float data ) { type = D_EVENT_FLOAT; value = *reinterpret_cast<int *>( &data ); };
|
||||
//HUMANHEAD: aob - added const to idVec3
|
||||
idEventArg( const idVec3 &data ) { type = D_EVENT_VECTOR; value = reinterpret_cast<int>( &data ); };
|
||||
idEventArg( const idStr &data ) { type = D_EVENT_STRING; value = reinterpret_cast<int>( data.c_str() ); };
|
||||
idEventArg( const char *data ) { type = D_EVENT_STRING; value = reinterpret_cast<int>( data ); };
|
||||
idEventArg( const class idEntity *data ) { type = D_EVENT_ENTITY; value = reinterpret_cast<int>( data ); };
|
||||
idEventArg( const struct trace_s *data ) { type = D_EVENT_TRACE; value = reinterpret_cast<int>( data ); };
|
||||
idEventArg( const idVec3 &data ) { type = D_EVENT_VECTOR; value = reinterpret_cast<intptr_t>( &data ); };
|
||||
idEventArg( const idStr &data ) { type = D_EVENT_STRING; value = reinterpret_cast<intptr_t>( data.c_str() ); };
|
||||
idEventArg( const char *data ) { type = D_EVENT_STRING; value = reinterpret_cast<intptr_t>( data ); };
|
||||
idEventArg( const class idEntity *data ) { type = D_EVENT_ENTITY; value = reinterpret_cast<intptr_t>( data ); };
|
||||
idEventArg( const struct trace_s *data ) { type = D_EVENT_TRACE; value = reinterpret_cast<intptr_t>( data ); };
|
||||
};
|
||||
|
||||
class idAllocError : public idException {
|
||||
@@ -206,7 +206,7 @@ public:
|
||||
bool ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7 );
|
||||
bool ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7, idEventArg arg8 );
|
||||
|
||||
bool ProcessEventArgPtr( const idEventDef *ev, int *data );
|
||||
bool ProcessEventArgPtr( const idEventDef *ev, intptr_t*data );
|
||||
void CancelEvents( const idEventDef *ev );
|
||||
virtual // HUMANHEAD nla
|
||||
void Event_Remove( void );
|
||||
|
||||
+186
-119
@@ -70,33 +70,43 @@ idEventDef::idEventDef( const char *command, const char *formatspec, char return
|
||||
for( i = 0; i < numargs; i++ ) {
|
||||
argOffset[ i ] = argsize;
|
||||
switch( formatspec[ i ] ) {
|
||||
case D_EVENT_FLOAT :
|
||||
case D_EVENT_FLOAT:
|
||||
bits |= 1 << i;
|
||||
argsize += sizeof( float );
|
||||
// RB: 64 bit fix, changed sizeof( float ) to sizeof( intptr_t )
|
||||
argsize += sizeof(intptr_t);
|
||||
// RB end
|
||||
break;
|
||||
|
||||
case D_EVENT_INTEGER :
|
||||
argsize += sizeof( int );
|
||||
case D_EVENT_INTEGER:
|
||||
// RB: 64 bit fix, changed sizeof( int ) to sizeof( intptr_t )
|
||||
argsize += sizeof(intptr_t);
|
||||
// RB end
|
||||
break;
|
||||
|
||||
case D_EVENT_VECTOR :
|
||||
argsize += sizeof( idVec3 );
|
||||
case D_EVENT_VECTOR:
|
||||
// RB: 64 bit fix, changed sizeof( idVec3 ) to E_EVENT_SIZEOF_VEC
|
||||
argsize += E_EVENT_SIZEOF_VEC;
|
||||
// RB end
|
||||
break;
|
||||
|
||||
case D_EVENT_STRING :
|
||||
case D_EVENT_STRING:
|
||||
argsize += MAX_STRING_LEN;
|
||||
break;
|
||||
|
||||
case D_EVENT_ENTITY :
|
||||
argsize += sizeof( idEntityPtr<idEntity> );
|
||||
case D_EVENT_ENTITY:
|
||||
// RB: 64 bit fix, sizeof( idEntityPtr<idEntity> ) to sizeof( intptr_t )
|
||||
argsize += sizeof(intptr_t);
|
||||
// RB end
|
||||
break;
|
||||
|
||||
case D_EVENT_ENTITY_NULL :
|
||||
argsize += sizeof( idEntityPtr<idEntity> );
|
||||
case D_EVENT_ENTITY_NULL:
|
||||
// RB: 64 bit fix, sizeof( idEntityPtr<idEntity> ) to sizeof( intptr_t )
|
||||
argsize += sizeof(intptr_t);
|
||||
// RB end
|
||||
break;
|
||||
|
||||
case D_EVENT_TRACE :
|
||||
argsize += sizeof( trace_t ) + MAX_STRING_LEN + sizeof( bool );
|
||||
case D_EVENT_TRACE:
|
||||
argsize += sizeof(trace_t) + MAX_STRING_LEN + sizeof(bool);
|
||||
break;
|
||||
|
||||
default :
|
||||
@@ -326,7 +336,7 @@ idEvent *idEvent::Alloc( const idEventDef *evdef, int numargs, va_list args ) {
|
||||
idEvent::CopyArgs
|
||||
================
|
||||
*/
|
||||
void idEvent::CopyArgs( const idEventDef *evdef, int numargs, va_list args, int data[ D_EVENT_MAXARGS ] ) {
|
||||
void idEvent::CopyArgs( const idEventDef *evdef, int numargs, va_list args, intptr_t data[ D_EVENT_MAXARGS ] ) {
|
||||
int i;
|
||||
const char *format;
|
||||
idEventArg *arg;
|
||||
@@ -455,7 +465,7 @@ idEvent::ServiceEvents
|
||||
void idEvent::ServiceEvents( void ) {
|
||||
idEvent *event;
|
||||
int num;
|
||||
int args[ D_EVENT_MAXARGS ];
|
||||
intptr_t args[ D_EVENT_MAXARGS ];
|
||||
int offset;
|
||||
int i;
|
||||
int numargs;
|
||||
@@ -628,68 +638,91 @@ int idEvent::NumQueuedEvents( const idClass *obj, const idEventDef *evdef ) {
|
||||
idEvent::Save
|
||||
================
|
||||
*/
|
||||
void idEvent::Save( idSaveGame *savefile ) {
|
||||
char *str;
|
||||
void idEvent::Save(idSaveGame* savefile) {
|
||||
char* str;
|
||||
int i, size;
|
||||
idEvent *event;
|
||||
byte *dataPtr;
|
||||
idEvent* event;
|
||||
byte* dataPtr;
|
||||
bool validTrace;
|
||||
const char *format;
|
||||
const char* format;
|
||||
// RB: for missing D_EVENT_STRING
|
||||
idStr s;
|
||||
// RB end
|
||||
|
||||
savefile->WriteInt( EventQueue.Num() );
|
||||
savefile->WriteInt(EventQueue.Num());
|
||||
|
||||
event = EventQueue.Next();
|
||||
while( event != NULL ) {
|
||||
savefile->WriteInt( event->time );
|
||||
savefile->WriteString( event->eventdef->GetName() );
|
||||
savefile->WriteString( event->typeinfo->classname );
|
||||
savefile->WriteObject( event->object );
|
||||
savefile->WriteInt( event->eventdef->GetArgSize() );
|
||||
while (event != NULL)
|
||||
{
|
||||
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();
|
||||
for ( i = 0, size = 0; i < event->eventdef->GetNumArgs(); ++i) {
|
||||
dataPtr = &event->data[ event->eventdef->GetArgOffset( i ) ];
|
||||
switch( format[ i ] ) {
|
||||
case D_EVENT_FLOAT :
|
||||
savefile->WriteFloat( *reinterpret_cast<float *>( dataPtr ) );
|
||||
size += sizeof( float );
|
||||
for (i = 0, size = 0; i < event->eventdef->GetNumArgs(); ++i)
|
||||
{
|
||||
dataPtr = &event->data[event->eventdef->GetArgOffset(i)];
|
||||
switch (format[i])
|
||||
{
|
||||
case D_EVENT_FLOAT:
|
||||
savefile->WriteFloat(*reinterpret_cast<float*>(dataPtr));
|
||||
// RB: 64 bit fix, changed sizeof( float ) to sizeof( intptr_t )
|
||||
size += sizeof(intptr_t);
|
||||
// RB end
|
||||
break;
|
||||
case D_EVENT_INTEGER :
|
||||
case D_EVENT_ENTITY :
|
||||
case D_EVENT_ENTITY_NULL :
|
||||
savefile->WriteInt( *reinterpret_cast<int *>( dataPtr ) );
|
||||
size += sizeof( int );
|
||||
case D_EVENT_INTEGER:
|
||||
// RB: 64 bit fix, changed sizeof( int ) to sizeof( intptr_t )
|
||||
savefile->WriteInt(*reinterpret_cast<int*>(dataPtr));
|
||||
size += sizeof(intptr_t);
|
||||
break;
|
||||
case D_EVENT_VECTOR :
|
||||
savefile->WriteVec3( *reinterpret_cast<idVec3 *>( dataPtr ) );
|
||||
size += sizeof( idVec3 );
|
||||
// RB end
|
||||
case D_EVENT_ENTITY:
|
||||
case D_EVENT_ENTITY_NULL:
|
||||
// RB: 64 bit fix, changed alignment to sizeof( intptr_t )
|
||||
reinterpret_cast<idEntityPtr<idEntity>*>(dataPtr)->Save(savefile);
|
||||
size += sizeof(intptr_t);
|
||||
// RB end
|
||||
break;
|
||||
case D_EVENT_TRACE :
|
||||
validTrace = *reinterpret_cast<bool *>( dataPtr );
|
||||
savefile->WriteBool( validTrace );
|
||||
size += sizeof( bool );
|
||||
if ( validTrace ) {
|
||||
size += sizeof( trace_t );
|
||||
const trace_t &t = *reinterpret_cast<trace_t *>( dataPtr + sizeof( bool ) );
|
||||
SaveTrace( savefile, t );
|
||||
if ( t.c.material ) {
|
||||
size += MAX_STRING_LEN;
|
||||
str = reinterpret_cast<char *>( dataPtr + sizeof( bool ) + sizeof( trace_t ) );
|
||||
savefile->Write( str, MAX_STRING_LEN );
|
||||
}
|
||||
}
|
||||
case D_EVENT_VECTOR:
|
||||
savefile->WriteVec3(*reinterpret_cast<idVec3*>(dataPtr));
|
||||
// RB: 64 bit fix, changed sizeof( int ) to E_EVENT_SIZEOF_VEC
|
||||
size += E_EVENT_SIZEOF_VEC;
|
||||
// RB end
|
||||
break;
|
||||
// HUMANHEAD mdl: Added support for saving strings passed in events
|
||||
#if 1
|
||||
// RB: added missing D_EVENT_STRING case
|
||||
case D_EVENT_STRING:
|
||||
str = reinterpret_cast<char *>( dataPtr );
|
||||
savefile->Write( str, MAX_STRING_LEN );
|
||||
s.Clear();
|
||||
s.Append(reinterpret_cast<char*>(dataPtr));
|
||||
savefile->WriteString(s);
|
||||
//size += s.Length();
|
||||
size += MAX_STRING_LEN;
|
||||
break;
|
||||
// HUMANHEAD END
|
||||
// RB end
|
||||
#endif
|
||||
case D_EVENT_TRACE:
|
||||
validTrace = *reinterpret_cast<bool*>(dataPtr);
|
||||
savefile->WriteBool(validTrace);
|
||||
size += sizeof(bool);
|
||||
if (validTrace)
|
||||
{
|
||||
size += sizeof(trace_t);
|
||||
const trace_t& t = *reinterpret_cast<trace_t*>(dataPtr + sizeof(bool));
|
||||
SaveTrace(savefile, t);
|
||||
if (t.c.material)
|
||||
{
|
||||
size += MAX_STRING_LEN;
|
||||
str = reinterpret_cast<char*>(dataPtr + sizeof(bool) + sizeof(trace_t));
|
||||
savefile->Write(str, MAX_STRING_LEN);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert( size == event->eventdef->GetArgSize() );
|
||||
assert(size == (int)event->eventdef->GetArgSize());
|
||||
event = event->eventNode.Next();
|
||||
}
|
||||
}
|
||||
@@ -699,96 +732,130 @@ void idEvent::Save( idSaveGame *savefile ) {
|
||||
idEvent::Restore
|
||||
================
|
||||
*/
|
||||
void idEvent::Restore( idRestoreGame *savefile ) {
|
||||
char *str;
|
||||
void idEvent::Restore(idRestoreGame* savefile) {
|
||||
char* str;
|
||||
int num, argsize, i, j, size;
|
||||
idStr name;
|
||||
byte *dataPtr;
|
||||
idEvent *event;
|
||||
const char *format;
|
||||
byte* dataPtr;
|
||||
idEvent* event;
|
||||
const char* format;
|
||||
// RB: for missing D_EVENT_STRING
|
||||
idStr s;
|
||||
// RB end
|
||||
|
||||
savefile->ReadInt( num );
|
||||
savefile->ReadInt(num);
|
||||
|
||||
for ( i = 0; i < num; i++ ) {
|
||||
if ( FreeEvents.IsListEmpty() ) {
|
||||
gameLocal.Error( "idEvent::Restore : No more free events" );
|
||||
for (i = 0; i < num; i++)
|
||||
{
|
||||
if (FreeEvents.IsListEmpty())
|
||||
{
|
||||
gameLocal.Error("idEvent::Restore : No more free events");
|
||||
}
|
||||
|
||||
event = FreeEvents.Next();
|
||||
event->eventNode.Remove();
|
||||
event->eventNode.AddToEnd( EventQueue );
|
||||
event->eventNode.AddToEnd(EventQueue);
|
||||
|
||||
savefile->ReadInt( event->time );
|
||||
savefile->ReadInt(event->time);
|
||||
|
||||
// read the event name
|
||||
savefile->ReadString( name );
|
||||
event->eventdef = idEventDef::FindEvent( name );
|
||||
if ( !event->eventdef ) {
|
||||
savefile->Error( "idEvent::Restore: unknown event '%s'", name.c_str() );
|
||||
savefile->ReadString(name);
|
||||
event->eventdef = idEventDef::FindEvent(name);
|
||||
if (event->eventdef == NULL)
|
||||
{
|
||||
savefile->Error("idEvent::Restore: unknown event '%s'", name.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
// read the classtype
|
||||
savefile->ReadString( name );
|
||||
event->typeinfo = idClass::GetClass( name );
|
||||
if ( !event->typeinfo ) {
|
||||
savefile->Error( "idEvent::Restore: unknown class '%s' on event '%s'", name.c_str(), event->eventdef->GetName() );
|
||||
savefile->ReadString(name);
|
||||
event->typeinfo = idClass::GetClass(name);
|
||||
if (event->typeinfo == NULL)
|
||||
{
|
||||
savefile->Error("idEvent::Restore: unknown class '%s' on event '%s'", name.c_str(), event->eventdef->GetName());
|
||||
return;
|
||||
}
|
||||
|
||||
savefile->ReadObject( event->object );
|
||||
savefile->ReadObject(event->object);
|
||||
|
||||
// read the args
|
||||
savefile->ReadInt( argsize );
|
||||
if ( argsize != event->eventdef->GetArgSize() ) {
|
||||
savefile->Error( "idEvent::Restore: arg size (%d) doesn't match saved arg size(%d) on event '%s'", event->eventdef->GetArgSize(), argsize, event->eventdef->GetName() );
|
||||
savefile->ReadInt(argsize);
|
||||
if (argsize != (int)event->eventdef->GetArgSize())
|
||||
{
|
||||
// RB: fixed wrong formatting
|
||||
savefile->Error("idEvent::Restore: arg size (%zd) doesn't match saved arg size(%zd) on event '%s'", event->eventdef->GetArgSize(), argsize, event->eventdef->GetName());
|
||||
// RB end
|
||||
}
|
||||
if ( argsize ) {
|
||||
event->data = eventDataAllocator.Alloc( argsize );
|
||||
if (argsize)
|
||||
{
|
||||
event->data = eventDataAllocator.Alloc(argsize);
|
||||
format = event->eventdef->GetArgFormat();
|
||||
assert( format );
|
||||
for ( j = 0, size = 0; j < event->eventdef->GetNumArgs(); ++j) {
|
||||
dataPtr = &event->data[ event->eventdef->GetArgOffset( j ) ];
|
||||
switch( format[ j ] ) {
|
||||
case D_EVENT_FLOAT :
|
||||
savefile->ReadFloat( *reinterpret_cast<float *>( dataPtr ) );
|
||||
size += sizeof( float );
|
||||
assert(format);
|
||||
for (j = 0, size = 0; j < event->eventdef->GetNumArgs(); ++j)
|
||||
{
|
||||
dataPtr = &event->data[event->eventdef->GetArgOffset(j)];
|
||||
switch (format[j])
|
||||
{
|
||||
case D_EVENT_FLOAT:
|
||||
savefile->ReadFloat(*reinterpret_cast<float*>(dataPtr));
|
||||
// RB: 64 bit fix, changed sizeof( float ) to sizeof( intptr_t )
|
||||
size += sizeof(intptr_t);
|
||||
// RB end
|
||||
break;
|
||||
case D_EVENT_INTEGER :
|
||||
case D_EVENT_ENTITY :
|
||||
case D_EVENT_ENTITY_NULL :
|
||||
savefile->ReadInt( *reinterpret_cast<int *>( dataPtr ) );
|
||||
size += sizeof( int );
|
||||
case D_EVENT_INTEGER:
|
||||
// RB: 64 bit fix
|
||||
savefile->ReadInt(*reinterpret_cast<int*>(dataPtr));
|
||||
size += sizeof(intptr_t);
|
||||
break;
|
||||
case D_EVENT_VECTOR :
|
||||
savefile->ReadVec3( *reinterpret_cast<idVec3 *>( dataPtr ) );
|
||||
size += sizeof( idVec3 );
|
||||
// RB end
|
||||
case D_EVENT_ENTITY:
|
||||
case D_EVENT_ENTITY_NULL:
|
||||
// RB: 64 bit fix, changed alignment to sizeof( intptr_t )
|
||||
reinterpret_cast<idEntityPtr<idEntity>*>(dataPtr)->Restore(savefile);
|
||||
size += sizeof(intptr_t);
|
||||
// RB end
|
||||
break;
|
||||
case D_EVENT_TRACE :
|
||||
savefile->ReadBool( *reinterpret_cast<bool *>( dataPtr ) );
|
||||
size += sizeof( bool );
|
||||
if ( *reinterpret_cast<bool *>( dataPtr ) ) {
|
||||
size += sizeof( trace_t );
|
||||
trace_t &t = *reinterpret_cast<trace_t *>( dataPtr + sizeof( bool ) );
|
||||
RestoreTrace( savefile, t) ;
|
||||
if ( t.c.material ) {
|
||||
size += MAX_STRING_LEN;
|
||||
str = reinterpret_cast<char *>( dataPtr + sizeof( bool ) + sizeof( trace_t ) );
|
||||
savefile->Read( str, MAX_STRING_LEN );
|
||||
}
|
||||
}
|
||||
case D_EVENT_VECTOR:
|
||||
savefile->ReadVec3(*reinterpret_cast<idVec3*>(dataPtr));
|
||||
// RB: 64 bit fix, changed sizeof( int ) to E_EVENT_SIZEOF_VEC
|
||||
size += E_EVENT_SIZEOF_VEC;
|
||||
// RB end
|
||||
break;
|
||||
// HUMANHEAD mdl: Added support for saving strings passed in events
|
||||
#if 1
|
||||
// RB: added missing D_EVENT_STRING case
|
||||
case D_EVENT_STRING:
|
||||
str = reinterpret_cast<char *>( dataPtr );
|
||||
savefile->Read( str, MAX_STRING_LEN );
|
||||
savefile->ReadString(s);
|
||||
//idStr::Copynz(reinterpret_cast<char *>( dataPtr ), s, s.Length() );
|
||||
//size += s.Length();
|
||||
idStr::Copynz(reinterpret_cast<char*>(dataPtr), s, MAX_STRING_LEN);
|
||||
size += MAX_STRING_LEN;
|
||||
break;
|
||||
// HUMANHEAD END
|
||||
// RB end
|
||||
#endif
|
||||
case D_EVENT_TRACE:
|
||||
savefile->ReadBool(*reinterpret_cast<bool*>(dataPtr));
|
||||
size += sizeof(bool);
|
||||
if (*reinterpret_cast<bool*>(dataPtr))
|
||||
{
|
||||
size += sizeof(trace_t);
|
||||
trace_t& t = *reinterpret_cast<trace_t*>(dataPtr + sizeof(bool));
|
||||
RestoreTrace(savefile, t);
|
||||
if (t.c.material)
|
||||
{
|
||||
size += MAX_STRING_LEN;
|
||||
str = reinterpret_cast<char*>(dataPtr + sizeof(bool) + sizeof(trace_t));
|
||||
savefile->Read(str, MAX_STRING_LEN);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert( size == event->eventdef->GetArgSize() );
|
||||
} else {
|
||||
assert(size == (int)event->eventdef->GetArgSize());
|
||||
}
|
||||
else
|
||||
{
|
||||
event->data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,9 @@ Event are used for scheduling tasks and for linking script commands.
|
||||
|
||||
#define MAX_EVENTS 4096
|
||||
|
||||
// stack size of idVec3, aligned to native pointer size
|
||||
#define E_EVENT_SIZEOF_VEC ((sizeof(idVec3) + (sizeof(intptr_t) - 1)) & ~(sizeof(intptr_t) - 1))
|
||||
|
||||
//HUMANHEAD: aob - needed for networking to send the least amount of bits
|
||||
extern const int MAX_EVENTS_NUM_BITS;
|
||||
//HUMANHEAD END
|
||||
@@ -50,7 +53,7 @@ public:
|
||||
const char *GetName( void ) const;
|
||||
const char *GetArgFormat( void ) const;
|
||||
unsigned int GetFormatspecIndex( void ) const;
|
||||
char GetReturnType( void ) const;
|
||||
int GetReturnType( void ) const;
|
||||
int GetEventNum( void ) const;
|
||||
int GetNumArgs( void ) const;
|
||||
size_t GetArgSize( void ) const;
|
||||
@@ -87,7 +90,7 @@ public:
|
||||
~idEvent();
|
||||
|
||||
static idEvent *Alloc( const idEventDef *evdef, int numargs, va_list args );
|
||||
static void CopyArgs( const idEventDef *evdef, int numargs, va_list args, int data[ D_EVENT_MAXARGS ] );
|
||||
static void CopyArgs( const idEventDef *evdef, int numargs, va_list args, intptr_t data[ D_EVENT_MAXARGS ] );
|
||||
|
||||
void Free( void );
|
||||
void Schedule( idClass *object, const idTypeInfo *cls, int time );
|
||||
@@ -152,7 +155,7 @@ ID_INLINE unsigned int idEventDef::GetFormatspecIndex( void ) const {
|
||||
idEventDef::GetReturnType
|
||||
================
|
||||
*/
|
||||
ID_INLINE char idEventDef::GetReturnType( void ) const {
|
||||
ID_INLINE int idEventDef::GetReturnType( void ) const {
|
||||
return returnType;
|
||||
}
|
||||
|
||||
|
||||
@@ -672,7 +672,9 @@ void idInterpreter::CallEvent( const function_t *func, int argsize ) {
|
||||
varEval_t var;
|
||||
int pos;
|
||||
int start;
|
||||
int data[ D_EVENT_MAXARGS ];
|
||||
// RB: 64 bit fixes, changed int to intptr_t
|
||||
intptr_t data[D_EVENT_MAXARGS];
|
||||
// RB end
|
||||
const idEventDef *evdef;
|
||||
const char *format;
|
||||
|
||||
@@ -686,6 +688,9 @@ void idInterpreter::CallEvent( const function_t *func, int argsize ) {
|
||||
start = localstackUsed - argsize;
|
||||
var.intPtr = ( int * )&localstack[ start ];
|
||||
eventEntity = GetEntity( *var.entityNumberPtr );
|
||||
static int testme;
|
||||
|
||||
testme = *var.entityNumberPtr;
|
||||
|
||||
if ( !eventEntity || !eventEntity->RespondsTo( *evdef ) ) {
|
||||
if ( eventEntity && developer.GetBool() ) {
|
||||
@@ -703,10 +708,11 @@ void idInterpreter::CallEvent( const function_t *func, int argsize ) {
|
||||
|
||||
// always return a safe value when an object doesn't exist
|
||||
switch( evdef->GetReturnType() ) {
|
||||
case D_EVENT_INTEGER :
|
||||
gameLocal.program.ReturnInteger( 0 );
|
||||
case D_EVENT_INTEGER:
|
||||
gameLocal.program.ReturnInteger(0);
|
||||
break;
|
||||
|
||||
|
||||
case D_EVENT_FLOAT :
|
||||
gameLocal.program.ReturnFloat( 0 );
|
||||
break;
|
||||
@@ -739,13 +745,18 @@ void idInterpreter::CallEvent( const function_t *func, int argsize ) {
|
||||
for( j = 0, i = 0, pos = type_object.Size(); ( pos < argsize ) || ( format[ i ] != 0 ); i++ ) {
|
||||
switch( format[ i ] ) {
|
||||
case D_EVENT_INTEGER :
|
||||
var.intPtr = ( int * )&localstack[ start + pos ];
|
||||
data[ i ] = int( *var.floatPtr );
|
||||
var.intPtr = (int*)&localstack[start + pos];
|
||||
// RB: fixed data alignment
|
||||
//data[ i ] = int( *var.floatPtr );
|
||||
(*(int*)&data[i]) = int(*var.floatPtr);
|
||||
// RB end
|
||||
break;
|
||||
|
||||
case D_EVENT_FLOAT :
|
||||
var.intPtr = ( int * )&localstack[ start + pos ];
|
||||
( *( float * )&data[ i ] ) = *var.floatPtr;
|
||||
static float value;
|
||||
value = (*(float*)&data[i]);
|
||||
break;
|
||||
|
||||
case D_EVENT_VECTOR :
|
||||
@@ -869,7 +880,9 @@ void idInterpreter::CallSysEvent( const function_t *func, int argsize ) {
|
||||
varEval_t source;
|
||||
int pos;
|
||||
int start;
|
||||
int data[ D_EVENT_MAXARGS ];
|
||||
// RB: 64 bit fixes, changed int to intptr_t
|
||||
intptr_t data[D_EVENT_MAXARGS];
|
||||
// RB end
|
||||
const idEventDef *evdef;
|
||||
const char *format;
|
||||
|
||||
@@ -1988,10 +2001,15 @@ bool idInterpreter::Execute( void ) {
|
||||
break;
|
||||
|
||||
case OP_PUSH_V:
|
||||
var_a = GetVariable( st->a );
|
||||
var_a = GetVariable(st->a);
|
||||
// RB: 64 bit fix, changed individual pushes with PushVector
|
||||
/*
|
||||
Push( *reinterpret_cast<int *>( &var_a.vectorPtr->x ) );
|
||||
Push( *reinterpret_cast<int *>( &var_a.vectorPtr->y ) );
|
||||
Push( *reinterpret_cast<int *>( &var_a.vectorPtr->z ) );
|
||||
*/
|
||||
PushVector(*var_a.vectorPtr);
|
||||
// RB end
|
||||
break;
|
||||
|
||||
case OP_PUSH_OBJ:
|
||||
@@ -2014,3 +2032,4 @@ bool idInterpreter::Execute( void ) {
|
||||
|
||||
return threadDying;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#define __SCRIPT_INTERPRETER_H__
|
||||
|
||||
#define MAX_STACK_DEPTH 64
|
||||
#define LOCALSTACK_SIZE 6144
|
||||
#define LOCALSTACK_SIZE (6144 * 2)
|
||||
|
||||
typedef struct prstack_s {
|
||||
int s;
|
||||
@@ -33,10 +33,11 @@ private:
|
||||
|
||||
idThread *thread;
|
||||
|
||||
void PushVector(const idVec3& vector);
|
||||
void PopParms( int numParms );
|
||||
void PushString( const char *string );
|
||||
public://HUMANHEAD: aob - so we can pass parms in manually
|
||||
void Push( int value );
|
||||
void Push( intptr_t value );
|
||||
private://HUMANHEAD: aob - undo the public declaration
|
||||
const char *FloatToString( float value );
|
||||
void AppendString( idVarDef *def, const char *from );
|
||||
@@ -115,12 +116,12 @@ ID_INLINE void idInterpreter::PopParms( int numParms ) {
|
||||
idInterpreter::Push
|
||||
====================
|
||||
*/
|
||||
ID_INLINE void idInterpreter::Push( int value ) {
|
||||
ID_INLINE void idInterpreter::Push(intptr_t value ) {
|
||||
if ( localstackUsed + sizeof( int ) > LOCALSTACK_SIZE ) {
|
||||
Error( "Push: locals stack overflow\n" );
|
||||
}
|
||||
*( int * )&localstack[ localstackUsed ] = value;
|
||||
localstackUsed += sizeof( int );
|
||||
*(intptr_t*)&localstack[localstackUsed] = value;
|
||||
localstackUsed += sizeof(intptr_t);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -248,4 +249,14 @@ ID_INLINE void idInterpreter::NextInstruction( int position ) {
|
||||
instructionPointer = position - 1;
|
||||
}
|
||||
|
||||
ID_INLINE void idInterpreter::PushVector(const idVec3& vector)
|
||||
{
|
||||
if (localstackUsed + E_EVENT_SIZEOF_VEC > LOCALSTACK_SIZE)
|
||||
{
|
||||
Error("Push: locals stack overflow\n");
|
||||
}
|
||||
*(idVec3*)&localstack[localstackUsed] = vector;
|
||||
localstackUsed += E_EVENT_SIZEOF_VEC;
|
||||
}
|
||||
|
||||
#endif /* !__SCRIPT_INTERPRETER_H__ */
|
||||
|
||||
@@ -16,23 +16,23 @@ static int globalOutputRunningSize = 0;
|
||||
|
||||
// simple types. function types are dynamically allocated
|
||||
idTypeDef type_void( ev_void, &def_void, "void", 0, NULL );
|
||||
idTypeDef type_scriptevent( ev_scriptevent, &def_scriptevent, "scriptevent", sizeof( void * ), NULL );
|
||||
idTypeDef type_namespace( ev_namespace, &def_namespace, "namespace", sizeof( void * ), NULL );
|
||||
idTypeDef type_scriptevent(ev_scriptevent, &def_scriptevent, "scriptevent", sizeof(intptr_t), NULL);
|
||||
idTypeDef type_namespace(ev_namespace, &def_namespace, "namespace", sizeof(intptr_t), NULL);
|
||||
//HUMANHEAD: aob - changed types to inherited types
|
||||
idTypeDefString type_string( ev_string, &def_string, "string", MAX_STRING_LEN, NULL );
|
||||
idTypeDefFloat type_float( ev_float, &def_float, "float", sizeof( float ), NULL );
|
||||
idTypeDefVector type_vector( ev_vector, &def_vector, "vector", sizeof( idVec3 ), NULL );
|
||||
idTypeDefEntity type_entity( ev_entity, &def_entity, "entity", sizeof( int * ), NULL ); // stored as entity number pointer
|
||||
idTypeDefFloat type_float( ev_float, &def_float, "float", sizeof(intptr_t), NULL );
|
||||
idTypeDefVector type_vector( ev_vector, &def_vector, "vector", E_EVENT_SIZEOF_VEC, NULL );
|
||||
idTypeDefEntity type_entity( ev_entity, &def_entity, "entity", sizeof(intptr_t), NULL ); // stored as entity number pointer
|
||||
//HUMANHEAD END
|
||||
idTypeDef type_field( ev_field, &def_field, "field", sizeof( void * ), NULL );
|
||||
idTypeDef type_function( ev_function, &def_function, "function", sizeof( void * ), &type_void );
|
||||
idTypeDef type_virtualfunction( ev_virtualfunction, &def_virtualfunction, "virtual function", sizeof( int ), NULL );
|
||||
idTypeDef type_pointer( ev_pointer, &def_pointer, "pointer", sizeof( void * ), NULL );
|
||||
idTypeDef type_object( ev_object, &def_object, "object", sizeof( int * ), NULL ); // stored as entity number pointer
|
||||
idTypeDef type_jumpoffset( ev_jumpoffset, &def_jumpoffset, "<jump>", sizeof( int ), NULL ); // only used for jump opcodes
|
||||
idTypeDef type_argsize( ev_argsize, &def_argsize, "<argsize>", sizeof( int ), NULL ); // only used for function call and thread opcodes
|
||||
idTypeDef type_field( ev_field, &def_field, "field", sizeof(intptr_t), NULL );
|
||||
idTypeDef type_function( ev_function, &def_function, "function", sizeof(intptr_t), &type_void );
|
||||
idTypeDef type_virtualfunction( ev_virtualfunction, &def_virtualfunction, "virtual function", sizeof(intptr_t), NULL );
|
||||
idTypeDef type_pointer( ev_pointer, &def_pointer, "pointer", sizeof(intptr_t), NULL );
|
||||
idTypeDef type_object( ev_object, &def_object, "object", sizeof(intptr_t), NULL ); // stored as entity number pointer
|
||||
idTypeDef type_jumpoffset( ev_jumpoffset, &def_jumpoffset, "<jump>", sizeof(intptr_t), NULL ); // only used for jump opcodes
|
||||
idTypeDef type_argsize( ev_argsize, &def_argsize, "<argsize>", sizeof(intptr_t), NULL ); // only used for function call and thread opcodes
|
||||
//HUMANHEAD: aob - changed types to inherited types
|
||||
idTypeDefBool type_boolean( ev_boolean, &def_boolean, "boolean", sizeof( int ), NULL );
|
||||
idTypeDefBool type_boolean( ev_boolean, &def_boolean, "boolean", sizeof(intptr_t), NULL );
|
||||
//HUMANHEAD END
|
||||
|
||||
idVarDef def_void( &type_void );
|
||||
@@ -1341,24 +1341,22 @@ idVarDef *idProgram::AllocDef( idTypeDef *type, const char *name, idVarDef *scop
|
||||
def->initialized = idVarDef::stackVariable;
|
||||
scope->value.functionPtr->locals += type->Size();
|
||||
} else if ( scope->TypeDef()->Inherits( &type_object ) ) {
|
||||
idTypeDef newtype( ev_field, NULL, "float field", 0, &type_float );
|
||||
idTypeDef *type = GetType( newtype, true );
|
||||
|
||||
idTypeDef newtype(ev_field, NULL, "float field", 0, &type_float);
|
||||
// RB: changed local type to ftype
|
||||
idTypeDef* ftype = GetType(newtype, true);
|
||||
// set the value to the variable's position in the object
|
||||
def->value.ptrOffset = scope->TypeDef()->Size();
|
||||
|
||||
// make automatic defs for the vectors elements
|
||||
// origin can be accessed as origin_x, origin_y, and origin_z
|
||||
sprintf( element, "%s_x", def->Name() );
|
||||
def_x = AllocDef( type, element, scope, constant );
|
||||
|
||||
sprintf( element, "%s_y", def->Name() );
|
||||
def_y = AllocDef( type, element, scope, constant );
|
||||
def_y->value.ptrOffset = def_x->value.ptrOffset + type_float.Size();
|
||||
|
||||
sprintf( element, "%s_z", def->Name() );
|
||||
def_z = AllocDef( type, element, scope, constant );
|
||||
def_z->value.ptrOffset = def_y->value.ptrOffset + type_float.Size();
|
||||
sprintf(element, "%s_x", def->Name());
|
||||
def_x = AllocDef(ftype, element, scope, constant);
|
||||
sprintf(element, "%s_y", def->Name());
|
||||
def_y = AllocDef(ftype, element, scope, constant);
|
||||
def_y->value.ptrOffset = def_x->value.ptrOffset + sizeof(float);
|
||||
sprintf(element, "%s_z", def->Name());
|
||||
def_z = AllocDef(ftype, element, scope, constant);
|
||||
def_z->value.ptrOffset = def_y->value.ptrOffset + sizeof(float);
|
||||
// RB end
|
||||
} else {
|
||||
// make automatic defs for the vectors elements
|
||||
// origin can be accessed as origin_x, origin_y, and origin_z
|
||||
@@ -1718,29 +1716,29 @@ idProgram::DisassembleStatement
|
||||
==============
|
||||
*/
|
||||
void idProgram::DisassembleStatement( idFile *file, int instructionPointer ) const {
|
||||
opcode_t *op;
|
||||
const statement_t *statement;
|
||||
opcode_t* op;
|
||||
const statement_t* statement;
|
||||
|
||||
statement = &statements[ instructionPointer ];
|
||||
op = &idCompiler::opcodes[ statement->op ];
|
||||
file->Printf( "%20s(%d):\t%6d: %15s\t", fileList[ statement->file ].c_str(), statement->linenumber, instructionPointer, op->opname );
|
||||
statement = &statements[instructionPointer];
|
||||
op = &idCompiler::opcodes[statement->op];
|
||||
file->Printf("%20s(%d):\t%6d: %15s\t", fileList[statement->file].c_str(), statement->linenumber, instructionPointer, op->opname);
|
||||
|
||||
if ( statement->a ) {
|
||||
file->Printf( "\ta: " );
|
||||
statement->a->PrintInfo( file, instructionPointer );
|
||||
if (statement->a) {
|
||||
file->Printf("\ta: ");
|
||||
statement->a->PrintInfo(file, instructionPointer);
|
||||
}
|
||||
|
||||
if ( statement->b ) {
|
||||
file->Printf( "\tb: " );
|
||||
statement->b->PrintInfo( file, instructionPointer );
|
||||
if (statement->b) {
|
||||
file->Printf("\tb: ");
|
||||
statement->b->PrintInfo(file, instructionPointer);
|
||||
}
|
||||
|
||||
if ( statement->c ) {
|
||||
file->Printf( "\tc: " );
|
||||
statement->c->PrintInfo( file, instructionPointer );
|
||||
if (statement->c) {
|
||||
file->Printf("\tc: ");
|
||||
statement->c->PrintInfo(file, instructionPointer);
|
||||
}
|
||||
|
||||
file->Printf( "\n" );
|
||||
file->Printf("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2257,6 +2255,7 @@ idProgram::ReturnEntity
|
||||
*/
|
||||
void idProgram::ReturnEntity( idEntity *ent ) {
|
||||
if ( ent ) {
|
||||
assert(ent->entityNumber + 1 <= MAX_GENTITIES);
|
||||
*returnDef->value.entityNumberPtr = ent->entityNumber + 1;
|
||||
} else {
|
||||
*returnDef->value.entityNumberPtr = 0;
|
||||
|
||||
@@ -346,6 +346,7 @@ typedef union varEval_s {
|
||||
int argSize;
|
||||
varEval_s *evalPtr;
|
||||
int ptrOffset;
|
||||
INT_PTR highPtr;
|
||||
} varEval_t;
|
||||
|
||||
class idVarDef {
|
||||
|
||||
+226
-110
@@ -122,6 +122,11 @@ void idMaterial::CommonInit() {
|
||||
decalInfo.end[1] = 0;
|
||||
decalInfo.end[2] = 0;
|
||||
decalInfo.end[3] = 0;
|
||||
|
||||
#ifdef PREY
|
||||
subviewClass = SC_MIRROR;
|
||||
directPortalDistance = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -279,20 +284,20 @@ static infoParm_t infoParms[] = {
|
||||
{"nosteps", 0, SURF_NOSTEPS, 0 }, // no footsteps
|
||||
|
||||
// material types for particle, sound, footstep feedback
|
||||
{"metal", 0, SURFTYPE_METAL, 0 }, // metal
|
||||
{"stone", 0, SURFTYPE_STONE, 0 }, // stone
|
||||
{"flesh", 0, SURFTYPE_FLESH, 0 }, // flesh
|
||||
{"wood", 0, SURFTYPE_WOOD, 0 }, // wood
|
||||
{"cardboard", 0, SURFTYPE_CARDBOARD, 0 }, // cardboard
|
||||
{"liquid", 0, SURFTYPE_LIQUID, 0 }, // liquid
|
||||
{"glass", 0, SURFTYPE_GLASS, 0 }, // glass
|
||||
{"tile", 0, SURFTYPE_TILE, 0 }, // tile
|
||||
{"matter_metal", 0, SURFTYPE_METAL, 0 }, // metal
|
||||
{"matter_stone", 0, SURFTYPE_STONE, 0 }, // stone
|
||||
{"matter_flesh", 0, SURFTYPE_FLESH, 0 }, // flesh
|
||||
{"matter_wood", 0, SURFTYPE_WOOD, 0 }, // wood
|
||||
{"matter_cardboard", 0, SURFTYPE_CARDBOARD, 0 }, // cardboard
|
||||
{"matter_liquid", 0, SURFTYPE_LIQUID, 0 }, // liquid
|
||||
{"matter_glass", 0, SURFTYPE_GLASS, 0 }, // glass
|
||||
{"matter_tile", 0, SURFTYPE_TILE, 0 }, // tile
|
||||
{"wallwalk", 0, SURFTYPE_WALLWALK, 0 }, // wallwalk surface
|
||||
{"altmetal", 0, SURFTYPE_ALTMETAL, 0 }, // alternate metal
|
||||
{"matter_altmetal", 0, SURFTYPE_ALTMETAL, 0 }, // alternate metal
|
||||
{"forcefield", 0, SURFTYPE_FORCEFIELD, 0 }, // forcefield material
|
||||
{"pipe", 0, SURFTYPE_PIPE, 0 }, // pipe
|
||||
{"spirit", 0, SURFTYPE_SPIRIT, 0 }, // spirit material
|
||||
{"chaff", 0, SURFTYPE_CHAFF, 0 }, // chaff material
|
||||
{"matter_pipe", 0, SURFTYPE_PIPE, 0 }, // pipe
|
||||
{"matter_spirit", 0, SURFTYPE_SPIRIT, 0 }, // spirit material
|
||||
{"matter_chaff", 0, SURFTYPE_CHAFF, 0 }, // chaff material
|
||||
};
|
||||
#else
|
||||
static infoParm_t infoParms[] = {
|
||||
@@ -1847,11 +1852,11 @@ Parse it into the global material variable. Later functions will optimize it.
|
||||
If there is any error during parsing, defaultShader will be set.
|
||||
=================
|
||||
*/
|
||||
void idMaterial::ParseMaterial( idLexer &src ) {
|
||||
void idMaterial::ParseMaterial(idLexer& src) {
|
||||
idToken token;
|
||||
int s;
|
||||
char buffer[1024];
|
||||
const char *str;
|
||||
const char* str;
|
||||
idLexer newSrc;
|
||||
int i;
|
||||
|
||||
@@ -1859,7 +1864,7 @@ void idMaterial::ParseMaterial( idLexer &src ) {
|
||||
|
||||
numOps = 0;
|
||||
numRegisters = EXP_REG_NUM_PREDEFINED; // leave space for the parms to be copied in
|
||||
for ( i = 0 ; i < numRegisters ; i++ ) {
|
||||
for (i = 0; i < numRegisters; i++) {
|
||||
pd->registerIsTemporary[i] = true; // they aren't constants that can be folded
|
||||
}
|
||||
|
||||
@@ -1867,41 +1872,41 @@ void idMaterial::ParseMaterial( idLexer &src ) {
|
||||
|
||||
textureRepeat_t trpDefault = TR_REPEAT; // allow a global setting for repeat
|
||||
|
||||
while ( 1 ) {
|
||||
if ( TestMaterialFlag( MF_DEFAULTED ) ) { // we have a parse error
|
||||
while (1) {
|
||||
if (TestMaterialFlag(MF_DEFAULTED)) { // we have a parse error
|
||||
return;
|
||||
}
|
||||
if ( !src.ExpectAnyToken( &token ) ) {
|
||||
SetMaterialFlag( MF_DEFAULTED );
|
||||
if (!src.ExpectAnyToken(&token)) {
|
||||
SetMaterialFlag(MF_DEFAULTED);
|
||||
return;
|
||||
}
|
||||
|
||||
// end of material definition
|
||||
if ( token == "}" ) {
|
||||
if (token == "}") {
|
||||
break;
|
||||
}
|
||||
else if ( !token.Icmp( "qer_editorimage") ) {
|
||||
src.ReadTokenOnLine( &token );
|
||||
else if (!token.Icmp("qer_editorimage")) {
|
||||
src.ReadTokenOnLine(&token);
|
||||
editorImageName = token.c_str();
|
||||
src.SkipRestOfLine();
|
||||
continue;
|
||||
}
|
||||
// description
|
||||
else if ( !token.Icmp( "description") ) {
|
||||
src.ReadTokenOnLine( &token );
|
||||
else if (!token.Icmp("description")) {
|
||||
src.ReadTokenOnLine(&token);
|
||||
desc = token.c_str();
|
||||
continue;
|
||||
}
|
||||
// check for the surface / content bit flags
|
||||
else if ( CheckSurfaceParm( &token ) ) {
|
||||
else if (CheckSurfaceParm(&token)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// polygonOffset
|
||||
else if ( !token.Icmp( "polygonOffset" ) ) {
|
||||
SetMaterialFlag( MF_POLYGONOFFSET );
|
||||
if ( !src.ReadTokenOnLine( &token ) ) {
|
||||
else if (!token.Icmp("polygonOffset")) {
|
||||
SetMaterialFlag(MF_POLYGONOFFSET);
|
||||
if (!src.ReadTokenOnLine(&token)) {
|
||||
polygonOffset = 1;
|
||||
continue;
|
||||
}
|
||||
@@ -1910,223 +1915,333 @@ void idMaterial::ParseMaterial( idLexer &src ) {
|
||||
continue;
|
||||
}
|
||||
// noshadow
|
||||
else if ( !token.Icmp( "noShadows" ) ) {
|
||||
SetMaterialFlag( MF_NOSHADOWS );
|
||||
else if (!token.Icmp("noShadows")) {
|
||||
SetMaterialFlag(MF_NOSHADOWS);
|
||||
continue;
|
||||
}
|
||||
else if ( !token.Icmp( "suppressInSubview" ) ) {
|
||||
else if (!token.Icmp("suppressInSubview")) {
|
||||
suppressInSubview = true;
|
||||
continue;
|
||||
}
|
||||
else if ( !token.Icmp( "portalSky" ) ) {
|
||||
else if (!token.Icmp("portalSky")) {
|
||||
portalSky = true;
|
||||
continue;
|
||||
}
|
||||
// noSelfShadow
|
||||
else if ( !token.Icmp( "noSelfShadow" ) ) {
|
||||
SetMaterialFlag( MF_NOSELFSHADOW );
|
||||
else if (!token.Icmp("noSelfShadow")) {
|
||||
SetMaterialFlag(MF_NOSELFSHADOW);
|
||||
continue;
|
||||
}
|
||||
// noPortalFog
|
||||
else if ( !token.Icmp( "noPortalFog" ) ) {
|
||||
SetMaterialFlag( MF_NOPORTALFOG );
|
||||
else if (!token.Icmp("noPortalFog")) {
|
||||
SetMaterialFlag(MF_NOPORTALFOG);
|
||||
continue;
|
||||
}
|
||||
// forceShadows allows nodraw surfaces to cast shadows
|
||||
else if ( !token.Icmp( "forceShadows" ) ) {
|
||||
SetMaterialFlag( MF_FORCESHADOWS );
|
||||
else if (!token.Icmp("forceShadows")) {
|
||||
SetMaterialFlag(MF_FORCESHADOWS);
|
||||
continue;
|
||||
}
|
||||
#ifdef PREY
|
||||
// HUMANHEAD PCF: explicitly skip collision clip for alpha-coverage surfaces.
|
||||
else if (!token.Icmp("skipClip")) {
|
||||
SetMaterialFlag(MF_SKIPCLIP);
|
||||
continue;
|
||||
}
|
||||
// HUMANHEAD bjk: don't cull tris with the light bounds.
|
||||
else if (!token.Icmp("lightWholeMesh")) {
|
||||
SetMaterialFlag(MF_LIGHT_WHOLE_MESH);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
// overlay / decal suppression
|
||||
else if ( !token.Icmp( "noOverlays" ) ) {
|
||||
else if (!token.Icmp("noOverlays")) {
|
||||
allowOverlays = false;
|
||||
continue;
|
||||
}
|
||||
// moster blood overlay forcing for alpha tested or translucent surfaces
|
||||
else if ( !token.Icmp( "forceOverlays" ) ) {
|
||||
else if (!token.Icmp("forceOverlays")) {
|
||||
pd->forceOverlays = true;
|
||||
continue;
|
||||
}
|
||||
// translucent
|
||||
else if ( !token.Icmp( "translucent" ) ) {
|
||||
else if (!token.Icmp("translucent")) {
|
||||
coverage = MC_TRANSLUCENT;
|
||||
continue;
|
||||
}
|
||||
// global zero clamp
|
||||
else if ( !token.Icmp( "zeroclamp" ) ) {
|
||||
else if (!token.Icmp("zeroclamp")) {
|
||||
trpDefault = TR_CLAMP_TO_ZERO;
|
||||
continue;
|
||||
}
|
||||
// global clamp
|
||||
else if ( !token.Icmp( "clamp" ) ) {
|
||||
else if (!token.Icmp("clamp")) {
|
||||
trpDefault = TR_CLAMP;
|
||||
continue;
|
||||
}
|
||||
// global clamp
|
||||
else if ( !token.Icmp( "alphazeroclamp" ) ) {
|
||||
else if (!token.Icmp("alphazeroclamp")) {
|
||||
trpDefault = TR_CLAMP_TO_ZERO;
|
||||
continue;
|
||||
}
|
||||
// forceOpaque is used for skies-behind-windows
|
||||
else if ( !token.Icmp( "forceOpaque" ) ) {
|
||||
else if (!token.Icmp("forceOpaque")) {
|
||||
coverage = MC_OPAQUE;
|
||||
continue;
|
||||
}
|
||||
// twoSided
|
||||
else if ( !token.Icmp( "twoSided" ) ) {
|
||||
else if (!token.Icmp("twoSided")) {
|
||||
cullType = CT_TWO_SIDED;
|
||||
// twoSided implies no-shadows, because the shadow
|
||||
// volume would be coplanar with the surface, giving depth fighting
|
||||
// we could make this no-self-shadows, but it may be more important
|
||||
// to receive shadows from no-self-shadow monsters
|
||||
SetMaterialFlag( MF_NOSHADOWS );
|
||||
SetMaterialFlag(MF_NOSHADOWS);
|
||||
}
|
||||
// backSided
|
||||
else if ( !token.Icmp( "backSided" ) ) {
|
||||
else if (!token.Icmp("backSided")) {
|
||||
cullType = CT_BACK_SIDED;
|
||||
// the shadow code doesn't handle this, so just disable shadows.
|
||||
// We could fix this in the future if there was a need.
|
||||
SetMaterialFlag( MF_NOSHADOWS );
|
||||
SetMaterialFlag(MF_NOSHADOWS);
|
||||
}
|
||||
// foglight
|
||||
else if ( !token.Icmp( "fogLight" ) ) {
|
||||
else if (!token.Icmp("fogLight")) {
|
||||
fogLight = true;
|
||||
continue;
|
||||
}
|
||||
// blendlight
|
||||
else if ( !token.Icmp( "blendLight" ) ) {
|
||||
else if (!token.Icmp("blendLight")) {
|
||||
blendLight = true;
|
||||
continue;
|
||||
}
|
||||
// ambientLight
|
||||
else if ( !token.Icmp( "ambientLight" ) ) {
|
||||
else if (!token.Icmp("ambientLight")) {
|
||||
ambientLight = true;
|
||||
continue;
|
||||
}
|
||||
// mirror
|
||||
else if ( !token.Icmp( "mirror" ) ) {
|
||||
else if (!token.Icmp("mirror")) {
|
||||
sort = SS_SUBVIEW;
|
||||
coverage = MC_OPAQUE;
|
||||
continue;
|
||||
}
|
||||
// noFog
|
||||
else if ( !token.Icmp( "noFog" ) ) {
|
||||
else if (!token.Icmp("noFog")) {
|
||||
noFog = true;
|
||||
continue;
|
||||
}
|
||||
// unsmoothedTangents
|
||||
else if ( !token.Icmp( "unsmoothedTangents" ) ) {
|
||||
else if (!token.Icmp("unsmoothedTangents")) {
|
||||
unsmoothedTangents = true;
|
||||
continue;
|
||||
}
|
||||
// lightFallofImage <imageprogram>
|
||||
// specifies the image to use for the third axis of projected
|
||||
// light volumes
|
||||
else if ( !token.Icmp( "lightFalloffImage" ) ) {
|
||||
str = R_ParsePastImageProgram( src );
|
||||
else if (!token.Icmp("lightFalloffImage")) {
|
||||
str = R_ParsePastImageProgram(src);
|
||||
idStr copy;
|
||||
|
||||
copy = str; // so other things don't step on it
|
||||
lightFalloffImage = globalImages->ImageFromFile( copy, TF_DEFAULT, false, TR_CLAMP /* TR_CLAMP_TO_ZERO */, TD_DEFAULT );
|
||||
lightFalloffImage = globalImages->ImageFromFile(copy, TF_DEFAULT, false, TR_CLAMP /* TR_CLAMP_TO_ZERO */, TD_DEFAULT);
|
||||
continue;
|
||||
}
|
||||
// guisurf <guifile> | guisurf entity
|
||||
// an entity guisurf must have an idUserInterface
|
||||
// specified in the renderEntity
|
||||
else if ( !token.Icmp( "guisurf" ) ) {
|
||||
src.ReadTokenOnLine( &token );
|
||||
if ( !token.Icmp( "entity" ) ) {
|
||||
else if (!token.Icmp("guisurf")) {
|
||||
src.ReadTokenOnLine(&token);
|
||||
if (!token.Icmp("entity")) {
|
||||
entityGui = 1;
|
||||
} else if ( !token.Icmp( "entity2" ) ) {
|
||||
}
|
||||
else if (!token.Icmp("entity2")) {
|
||||
entityGui = 2;
|
||||
} else if ( !token.Icmp( "entity3" ) ) {
|
||||
}
|
||||
else if (!token.Icmp("entity3")) {
|
||||
entityGui = 3;
|
||||
} else {
|
||||
gui = uiManager->FindGui( token.c_str(), true );
|
||||
}
|
||||
else {
|
||||
gui = uiManager->FindGui(token.c_str(), true);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// sort
|
||||
else if ( !token.Icmp( "sort" ) ) {
|
||||
ParseSort( src );
|
||||
else if (!token.Icmp("sort")) {
|
||||
ParseSort(src);
|
||||
continue;
|
||||
}
|
||||
// spectrum <integer>
|
||||
else if ( !token.Icmp( "spectrum" ) ) {
|
||||
src.ReadTokenOnLine( &token );
|
||||
spectrum = atoi( token.c_str() );
|
||||
else if (!token.Icmp("spectrum")) {
|
||||
src.ReadTokenOnLine(&token);
|
||||
spectrum = atoi(token.c_str());
|
||||
continue;
|
||||
}
|
||||
// deform < sprite | tube | flare >
|
||||
else if ( !token.Icmp( "deform" ) ) {
|
||||
ParseDeform( src );
|
||||
else if (!token.Icmp("deform")) {
|
||||
ParseDeform(src);
|
||||
continue;
|
||||
}
|
||||
// decalInfo <staySeconds> <fadeSeconds> ( <start rgb> ) ( <end rgb> )
|
||||
else if ( !token.Icmp( "decalInfo" ) ) {
|
||||
ParseDecalInfo( src );
|
||||
else if (!token.Icmp("decalInfo")) {
|
||||
ParseDecalInfo(src);
|
||||
continue;
|
||||
}
|
||||
// renderbump <args...>
|
||||
else if ( !token.Icmp( "renderbump") ) {
|
||||
src.ParseRestOfLine( renderBump );
|
||||
else if (!token.Icmp("renderbump")) {
|
||||
src.ParseRestOfLine(renderBump);
|
||||
continue;
|
||||
}
|
||||
#ifdef PREY
|
||||
else if (!token.Icmp("glowmap")) {
|
||||
src.ReadTokenOnLine(&token);
|
||||
continue;
|
||||
}
|
||||
|
||||
else if (!token.Icmp("highres")) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
// diffusemap for stage shortcut
|
||||
else if ( !token.Icmp( "diffusemap" ) ) {
|
||||
str = R_ParsePastImageProgram( src );
|
||||
idStr::snPrintf( buffer, sizeof( buffer ), "blend diffusemap\nmap %s\n}\n", str );
|
||||
newSrc.LoadMemory( buffer, strlen(buffer), "diffusemap" );
|
||||
newSrc.SetFlags( LEXFL_NOFATALERRORS | LEXFL_NOSTRINGCONCAT | LEXFL_NOSTRINGESCAPECHARS | LEXFL_ALLOWPATHNAMES );
|
||||
ParseStage( newSrc, trpDefault );
|
||||
else if (!token.Icmp("diffusemap")) {
|
||||
str = R_ParsePastImageProgram(src);
|
||||
idStr::snPrintf(buffer, sizeof(buffer), "blend diffusemap\nmap %s\n}\n", str);
|
||||
newSrc.LoadMemory(buffer, strlen(buffer), "diffusemap");
|
||||
newSrc.SetFlags(LEXFL_NOFATALERRORS | LEXFL_NOSTRINGCONCAT | LEXFL_NOSTRINGESCAPECHARS | LEXFL_ALLOWPATHNAMES);
|
||||
ParseStage(newSrc, trpDefault);
|
||||
newSrc.FreeSource();
|
||||
continue;
|
||||
}
|
||||
// specularmap for stage shortcut
|
||||
else if ( !token.Icmp( "specularmap" ) ) {
|
||||
str = R_ParsePastImageProgram( src );
|
||||
idStr::snPrintf( buffer, sizeof( buffer ), "blend specularmap\nmap %s\n}\n", str );
|
||||
newSrc.LoadMemory( buffer, strlen(buffer), "specularmap" );
|
||||
newSrc.SetFlags( LEXFL_NOFATALERRORS | LEXFL_NOSTRINGCONCAT | LEXFL_NOSTRINGESCAPECHARS | LEXFL_ALLOWPATHNAMES );
|
||||
ParseStage( newSrc, trpDefault );
|
||||
else if (!token.Icmp("specularmap")) {
|
||||
str = R_ParsePastImageProgram(src);
|
||||
idStr::snPrintf(buffer, sizeof(buffer), "blend specularmap\nmap %s\n}\n", str);
|
||||
newSrc.LoadMemory(buffer, strlen(buffer), "specularmap");
|
||||
newSrc.SetFlags(LEXFL_NOFATALERRORS | LEXFL_NOSTRINGCONCAT | LEXFL_NOSTRINGESCAPECHARS | LEXFL_ALLOWPATHNAMES);
|
||||
ParseStage(newSrc, trpDefault);
|
||||
newSrc.FreeSource();
|
||||
continue;
|
||||
}
|
||||
// normalmap for stage shortcut
|
||||
else if ( !token.Icmp( "bumpmap" ) ) {
|
||||
str = R_ParsePastImageProgram( src );
|
||||
idStr::snPrintf( buffer, sizeof( buffer ), "blend bumpmap\nmap %s\n}\n", str );
|
||||
newSrc.LoadMemory( buffer, strlen(buffer), "bumpmap" );
|
||||
newSrc.SetFlags( LEXFL_NOFATALERRORS | LEXFL_NOSTRINGCONCAT | LEXFL_NOSTRINGESCAPECHARS | LEXFL_ALLOWPATHNAMES );
|
||||
ParseStage( newSrc, trpDefault );
|
||||
else if (!token.Icmp("bumpmap")) {
|
||||
str = R_ParsePastImageProgram(src);
|
||||
idStr::snPrintf(buffer, sizeof(buffer), "blend bumpmap\nmap %s\n}\n", str);
|
||||
newSrc.LoadMemory(buffer, strlen(buffer), "bumpmap");
|
||||
newSrc.SetFlags(LEXFL_NOFATALERRORS | LEXFL_NOSTRINGCONCAT | LEXFL_NOSTRINGESCAPECHARS | LEXFL_ALLOWPATHNAMES);
|
||||
ParseStage(newSrc, trpDefault);
|
||||
newSrc.FreeSource();
|
||||
continue;
|
||||
}
|
||||
// DECAL_MACRO for backwards compatibility with the preprocessor macros
|
||||
else if ( !token.Icmp( "DECAL_MACRO" ) ) {
|
||||
else if (!token.Icmp("DECAL_MACRO")) {
|
||||
// polygonOffset
|
||||
SetMaterialFlag( MF_POLYGONOFFSET );
|
||||
SetMaterialFlag(MF_POLYGONOFFSET);
|
||||
polygonOffset = 1;
|
||||
|
||||
// discrete
|
||||
surfaceFlags |= SURF_DISCRETE;
|
||||
#ifdef PREY
|
||||
surfaceFlags |= SURF_NOIMPACT;
|
||||
#endif
|
||||
contentFlags &= ~CONTENTS_SOLID;
|
||||
|
||||
// sort decal
|
||||
sort = SS_DECAL;
|
||||
|
||||
// noShadows
|
||||
SetMaterialFlag( MF_NOSHADOWS );
|
||||
SetMaterialFlag(MF_NOSHADOWS);
|
||||
#ifdef PREY
|
||||
coverage = MC_TRANSLUCENT;
|
||||
allowOverlays = false;
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
else if ( token == "{" ) {
|
||||
#ifdef PREY
|
||||
// HUMANHEAD tmj: render this subview as a skybox portal.
|
||||
else if (!token.Icmp("skyboxPortal")) {
|
||||
sort = SS_SUBVIEW;
|
||||
coverage = MC_OPAQUE;
|
||||
subviewClass = SC_PORTAL_SKYBOX;
|
||||
continue;
|
||||
}
|
||||
// HUMANHEAD CJR: render this subview as a direct portal, with distance-cull expression.
|
||||
else if (!token.Icmp("directPortal")) {
|
||||
sort = SS_SUBVIEW;
|
||||
coverage = MC_OPAQUE;
|
||||
subviewClass = SC_PORTAL;
|
||||
directPortalDistance = ParseExpressionPriority(src, 4);
|
||||
continue;
|
||||
}
|
||||
else if (!token.Icmp("DECAL_ALPHATEST_MACRO")) {
|
||||
surfaceFlags |= SURF_NOIMPACT | SURF_DISCRETE;
|
||||
contentFlags &= ~CONTENTS_SOLID;
|
||||
sort = SS_DECAL;
|
||||
SetMaterialFlag(MF_NOSHADOWS);
|
||||
coverage = MC_TRANSLUCENT;
|
||||
allowOverlays = false;
|
||||
continue;
|
||||
}
|
||||
else if (!token.Icmp("SCORCH_MACRO") || !token.Icmp("OVERLAY_MACRO")) {
|
||||
SetMaterialFlag(MF_POLYGONOFFSET);
|
||||
polygonOffset = 1;
|
||||
surfaceFlags |= SURF_NOIMPACT | SURF_DISCRETE;
|
||||
contentFlags &= ~CONTENTS_SOLID;
|
||||
sort = SS_DECAL;
|
||||
SetMaterialFlag(MF_NOSHADOWS);
|
||||
coverage = MC_TRANSLUCENT;
|
||||
allowOverlays = false;
|
||||
continue;
|
||||
}
|
||||
else if (!token.Icmp("GLASS_MACRO")) {
|
||||
coverage = MC_TRANSLUCENT;
|
||||
SetMaterialFlag(MF_NOSHADOWS);
|
||||
pd->forceOverlays = true;
|
||||
contentFlags &= ~CONTENTS_OPAQUE;
|
||||
surfaceFlags = (surfaceFlags & ~SURF_TYPE_MASK) | SURFTYPE_GLASS;
|
||||
sort = SS_MEDIUM;
|
||||
continue;
|
||||
}
|
||||
else if (!token.Icmp("ALPHA_MACRO")) {
|
||||
coverage = MC_TRANSLUCENT;
|
||||
SetMaterialFlag(MF_NOSHADOWS);
|
||||
surfaceFlags |= SURF_NOIMPACT;
|
||||
cullType = CT_TWO_SIDED;
|
||||
continue;
|
||||
}
|
||||
else if (!token.Icmp("EFFECT_MACRO")) {
|
||||
coverage = MC_TRANSLUCENT;
|
||||
SetMaterialFlag(MF_NOSHADOWS);
|
||||
contentFlags &= ~CONTENTS_SOLID;
|
||||
surfaceFlags |= SURF_NOIMPACT;
|
||||
cullType = CT_TWO_SIDED;
|
||||
continue;
|
||||
}
|
||||
else if (!token.Icmp("SPRITE_MACRO")) {
|
||||
surfaceFlags |= SURF_DISCRETE;
|
||||
contentFlags &= ~CONTENTS_SOLID;
|
||||
SetMaterialFlag(MF_NOSHADOWS);
|
||||
coverage = MC_TRANSLUCENT;
|
||||
deform = DFRM_SPRITE;
|
||||
cullType = CT_TWO_SIDED;
|
||||
continue;
|
||||
}
|
||||
else if (!token.Icmp("SKYBOX_MACRO")) {
|
||||
SetMaterialFlag(MF_NOSHADOWS | MF_NOSELFSHADOW);
|
||||
allowOverlays = false;
|
||||
coverage = MC_OPAQUE;
|
||||
surfaceFlags |= SURF_NOIMPACT | SURF_NOFRAGMENT;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
else if (token == "{") {
|
||||
// create the new stage
|
||||
ParseStage( src, trpDefault );
|
||||
ParseStage(src, trpDefault);
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
common->Warning( "unknown general material parameter '%s' in '%s'", token.c_str(), GetName() );
|
||||
SetMaterialFlag( MF_DEFAULTED );
|
||||
common->Warning("unknown general material parameter '%s' in '%s'", token.c_str(), GetName());
|
||||
SetMaterialFlag(MF_DEFAULTED);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -2144,10 +2259,10 @@ void idMaterial::ParseMaterial( idLexer &src ) {
|
||||
|
||||
// we can't just call ReceivesLighting(), because the stages are still
|
||||
// in temporary form
|
||||
if ( cullType == CT_TWO_SIDED ) {
|
||||
for ( i = 0 ; i < numStages ; i++ ) {
|
||||
if ( pd->parseStages[i].lighting != SL_AMBIENT || pd->parseStages[i].texture.texgen != TG_EXPLICIT ) {
|
||||
if ( cullType == CT_TWO_SIDED ) {
|
||||
if (cullType == CT_TWO_SIDED) {
|
||||
for (i = 0; i < numStages; i++) {
|
||||
if (pd->parseStages[i].lighting != SL_AMBIENT || pd->parseStages[i].texture.texgen != TG_EXPLICIT) {
|
||||
if (cullType == CT_TWO_SIDED) {
|
||||
cullType = CT_FRONT_SIDED;
|
||||
shouldCreateBackSides = true;
|
||||
}
|
||||
@@ -2158,12 +2273,13 @@ void idMaterial::ParseMaterial( idLexer &src ) {
|
||||
|
||||
// currently a surface can only have one unique texgen for all the stages on old hardware
|
||||
texgen_t firstGen = TG_EXPLICIT;
|
||||
for ( i = 0; i < numStages; i++ ) {
|
||||
if ( pd->parseStages[i].texture.texgen != TG_EXPLICIT ) {
|
||||
if ( firstGen == TG_EXPLICIT ) {
|
||||
for (i = 0; i < numStages; i++) {
|
||||
if (pd->parseStages[i].texture.texgen != TG_EXPLICIT) {
|
||||
if (firstGen == TG_EXPLICIT) {
|
||||
firstGen = pd->parseStages[i].texture.texgen;
|
||||
} else if ( firstGen != pd->parseStages[i].texture.texgen ) {
|
||||
common->Warning( "material '%s' has multiple stages with a texgen", GetName() );
|
||||
}
|
||||
else if (firstGen != pd->parseStages[i].texture.texgen) {
|
||||
common->Warning("material '%s' has multiple stages with a texgen", GetName());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
+147
-109
@@ -42,6 +42,15 @@ class idCinematic;
|
||||
class idUserInterface;
|
||||
class idMegaTexture;
|
||||
|
||||
#ifdef PREY
|
||||
// HUMANHEAD tmj: type of subview that this surface represents
|
||||
typedef enum {
|
||||
SC_MIRROR,
|
||||
SC_PORTAL,
|
||||
SC_PORTAL_SKYBOX,
|
||||
} subviewClass_t;
|
||||
#endif
|
||||
|
||||
// moved from image.h for default parm
|
||||
typedef enum {
|
||||
TF_LINEAR,
|
||||
@@ -133,6 +142,10 @@ typedef enum {
|
||||
EXP_REG_GLOBAL6,
|
||||
EXP_REG_GLOBAL7,
|
||||
|
||||
#ifdef PREY
|
||||
EXP_REG_DISTANCE, // HUMANHEAD: CJR
|
||||
#endif
|
||||
|
||||
EXP_REG_NUM_PREDEFINED
|
||||
} expRegister_t;
|
||||
|
||||
@@ -157,8 +170,8 @@ typedef enum {
|
||||
} texgen_t;
|
||||
|
||||
typedef struct {
|
||||
idCinematic * cinematic;
|
||||
idImage * image;
|
||||
idCinematic* cinematic;
|
||||
idImage* image;
|
||||
texgen_t texgen;
|
||||
bool hasMatrix;
|
||||
int matrix[2][3]; // we only allow a subset of the full projection matrix
|
||||
@@ -195,9 +208,9 @@ typedef struct {
|
||||
|
||||
int fragmentProgram;
|
||||
int numFragmentProgramImages;
|
||||
idImage * fragmentProgramImages[MAX_FRAGMENT_IMAGES];
|
||||
idImage* fragmentProgramImages[MAX_FRAGMENT_IMAGES];
|
||||
|
||||
idMegaTexture *megaTexture; // handles all the binding and parameter setting
|
||||
idMegaTexture* megaTexture; // handles all the binding and parameter setting
|
||||
} newShaderStage_t;
|
||||
|
||||
typedef struct {
|
||||
@@ -213,7 +226,7 @@ typedef struct {
|
||||
// if the surface is alpha tested
|
||||
float privatePolygonOffset; // a per-stage polygon offset
|
||||
|
||||
newShaderStage_t *newStage; // vertex / fragment program based stage
|
||||
newShaderStage_t* newStage; // vertex / fragment program based stage
|
||||
} shaderStage_t;
|
||||
|
||||
typedef enum {
|
||||
@@ -266,6 +279,10 @@ typedef enum {
|
||||
MF_NOSELFSHADOW = BIT(4),
|
||||
MF_NOPORTALFOG = BIT(5), // this fog volume won't ever consider a portal fogged out
|
||||
MF_EDITOR_VISIBLE = BIT(6), // in use (visible) per editor
|
||||
#ifdef PREY
|
||||
MF_USESDISTANCE = BIT(7), // HUMANHEAD pdm: distance optimization
|
||||
MF_LIGHT_WHOLE_MESH = BIT(8), // HUMANHEAD bjk: don't cull tris with light bounds
|
||||
#endif
|
||||
MF_SKIPCLIP = BIT(9)
|
||||
} materialFlags_t;
|
||||
|
||||
@@ -314,7 +331,7 @@ typedef enum {
|
||||
CONTENTS_NOCSG = BIT(21), // don't cut this brush with CSG operations in the editor
|
||||
#endif
|
||||
|
||||
CONTENTS_REMOVE_UTIL = ~(CONTENTS_AREAPORTAL|CONTENTS_NOCSG)
|
||||
CONTENTS_REMOVE_UTIL = ~(CONTENTS_AREAPORTAL | CONTENTS_NOCSG)
|
||||
} contentsFlags_t;
|
||||
|
||||
// surface types
|
||||
@@ -367,7 +384,7 @@ typedef enum {
|
||||
SURF_TYPE_BIT1 = BIT(1), // "
|
||||
SURF_TYPE_BIT2 = BIT(2), // "
|
||||
SURF_TYPE_BIT3 = BIT(3), // "
|
||||
SURF_TYPE_MASK = ( 1 << NUM_SURFACE_BITS ) - 1,
|
||||
SURF_TYPE_MASK = (1 << NUM_SURFACE_BITS) - 1,
|
||||
|
||||
SURF_NODAMAGE = BIT(4), // never give falling damage
|
||||
SURF_SLICK = BIT(5), // effects game physics
|
||||
@@ -388,106 +405,115 @@ public:
|
||||
idMaterial();
|
||||
virtual ~idMaterial();
|
||||
|
||||
virtual size_t Size( void ) const;
|
||||
virtual bool SetDefaultText( void );
|
||||
virtual const char *DefaultDefinition( void ) const;
|
||||
virtual bool Parse( const char *text, const int textLength );
|
||||
virtual void FreeData( void );
|
||||
virtual void Print( void ) const;
|
||||
virtual size_t Size(void) const;
|
||||
virtual bool SetDefaultText(void);
|
||||
virtual const char* DefaultDefinition(void) const;
|
||||
virtual bool Parse(const char* text, const int textLength);
|
||||
virtual void FreeData(void);
|
||||
virtual void Print(void) const;
|
||||
|
||||
//BSM Nerve: Added for material editor
|
||||
bool Save( const char *fileName = NULL );
|
||||
bool Save(const char* fileName = NULL);
|
||||
|
||||
// returns the internal image name for stage 0, which can be used
|
||||
// for the renderer CaptureRenderToImage() call
|
||||
// I'm not really sure why this needs to be virtual...
|
||||
virtual const char *ImageName( void ) const;
|
||||
virtual const char* ImageName(void) const;
|
||||
|
||||
void ReloadImages( bool force ) const;
|
||||
void ReloadImages(bool force) const;
|
||||
|
||||
// returns number of stages this material contains
|
||||
const int GetNumStages( void ) const { return numStages; }
|
||||
const int GetNumStages(void) const { return numStages; }
|
||||
|
||||
// get a specific stage
|
||||
const shaderStage_t *GetStage( const int index ) const { assert(index >= 0 && index < numStages); return &stages[index]; }
|
||||
const shaderStage_t* GetStage(const int index) const { assert(index >= 0 && index < numStages); return &stages[index]; }
|
||||
|
||||
// get the first bump map stage, or NULL if not present.
|
||||
// used for bumpy-specular
|
||||
const shaderStage_t *GetBumpStage( void ) const;
|
||||
const shaderStage_t* GetBumpStage(void) const;
|
||||
|
||||
#ifdef PREY
|
||||
// HUMANHEAD tmj: returns how the subview should be rendered (mirror/portal/skybox)
|
||||
subviewClass_t GetSubviewClass(void) const { return subviewClass; }
|
||||
#endif
|
||||
|
||||
// returns true if the material will draw anything at all. Triggers, portals,
|
||||
// etc, will not have anything to draw. A not drawn surface can still castShadow,
|
||||
// which can be used to make a simplified shadow hull for a complex object set
|
||||
// as noShadow
|
||||
bool IsDrawn( void ) const { return ( numStages > 0 || entityGui != 0 || gui != NULL ); }
|
||||
bool IsDrawn(void) const { return (numStages > 0 || entityGui != 0 || gui != NULL); }
|
||||
|
||||
// returns true if the material will draw any non light interaction stages
|
||||
bool HasAmbient( void ) const { return ( numAmbientStages > 0 ); }
|
||||
bool HasAmbient(void) const { return (numAmbientStages > 0); }
|
||||
|
||||
// returns true if material has a gui
|
||||
bool HasGui( void ) const { return ( entityGui != 0 || gui != NULL ); }
|
||||
bool HasGui(void) const { return (entityGui != 0 || gui != NULL); }
|
||||
|
||||
// returns true if the material will generate another view, either as
|
||||
// a mirror or dynamic rendered image
|
||||
bool HasSubview( void ) const { return hasSubview; }
|
||||
bool HasSubview(void) const { return hasSubview; }
|
||||
|
||||
// returns true if the material will generate shadows, not making a
|
||||
// distinction between global and no-self shadows
|
||||
bool SurfaceCastsShadow( void ) const { return TestMaterialFlag( MF_FORCESHADOWS ) || !TestMaterialFlag( MF_NOSHADOWS ); }
|
||||
bool SurfaceCastsShadow(void) const { return TestMaterialFlag(MF_FORCESHADOWS) || !TestMaterialFlag(MF_NOSHADOWS); }
|
||||
|
||||
// returns true if the material will generate interactions with fog/blend lights
|
||||
// All non-translucent surfaces receive fog unless they are explicitly noFog
|
||||
bool ReceivesFog( void ) const { return ( IsDrawn() && !noFog && coverage != MC_TRANSLUCENT ); }
|
||||
// jmarshall
|
||||
bool ReceivesFog(void) const { return (IsDrawn() && !noFog && coverage != MC_TRANSLUCENT); }
|
||||
// jmarshall
|
||||
idImage* GetDiffuseImage(void) const;
|
||||
idImage* GetBumpImage(void) const;
|
||||
bool IsSky(void) const;
|
||||
// jmarshall end
|
||||
// jmarshall end
|
||||
// returns true if the material will generate interactions with normal lights
|
||||
// Many special effect surfaces don't have any bump/diffuse/specular
|
||||
// stages, and don't interact with lights at all
|
||||
bool ReceivesLighting( void ) const { return numAmbientStages != numStages; }
|
||||
bool ReceivesLighting(void) const { return numAmbientStages != numStages; }
|
||||
|
||||
// returns true if the material should generate interactions on sides facing away
|
||||
// from light centers, as with noshadow and noselfshadow options
|
||||
bool ReceivesLightingOnBackSides( void ) const { return ( materialFlags & (MF_NOSELFSHADOW|MF_NOSHADOWS) ) != 0; }
|
||||
bool ReceivesLightingOnBackSides(void) const { return (materialFlags & (MF_NOSELFSHADOW | MF_NOSHADOWS)) != 0; }
|
||||
|
||||
// Standard two-sided triangle rendering won't work with bump map lighting, because
|
||||
// the normal and tangent vectors won't be correct for the back sides. When two
|
||||
// sided lighting is desired. typically for alpha tested surfaces, this is
|
||||
// addressed by having CleanupModelSurfaces() create duplicates of all the triangles
|
||||
// with apropriate order reversal.
|
||||
bool ShouldCreateBackSides( void ) const { return shouldCreateBackSides; }
|
||||
bool ShouldCreateBackSides(void) const { return shouldCreateBackSides; }
|
||||
|
||||
// characters and models that are created by a complete renderbump can use a faster
|
||||
// method of tangent and normal vector generation than surfaces which have a flat
|
||||
// renderbump wrapped over them.
|
||||
bool UseUnsmoothedTangents( void ) const { return unsmoothedTangents; }
|
||||
bool UseUnsmoothedTangents(void) const { return unsmoothedTangents; }
|
||||
|
||||
// by default, monsters can have blood overlays placed on them, but this can
|
||||
// be overrided on a per-material basis with the "noOverlays" material command.
|
||||
// This will always return false for translucent surfaces
|
||||
bool AllowOverlays( void ) const { return allowOverlays; }
|
||||
bool AllowOverlays(void) const { return allowOverlays; }
|
||||
|
||||
// MC_OPAQUE, MC_PERFORATED, or MC_TRANSLUCENT, for interaction list linking and
|
||||
// dmap flood filling
|
||||
// The depth buffer will not be filled for MC_TRANSLUCENT surfaces
|
||||
// FIXME: what do nodraw surfaces return?
|
||||
materialCoverage_t Coverage( void ) const { return coverage; }
|
||||
materialCoverage_t Coverage(void) const { return coverage; }
|
||||
|
||||
// returns true if this material takes precedence over other in coplanar cases
|
||||
bool HasHigherDmapPriority( const idMaterial &other ) const { return ( IsDrawn() && !other.IsDrawn() ) ||
|
||||
( Coverage() < other.Coverage() ); }
|
||||
bool HasHigherDmapPriority(const idMaterial& other) const {
|
||||
return (IsDrawn() && !other.IsDrawn()) ||
|
||||
(Coverage() < other.Coverage());
|
||||
}
|
||||
|
||||
// returns a idUserInterface if it has a global gui, or NULL if no gui
|
||||
idUserInterface * GlobalGui( void ) const { return gui; }
|
||||
idUserInterface* GlobalGui(void) const { return gui; }
|
||||
|
||||
// a discrete surface will never be merged with other surfaces by dmap, which is
|
||||
// necessary to prevent mutliple gui surfaces, mirrors, autosprites, and some other
|
||||
// special effects from being combined into a single surface
|
||||
// guis, merging sprites or other effects, mirrors and remote views are always discrete
|
||||
bool IsDiscrete( void ) const { return ( entityGui || gui || deform != DFRM_NONE || sort == SS_SUBVIEW ||
|
||||
( surfaceFlags & SURF_DISCRETE ) != 0 ); }
|
||||
bool IsDiscrete(void) const {
|
||||
return (entityGui || gui || deform != DFRM_NONE || sort == SS_SUBVIEW ||
|
||||
(surfaceFlags & SURF_DISCRETE) != 0);
|
||||
}
|
||||
|
||||
// Normally, dmap chops each surface by every BSP boundary, then reoptimizes.
|
||||
// For gigantic polygons like sky boxes, this can cause a huge number of planar
|
||||
@@ -497,7 +523,7 @@ public:
|
||||
// of not automatically fixing up interpenetrations, so when this is used, you
|
||||
// should manually make the edges of your sky box exactly meet, instead of poking
|
||||
// into each other.
|
||||
bool NoFragment( void ) const { return ( surfaceFlags & SURF_NOFRAGMENT ) != 0; }
|
||||
bool NoFragment(void) const { return (surfaceFlags & SURF_NOFRAGMENT) != 0; }
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// light shader specific functions, only called for light entities
|
||||
@@ -513,8 +539,10 @@ public:
|
||||
|
||||
// implicitly no-shadows lights (ambients, fogs, etc) will never cast shadows
|
||||
// but individual light entities can also override this value
|
||||
bool LightCastsShadows() const { return TestMaterialFlag( MF_FORCESHADOWS ) ||
|
||||
( !fogLight && !ambientLight && !blendLight && !TestMaterialFlag( MF_NOSHADOWS ) ); }
|
||||
bool LightCastsShadows() const {
|
||||
return TestMaterialFlag(MF_FORCESHADOWS) ||
|
||||
(!fogLight && !ambientLight && !blendLight && !TestMaterialFlag(MF_NOSHADOWS));
|
||||
}
|
||||
|
||||
// fog lights, blend lights, ambient lights, etc will all have to have interaction
|
||||
// triangles generated for sides facing away from the light as well as those
|
||||
@@ -525,97 +553,97 @@ public:
|
||||
bool LightEffectsBackSides() const { return fogLight || ambientLight || blendLight; }
|
||||
|
||||
// NULL unless an image is explicitly specified in the shader with "lightFalloffShader <image>"
|
||||
idImage * LightFalloffImage() const { return lightFalloffImage; }
|
||||
idImage* LightFalloffImage() const { return lightFalloffImage; }
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
||||
// returns the renderbump command line for this shader, or an empty string if not present
|
||||
const char * GetRenderBump() const { return renderBump; };
|
||||
const char* GetRenderBump() const { return renderBump; };
|
||||
|
||||
// set specific material flag(s)
|
||||
void SetMaterialFlag( const int flag ) const { materialFlags |= flag; }
|
||||
void SetMaterialFlag(const int flag) const { materialFlags |= flag; }
|
||||
|
||||
// clear specific material flag(s)
|
||||
void ClearMaterialFlag( const int flag ) const { materialFlags &= ~flag; }
|
||||
void ClearMaterialFlag(const int flag) const { materialFlags &= ~flag; }
|
||||
|
||||
// test for existance of specific material flag(s)
|
||||
bool TestMaterialFlag( const int flag ) const { return ( materialFlags & flag ) != 0; }
|
||||
bool TestMaterialFlag(const int flag) const { return (materialFlags & flag) != 0; }
|
||||
|
||||
// get content flags
|
||||
const int GetContentFlags( void ) const { return contentFlags; }
|
||||
const int GetContentFlags(void) const { return contentFlags; }
|
||||
|
||||
// get surface flags
|
||||
const int GetSurfaceFlags( void ) const { return surfaceFlags; }
|
||||
const int GetSurfaceFlags(void) const { return surfaceFlags; }
|
||||
|
||||
// gets name for surface type (stone, metal, flesh, etc.)
|
||||
const surfTypes_t GetSurfaceType( void ) const { return static_cast<surfTypes_t>( surfaceFlags & SURF_TYPE_MASK ); }
|
||||
const surfTypes_t GetSurfaceType(void) const { return static_cast<surfTypes_t>(surfaceFlags & SURF_TYPE_MASK); }
|
||||
|
||||
// get material description
|
||||
const char * GetDescription( void ) const { return desc; }
|
||||
const char* GetDescription(void) const { return desc; }
|
||||
|
||||
// get sort order
|
||||
const float GetSort( void ) const { return sort; }
|
||||
const float GetSort(void) const { return sort; }
|
||||
// this is only used by the gui system to force sorting order
|
||||
// on images referenced from tga's instead of materials.
|
||||
// this is done this way as there are 2000 tgas the guis use
|
||||
void SetSort( float s ) const { sort = s; };
|
||||
void SetSort(float s) const { sort = s; };
|
||||
|
||||
// DFRM_NONE, DFRM_SPRITE, etc
|
||||
deform_t Deform( void ) const { return deform; }
|
||||
deform_t Deform(void) const { return deform; }
|
||||
|
||||
// flare size, expansion size, etc
|
||||
const int GetDeformRegister( int index ) const { return deformRegisters[index]; }
|
||||
const int GetDeformRegister(int index) const { return deformRegisters[index]; }
|
||||
|
||||
// particle system to emit from surface and table for turbulent
|
||||
const idDecl *GetDeformDecl( void ) const { return deformDecl; }
|
||||
const idDecl* GetDeformDecl(void) const { return deformDecl; }
|
||||
|
||||
// currently a surface can only have one unique texgen for all the stages
|
||||
texgen_t Texgen() const;
|
||||
|
||||
// wobble sky parms
|
||||
const int * GetTexGenRegisters( void ) const { return texGenRegisters; }
|
||||
const int* GetTexGenRegisters(void) const { return texGenRegisters; }
|
||||
|
||||
// get cull type
|
||||
const cullType_t GetCullType( void ) const { return cullType; }
|
||||
const cullType_t GetCullType(void) const { return cullType; }
|
||||
|
||||
float GetEditorAlpha( void ) const { return editorAlpha; }
|
||||
float GetEditorAlpha(void) const { return editorAlpha; }
|
||||
|
||||
int GetEntityGui( void ) const { return entityGui; }
|
||||
int GetEntityGui(void) const { return entityGui; }
|
||||
|
||||
decalInfo_t GetDecalInfo( void ) const { return decalInfo; }
|
||||
decalInfo_t GetDecalInfo(void) const { return decalInfo; }
|
||||
|
||||
// spectrums are used for "invisible writing" that can only be
|
||||
// illuminated by a light of matching spectrum
|
||||
int Spectrum( void ) const { return spectrum; }
|
||||
int Spectrum(void) const { return spectrum; }
|
||||
|
||||
float GetPolygonOffset( void ) const { return polygonOffset; }
|
||||
float GetPolygonOffset(void) const { return polygonOffset; }
|
||||
|
||||
float GetSurfaceArea( void ) const { return surfaceArea; }
|
||||
void AddToSurfaceArea( float area ) { surfaceArea += area; }
|
||||
float GetSurfaceArea(void) const { return surfaceArea; }
|
||||
void AddToSurfaceArea(float area) { surfaceArea += area; }
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
||||
// returns the length, in milliseconds, of the videoMap on this material,
|
||||
// or zero if it doesn't have one
|
||||
int CinematicLength( void ) const;
|
||||
int CinematicLength(void) const;
|
||||
|
||||
void CloseCinematic( void ) const;
|
||||
void CloseCinematic(void) const;
|
||||
|
||||
void ResetCinematicTime( int time ) const;
|
||||
void ResetCinematicTime(int time) const;
|
||||
|
||||
void UpdateCinematic( int time ) const;
|
||||
void UpdateCinematic(int time) const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
||||
// gets an image for the editor to use
|
||||
idImage * GetEditorImage( void ) const;
|
||||
int GetImageWidth( void ) const;
|
||||
int GetImageHeight( void ) const;
|
||||
idImage* GetEditorImage(void) const;
|
||||
int GetImageWidth(void) const;
|
||||
int GetImageHeight(void) const;
|
||||
|
||||
void SetGui( const char *_gui ) const;
|
||||
void SetGui(const char* _gui) const;
|
||||
|
||||
// just for resource tracking
|
||||
void SetImageClassifications( int tag ) const;
|
||||
void SetImageClassifications(int tag) const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
||||
@@ -623,61 +651,71 @@ public:
|
||||
const int GetNumRegisters() const { return numRegisters; }
|
||||
|
||||
// regs should point to a float array large enough to hold GetNumRegisters() floats
|
||||
void EvaluateRegisters( float *regs, const float entityParms[MAX_ENTITY_SHADER_PARMS],
|
||||
const struct viewDef_s *view, idSoundEmitter *soundEmitter = NULL ) const;
|
||||
void EvaluateRegisters(float* regs, const float entityParms[MAX_ENTITY_SHADER_PARMS],
|
||||
const struct viewDef_s* view, idSoundEmitter* soundEmitter = NULL) const;
|
||||
|
||||
// if a material only uses constants (no entityParm or globalparm references), this
|
||||
// will return a pointer to an internal table, and EvaluateRegisters will not need
|
||||
// to be called. If NULL is returned, EvaluateRegisters must be used.
|
||||
const float * ConstantRegisters() const;
|
||||
const float* ConstantRegisters() const;
|
||||
|
||||
bool SuppressInSubview() const { return suppressInSubview; };
|
||||
bool IsPortalSky() const { return portalSky; };
|
||||
void AddReference();
|
||||
|
||||
#ifdef PREY
|
||||
int GetDirectPortalDistance() const { return directPortalDistance; } // HUMANHEAD CJR
|
||||
#endif
|
||||
|
||||
private:
|
||||
// parse the entire material
|
||||
void CommonInit();
|
||||
void ParseMaterial( idLexer &src );
|
||||
bool MatchToken( idLexer &src, const char *match );
|
||||
void ParseSort( idLexer &src );
|
||||
void ParseBlend( idLexer &src, shaderStage_t *stage );
|
||||
void ParseVertexParm( idLexer &src, newShaderStage_t *newStage );
|
||||
void ParseFragmentMap( idLexer &src, newShaderStage_t *newStage );
|
||||
void ParseStage( idLexer &src, const textureRepeat_t trpDefault = TR_REPEAT );
|
||||
void ParseDeform( idLexer &src );
|
||||
void ParseDecalInfo( idLexer &src );
|
||||
bool CheckSurfaceParm( idToken *token );
|
||||
int GetExpressionConstant( float f );
|
||||
int GetExpressionTemporary( void );
|
||||
expOp_t * GetExpressionOp( void );
|
||||
int EmitOp( int a, int b, expOpType_t opType );
|
||||
int ParseEmitOp( idLexer &src, int a, expOpType_t opType, int priority );
|
||||
int ParseTerm( idLexer &src );
|
||||
int ParseExpressionPriority( idLexer &src, int priority );
|
||||
int ParseExpression( idLexer &src );
|
||||
void ClearStage( shaderStage_t *ss );
|
||||
int NameToSrcBlendMode( const idStr &name );
|
||||
int NameToDstBlendMode( const idStr &name );
|
||||
void MultiplyTextureMatrix( textureStage_t *ts, int registers[2][3] ); // FIXME: for some reason the const is bad for gcc and Mac
|
||||
void ParseMaterial(idLexer& src);
|
||||
bool MatchToken(idLexer& src, const char* match);
|
||||
void ParseSort(idLexer& src);
|
||||
void ParseBlend(idLexer& src, shaderStage_t* stage);
|
||||
void ParseVertexParm(idLexer& src, newShaderStage_t* newStage);
|
||||
void ParseFragmentMap(idLexer& src, newShaderStage_t* newStage);
|
||||
void ParseStage(idLexer& src, const textureRepeat_t trpDefault = TR_REPEAT);
|
||||
void ParseDeform(idLexer& src);
|
||||
void ParseDecalInfo(idLexer& src);
|
||||
bool CheckSurfaceParm(idToken* token);
|
||||
int GetExpressionConstant(float f);
|
||||
int GetExpressionTemporary(void);
|
||||
expOp_t* GetExpressionOp(void);
|
||||
int EmitOp(int a, int b, expOpType_t opType);
|
||||
int ParseEmitOp(idLexer& src, int a, expOpType_t opType, int priority);
|
||||
int ParseTerm(idLexer& src);
|
||||
int ParseExpressionPriority(idLexer& src, int priority);
|
||||
int ParseExpression(idLexer& src);
|
||||
void ClearStage(shaderStage_t* ss);
|
||||
int NameToSrcBlendMode(const idStr& name);
|
||||
int NameToDstBlendMode(const idStr& name);
|
||||
void MultiplyTextureMatrix(textureStage_t* ts, int registers[2][3]); // FIXME: for some reason the const is bad for gcc and Mac
|
||||
void SortInteractionStages();
|
||||
void AddImplicitStages( const textureRepeat_t trpDefault = TR_REPEAT );
|
||||
void AddImplicitStages(const textureRepeat_t trpDefault = TR_REPEAT);
|
||||
void CheckForConstantRegisters();
|
||||
|
||||
private:
|
||||
#ifdef PREY
|
||||
subviewClass_t subviewClass; // HUMANHEAD tmj: Type of subview this surface points to
|
||||
#endif
|
||||
idStr desc; // description
|
||||
idStr renderBump; // renderbump command options, without the "renderbump" at the start
|
||||
|
||||
idImage * lightFalloffImage;
|
||||
idImage* lightFalloffImage;
|
||||
|
||||
int entityGui; // draw a gui with the idUserInterface from the renderEntity_t
|
||||
// non zero will draw gui, gui2, or gui3 from renderEnitty_t
|
||||
mutable idUserInterface *gui; // non-custom guis are shared by all users of a material
|
||||
mutable idUserInterface* gui; // non-custom guis are shared by all users of a material
|
||||
|
||||
bool noFog; // surface does not create fog interactions
|
||||
|
||||
int spectrum; // for invisible writing, used for both lights and surfaces
|
||||
|
||||
#ifdef PREY
|
||||
int directPortalDistance; // HUMANHEAD: Distance at which direct render portals are drawn
|
||||
#endif
|
||||
float polygonOffset;
|
||||
|
||||
int contentFlags; // content flags
|
||||
@@ -690,7 +728,7 @@ private:
|
||||
mutable float sort; // lower numbered shaders draw before higher numbered
|
||||
deform_t deform;
|
||||
int deformRegisters[4]; // numeric parameter for deforms
|
||||
const idDecl *deformDecl; // for surface emitted particle deforms and tables
|
||||
const idDecl* deformDecl; // for surface emitted particle deforms and tables
|
||||
|
||||
int texGenRegisters[MAX_TEXGEN_REGISTERS]; // for wobbleSky
|
||||
|
||||
@@ -706,19 +744,19 @@ private:
|
||||
bool allowOverlays;
|
||||
|
||||
int numOps;
|
||||
expOp_t * ops; // evaluate to make expressionRegisters
|
||||
expOp_t* ops; // evaluate to make expressionRegisters
|
||||
|
||||
int numRegisters; //
|
||||
float * expressionRegisters;
|
||||
float* expressionRegisters;
|
||||
|
||||
float * constantRegisters; // NULL if ops ever reference globalParms or entityParms
|
||||
float* constantRegisters; // NULL if ops ever reference globalParms or entityParms
|
||||
|
||||
int numStages;
|
||||
int numAmbientStages;
|
||||
|
||||
shaderStage_t * stages;
|
||||
shaderStage_t* stages;
|
||||
|
||||
struct mtrParsingData_s *pd; // only used during parsing
|
||||
struct mtrParsingData_s* pd; // only used during parsing
|
||||
|
||||
float surfaceArea; // only for listSurfaceAreas
|
||||
|
||||
@@ -726,7 +764,7 @@ private:
|
||||
// all the invisible and uncompressed images.
|
||||
// If editorImage is NULL, it will atempt to load editorImageName, and set editorImage to that or defaultImage
|
||||
idStr editorImageName;
|
||||
mutable idImage * editorImage; // image used for non-shaded preview
|
||||
mutable idImage* editorImage; // image used for non-shaded preview
|
||||
float editorAlpha;
|
||||
|
||||
bool suppressInSubview;
|
||||
@@ -734,6 +772,6 @@ private:
|
||||
int refCount;
|
||||
};
|
||||
|
||||
typedef idList<const idMaterial *> idMatList;
|
||||
typedef idList<const idMaterial*> idMatList;
|
||||
|
||||
#endif /* !__MATERIAL_H__ */
|
||||
|
||||
Reference in New Issue
Block a user