#pragma once #if !defined(CROFFSYSTEM_H_INC) #define CROFFSYSTEM_H_INC #ifndef __Q_SHARED_H #include "../game/q_shared.h" //needs to be in here for entityState_t #endif #if !defined(SERVER_H_INC) #include "../server/server.h" #endif #pragma warning (push, 3) //go back down to 3 for the stl include #include #include #pragma warning (pop) using namespace std; // ROFF Defines //------------------- #define ROFF_VERSION 1 #define ROFF_NEW_VERSION 2 #define ROFF_STRING "ROFF" #define ROFF_SAMPLE_RATE 10 // 10hz #define ROFF_AUTO_FIX_BAD_ANGLES // exporter can mess up angles, // defining this attempts to detect and fix these problems // The CROFFSystem object provides all of the functionality of ROFF // caching, playback, and clean-up, plus some useful debug features. //-------------------------------------- class CROFFSystem //-------------------------------------- { private: //------ // forward declarations class CROFF; struct SROFFEntity; typedef map TROFFList; typedef vector TROFFEntList; TROFFList mROFFList; // List of cached roffs int mID; // unique ID generator for new roff objects TROFFEntList mROFFEntList; // List of roffing entities // ROFF Header file definition, nothing else needs to see this typedef struct tROFFHeader //------------------------------- { char mHeader[4]; // should match roff_string defined above long mVersion; // version num, supported version defined above float mCount; // I think this is a float because of a limitation of the roff exporter } TROFFHeader; // ROFF Entry, nothing else needs to see this typedef struct tROFFEntry //------------------------------- { float mOriginOffset[3]; float mRotateOffset[3]; } TROFFEntry; typedef struct tROFF2Header //------------------------------- { char mHeader[4]; // should match roff_string defined above long mVersion; // version num, supported version defined above int mCount; // I think this is a float because of a limitation of the roff exporter int mFrameRate; // Frame rate the roff should be played at int mNumNotes; // number of notes (null terminated strings) after the roff data } TROFF2Header; // ROFF Entry, nothing else needs to see this typedef struct tROFF2Entry //------------------------------- { float mOriginOffset[3]; float mRotateOffset[3]; int mStartNote, mNumNotes; // note track info } TROFF2Entry; // An individual ROFF object, // contains actual rotation/offset information //-------------------------------------- class CROFF //-------------------------------------- { public: //------ int mID; // id for this roff file char mROFFFilePath[MAX_QPATH]; // roff file path int mROFFEntries; // count of move/rotate commands int mFrameTime; // frame rate int mLerp; // Lerp rate (FPS) TROFF2Entry *mMoveRotateList; // move rotate/command list int mNumNoteTracks; char **mNoteTrackIndexes; qboolean mUsedByClient; qboolean mUsedByServer; CROFF() { mUsedByClient = mUsedByServer = qfalse; } CROFF( char *file, int id ); ~CROFF(); }; // class CROFF // The roff system tracks entities that are // roffing, so this is the internal structure // that represents these objects. //-------------------------------------- struct SROFFEntity //-------------------------------------- { int mEntID; // the entity that is currently roffing int mROFFID; // the roff to be applied to that entity int mNextROFFTime; // next time we should roff int mROFFFrame; // current roff frame we are applying qboolean mKill; // flag to kill a roffing ent qboolean mSignal; // TODO: Need to implement some sort of signal to Icarus when roff is done. qboolean mTranslated; // should this roff be "rotated" to fit the entity's initial position? qboolean mIsClient; vec3_t mStartAngles; // initial angle of the entity }; // struct SROFFEntity qboolean IsROFF( byte *file ); // Makes sure the file is a valid roff file qboolean InitROFF( byte *file, CROFF *obj ); // Handles stashing raw roff data into the roff object qboolean InitROFF2( byte *file, CROFF *obj ); // Handles stashing raw roff data into the roff object void FixBadAngles(CROFF *obj); int NewID() { return ++mID; } // Increment before return so we can use zero as failed return val qboolean ApplyROFF( SROFFEntity *roff_ent, CROFFSystem::CROFF *roff ); // True = success; False = roff complete void ProcessNote(SROFFEntity *roff_ent, char *note); void SetLerp( trajectory_t *tr, trType_t, vec3_t origin, vec3_t delta, int time, int rate ); qboolean ClearLerp( SROFFEntity *roff_ent ); // Clears out the angular and position lerp fields public: //------ CROFFSystem() { mID = 0; } ~CROFFSystem() { Restart(); } qboolean Restart(); // Free up all system resources and reset the ID counter int Cache( char *file, qboolean isClient ); // roffs should be precached at the start of each level int GetID( char *file ); // find the roff id by filename qboolean Unload( int id ); // when a roff is done, it can be removed to free up resources qboolean Clean(qboolean isClient); // should be called when level is done, frees all roff resources void List(void); // dumps a list of all cached roff files to the console qboolean List( int id ); // dumps the contents of the specified roff to the console qboolean Play( int entID, int roffID, qboolean doTranslation, qboolean isClient); // TODO: implement signal on playback completion. void ListEnts(); // List the entities that are currently roffing qboolean PurgeEnt( int entID, qboolean isClient ); // Purge the specified entity from the entity list by id qboolean PurgeEnt( char *file ); // Purge the specified entity from the entity list by name void UpdateEntities(qboolean isClient); // applys roff data to roffing entities. }; // class CROFFSystem extern CROFFSystem theROFFSystem; #endif // CROFFSYSTEM_H_INC