2013-04-19 02:52:48 +00:00
|
|
|
#if defined (_MSC_VER) && (_MSC_VER >= 1020)
|
|
|
|
#pragma once
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#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 <vector>
|
|
|
|
#include <map>
|
|
|
|
#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 <int, CROFF *> TROFFList;
|
|
|
|
typedef vector <SROFFEntity *> 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( const 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; mROFFEntList.clear(); }
|
|
|
|
~CROFFSystem() { Restart(); }
|
|
|
|
|
|
|
|
|
|
|
|
qboolean Restart(); // Free up all system resources and reset the ID counter
|
|
|
|
|
|
|
|
int Cache( const char *file, qboolean isClient ); // roffs should be precached at the start of each level
|
|
|
|
int GetID( const 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
|