1 /*
2 	Relay -- a tool to record and play Quake2 demos
3 	Copyright (C) 2000 Conor Davis
4 
5 	This program is free software; you can redistribute it and/or
6 	modify it under the terms of the GNU General Public License
7 	as published by the Free Software Foundation; either version 2
8 	of the License, or (at your option) any later version.
9 
10 	This program is distributed in the hope that it will be useful,
11 	but WITHOUT ANY WARRANTY; without even the implied warranty of
12 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 	GNU General Public License for more details.
14 
15 	You should have received a copy of the GNU General Public License
16 	along with this program; if not, write to the Free Software
17 	Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18 
19 	Conor Davis
20 	cedavis@planetquake.com
21 */
22 
23 #ifndef __DM2_H
24 #define __DM2_H
25 
26 #include <stdio.h>
27 
28 #include "block.h"
29 #include "bsp.h"	// for MAX_MAP_AREAS
30 #include "pak.h"
31 #include "q2defines.h"
32 #include "shared.h"
33 
34 #define RECORD_NETWORK	0
35 #define RECORD_CLIENT	1
36 #define RECORD_SERVER	2
37 // these are readable only by q2relay
38 #define RECORD_RELAY	0x80
39 
40 // number of previous states to store for delta referencing
41 #define UPDATE_BACKUP	16
42 #define UPDATE_MASK 	(UPDATE_BACKUP-1)
43 
44 #define BASELINES_FRAME 0xffffffff
45 
46 // server-to-client commands
47 #define SVC_BAD 				0x00
48 #define SVC_MUZZLEFLASH 		0x01
49 #define SVC_MUZZLEFLASH2		0x02
50 #define SVC_TEMP_ENTITY 		0x03
51 #define SVC_LAYOUT				0x04
52 #define SVC_INVENTORY			0x05
53 #define SVC_NOP 				0x06
54 #define SVC_DISCONNECT			0x07
55 #define SVC_RECONNECT			0x08
56 #define SVC_SOUND				0x09
57 #define SVC_PRINT				0x0a
58 #define SVC_STUFFTEXT			0x0b
59 #define SVC_SERVERDATA			0x0c
60 #define SVC_CONFIGSTRING		0x0d
61 #define SVC_SPAWNBASELINE		0x0e
62 #define SVC_CENTERPRINT 		0x0f
63 #define SVC_DOWNLOAD			0x10
64 #define SVC_PLAYERINFO			0x11
65 #define SVC_PACKETENTITIES		0x12
66 #define SVC_DELTAPACKETENTITIES 0x13
67 #define SVC_FRAME				0x14
68 
69 // by default, messages are multicast
70 // if the id byte contains this bit, the message
71 // is unicast
72 #define MSG_UNICAST 			0x80
73 
74 // most of these bits are from a serverrecord sample sent to Tom Vykruta
75 // http://www.stomped.com/demented2/dm2specs.htm
76 
77 // client-to-server commands
78 #define CLC_BAD 			0x00
79 #define CLC_NOP 			0x01
80 #define CLC_MOVE			0x02
81 #define CLC_USERINFO		0x03
82 #define CLC_STRINGCMD		0x04
83 
84 
85 // player_state_t mask bits
86 #define PS_M_TYPE			(1<<0)
87 #define PS_M_ORIGIN 		(1<<1)
88 #define PS_M_VELOCITY		(1<<2)
89 #define PS_M_TIME			(1<<3)
90 #define PS_M_FLAGS			(1<<4)
91 #define PS_M_GRAVITY		(1<<5)
92 #define PS_M_DELTA_ANGLES	(1<<6)
93 #define PS_VIEWOFFSET		(1<<7)
94 #define PS_VIEWANGLES		(1<<8)
95 #define PS_KICKANGLES		(1<<9)
96 #define PS_BLEND			(1<<10)
97 #define PS_FOV				(1<<11)
98 #define PS_WEAPONINDEX		(1<<12)
99 #define PS_WEAPONFRAME		(1<<13)
100 #define PS_RDFLAGS			(1<<14)
101 
102 // usercmd_t mask bits
103 // ms and light are allways sent, the others are optional
104 #define CM_ANGLE1	(1<<0)
105 #define CM_ANGLE2	(1<<1)
106 #define CM_ANGLE3	(1<<2)
107 #define CM_FORWARD	(1<<3)
108 #define CM_SIDE 	(1<<4)
109 #define CM_UP		(1<<5)
110 #define CM_BUTTONS	(1<<6)
111 #define CM_IMPULSE	(1<<7)
112 
113 // sound mask bits
114 // a sound without an ent or pos will be a local only sound
115 #define SND_VOLUME		(1<<0)		// a byte
116 #define SND_ATTENUATION (1<<1)		// a byte
117 #define SND_POS 		(1<<2)		// three coordinates
118 #define SND_ENT 		(1<<3)		// a short 0-2: channel, 3-12: entity
119 #define SND_OFFSET		(1<<4)		// a byte, msec offset from frame start
120 // sound defaults
121 #define DEFAULT_SOUND_PACKET_VOLUME 1.0F
122 #define DEFAULT_SOUND_PACKET_ATTENUATION 1.0F
123 
124 // entity_state_t mask bits
125 // try to pack the common update flags into the first byte
126 #define U_ORIGIN1	(1<<0)
127 #define U_ORIGIN2	(1<<1)
128 #define U_ANGLE2	(1<<2)
129 #define U_ANGLE3	(1<<3)
130 #define U_FRAME8	(1<<4)		// frame is a byte
131 #define U_EVENT 	(1<<5)
132 #define U_REMOVE	(1<<6)		// REMOVE this entity, don't add it
133 #define U_MOREBITS1 (1<<7)		// read one additional byte
134 
135 // second byte
136 #define U_NUMBER16	(1<<8)		// NUMBER8 is implicit if not set
137 #define U_ORIGIN3	(1<<9)
138 #define U_ANGLE1	(1<<10)
139 #define U_MODEL 	(1<<11)
140 #define U_RENDERFX8 (1<<12) 	// fullbright, etc
141 #define U_EFFECTS8	(1<<14) 	// autorotate, trails, etc
142 #define U_MOREBITS2 (1<<15) 	// read one additional byte
143 
144 // third byte
145 #define U_SKIN8 	(1<<16)
146 #define U_FRAME16	(1<<17) 	// frame is a short
147 #define U_RENDERFX16 (1<<18)	// 8 + 16 = 32
148 #define U_EFFECTS16 (1<<19) 	// 8 + 16 = 32
149 #define U_MODEL2	(1<<20) 	// weapons, flags, etc
150 #define U_MODEL3	(1<<21)
151 #define U_MODEL4	(1<<22)
152 #define U_MOREBITS3 (1<<23) 	// read one additional byte
153 
154 // fourth byte
155 #define U_OLDORIGIN (1<<24) 	// FIXME: get rid of this
156 #define U_SKIN16	(1<<25)
157 #define U_SOUND 	(1<<26)
158 #define U_SOLID 	(1<<27)
159 
160 // dm2 message types
161 typedef struct
162 {
163 	short	entity;
164 	byte	value;
165 } muzzleflash_t;
166 
167 typedef struct
168 {
169 	byte	type;
170 	vec3_t	origin;
171 	vec3_t	movedir;
172 	vec3_t	endpos;
173 	vec3_t	pos1;
174 	vec3_t	pos2;
175 	vec3_t	pos3;
176 	vec3_t	pos4;
177 	short	entity;
178 	short	dest_entity;
179 	short	count;
180 	short	style;
181 	short	plat2flags;
182 	short	nextid;
183 	long	wait;
184 } temp_entity_t;
185 
186 typedef struct
187 {
188 	byte		soundnum;
189 	float		volume;
190 	float		attenuation;
191 	float		timeofs;
192 	short		entity;
193 	byte		channel;
194 	vec3_t		origin;
195 	qboolean	positioned;
196 } sound_t;
197 
198 typedef struct
199 {
200 	byte		level;
201 	char		string[MAX_MSGLEN];
202 } print_t;
203 
204 typedef struct
205 {
206 	long	version;
207 	short	relayversion;
208 	long	key;
209 	byte	isdemo;
210 	char	game[MAX_QPATH];
211 	short	player;
212 	char	mapname[MAX_QPATH];
213 } serverdata_t;
214 
215 typedef struct
216 {
217 	short	index;
218 	char	string[MAX_MSGLEN];
219 } configstring_t;
220 
221 typedef struct
222 {
223 	size_t	seq1;
224 	size_t	seq2;
225 	byte	area_count;
226 	char	areas[MAX_MAP_AREAS/8];
227 	byte	connected_count;
228 	char	connected[MAX_CLIENTS/8];
229 } frame_t;
230 
231 // new, q2relay-specific message types
232 typedef struct
233 {
234 	int 	maxclients;
235 } relayinfo_t;
236 
237 typedef struct
238 {
239 	long			frame;
240 	block_t 		block;
241 	char			block_buffer[MAX_MSGLEN];
242 } delta_t;
243 
244 typedef struct
245 {
246 	size_t			frame;
247 	entity_state_t	entities[MAX_EDICTS];
248 	byte			active[MAX_EDICTS/8];
249 	byte			areas[MAX_MAP_AREAPORTALS/8];	// visible areas in client demos, open areaportals in relay demos
250 	// relay-specific data
251 	byte		connected[MAX_CLIENTS/8];
252 } state_t;
253 
254 typedef struct
255 {
256 	char			layout[MAX_MSGLEN];
257 	short			inventory[MAX_ITEMS];
258 	player_state_t	ps[UPDATE_BACKUP];
259 } player_t;
260 
261 typedef struct
262 {
263 	serverdata_t	svd;
264 	char			configstrings[MAX_CONFIGSTRINGS][64];
265 	state_t 		baselines;
266 	state_t 		states[UPDATE_BACKUP];
267 	player_t		*players;	// client demos will have one player, relay will have maxclients
268 	int 			maxclients; // determines size of players array. must be 1 for client demos!
269 	size_t			current_frame;
270 	size_t			delta_frame;
271 } dm2_t;
272 
273 extern void DM2_Init(dm2_t *dm2);
274 extern void DM2_FillConfigstrings(char (*configstrings)[64]);
275 extern int DM2_ReadBlock(block_t *block, PFILE *fd);
276 extern int DM2_WriteBlock(block_t *block, PFILE *fd);
277 
278 extern int DM2_ReadGenericString(block_t *block, char *p, size_t len);
279 extern int DM2_WriteGenericString(block_t *block, const char *p);
280 #define DM2_ReadLayout(a,b,c)		DM2_ReadGenericString(a,b,c)
281 #define DM2_WriteLayout(a,b)		DM2_WriteGenericString(a,b)
282 #define DM2_ReadStufftext(a,b,c)	DM2_ReadGenericString(a,b,c)
283 #define DM2_WriteStufftext(a,b) 	DM2_WriteGenericString(a,b)
284 #define DM2_ReadCenterprint(a,b,c)	DM2_ReadGenericString(a,b,c)
285 #define DM2_WriteCenterprint(a,b)	DM2_WriteGenericString(a,b)
286 
287 extern int DM2_ReadMuzzleflash(block_t *block, int *entity, int *value);
288 extern int DM2_WriteMuzzleflash(block_t *block, int entity, int value);
289 extern int DM2_ReadTempEntity(block_t *block, const dm2_t *dm2, temp_entity_t *p);
290 extern int DM2_WriteTempEntity(block_t *block, const dm2_t *dm2, const temp_entity_t *p);
291 extern int DM2_ReadInventory(block_t *block, short p[MAX_ITEMS]);
292 extern int DM2_WriteInventory(block_t *block, const short p[MAX_ITEMS]);
293 extern int DM2_ReadSound(block_t *block, int *soundindex, float *volume, float *attenuation, float *timeofs, int *entity, int *channel, vec3_t origin, qboolean *positioned);
294 extern int DM2_WriteSound(block_t *block, int soundindex, float volume, float attenuation, float timeofs, int entity, int channel, vec3_t origin, qboolean positioned);
295 extern int DM2_ReadPrint(block_t *block, int *level, char *string, size_t len);
296 extern int DM2_WritePrint(block_t *block, int level, const char *string);
297 extern int DM2_ReadServerdata(block_t *block, serverdata_t *p);
298 extern int DM2_WriteServerdata(block_t *block, const serverdata_t *p);
299 extern int DM2_ReadConfigstring(block_t *block, int *index, char *string);
300 extern int DM2_WriteConfigstring(block_t *block, int index, const char *string);
301 extern int DM2_ReadFrame(block_t *block, const serverdata_t *svd, int *seq1, int *seq2, int *area_count, byte *areas, int *connected_count, byte *connected);
302 extern int DM2_WriteFrame(block_t *block, const serverdata_t *svd, int seq1, int seq2, int area_count, const byte *areas, int connected_count, const byte *connected);
303 
304 extern int DM2_ReadPS(block_t *block, player_state_t *ps);
305 extern int DM2_WritePS(block_t *block, const player_state_t *to, const player_state_t *from);
306 extern int DM2_ReadEntityMask(block_t *block, int *mask);
307 extern qboolean DM2_ReadEntity(block_t *block, entity_state_t *es, int mask);
308 extern int DM2_ReadPacketEntity(block_t *block, state_t *state, const state_t *baselines);
309 extern int DM2_ReadBaselineEntity(block_t *block, state_t *baselines);
310 extern int DM2_WriteEntity(block_t *block, const entity_state_t *to, const entity_state_t *from, qboolean is_active, qboolean was_active);
311 extern int DM2_WritePacketEntities(block_t *block, const state_t *current, const state_t *delta, const state_t *baselines);
312 
313 extern int DM2_WriteConfigstrings(block_t *block, const char (*configstrings)[64], int start, size_t stopsize);
314 extern int DM2_WriteBaselines(block_t *block, const state_t *baselines, int start, size_t stopsize);
315 extern int DM2_ReadPreFrame(serverdata_t *svd, relayinfo_t *relayinfo, char (*configstrings)[64], state_t *baselines, PFILE *fd);
316 extern int DM2_WritePreFrame(const serverdata_t *svd, const relayinfo_t *relayinfo, const char (*configstrings)[64], const state_t *baselines, PFILE *fd);
317 
318 #endif	// __DM2_H
319 
320