1 /*
2 ===========================================================================
3 Copyright (C) 2000 - 2013, Raven Software, Inc.
4 Copyright (C) 2001 - 2013, Activision, Inc.
5 Copyright (C) 2013 - 2015, OpenJK contributors
6 
7 This file is part of the OpenJK source code.
8 
9 OpenJK is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License version 2 as
11 published by the Free Software Foundation.
12 
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, see <http://www.gnu.org/licenses/>.
20 ===========================================================================
21 */
22 
23 #pragma once
24 
25 #include "qcommon/q_shared.h"	//needs to be in here for entityState_t
26 #include "server/server.h"
27 
28 #include <vector>
29 #include <map>
30 
31 // ROFF Defines
32 //-------------------
33 #define ROFF_VERSION				1
34 #define ROFF_NEW_VERSION			2
35 #define ROFF_STRING					"ROFF"
36 #define ROFF_SAMPLE_RATE			10	// 10hz
37 #define ROFF_AUTO_FIX_BAD_ANGLES	// exporter can mess up angles,
38 									//	defining this attempts to detect and fix these problems
39 
40 
41 // The CROFFSystem object provides all of the functionality of ROFF
42 //	caching, playback, and clean-up, plus some useful debug features.
43 //--------------------------------------
44 class CROFFSystem
45 //--------------------------------------
46 {
47 private:
48 //------
49 
50 	// forward declarations
51 	class			CROFF;
52 	struct			SROFFEntity;
53 
54 	typedef	std::map	<int, CROFF *> TROFFList;
55 	typedef std::vector	<SROFFEntity *> TROFFEntList;
56 
57 	TROFFList		mROFFList;				// List of cached roffs
58 	int				mID;					// unique ID generator for new roff objects
59 
60 	TROFFEntList	mROFFEntList;			// List of roffing entities
61 
62 	// ROFF Header file definition, nothing else needs to see this
63 	typedef struct tROFFHeader
64 	//-------------------------------
65 	{
66 		char	mHeader[4];				// should match roff_string defined above
67 		long	mVersion;				// version num, supported version defined above
68 		float	mCount;					// I think this is a float because of a limitation of the roff exporter
69 
70 	} TROFFHeader;
71 
72 	// ROFF Entry, nothing else needs to see this
73 	typedef struct tROFFEntry
74 	//-------------------------------
75 	{
76 		float		mOriginOffset[3];
77 		float		mRotateOffset[3];
78 	} TROFFEntry;
79 
80 	typedef struct tROFF2Header
81 	//-------------------------------
82 	{
83 		char	mHeader[4];				// should match roff_string defined above
84 		long	mVersion;				// version num, supported version defined above
85 		int		mCount;					// I think this is a float because of a limitation of the roff exporter
86 		int		mFrameRate;				// Frame rate the roff should be played at
87 		int		mNumNotes;				// number of notes (null terminated strings) after the roff data
88 
89 	} TROFF2Header;
90 
91 	// ROFF Entry, nothing else needs to see this
92 	typedef struct tROFF2Entry
93 	//-------------------------------
94 	{
95 		float		mOriginOffset[3];
96 		float		mRotateOffset[3];
97 		int			mStartNote, mNumNotes;		// note track info
98 	} TROFF2Entry;
99 
100 	// An individual ROFF object,
101 	//	contains actual rotation/offset information
102 	//--------------------------------------
103 	class CROFF
104 	//--------------------------------------
105 	{
106 	public:
107 	//------
108 
109 		int			mID;						// id for this roff file
110 		char		mROFFFilePath[MAX_QPATH];	// roff file path
111 		int			mROFFEntries;				// count of move/rotate commands
112 		int			mFrameTime;					// frame rate
113 		int			mLerp;						// Lerp rate (FPS)
114 		TROFF2Entry	*mMoveRotateList;			// move rotate/command list
115 		int			mNumNoteTracks;
116 		char		**mNoteTrackIndexes;
117 		qboolean	mUsedByClient;
118 		qboolean	mUsedByServer;
119 
CROFF()120 		CROFF()
121 		{
122 			mUsedByClient = mUsedByServer = qfalse;
123 		}
124 		CROFF( const char *file, int id );
125 		~CROFF();
126 
127 	}; // class CROFF
128 
129 
130 	// The roff system tracks entities that are
131 	//	roffing, so this is the internal structure
132 	//	that represents these objects.
133 	//--------------------------------------
134 	struct SROFFEntity
135 	//--------------------------------------
136 	{
137 		int			mEntID;			// the entity that is currently roffing
138 
139 		int			mROFFID;		// the roff to be applied to that entity
140 		int			mNextROFFTime;	// next time we should roff
141 		int			mROFFFrame;		// current roff frame we are applying
142 
143 		qboolean		mKill;			// flag to kill a roffing ent
144 		qboolean		mSignal;		// TODO:  Need to implement some sort of signal to Icarus when roff is done.
145 		qboolean	mTranslated;	// should this roff be "rotated" to fit the entity's initial position?
146 		qboolean	mIsClient;
147 		vec3_t		mStartAngles;	// initial angle of the entity
148 	}; // struct SROFFEntity
149 
150 
151 	qboolean	IsROFF( byte *file );				// Makes sure the file is a valid roff file
152 	qboolean	InitROFF( byte *file, CROFF *obj );	// Handles stashing raw roff data into the roff object
153 	qboolean	InitROFF2( byte *file, CROFF *obj );	// Handles stashing raw roff data into the roff object
154 	void	FixBadAngles(CROFF *obj);
NewID()155 	int		NewID() { return ++mID; }			// Increment before return so we can use zero as failed return val
156 	qboolean	ApplyROFF( SROFFEntity *roff_ent,
157 					CROFFSystem::CROFF *roff );	// True = success; False = roff complete
158 
159 	void	ProcessNote(SROFFEntity *roff_ent, char *note);
160 
161 	void	SetLerp( trajectory_t *tr,
162 					trType_t, vec3_t origin,
163 					vec3_t delta, int time, int rate );
164 
165 	qboolean	ClearLerp( SROFFEntity *roff_ent );				// Clears out the angular and position lerp fields
166 
167 public:
168 //------
169 
CROFFSystem()170 	CROFFSystem()	{	mID = 0; mROFFEntList.clear();	}
~CROFFSystem()171 	~CROFFSystem()	{	Restart();	}
172 
173 
174 	qboolean		Restart();						// Free up all system resources and reset the ID counter
175 
176 	int			Cache( const char *file, qboolean isClient );			// roffs should be precached at the start of each level
177 	int			GetID( const char *file );			// find the roff id by filename
178 	qboolean		Unload( int id );				// when a roff is done, it can be removed to free up resources
179 	qboolean	Clean(qboolean isClient);					// should be called when level is done, frees all roff resources
180 	void		List(void);						// dumps a list of all cached roff files to the console
181 	qboolean		List( int id );					// dumps the contents of the specified roff to the console
182 
183 	qboolean	Play( int entID, int roffID, qboolean doTranslation, qboolean isClient);	// TODO: implement signal on playback completion.
184 	void		ListEnts();						// List the entities that are currently roffing
185 	qboolean	PurgeEnt( int entID, qboolean isClient );			// Purge the specified entity from the entity list by id
186 	qboolean		PurgeEnt( char *file );			// Purge the specified entity from the entity list by name
187 	void		UpdateEntities(qboolean isClient);			// applys roff data to roffing entities.
188 
189 }; // class CROFFSystem
190 
191 
192 extern CROFFSystem theROFFSystem;
193