// This file is distributed under a BSD license. See LICENSE.txt for details. #ifndef __KDOC_HPP__ #define __KDOC_HPP__ #include "_types.hpp" #include "_start.hpp" /****************************************************************************/ struct KLogic; // game logic operation struct KOp; // Operator struct KEvent; // Event in timeline struct KSpline; // Spline struct KInstanceMem; // per event and operator memory class KEnvironment; // glue everything together /****************************************************************************/ // program limits #define KK_MAXLINK 16 // linked inputs #define KK_MAXSPLINE 8 // spline inpuits #define KK_MAXINPUT 256 // conected inputs #define KK_MAXKEYS 128 // keys per spline, each dimension has it's own #define KK_NAME 32 // editor-name (not stored here) #define KK_MAXVAR 32 // variables for animation #define KK_MAXVARSAVE 256 // space for saving variables #define KK_MAXJOBS 1024 // max paintjobs #define MAX_OP_ROOT 16 // there are multiple roots nowadays // animation options #define KAF_INT 0 // integral numbers #define KAF_FIXED 1 // 16 bit fixed point #define KAF_FLOAT 2 // 32 bit float #define KAF_UBYTE 3 // ubyte, like for colors #define KAM_MUL 0x0001 // multiply instead of adding #define KAM_VELOCIFY 0x0002 // multiply spline with velocity #define KAM_MODULATE 0x0004 // multiply spline with modulation #define KAM_SELECT 0x0010 // replace time with select #define KAM_MOUSEX 0x0020 // replace time with mousex #define KAM_MOUSEY 0x0030 // replace time with mousex // KObject Class ID's #define KC_NULL 0 // no input allowed #define KC_BITMAP 1 // bitmap #define KC_MINMESH 2 // minimal mesh #define KC_SCENE 3 // list of meshes #define KC_KKRIEGER 4 // the game itself #define KC_MATERIAL 5 // material #define KC_MESH 6 // a real mesh #define KC_IPP 8 // image postprocessing #define KC_EFFECT 9 // special effect, painted in scene like meshes but with own code #define KC_SMESH 10 // simple mesh (but with bsp) #define KC_DEMO 11 // image postprocessing #define KC_SCENE2 12 // new scene. this is no OP! #define KC_SPLINE 13 // some kind of spline #define KC_IMGLIST 14 // image list #define KC_COUNT 15 // number of distinct object classes //#define KC_UPDATE 254 // an update object, that's no real object #define KC_ANY 255 // any class allowed as input /****************************************************************************/ #define KA_NOP 0x00 // no operation #define KA_END 0x01 // end of program #define KA_LOADVAR 0x02 // load variable #define KA_LOADPARA1 0x03 // load original operator parameter #define KA_LOADPARA2 0x04 // load original operator parameter #define KA_LOADPARA3 0x05 // load original operator parameter #define KA_LOADPARA4 0x06 // load original operator parameter #define KA_SWIZZLEX 0x07 // x -> xyzw #define KA_SWIZZLEY 0x08 // y -> xyzw #define KA_SWIZZLEZ 0x09 // z -> xyzw #define KA_SWIZZLEW 0x0a // w -> xyzw #define KA_ADD 0x0b // a+b #define KA_SUB 0x0c // a-b #define KA_MUL 0x0d // a*b #define KA_DIV 0x0e // a/b #define KA_MOD 0x0f // a%1 #define KA_INVERT 0x10 // 1-a #define KA_NEG 0x11 // -a #define KA_SIN 0x12 // sin(t) #define KA_COS 0x13 // cos(t) #define KA_PULSE 0x14 // pulse(t,phase) #define KA_RAMP 0x15 // ramp(t) #define KA_CONSTV 0x16 // const float vector #define KA_CONSTC 0x17 // const color #define KA_CONSTS 0x18 // const scalar #define KA_SPLINE 0x19 // spline(t,"name") #define KA_EVENTSPLINE 0x1a // eventspline(t) -> use spline from event #define KA_MATRIX 0x1b // apply matrix #define KA_NOISE 0x1c // noise #define KA_EASE 0x1d // ease in / out #define KA_TIMESHIFT 0x1e // remap time range #define KA_POW 0x1f // a^b #define KA_LOG2 0x20 // log2(x) #define KA_POW2 0x21 // 2^x (float) #define KA_STOREVAR 0x80 // store variable, with writemask #define KA_STOREPARAFLOAT 0x90 // store parameter, with writemask #define KA_STOREPARAINT 0xa0 // store parameter, with writemask #define KA_STOREPARABYTE 0xb0 // store parameter, with writemask #define KA_CHANGEPARAFLOAT 0xd0 // store parameter, with writemask, changing #define KA_CHANGEPARAINT 0xe0 // store parameter, with writemask, changing #define KA_CHANGEPARABYTE 0xf0 // store parameter, with writemask, changing sInt CalcCmdSize(sU8 *bytecode); // calc size of one single bytecode command sInt CalcCodeSize(sU8 *bytecode); // returns size of bytecode fragment sBool AnimCodeWritesTo(sU8 *code,sInt offset); // find if offset is changed by code /****************************************************************************/ #define KV_TIME 0x00 // basic event #define KV_VELOCITY 0x01 #define KV_MODULATION 0x02 #define KV_SELECT 0x03 // count for multiply / particles #define KV_EVENT_S 0x04 // event matrix #define KV_EVENT_R 0x05 #define KV_EVENT_T 0x06 #define KV_EVENT_C 0x07 // event color #define KV_CAM_S 0x08 // camera matrix #define KV_CAM_R 0x09 #define KV_CAM_T 0x0a #define KV_FRACTION 0x0b // fraction for particles #define KV_PLAYER_S 0x0c // player matrix #define KV_PLAYER_R 0x0d #define KV_PLAYER_T 0x0e #define KV_0f 0x0f // unused #define KV_LEG_L0 0x10 // walker-leg position #define KV_LEG_R0 0x11 #define KV_LEG_L1 0x12 #define KV_LEG_R1 0x13 #define KV_LEG_L2 0x14 #define KV_LEG_R2 0x15 #define KV_LEG_L3 0x16 #define KV_LEG_R3 0x17 #define KV_18 0x18 // unused #define KV_19 0x19 // unused #define KV_1a 0x1a #define KV_LEG_TIMES 0x1b // walker timing { time, 0, 0, 0 } #define KV_MATRIX_I 0x1c // general purpose matrix (set by Limb) #define KV_MATRIX_J 0x1d #define KV_MATRIX_K 0x1e #define KV_MATRIX_L 0x1f // variable misuse for monster // KV_EVENT_S // attack timer { melee, ranged, life-percent, 0 } /****************************************************************************/ // calling convention bitmasks, in the order of parameters sInt inline OPC_GETDATA(sU32 x) {return (x&0x000000ff);} sInt inline OPC_GETINPUT(sU32 x) {return (x&0x00000f00)>>8;} sInt inline OPC_GETLINK(sU32 x) {return (x&0x0000f000)>>12;} sInt inline OPC_GETSTRING(sU32 x) {return (x&0x00070000)>>16;} sInt inline OPC_GETSPLINE(sU32 x) {return (x&0x00700000)>>20;} // i assume that 2 bit are enough, tho #define OPC_BLOB 0x00080000 // blob is stored in op. this does not change the actual calling convention #define OPC_KENV 0x00800000 // push KENV in INIT #define OPC_VARIABLEINPUT 0x01000000 // use Call(x,y,...); convention (for add) #define OPC_SKIPEXEC 0x02000000 // nothing special happens during the exec phase #define OPC_ALTEXEC 0x04000000 // alternative calling convention for exec (no parameter) //#define OPC_OUTPUTCOUNT 0x08000000 // add outputcount as parameter (removed!) #define OPC_STRIPPEDIN 0x08000000 // op accepts stripped inputs #define OPC_DONTCALLLINK 0x10000000 // don't call link. used to pass events. #define OPC_ALTINIT 0x20000000 // alternative calling convention for ínit (no parameter except op) #define OPC_KOP 0x40000000 // push KOp in INIT (op is before env) #define OPC_FLEXINPUT 0x80000000 // non-fixed number of input parameters (only in export) // - the inputcount will be in the specified range // - all inputs within inputcount are valid // - links may be failty // - if there is is an op as input or link, it will have a cached object // this is true for Init and Exec // in the player, this is explicitly assumed // in the werkkzeug, this is checked in Init / Exec // if DONTCALLLINK is set, links are not checked in Init. /****************************************************************************/ struct KLogic // effect connected to cell { sU8 Code; // KKEC_??? KKEE_??? sU8 Condition; // additional switch condition for switch and value groups. use switch 0 which is always on sU8 Output; // output: event or switch sU8 pad; sInt Value; // value for value-group, switch for logic group KOp *Event[2]; // (possible) event to issue }; // what to do #define KKEC_NOP 0x00 // nothing // switches #define KKEC_ENABLESWITCH 0x01 // set switch on event #define KKEC_DISABLESWITCH 0x02 // clear switch on event #define KKEC_TOGGLESWITCH 0x03 // toggle switch on event #define KKEC_SETSWITCH 0x04 // set event (0/1) to switch // collectables #define KKEC_SETVALUE 0x05 // output = value #define KKEC_MAXVALUE 0x06 // output = max(output,value) #define KKEC_MINVALUE 0x07 // output = min(output,value) #define KKEC_INCVALUE 0x08 // output = output + value #define KKEC_DECVALUE 0x09 // output = output - value // game physics #define KKEC_JUMP 0x0a // accelerate up by value*0.001f #define KKEC_RESPAWN 0x0b // set respawn zone for player, value=0..9 /* // switch logic #define KKEC_ANDLOGIC 0x0a // output = condition & value #define KKEC_ORLOGIC 0x0b // output = condition | value #define KKEC_NOTLOGIC 0x0c // output = !condition */ // when to do #define KKEE_NOP 0x00 // never #define KKEE_ENTER 0x10 // when entering a zone #define KKEE_LEAVE 0x20 // when leaving a zone #define KKEE_COLLECT 0x30 // when entering a zone, once #define KKEE_RESPAWN0 0x40 // when entering a zone, will respawn soon #define KKEE_RESPAWN1 0x50 // when entering a zone, will respawn #define KKEE_RESPAWN2 0x60 // when entering a zone, will respawn #define KKEE_RESPAWN3 0x70 // when entering a zone, will respawn late #define KKEE_USE 0x80 // when pressing the use button inside a zone #define KKEE_HIT 0x90 // when a shot "enters" a zone #define KKEE_ALWAYS 0xa0 // always, with respect to the condition #define KKEE_INSIDE 0xb0 // when inside #define KKEE_HITORENTER 0xc0 // when hit or entered /****************************************************************************/ class KObject // base cass { public: sInt ClassId; // KC_?? sInt RefCount; // KObject(); protected: virtual ~KObject(); public: virtual void Copy(KObject *o); // copy from object virtual KObject *Copy(); // duplicate object void AddRef() {RefCount++;} void Release() {RefCount--;if(RefCount==0) delete this;} virtual sBool Strip(); // throw away anything that's not necessary after init. return if this object has usable data left. virtual sBool IsStripped(); // has this object been stripped? }; // =12 bytes (vtable+8) /****************************************************************************/ struct KInstanceMem // used for instance-storage. derive from this { KOp *Operator; // operator requesting storage KInstanceMem *Next; // next instance mem KInstanceMem **DeleteChild; // recurse to this child when DeleteChain(). KInstanceMem **DeleteChild2; // recurse to this child when DeleteChain(). void *DeleteArray; // call delete[] on this when DeleteChain(). sBool Reset; // set true on first encounter, automatically reset void DeleteChain(); // delete a list of KInstanceMem, beginning with *this. can be called on 0-pointers }; struct KEvent // timeline event { void Init(); // clear all void Exit(); void Stop(); // stop event by changing time. do this only to dynamic events! sMatrix Matrix; // event base matrix KOp *Op; // execute this operator KEvent *NextOp; // linked list of active events per op sInt Start; // time start sInt End; // time end sInt Mark; // connect KEvent and KSpline sInt ShotTime; // only used for reflect shots sInt Active; // obsolete KInstanceMem *FirstInstance; // first instance in chain sInt Dynamic; // dynamic events must be deleted when removed sInt RemoveMe; // terminate this event sInt Flags; // various flags sF32 Velocity; // event variable velocity sF32 Modulation; // event variable modulation sInt Select; // event variable selection, 0..16 maps to time 0..1 sVector Scale; // event variable sVector Rotate; // event variable sVector Translate; // event variable sU32 Color; // event variable KSpline *Spline; // spline for event sF32 StartInterval; // start interval time (default: 0) sF32 EndInterval; // end interval time (default 1) // obscure special hardcoded shit... // sMatrix ReturnMatrix; // pass back a matrix to system, used by WALK struct KKriegerMonster *Monster;// connect collision to monster, used by PHYSIC sInt CullDist; // set if you want distance-culling }; #define KEF_NOTIME 0x0001 // don't manipulate time /****************************************************************************/ /****************************************************************************/ struct KLetterMetric { sFRect UV; sF32 PreSpace; sF32 Width; }; /****************************************************************************/ // calc-flags #define KCF_NEED 0x0001 // result is really needed. this flag is cleared during recursion when no changes are found. #define KCF_ROOT 0x0002 // tool-memory-management: do not flush root #define KCF_PRECALC 0x0004 // progress bar and memory management #define KCF_STRIPPEDOK 0x0008 // accept stripped ops as valid class KEnvironment // variables for { public: KEnvironment(); ~KEnvironment(); void InitView(); // prepare for viewing. Set after Init and before Exec, or whenever the viewed op was changed in the editor void InitFrame(sInt beattime,sInt timems); // prepare for frame and time void ExitFrame(); // clean up afterwards // void Calc(KOp *op); // call Init_???() void AddDynamicEvent(KEvent *event); // call this to register event. event gets deleted by KEnv. this is used by TRIGGER void AddStaticEvent(KEvent *event); // add static events. memory is managed by caller. call this directly after InitFrame(). Events come from Document and Game sInt ExecuteAnim(KOp *,sU8 *bytecode); // calculate animation void Pop(sInt count); // always call this with the result of Calc to rollback changed variables void *GetInstImpl(KOp *me,sInt size); // get next instance-mem (implementation) template t *GetInst(KOp *me); // get next instance-mem (or alloc new) void SetMatrix(sMatrix &mat,sMatrix &save); // set matrix in variable, void RestoreMatrix(sMatrix &save); // clean it up; // internal state sMemStack Mem; // memory for all kinds of structures sVector Stack[KK_MAXVARSAVE]; // save modified variables here for rollback sU8 StackAdr[KK_MAXVARSAVE]; // save it here. sInt Index; // for stack sArray DynamicEvents; // use AddDynamicEvent() to add here sArray EventOpsCleanup; // reset event-chain in these ops // current event environment sVector Var[KK_MAXVAR]; // current set of variables KSpline *EventSpline; // spline attached to current event (or 0) struct KKriegerMonster *EventMonster;// monster from event KEvent *CurrentEvent; // instance memory KInstanceMem *NextInstance; // if there is instance storage, this is the next chunk KInstanceMem **LinkInstance; // if there isn't, allocate new and store here KInstanceMem *DefaultInstance; // instance-list for "no event" state sInt ClearInstanceMem; // clear instance-mem for all static events added. this is set by InitView // set by caller KSpline **Splines; // link to splines sInt SplineCount; struct KKriegerGame *Game; // link to game #if sLINK_KKRIEGER sInt NextMonsterOverride; // use the following values to override next monster created sInt NextMonsterKillSwitch; sInt NextMonsterSpawnSwitch; sInt NextMonsterFlags; #endif sMaterialEnv GameCam; // camera from game or user-interface. sMaterialEnv CurrentCam; // camera from viewport op. #if !sPLAYER sVector CameraDataRot; // for cam -> freecamera 'Z' option sVector CameraDataPos; sF32 CameraDataZoom; #endif sF32 Aspect; sInt BeatTime; // current time in 16:16 beats sInt CurrentTime; // current time in ms sInt LastTime; // last frames time sInt TimeDelta; // current-last sInt TimeSlices; // timeslices since last frame (10ms) sInt TimeJitter; // fraction of time since last frame sInt TimeReset; // noticed backwards movement in time sMatrix Markers[32]; // use Scene_Marker to set. useful hack for Effect_ChainLine struct BlobCameraInfo { sMatrix Matrix; sF32 ZoomX; sF32 ZoomY; } Camera; // fonts KLetterMetric Letters[8][256]; // set by TEXT, used by PRINT sMatrixStack ExecStack; // Matrix stack for scene transforms #if !PLAYER sU8 *DebugOpByte; // bytecode address of op for debugging sVector DebugOpOutput; // store output of specifired bytecode op here sInt CalcAbort; #endif }; /****************************************************************************/ struct KClass // Operator class { sU32 Convention; // calling convention +flag 0x10000000 (varinputs) sChar *Packing; // packing string void *InitHandler; // initialize operator void *ExecHandler; // execute operator }; // =16 bytes struct KHandler // Operator handler { sInt Id; // operator id void *InitHandler; // initialize operator void *ExecHandler; // execute operator }; extern KHandler KHandlers[]; /****************************************************************************/ struct KOp // Operator { friend class KEnvironment; sInt Command; // class of operator sInt Result; // class of result KObject *Cache; // result pointers, depending on class #if sPLAYER sBool CacheFreed; // cache is freed #endif sInt Changed; // cache is dirty sInt DataInvalid; // this operator has been animated, please copy DataCopy to Data sInt CacheCount; // on creation set to output-count, then reduced with each link sInt WheelSpeed; // used only for spinning wheels in the gui... KEvent *FirstEvent; // list of active events for this operator void *InitHandler; // the actual code void *ExecHandler; // the actual code sInt CalcError; // could not calculate cache sU32 Convention; // calling conventions for code sU32 ChangeMask; // which inputs don't update the "change" bit? sInt OpId; // operator id (used to locate blobs+shaders) sInt SkipExec; // dont' call exec phase when (a) all ops are not animated and (b) all ops don't need exec sInt SkipCalc; // if the op is not changed, you may stop recursion here... sInt Tag; // for counting #if !sPLAYER sInt Highlight; // this operator is above the edit operator in the op-tree sInt CycleFlag; // for cyclic check sInt CycleChangeFlag; // for cyclic check sInt CacheSize; // for memory management sBool Blocked; // for memory management #endif sBool AnimFlag; // op is (somehow) animated sInt VarStart; // animated variable range of this op sInt VarCount; // (generated during Init_, used during Exec_) KInstanceMem *SceneMemLink; // linked list of instance memory used for scenejobs private: sInt InputMax; // allocated per configuration sInt LinkMax; sInt OutputMax; sInt DataMax; sInt StringMax; // number of strings, size of strings not included sInt SplineMax; // number of splines sInt AnimMax; // size of command-string, 4-byte aligned sInt InputCount; // inputs used sInt OutputCount; // outputs used sU32 *Memory; // a block of memory, for everything to do KOp **Input; // inputs KOp **Link; // links KOp **Output; // outputs (not set in player!) sChar **String; // dynamic strings KSpline **Spline; // array of spline-pointers sU8 *AnimCode; // animation code sU32 *DataEdit; // dynamic parameter array sU32 *DataAnim; // dynamic parameter array sInt BlobSize; // binary large object. Set OPC_BLOB to use! const sU8 *BlobData; // in Player, this points directly into export data. in Werkkzeug, this gets deleted[] on Exit(). public: // interface sInt Calc(KEnvironment *,sInt flags); // recursivly calculate, returns sTRUE when changed KObject *Call(KEnvironment *); // InitHandler Recursion just call this op void ExecWithNewMem(KEnvironment *,KInstanceMem **link); void ExecEvent(KEnvironment *,KEvent *,sBool newmem);// ExecHandler Recursion, set and reset variables for event void Exec(KEnvironment *); // (*ExecHandler)(op,kenv,...) void ExecInputs(KEnvironment *);// ExecHandler Recursion void ExecInput(KEnvironment *,sInt i);// ExecHandler Recursion void Change(sInt input=-1); // do all stuff needed to update change status sBool CheckOutput(sInt kc); // check that this op outputs a valid object of the specified type. this also checks the THIS pointer for 0, so you may call it on zero pointers void UpdateVar(sInt start,sInt count); sBool IsWrittenTo(sInt offset); // checks if offset is written to in bytecode /* sU32 GetU(sInt i) {return DataU[i];} // getter for ops sS32 GetS(sInt i) {return DataS[i];} sF32 GetF(sInt i) {return DataF[i];} */ KOp *GetInput(sInt i) {return iCache:0):0;} KOp *GetOutput(sInt i) {return Output[i];} sChar *GetString(sInt i) {return String[i];} KSpline *GetSpline(sInt i) {return i Ops; sArray Events; sArray Splines; KOp *RootOps[MAX_OP_ROOT]; sInt CurrentRoot; void Reset(); void Precalc(KEnvironment *kenv); void AddEvents(KEnvironment *kenv); sInt CountOps(KOp *start); }; /****************************************************************************/ #if !sPLAYER struct KObjectList // object list for KMemoryManager { sInt Size; // memory size currently spent in that class sInt Budget; // memory budget available sArray Ops; // op pointers (LRU order) }; class KMemoryManager_ { KObjectList Objects[KC_COUNT]; // one for each class public: KMemoryManager_(); ~KMemoryManager_(); sInt GetBudget(sInt type); void SetBudget(sInt type,sInt size); // set budget for that object type sInt GetSize(sInt type); // size currently spent for that type sInt GetCount(sInt type); // # of cached ops in that type void Use(KOp *op); // mark op as used void Remove(KOp *op); // remove op from list (and from memory) void Manage(); // make room if necessary void Validate(); // consistency check }; extern KMemoryManager_ *KMemoryManager; void MemManagerInit(); void MemManagerExit(); #endif /****************************************************************************/ /****************************************************************************/ class GenScene; KObject * __stdcall Init_Misc_Nop(KOp *op); KObject * __stdcall Init_Misc_If(KOp *op); KObject * __stdcall Init_Misc_Load(KObject *o); KObject * __stdcall Init_Misc_Event(KObject *o,sF32 duration); KObject * __stdcall Init_Misc_EventTime(KObject *o); KObject * __stdcall Init_Misc_Trigger(KObject *o,KOp *event, sF32 trigger,sF32 tresh,sF32 delay,sF32 duration,sInt flags, sF32 mod,sF32 vel,sInt sel,sF323 s,sF323 r,sF323 t,sU32 col,KSpline *spline); GenScene * __stdcall Init_Misc_PlaySample(GenScene *scene,sInt sw,sInt val,sF32 tresh,sInt sample,sF32 volume,sF32 retrigger,sF32 halfrange); KObject * __stdcall Init_Misc_Demo(KOp *op); KObject * __stdcall Init_Misc_MasterCam(sF323 rot,sF323 pos,sF32 farclip,sF32 nearclip,sF32 centerx,sF32 centery,sF32 zoomx,sF32 zoomy); void __stdcall Exec_Misc_Nop(KOp *op,KEnvironment *kenv); void __stdcall Exec_Misc_Load(KOp *op,KEnvironment *kenv); void __stdcall Exec_Misc_Time(KOp *op,KEnvironment *kenv); void __stdcall Exec_Misc_Event(KOp *op,KEnvironment *kenv,sF32 duration); void __stdcall Exec_Misc_EventTime(KOp *op,KEnvironment *kenv); void __stdcall Exec_Misc_Trigger(KOp *op,KEnvironment *kenv, sF32 trigger,sF32 tresh,sF32 delay,sF32 duration,sInt flags, sF32 mod,sF32 vel,sInt sel,sF323 s,sF323 r,sF323 t,sU32 col,KSpline *spline); void __stdcall Exec_Misc_Delay(KOp *op,KEnvironment *kenv,sInt flags,sInt sw,sF32 tresh,sF32 hyst,sF32 time0,sF32 time1,sF32 time2); void __stdcall Exec_Misc_State(KOp *op,KEnvironment *kenv,sInt sw,sInt val,sInt cond,sInt condsw,sInt condval); void __stdcall Exec_Misc_SetIf(KOp *op,KEnvironment *kenv,sInt sw,sInt val,sInt var,sInt osw); void __stdcall Exec_Misc_Menu(KOp *op,KEnvironment *kenv,sInt sw,sInt max,sInt flags); void __stdcall Exec_Misc_If(KOp *op,KEnvironment *kenv,sInt sw,sInt val); void __stdcall Exec_Misc_PlaySample(KOp *op,KEnvironment *kenv,sInt sw,sInt val,sF32 tresh,sInt sample,sF32 volume,sF32 retrigger,sF32 halfrange); void __stdcall Exec_Misc_Demo(KOp *op,KEnvironment *kenv); void __stdcall Exec_Misc_Menu(KOp *op,KEnvironment *kenv,sInt sw,sInt max,sInt flags); void __stdcall Exec_Misc_MasterCam(KOp *op,KEnvironment *kenv,sF323 rot,sF323 pos,sF32 farclip,sF32 nearclip,sF32 centerx,sF32 centery,sF32 zoomx,sF32 zoomy); class GenDemo : public KObject { public: GenDemo(); ~GenDemo(); }; /****************************************************************************/ /****************************************************************************/ template __forceinline t * KEnvironment::GetInst(KOp *me) { return (t *)GetInstImpl(me,sizeof(t)); } /****************************************************************************/ /****************************************************************************/ #endif