/*============================================================================= Name : ETG.H Purpose : Effects Tool. OF THE GODS! Parsing and execution definitions. Created 11/11/1997 by lmoloney Copyright Relic Entertainment, Inc. All rights reserved. =============================================================================*/ #ifndef ___ETG_H #define ___ETG_H #include "spaceobj.h" #include "vector.h" #include "matrix.h" /*============================================================================= Switches: =============================================================================*/ #define ETG_SELECT_EXPLOSION 1 //logic for selecting explosion types #define ETG_DEFAULT_EXPLOSIONS 1 //still support older 'explosionType' in .shp files #ifndef HW_Release #define ETG_ERROR_CHECKING 1 //general error checking #define ETG_VERBOSE_LEVEL 1 //control specific output code #define ETG_TESTING 1 //enable effects testing #define ETG_RELOAD_KEY RKEY //reload all effects key #define ETG_DISABLEABLE 1 //disable effects #define ETG_DETATCH_STATS 1 //display special owner detachment stats #else //HW_Debug #define ETG_ERROR_CHECKING 0 //general error checking #define ETG_VERBOSE_LEVEL 0 //control specific output code #define ETG_TESTING 0 //enable effects testing #define ETG_RELOAD_KEY 0 #define ETG_DISABLEABLE 0 //disable effects #define ETG_DETATCH_STATS 0 //display special owner detachment stats #endif //HW_Debug /*============================================================================= Definitions: =============================================================================*/ //Tokens representing type of structure in an effect program. These are //basically 'opcodes' where the rest of the structure is the operands. //suffix definitions: V = Variable, C = constant (default), // F - float, I - Int, Co - RGB color, Ca - RGBA color, Vec - vector typedef enum { //0 EOP_Nop, //do nothing //time-index code block comparison operations EOP_Before, EOP_BeforeVar, EOP_After, EOP_AfterVar, EOP_At, EOP_AtVar, //same as at but uses a variable EOP_Between, EOP_Every, EOP_EveryVar, //same as every but uses a variable //10 EOP_EffectorCCI, //Constant-constant, integer EOP_EffectorCCF, // , float EOP_EffectorCCCo, // , RGB EOP_EffectorCCCa, // , RGBA EOP_EffectorCVI, //Constant-variable, integer EOP_EffectorCVF, // , float EOP_EffectorCVCo, // , RGB EOP_EffectorCVCa, // , RGBA EOP_EffectorVCI, //variable-constant, integer EOP_EffectorVCF, // , float //20 EOP_EffectorVCCo, // , RGB EOP_EffectorVCCa, // , RGBA EOP_EffectorVVI, //variable-variable, integer EOP_EffectorVVF, // , float EOP_EffectorVVCo, // , RGB EOP_EffectorVVCa, // , RGBA EOP_EffectorVI, //current-variable , integer EOP_EffectorVF, // , float EOP_EffectorVCo, // , RGB EOP_EffectorVCa, // , RGBA //30 EOP_EffectorCI, //current-constant , integer EOP_EffectorCF, // , float EOP_EffectorCCo, // , RGB EOP_EffectorCCa, // , RGBA //process-control EOP_Delete, EOP_End, EOP_Yeild, //branching EOP_Goto, EOP_Call, EOP_Return, //40 EOP_Spawn, EOP_Start, //conditionals EOP_EqualVCI, //variable, constant, integer EOP_NotEqualVCI, EOP_GreaterVCI, EOP_GreaterEqualVCI, EOP_LessVCI, EOP_LessEqualVCI, EOP_EqualVVI, //variable, variable, integer EOP_NotEqualVVI, //50 EOP_GreaterVVI, EOP_GreaterEqualVVI, EOP_LessVVI, EOP_LessEqualVVI, EOP_EqualVCF, //variable, constant, float EOP_NotEqualVCF, EOP_GreaterVCF, EOP_GreaterEqualVCF, EOP_LessVCF, EOP_LessEqualVCF, //60 EOP_EqualVVF, //variable, variable, float EOP_NotEqualVVF, EOP_GreaterVVF, EOP_GreaterEqualVVF, EOP_LessVVF, EOP_LessEqualVVF, EOP_ZeroVI, //variable, integer EOP_NotZeroVI, EOP_ZeroVF, //variable, float EOP_NotZeroVF, //general //70 EOP_VariableCopy, //copy a variable EOP_VariableAssign, //assign a variable a constant value EOP_Function, //execute a function EOP_Alternate, //perform an alternate decision (random) EOP_Case, //perform a case decision (from integer) EOP_LastOp, EOP_Resolve = 0x4000 //resolve forward references on pass2 } etgopcode; #define EOP_LowestConditional EOP_EqualVCI #define EOP_HighestConsitional EOP_NotZeroVF //flags for a parse table entry #define PTF_Parameters 1 //opcode has parameters in parenthesis #define PTF_RestOfLine 2 //has parameters, but not in parenteses #define PTF_Return 4 //opcode expects a return value #define PTF_ReturnOptional 8 //opcode can have a return value //variable types. Bit fields to permit specification of a variety of types #define EVT_Void 0 #define EVT_Int 1 #define EVT_Float 2 #define EVT_RGB 3 #define EVT_RGBA 4 #define EVT_Pointer 5 #define EVT_Constant 6 //constant number #define EVT_Label 7 //not really a variable, but saves on code #define EVT_ConstLabel 8 //offset in the constData block #define EVT_VarLabel 9 //offset in the variables block #define EVT_This 10 //include a 'this' pointer //amounts to allocate during parsing of an effect #define ETG_StartupParseSize 16384 #define ETG_EachFrameParseSize 16384 #define ETG_TimeIndexParseSize 8192 #define ETG_VarTableParseLength 256 #define ETG_NewParticleLength 8 #define ETG_ConstDataPool 32768 //parser modes #define EPM_Startup 0 //defining startup code block #define EPM_EachFrame 1 //defining eachframe code block #define EPM_TimeIndex 2 //defining time index code block #define ETG_NumberCodeBlocks 3 //total number of code blocks #define EPM_Variables 3 //defining variables #define EPM_Nothing 64 //not in any type of block #define EPM_Constant EPM_Nothing //define constants, such as texture animations //alternate stuffs #define EAT_Int 0 //alternate type (int/float) #define EAT_Float 1 #define ETG_MaxAlternates 32 //maximum number of alternates in a single effect //general #define ETG_MaxParams 9 //max number of parameters in an function call #define ETG_VariableParams 128 //variable number of parameters (like the ... operator) #define ETG_NestStackDepth 10 //max depth of nesting stack #define ETG_EventListLength 256 //max number of effect events #define ETG_DecisionMax 128 //max size of an alternate opcode's offset table #define ETG_NumberMeshes 128 //number of ETG-specific meshes //etg script file #define ETG_Directory "ETG\\" #define ETG_Script "etg.script" #define ETG_NumberTestKeys 8 //event types #define EDT_AccumDamage 0 #define EDT_ProjectileHit 1 #define EDT_BeamHit 2 #define EDT_Collision 3 #define EDT_Special 4 #define EDT_NumberExplosionTypes 5 #define EGT_GunFire 0 //muzzle flash effect #define EGT_GunHit 1 //bullet hit effect #define EGT_GunBullet 2 //effect for the actual bullet #define EGT_BulletDestroyed 3 //bullet destroyed by defense fighter //#define EGT_BulletExpired 5 //bullet expired because it ran out of time #define EGT_NumberGunTypes 5 #define ETG_AsteroidEffect 0 //effect by resource type enumeration #define ETG_GaseousEffect 1 #define ETG_NumberResourceTypes 2 #define DMG_NumberDamageTypes 3 #define DMG_Light 0 #define DMG_Heavy 1 #define DMG_Dying 2 #define DMG_All 3 #define ETG_DefaultBoom "ETG\\genericBOOM.ebg" #define ETG_DefaultBlast "ETG\\defaultBlast.ebg" #define ETG_UpdateRoundOff (UNIVERSE_UPDATE_PERIOD / 2.0f) //default bullet colors #define ETG_DefaultBulletColor colRGB(100,184,255) #define ETG_R1BulletColor colRGB(255,180,0) //parameter indices and whatnot #define ETG_LengthVariable 2 //length parameter of bullet effects #define ETG_SpecialDurationParam 1 //duration of special effects #define ETG_BulletDurationParam 3 //duration of bullet effects #define ETG_ResourceLengthParam 0 //length parameter of resourcing effects #define ETG_ResourceRadiusParam 1 //width parameter of resourcing effects #define ETG_ResourceDurationParam 2 //duration parameter of resourcing effects #define ETG_NumberParameters 8 //number of parameters supported by variable-parameter functions //effect flags #define EF_Rendered 0x00000010 #define EF_ToBeDeleted 0x00000001 #define EM_ToBeDeleted 0x0000000f #define EM_ForceDelete 0x00000003 #define EAF_Position SOF_AttachPosition #define EAF_Velocity SOF_AttachVelocity #define EAF_Coordsys SOF_AttachCoordsys #define EAF_NLips SOF_AttachNLips #define EAF_PosVel (SOF_AttachPosition | SOF_AttachVelocity) #define EAF_PosCoord (SOF_AttachPosition | SOF_AttachCoordsys) #define EAF_VelCoord (SOF_AttachVelocity | SOF_AttachCoordsys) #define EAF_Full (SOF_AttachPosition | SOF_AttachCoordsys | SOF_AttachVelocity | SOF_AttachNLips) #define EAF_AllButNLips (SOF_AttachPosition | SOF_AttachCoordsys | SOF_AttachVelocity) #define EAF_PlayingSpeech 0x20000000 #define EAF_OwnerCoordSys 0x01000000 //effect history stuff #define EH_DefaultSize -1 #define EH_TimeElapsed 1.0f //effect special operations #define ESO_SelfDeleting 0x00000001 //effect has a delete() opcode #define ESO_SortForward 0x00000002 //effect should be sorted forward, in front of ships #define ESO_WorldRender 0x00000004 //effect will be rendered like a planet, i.e. really far away //#define ESO_ForceVisible 0x00000008 //force effect to stay in render list //optimization tweakable defaults #define ETG_HistoryScalarMin 64 #define ETG_HistoryScalar 256 #define ETG_SoftwareScalarDamage 0.707f //square root(0.5) #define ETG_SoftwareScalarHit 0.707f //square root(0.5) #define ETG_SoftwareScalarFire 0.866f //square root(0.75) #define ETG_TokenDelimiters ", \t" /*============================================================================= Type definitions: =============================================================================*/ // ****** Structures for various p-code operations. The first member is the actual opcode //EOP_Nop typedef struct { etgopcode opcode; } etgnop; //EOP_Yield, EOP_Delete, EOP_End typedef struct { etgopcode opcode; } etgprocesscontrol; //EOP_Before/EOP_After/EOP_At typedef struct { etgopcode opcode; sdword codeBytes; //bytes to skip if wrong time real32 time; //time delimiter } etgbeforeafterat; //EOP_Before/EOP_After/EOP_At typedef struct { etgopcode opcode; sdword codeBytes; //bytes to skip if wrong time udword variable; //time delimiter variable } etgbeforeafteratvar; //EOP_Between typedef struct { etgopcode opcode; real32 start; //bounds of when to execute real32 end; udword startVar; //variable bounds udword endVar; sdword codeBytes; //bytes to skip if wrong time } etgbetween; //EOP_Effector[CC,CV,VC,VV][I,F,Co,Ca] typedef struct { etgopcode opcode; udword start, end; //end-points of range, cast to different types udword effector; //offset in variable block udword rate; //offset in rate block ubyte effectorID; //current effectorID } etgeffector; //EOP_Effector[C,V][I,F,Co,Ca] (current to variable or constant) typedef struct { etgopcode opcode; udword end; //end of range, cast to different types udword effector; //offset in variable block udword rate; //offset in rate block ubyte effectorID; //current effectorID } etgseffector; //EOP_Goto, EOP_Call typedef struct { etgopcode opcode; udword codeBlock; udword branchTo; //location to branch to } etgbranch; //EOP_Return typedef struct { etgopcode opcode; //no other info needed } etgreturn; //EOP_xxxx same structure for all conditionals typedef struct { etgopcode opcode; udword param0, param1; //can be constants or variable offsets sdword codeBytes; //bytes of conditional code // sdword elseBytes; //bytes of conditional else code } etgconditional; //EOP_VariableCopy typedef struct { etgopcode opcode; udword source, dest; //source and destination of var copy } etgvariablecopy; //EOP_Function typedef struct { etgopcode opcode; udword (*function)(void); //function to call udword nParameters; //number of parameters to pass udword returnValue; //variable to assign return value to, if any bool passThis; //shall we pass a reference to this effect? struct { udword type; //type of parameter, see above udword param; //constant, variable or pointer } parameter[1]; //ragged array of parameters to pass } etgfunctioncall; //EOP_Alternate, EOP_Variable typedef udword decisionoffset; typedef struct { udword opcode; udword criteria; //variable or alternate to use for criteria udword tableLength; //number of offsets in following arrays udword codeBytes; //length of the total alternate table (for branching) decisionoffset *offset; //actual decision members relative to this opcode } etgdecision; //opcode-handler function dispatch table entry typedef sdword (*ophandlefunction)(struct Effect *effect, struct etgeffectstatic *stat, ubyte *opcode); typedef struct { sdword length; //length of opcode structure ophandlefunction function; //handler function } ophandleentry; //opcode-parsing table entry typedef sdword (*opparsefunction)(struct etgeffectstatic *stat, ubyte *dest, char *opcode, char *params, char *ret); typedef struct { char *name; //corresponding op-code name, if any udword flags; //parsing flags opparsefunction function; //function to handle parsing/creation of the opcode } opparseentry; //function-call-resolve function pointer, for hand-tweaking the results of a function call. typedef void (*etgresolvefunction)(struct etgeffectstatic *stat, etgfunctioncall *call); //function-parsing table entry typedef struct { char *name; //name of function void *function; //function pointer ubyte returnType; //return value type, if any ubyte passThis; etgresolvefunction resolve; ubyte nParams; //number of parameters to this function ubyte type[ETG_MaxParams]; //parameter types } opfunctionentry; //entry in a variable-name list for this effect typedef struct { char *name; //name of variable udword offset; //offset in variable block of this effect udword rateOffset; //offset in the variable rate block or 0xffffffff udword initial; //initial value of type, if any ubyte bInitial; //flag set nonzero if there is an initial value ubyte type; //type of variable ubyte size; //optional size of pointer-variable, not needed for dword types ubyte codeBlock; //etgParseMode when created } etgvarentry; //structure for an entry on the brace nesting stack typedef void (*nestfunction)(sdword codeBlock, sdword offset, sdword newOffset, ubyte *userData); typedef void (*nestopenfunction)(sdword codeBlock, sdword offset, ubyte *userData); typedef struct { nestopenfunction openFunction; //function to call on brace open, if any nestfunction function; //function to call on brace close sdword codeBlock; //which block it started in (EPM_Startup etc.) sdword offset; //offset the conditional instruction ubyte *userData; //whatever you like } etgnestentry; //structure for parsing conditional statements typedef struct { char symbol[4]; //comparisson symbol char transpose[4]; //symbol to use if parameters are reversed etgopcode opcode[4]; //variable-constant-integer //variable-variable-integer //variable-constant-Float //variable-variable-Float } etgcondentry; //structure for a code block within an effect's static info block typedef struct { ubyte *code; //actual code block udword length; //length of code block udword offset; //current offset in code block (if applicable) } etgcodeblock; //structure for making an alternate decision typedef struct { udword type; udword low; udword high; } etgalternate; typedef struct { etgalternate alt; etgdecision *decision; } etgextalt; //structure for an effect object's static information typedef struct etgeffectstatic { char *name; //name of effect struct etgeffectstatic *softwareVersion; //version of effect to play in software, if any udword nParticleBlocks; //number of particle block pointers to allocate udword variableSize; //size of variables block udword rateSize; //size of variables rates block. sdword effectSize; //total size of the effect (sans particle systems) ubyte *variableOffsets; //variable initialization data udword *variableInitData; //variable init data sdword initLength; //length of variable init data ubyte *constData; //constant data, such as texture animations udword constLength; //length of constant data sdword nDecisions; //data for making alternate decisions etgalternate *decisions; udword *alternateOffsets; //offset tables for alternates etgcodeblock codeBlock[ETG_NumberCodeBlocks];//startup, eachframe and time index sdword nHistoryList; //length of history list sdword iHistoryList; //index into history list real32 *historyList; //actual history list // bool8 bSelfDeleting; //has a delete() opcode // char pad[3]; //round the size up udword specialOps; //special operations this effect does } etgeffectstatic; //strucutre for LOD of effects typedef struct { sdword nLevels; //number of levels etgeffectstatic *level[1]; //array of levels } etglod; //structure for an entry in the effect event registry typedef struct { // char *name; struct etgeffectstatic *effectStatic; sdword loadCount; } etgevent; //entry in the p-code call stack typedef struct { udword codeBlock; udword codeOffset; } etgcallstackentry; //effector-rate structures for RGB and RGBA types typedef struct { udword red, green, blue; } etgratergb; typedef struct { udword red, green, blue, alpha; } etgratergba; /*============================================================================= Data: =============================================================================*/ //dispatch tables for standard events extern etgeffectstatic *etgDefaultBoom; extern etgeffectstatic *etgDefaultBlast; extern etglod *etgDeathEventTable[NUM_RACES][NUM_CLASSES][EDT_NumberExplosionTypes]; extern etglod *etgDeathEventTableDerelict[NUM_DERELICTTYPES][EDT_NumberExplosionTypes]; extern etglod *etgGunEventTable[NUM_RACES][NUM_GUN_SOUND_TYPES][EGT_NumberGunTypes]; extern etglod *etgResourceEffectTable[NUM_RACES][ETG_NumberResourceTypes]; extern etglod *etgTractorBeamEffectTable[NUM_RACES]; extern etglod *etgSpecialPurposeEffectTable[EGT_NumberOfSpecialEffects]; extern etglod *etgDamageEffectTable[NUM_CLASSES][DMG_NumberDamageTypes]; extern etglod *etgHyperspaceEffect; extern color etgBulletColor[NUM_RACES][NUM_GUN_SOUND_TYPES]; extern sdword etgBigDeathFactor[NUM_RACES][NUM_CLASSES]; extern sdword etgBigDeathFactorDerelict[NUM_DERELICTTYPES]; extern ubyte etgDeathModeByGunType[]; extern sdword etgEffectsEnabled; extern bool etgErrorRecoverable; extern bool etgErrorEncountered; //variables for ETG user tweaks: extern real32 etgSoftwareScalarDamage; //scale certain effects down when in software mode. extern real32 etgSoftwareScalarHit; //scale certain effects down when in software mode. extern real32 etgSoftwareScalarFire; //scale certain effects down when in software mode. extern sdword etgHistoryScalar; //from etgHistoryScalarMin to 256 inclusive extern sdword etgHistoryScalarMin; extern bool etgDamageEffectsEnabled; extern bool etgHitEffectsEnabled; extern bool etgFireEffectsEnabled; extern bool etgBulletEffectsEnabled; /*============================================================================= Macros: =============================================================================*/ #define etgFunctionSize(n) (sizeof(etgfunctioncall) + sizeof(sdword) * 2 * ((n) - 1)) #define etgEffectSize(n) (sizeof(Effect) + sizeof(ubyte *) * ((n) - 1)) #define etgDecisionSize(n) (sizeof(etgdecision) + sizeof(decisionoffset) * ((n) - 1)) #define etgLODSize(n) (sizeof(etglod) + sizeof(etgeffectstatic *) * ((n) - 1)) //#define etgEffectStaticSize(n) (sizeof(etgeffectstatic) + sizeof(real32) * ((n) - 1)) #define etgHistoryRegister(stat) if ((stat)->historyList != NULL) etgHistoryRegisterFunction(stat); /*============================================================================= Functions: =============================================================================*/ //startup/shutdown effects module void etgStartup(void); void etgShutdown(void); void etgReset(void); void etgReloadReset(void); void etgFixupUV(void); //load in an effect template from an effect file and then delete. etgeffectstatic *etgEffectCodeLoad(char *fileName); etgeffectstatic *etgEffectStaticFind(char *name, bool bRegister); void etgEffectCodeDelete(etgeffectstatic *stat, bool bFullDelete); //create effects void etgEffectCodeStart(etgeffectstatic *stat, void *effect, sdword nParams, ...); void etgEffectDelete(void *effect); void *etgEffectCreate(etgeffectstatic *stat, void *owner, vector *pos, vector *vel, matrix *coordsys, real32 nLips, udword flags, sdword nParams, ...); bool etgFrequencyExceeded(etgeffectstatic *stat); void etgHistoryRegisterFunction(etgeffectstatic *stat); //update effects bool etgEffectUpdate(void *effect, real32 timeElapsed); void etgEffectDraw(void *effect); void etgShipDied(void *deadDuck); sdword etgDeleteEffectsOwnedBy(void *owner); //mesh registry stuff meshdata *etgMeshRegister(char *filename); void etgMeshRegistryReset(void); //etg random stream extern udword etgFRandom(real32 low, real32 high); // Save Game stuff sdword saveEtglodGunEventToIndex(etglod *lod); etglod *saveIndexToEtglodGunEvent(sdword index); #endif //___ETG_H