1 /*
2 ===========================================================================
3 Copyright (C) 1999 - 2005, Id Software, Inc.
4 Copyright (C) 2000 - 2013, Raven Software, Inc.
5 Copyright (C) 2001 - 2013, Activision, Inc.
6 Copyright (C) 2005 - 2015, ioquake3 contributors
7 Copyright (C) 2013 - 2015, OpenJK contributors
8 
9 This file is part of the OpenJK source code.
10 
11 OpenJK is free software; you can redistribute it and/or modify it
12 under the terms of the GNU General Public License version 2 as
13 published by the Free Software Foundation.
14 
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 GNU General Public License for more details.
19 
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, see <http://www.gnu.org/licenses/>.
22 ===========================================================================
23 */
24 
25 #pragma once
26 
27 // qcommon.h -- definitions common between client and server, but not game.or ref modules
28 
29 #include "qcommon/q_shared.h"
30 #include "sys/sys_public.h"
31 
32 //============================================================================
33 
34 //
35 // msg.c
36 //
37 typedef struct msg_s {
38 	qboolean	allowoverflow;	// if false, do a Com_Error
39 	qboolean	overflowed;		// set to true if the buffer size failed (with allowoverflow set)
40 	qboolean	oob;			// set to true if the buffer size failed (with allowoverflow set)
41 	byte	*data;
42 	int		maxsize;
43 	int		cursize;
44 	int		readcount;
45 	int		bit;				// for bitwise reads and writes
46 } msg_t;
47 
48 void MSG_Init (msg_t *buf, byte *data, int length);
49 void MSG_InitOOB( msg_t *buf, byte *data, int length );
50 void MSG_Clear (msg_t *buf);
51 void MSG_WriteData (msg_t *buf, const void *data, int length);
52 void MSG_Bitstream( msg_t *buf );
53 
54 struct usercmd_s;
55 struct entityState_s;
56 struct playerState_s;
57 
58 void MSG_WriteBits( msg_t *msg, int value, int bits );
59 
60 void MSG_WriteChar (msg_t *sb, int c);
61 void MSG_WriteByte (msg_t *sb, int c);
62 void MSG_WriteShort (msg_t *sb, int c);
63 void MSG_WriteLong (msg_t *sb, int c);
64 void MSG_WriteFloat (msg_t *sb, float f);
65 void MSG_WriteString (msg_t *sb, const char *s);
66 void MSG_WriteBigString (msg_t *sb, const char *s);
67 void MSG_WriteAngle16 (msg_t *sb, float f);
68 
69 void	MSG_BeginReading (msg_t *sb);
70 void	MSG_BeginReadingOOB(msg_t *sb);
71 
72 int		MSG_ReadBits( msg_t *msg, int bits );
73 
74 int		MSG_ReadChar (msg_t *sb);
75 int		MSG_ReadByte (msg_t *sb);
76 int		MSG_ReadShort (msg_t *sb);
77 int		MSG_ReadLong (msg_t *sb);
78 float	MSG_ReadFloat (msg_t *sb);
79 char	*MSG_ReadString (msg_t *sb);
80 char	*MSG_ReadBigString (msg_t *sb);
81 char	*MSG_ReadStringLine (msg_t *sb);
82 float	MSG_ReadAngle16 (msg_t *sb);
83 void	MSG_ReadData (msg_t *sb, void *buffer, int size);
84 
85 
86 void MSG_WriteDeltaUsercmdKey( msg_t *msg, int key, usercmd_t *from, usercmd_t *to );
87 void MSG_ReadDeltaUsercmdKey( msg_t *msg, int key, usercmd_t *from, usercmd_t *to );
88 
89 void MSG_WriteDeltaEntity( msg_t *msg, struct entityState_s *from, struct entityState_s *to
90 						   , qboolean force );
91 void MSG_ReadDeltaEntity( msg_t *msg, entityState_t *from, entityState_t *to,
92 						 int number );
93 
94 #ifdef _ONEBIT_COMBO
95 void MSG_WriteDeltaPlayerstate( msg_t *msg, struct playerState_s *from, struct playerState_s *to, int *bitComboDelta, int *bitNumDelta, qboolean isVehiclePS = qfalse );
96 #else
97 void MSG_WriteDeltaPlayerstate( msg_t *msg, struct playerState_s *from, struct playerState_s *to, qboolean isVehiclePS = qfalse );
98 #endif
99 void MSG_ReadDeltaPlayerstate( msg_t *msg, struct playerState_s *from, struct playerState_s *to, qboolean isVehiclePS = qfalse );
100 
101 #ifndef FINAL_BUILD
102 void MSG_ReportChangeVectors_f( void );
103 #endif
104 
105 //============================================================================
106 
107 /*
108 ==============================================================
109 
110 NET
111 
112 ==============================================================
113 */
114 
115 #define NET_ENABLEV4		0x01
116 
117 #define	PACKET_BACKUP	32	// number of old messages that must be kept on client and
118 							// server for delta comrpession and ping estimation
119 #define	PACKET_MASK		(PACKET_BACKUP-1)
120 
121 #define	MAX_PACKET_USERCMDS		32		// max number of usercmd_t in a packet
122 
123 #define	MAX_SNAPSHOT_ENTITIES	256
124 
125 #define	PORT_ANY			-1
126 
127 #define	MAX_RELIABLE_COMMANDS	128			// max string commands buffered for restransmit
128 
129 typedef enum {
130 	NS_CLIENT,
131 	NS_SERVER
132 } netsrc_t;
133 
134 void		NET_Init( void );
135 void		NET_Shutdown( void );
136 void		NET_Restart_f( void );
137 void		NET_Config( qboolean enableNetworking );
138 
139 void		NET_SendPacket (netsrc_t sock, int length, const void *data, netadr_t to);
140 void		NET_OutOfBandPrint( netsrc_t net_socket, netadr_t adr, const char *format, ...);
141 void		NET_OutOfBandData( netsrc_t sock, netadr_t adr, byte *format, int len );
142 
143 qboolean	NET_CompareAdr (netadr_t a, netadr_t b);
144 qboolean	NET_CompareBaseAdrMask( netadr_t a, netadr_t b, int netmask );
145 qboolean	NET_CompareBaseAdr (netadr_t a, netadr_t b);
146 qboolean	NET_IsLocalAddress (netadr_t adr);
147 const char	*NET_AdrToString (netadr_t a);
148 qboolean	NET_StringToAdr ( const char *s, netadr_t *a);
149 qboolean	NET_GetLoopPacket (netsrc_t sock, netadr_t *net_from, msg_t *net_message);
150 void		NET_Sleep(int msec);
151 
152 void		Sys_SendPacket( int length, const void *data, netadr_t to );
153 //Does NOT parse port numbers, only base addresses.
154 qboolean	Sys_StringToAdr( const char *s, netadr_t *a );
155 qboolean	Sys_IsLANAddress (netadr_t adr);
156 void		Sys_ShowIP(void);
157 
158 
159 #define	MAX_MSGLEN				49152		// max length of a message, which may
160 											// be fragmented into multiple packets
161 
162 //rww - 6/28/02 - Changed from 16384 to match sof2's. This does seem rather huge, but I guess it doesn't really hurt anything.
163 
164 #define MAX_DOWNLOAD_WINDOW			8		// max of eight download frames
165 #define MAX_DOWNLOAD_BLKSIZE		2048	// 2048 byte block chunks
166 
167 
168 /*
169 Netchan handles packet fragmentation and out of order / duplicate suppression
170 */
171 
172 typedef struct netchan_s {
173 	netsrc_t	sock;
174 
175 	int			dropped;			// between last packet and previous
176 
177 	netadr_t	remoteAddress;
178 	int			qport;				// qport value to write when transmitting
179 
180 	// sequencing variables
181 	int			incomingSequence;
182 	int			outgoingSequence;
183 
184 	// incoming fragment assembly buffer
185 	int			fragmentSequence;
186 	int			fragmentLength;
187 	byte		fragmentBuffer[MAX_MSGLEN];
188 
189 	// outgoing fragment buffer
190 	// we need to space out the sending of large fragmented messages
191 	qboolean	unsentFragments;
192 	int			unsentFragmentStart;
193 	int			unsentLength;
194 	byte		unsentBuffer[MAX_MSGLEN];
195 } netchan_t;
196 
197 void Netchan_Init( int qport );
198 void Netchan_Setup( netsrc_t sock, netchan_t *chan, netadr_t adr, int qport );
199 
200 void Netchan_Transmit( netchan_t *chan, int length, const byte *data );
201 void Netchan_TransmitNextFragment( netchan_t *chan );
202 
203 qboolean Netchan_Process( netchan_t *chan, msg_t *msg );
204 
205 
206 /*
207 ==============================================================
208 
209 PROTOCOL
210 
211 ==============================================================
212 */
213 
214 #define	PROTOCOL_VERSION	26
215 
216 #define	UPDATE_SERVER_NAME			"updatejk3.ravensoft.com"
217 #define MASTER_SERVER_NAME			"masterjk3.ravensoft.com"
218 
219 #define JKHUB_MASTER_SERVER_NAME	"master.jkhub.org"
220 #define JKHUB_UPDATE_SERVER_NAME	"update.jkhub.org"
221 
222 #define	PORT_MASTER			29060
223 #define	PORT_UPDATE			29061
224 #define	PORT_SERVER			29070	//...+9 more for multiple servers
225 #define	NUM_SERVER_PORTS	4		// broadcast scan this many ports after PORT_SERVER so a single machine can run multiple servers
226 
227 // the svc_strings[] array in cl_parse.c should mirror this
228 //
229 // server to client
230 //
231 enum svc_ops_e {
232 	svc_bad,
233 	svc_nop,
234 	svc_gamestate,
235 	svc_configstring,			// [short] [string] only in gamestate messages
236 	svc_baseline,				// only in gamestate messages
237 	svc_serverCommand,			// [string] to be executed by client game module
238 	svc_download,				// [short] size [size bytes]
239 	svc_snapshot,
240 	svc_setgame,
241 	svc_mapchange,
242 	svc_EOF
243 };
244 
245 
246 //
247 // client to server
248 //
249 enum clc_ops_e {
250 	clc_bad,
251 	clc_nop,
252 	clc_move,				// [[usercmd_t]
253 	clc_moveNoDelta,		// [[usercmd_t]
254 	clc_clientCommand,		// [string] message
255 	clc_EOF
256 };
257 
258 /*
259 ==============================================================
260 
261 VIRTUAL MACHINE
262 
263 ==============================================================
264 */
265 
266 typedef enum vmSlots_e {
267 	VM_GAME=0,
268 	VM_CGAME,
269 	VM_UI,
270 	MAX_VM
271 } vmSlots_t;
272 
273 typedef struct vm_s {
274 	vmSlots_t	slot; // VM_GAME, VM_CGAME, VM_UI
275     char		name[MAX_QPATH];
276 	void		*dllHandle;
277 	qboolean	isLegacy; // uses the legacy syscall/vm_call api, is set by VM_CreateLegacy
278 
279 	// fill the import/export tables
280 	void *		(*GetModuleAPI)( int apiVersion, ... );
281 
282 	// legacy stuff
283 	struct {
284 		VMMainProc* main; // module vmMain
285 		intptr_t	(QDECL *syscall)( intptr_t *parms );	// engine syscall handler
286 	} legacy;
287 } vm_t;
288 
289 extern vm_t *currentVM;
290 
291 class VMSwap {
292 private:
293 	VMSwap();
294 	vm_t *oldVM;
295 public:
VMSwap(vm_t * newVM)296 	VMSwap( vm_t *newVM ) : oldVM( currentVM ) { currentVM = newVM; };
~VMSwap()297 	~VMSwap() { if ( oldVM ) currentVM = oldVM; };
298 };
299 
300 extern const char *vmStrs[MAX_VM];
301 
302 typedef enum {
303 	TRAP_MEMSET = 100,
304 	TRAP_MEMCPY,
305 	TRAP_STRNCPY,
306 	TRAP_SIN,
307 	TRAP_COS,
308 	TRAP_ATAN2,
309 	TRAP_SQRT,
310 	TRAP_MATRIXMULTIPLY,
311 	TRAP_ANGLEVECTORS,
312 	TRAP_PERPENDICULARVECTOR,
313 	TRAP_FLOOR,
314 	TRAP_CEIL,
315 
316 	TRAP_TESTPRINTINT,
317 	TRAP_TESTPRINTFLOAT,
318 
319 	TRAP_ACOS,
320 	TRAP_ASIN
321 } sharedTraps_t;
322 
323 void			VM_Init( void );
324 vm_t			*VM_CreateLegacy( vmSlots_t vmSlot, intptr_t (*systemCalls)(intptr_t *) );
325 vm_t			*VM_Create( vmSlots_t vmSlot );
326 void			 VM_Free( vm_t *vm );
327 void			 VM_Clear(void);
328 vm_t			*VM_Restart( vm_t *vm );
329 intptr_t QDECL	 VM_Call( vm_t *vm, int callNum, intptr_t arg0 = 0, intptr_t arg1 = 0, intptr_t arg2 = 0, intptr_t arg3 = 0, intptr_t arg4 = 0, intptr_t arg5 = 0, intptr_t arg6 = 0, intptr_t arg7 = 0, intptr_t arg8 = 0, intptr_t arg9 = 0, intptr_t arg10 = 0, intptr_t arg11 = 0 );
330 void			 VM_Shifted_Alloc( void **ptr, int size );
331 void			 VM_Shifted_Free( void **ptr );
332 void			*VM_ArgPtr( intptr_t intValue );
333 void			*VM_ExplicitArgPtr( vm_t *vm, intptr_t intValue );
334 float			_vmf( intptr_t x );
335 
336 #define	VMA(x) VM_ArgPtr( args[x] )
337 #define	VMF(x) _vmf( args[x] )
338 
339 /*
340 ==============================================================
341 
342 CMD
343 
344 Command text buffering and command execution
345 
346 ==============================================================
347 */
348 
349 /*
350 
351 Any number of commands can be added in a frame, from several different sources.
352 Most commands come from either keybindings or console line input, but entire text
353 files can be execed.
354 
355 */
356 
357 void Cbuf_Init (void);
358 // allocates an initial text buffer that will grow as needed
359 
360 void Cbuf_AddText( const char *text );
361 // Adds command text at the end of the buffer, does NOT add a final \n
362 
363 void Cbuf_ExecuteText( int exec_when, const char *text );
364 // this can be used in place of either Cbuf_AddText or Cbuf_InsertText
365 
366 void Cbuf_Execute (void);
367 // Pulls off \n terminated lines of text from the command buffer and sends
368 // them through Cmd_ExecuteString.  Stops when the buffer is empty.
369 // Normally called once per frame, but may be explicitly invoked.
370 // Do not call inside a command function, or current args will be destroyed.
371 
372 //===========================================================================
373 
374 /*
375 
376 Command execution takes a null terminated string, breaks it into tokens,
377 then searches for a command or variable that matches the first token.
378 
379 */
380 
381 typedef void (*xcommand_t) (void);
382 
383 typedef void ( *callbackFunc_t )( const char *s );
384 
385 void	Cmd_Init (void);
386 
387 void	Cmd_AddCommand( const char *cmd_name, xcommand_t function, const char *cmd_desc=NULL );
388 // called by the init functions of other parts of the program to
389 // register commands and functions to call for them.
390 // The cmd_name is referenced later, so it should not be in temp memory
391 // if function is NULL, the command will be forwarded to the server
392 // as a clc_clientCommand instead of executed locally
393 
394 void	Cmd_RemoveCommand( const char *cmd_name );
395 void	Cmd_VM_RemoveCommand( const char *cmd_name, vmSlots_t vmslot );
396 typedef void (*completionFunc_t)( char *args, int argNum );
397 
398 typedef struct cmdList_s
399 {
400 	const char *name;
401 	const char *description;
402 	xcommand_t func;
403 	completionFunc_t complete;
404 } cmdList_t;
405 
406 void Cmd_AddCommandList( const cmdList_t *cmdList );
407 void Cmd_RemoveCommandList( const cmdList_t *cmdList );
408 
409 void	Cmd_CommandCompletion( callbackFunc_t callback );
410 // callback with each valid string
411 void Cmd_SetCommandCompletionFunc( const char *command, completionFunc_t complete );
412 void Cmd_CompleteArgument( const char *command, char *args, int argNum );
413 void Cmd_CompleteCfgName( char *args, int argNum );
414 
415 int		Cmd_Argc (void);
416 char	*Cmd_Argv (int arg);
417 void	Cmd_ArgvBuffer( int arg, char *buffer, int bufferLength );
418 char	*Cmd_Args (void);
419 char	*Cmd_ArgsFrom( int arg );
420 void	Cmd_ArgsBuffer( char *buffer, int bufferLength );
421 void	Cmd_ArgsFromBuffer( int arg, char *buffer, int bufferLength );
422 char	*Cmd_Cmd (void);
423 void	Cmd_Args_Sanitize( size_t length = MAX_CVAR_VALUE_STRING, const char *strip = "\n\r;", const char *repl = "   " );
424 // The functions that execute commands get their parameters with these
425 // functions. Cmd_Argv () will return an empty string, not a NULL
426 // if arg > argc, so string operations are allways safe.
427 
428 void	Cmd_TokenizeString( const char *text );
429 void	Cmd_TokenizeStringIgnoreQuotes( const char *text_in );
430 // Takes a null terminated string.  Does not need to be /n terminated.
431 // breaks the string up into arg tokens.
432 
433 void	Cmd_ExecuteString( const char *text );
434 // Parses a single line of text into arguments and tries to execute it
435 // as if it was typed at the console
436 
437 
438 /*
439 ==============================================================
440 
441 CVAR
442 
443 ==============================================================
444 */
445 
446 /*
447 
448 cvar_t variables are used to hold scalar or string variables that can be changed
449 or displayed at the console or prog code as well as accessed directly
450 in C code.
451 
452 The user can access cvars from the console in three ways:
453 r_draworder			prints the current value
454 r_draworder 0		sets the current value to 0
455 set r_draworder 0	as above, but creates the cvar if not present
456 
457 Cvars are restricted from having the same names as commands to keep this
458 interface from being ambiguous.
459 
460 The are also occasionally used to communicated information between different
461 modules of the program.
462 
463 */
464 
465 cvar_t *Cvar_Get( const char *var_name, const char *value, uint32_t flags, const char *var_desc=NULL );
466 // creates the variable if it doesn't exist, or returns the existing one
467 // if it exists, the value will not be changed, but flags will be ORed in
468 // that allows variables to be unarchived without needing bitflags
469 // if value is "", the value will not override a previously set value.
470 
471 void	Cvar_Register( vmCvar_t *vmCvar, const char *varName, const char *defaultValue, uint32_t flags );
472 // basically a slightly modified Cvar_Get for the interpreted modules
473 
474 void	Cvar_Update( vmCvar_t *vmCvar );
475 // updates an interpreted modules' version of a cvar
476 
477 cvar_t	*Cvar_Set2(const char *var_name, const char *value, uint32_t defaultFlags, qboolean force);
478 //
479 
480 cvar_t	*Cvar_Set( const char *var_name, const char *value );
481 // will create the variable with no flags if it doesn't exist
482 
483 cvar_t	*Cvar_SetSafe( const char *var_name, const char *value );
484 // same as Cvar_Set, but doesn't force setting the value (respects CVAR_ROM, etc)
485 
486 cvar_t	*Cvar_User_Set( const char *var_name, const char *value );
487 // same as Cvar_SetSafe, but defaults to CVAR_USER_CREATED
488 
489 void	Cvar_Server_Set( const char *var_name, const char *value );
490 void	Cvar_VM_Set( const char *var_name, const char *value, vmSlots_t vmslot );
491 // sometimes we set variables from an untrusted source: fail if flags & CVAR_PROTECTED
492 
493 cvar_t	*Cvar_SetValue( const char *var_name, float value );
494 void	Cvar_User_SetValue( const char *var_name, float value );
495 void	Cvar_VM_SetValue( const char *var_name, float value, vmSlots_t vmslot );
496 // expands value to a string and calls Cvar_Set/Cvar_User_Set/Cvar_VM_Set
497 
498 float	Cvar_VariableValue( const char *var_name );
499 int		Cvar_VariableIntegerValue( const char *var_name );
500 // returns 0 if not defined or non numeric
501 
502 char	*Cvar_VariableString( const char *var_name );
503 void	Cvar_VariableStringBuffer( const char *var_name, char *buffer, int bufsize );
504 // returns an empty string if not defined
505 
506 uint32_t	Cvar_Flags(const char *var_name);
507 // returns CVAR_NONEXISTENT if cvar doesn't exist or the flags of that particular CVAR.
508 
509 void	Cvar_CommandCompletion( callbackFunc_t callback );
510 // callback with each valid string
511 
512 void 	Cvar_Reset( const char *var_name );
513 void 	Cvar_ForceReset( const char *var_name );
514 
515 void	Cvar_SetCheatState( void );
516 // reset all testing vars to a safe value
517 
518 qboolean Cvar_Command( void );
519 // called by Cmd_ExecuteString when Cmd_Argv(0) doesn't match a known
520 // command.  Returns true if the command was a variable reference that
521 // was handled. (print or change)
522 
523 void 	Cvar_WriteVariables( fileHandle_t f );
524 // writes lines containing "set variable value" for all variables
525 // with the archive flag set to true.
526 
527 cvar_t *Cvar_Unset(cvar_t *cv);
528 
529 void	Cvar_Init( void );
530 
531 char	*Cvar_InfoString( int bit );
532 char	*Cvar_InfoString_Big( int bit );
533 // returns an info string containing all the cvars that have the given bit set
534 // in their flags ( CVAR_USERINFO, CVAR_SERVERINFO, CVAR_SYSTEMINFO, etc )
535 void	Cvar_InfoStringBuffer( int bit, char *buff, int buffsize );
536 void Cvar_CheckRange( cvar_t *cv, float minVal, float maxVal, qboolean shouldBeIntegral );
537 
538 void	Cvar_Restart(qboolean unsetVM);
539 void	Cvar_Restart_f( void );
540 
541 void Cvar_CompleteCvarName( char *args, int argNum );
542 
543 extern uint32_t cvar_modifiedFlags;
544 // whenever a cvar is modifed, its flags will be OR'd into this, so
545 // a single check can determine if any CVAR_USERINFO, CVAR_SERVERINFO,
546 // etc, variables have been modified since the last check.  The bit
547 // can then be cleared to allow another change detection.
548 
549 /*
550 ==============================================================
551 
552 FILESYSTEM
553 
554 No stdio calls should be used by any part of the game, because
555 we need to deal with all sorts of directory and seperator char
556 issues.
557 ==============================================================
558 */
559 
560 // referenced flags
561 // these are in loop specific order so don't change the order
562 #define FS_GENERAL_REF	0x01
563 #define FS_UI_REF		0x02
564 #define FS_CGAME_REF	0x04
565 #define FS_GAME_REF		0x08
566 // number of id paks that will never be autodownloaded from base
567 #define NUM_ID_PAKS		9
568 
569 #define	MAX_FILE_HANDLES	64
570 
571 #ifdef DEDICATED
572 #	define Q3CONFIG_CFG PRODUCT_NAME "_server.cfg"
573 #else
574 #	define Q3CONFIG_CFG PRODUCT_NAME ".cfg"
575 #endif
576 
577 qboolean FS_Initialized();
578 
579 void	FS_InitFilesystem (void);
580 void	FS_Shutdown( qboolean closemfp );
581 
582 qboolean	FS_ConditionalRestart( int checksumFeed );
583 void	FS_Restart( int checksumFeed );
584 // shutdown and restart the filesystem so changes to fs_gamedir can take effect
585 
586 char	**FS_ListFiles( const char *directory, const char *extension, int *numfiles );
587 // directory should not have either a leading or trailing /
588 // if extension is "/", only subdirectories will be returned
589 // the returned files will not include any directories or /
590 
591 void	FS_FreeFileList( char **fileList );
592 //rwwRMG - changed to fileList to not conflict with list type
593 
594 void FS_Remove( const char *osPath );
595 void FS_HomeRemove( const char *homePath );
596 
597 void FS_Rmdir( const char *osPath, qboolean recursive );
598 void FS_HomeRmdir( const char *homePath, qboolean recursive );
599 
600 qboolean FS_FileExists( const char *file );
601 
602 char   *FS_BuildOSPath( const char *base, const char *game, const char *qpath );
603 qboolean FS_CompareZipChecksum(const char *zipfile);
604 
605 int		FS_GetFileList(  const char *path, const char *extension, char *listbuf, int bufsize );
606 int		FS_GetModList(  char *listbuf, int bufsize );
607 
608 fileHandle_t	FS_FOpenFileWrite( const char *qpath, qboolean safe=qtrue );
609 // will properly create any needed paths and deal with seperater character issues
610 
611 int		FS_filelength( fileHandle_t f );
612 fileHandle_t FS_SV_FOpenFileWrite( const char *filename );
613 fileHandle_t FS_SV_FOpenFileAppend( const char *filename );
614 int		FS_SV_FOpenFileRead( const char *filename, fileHandle_t *fp );
615 void	FS_SV_Rename( const char *from, const char *to, qboolean safe );
616 long		FS_FOpenFileRead( const char *qpath, fileHandle_t *file, qboolean uniqueFILE );
617 // if uniqueFILE is true, then a new FILE will be fopened even if the file
618 // is found in an already open pak file.  If uniqueFILE is false, you must call
619 // FS_FCloseFile instead of fclose, otherwise the pak FILE would be improperly closed
620 // It is generally safe to always set uniqueFILE to true, because the majority of
621 // file IO goes through FS_ReadFile, which Does The Right Thing already.
622 
623 int		FS_FileIsInPAK(const char *filename, int *pChecksum );
624 // returns 1 if a file is in the PAK file, otherwise -1
625 
626 qboolean FS_FindPureDLL(const char *name);
627 
628 int		FS_Write( const void *buffer, int len, fileHandle_t f );
629 
630 int		FS_Read( void *buffer, int len, fileHandle_t f );
631 // properly handles partial reads and reads from other dlls
632 
633 void	FS_FCloseFile( fileHandle_t f );
634 // note: you can't just fclose from another DLL, due to MS libc issues
635 
636 long		FS_ReadFile( const char *qpath, void **buffer );
637 // returns the length of the file
638 // a null buffer will just return the file length without loading
639 // as a quick check for existance. -1 length == not present
640 // A 0 byte will always be appended at the end, so string ops are safe.
641 // the buffer should be considered read-only, because it may be cached
642 // for other uses.
643 
644 void	FS_ForceFlush( fileHandle_t f );
645 // forces flush on files we're writing to.
646 
647 void	FS_FreeFile( void *buffer );
648 // frees the memory returned by FS_ReadFile
649 
650 void	FS_WriteFile( const char *qpath, const void *buffer, int size );
651 // writes a complete file, creating any subdirectories needed
652 
653 int		FS_filelength( fileHandle_t f );
654 // doesn't work for files that are opened from a pack file
655 
656 int		FS_FTell( fileHandle_t f );
657 // where are we?
658 
659 void	FS_Flush( fileHandle_t f );
660 
661 void	FS_FilenameCompletion( const char *dir, const char *ext, qboolean stripExt, callbackFunc_t callback, qboolean allowNonPureFilesOnDisk );
662 
663 const char *FS_GetCurrentGameDir(bool emptybase=false);
664 
665 #ifdef MACOS_X
666 bool FS_LoadMachOBundle( const char *name );
667 #endif
668 
669 void 	QDECL FS_Printf( fileHandle_t f, const char *fmt, ... );
670 // like fprintf
671 
672 int		FS_FOpenFileByMode( const char *qpath, fileHandle_t *f, fsMode_t mode );
673 // opens a file for reading, writing, or appending depending on the value of mode
674 
675 int		FS_Seek( fileHandle_t f, long offset, int origin );
676 // seek on a file
677 
678 qboolean FS_FilenameCompare( const char *s1, const char *s2 );
679 
680 const char *FS_LoadedPakNames( void );
681 const char *FS_LoadedPakChecksums( void );
682 const char *FS_LoadedPakPureChecksums( void );
683 // Returns a space separated string containing the checksums of all loaded pk3 files.
684 // Servers with sv_pure set will get this string and pass it to clients.
685 
686 const char *FS_ReferencedPakNames( void );
687 const char *FS_ReferencedPakChecksums( void );
688 const char *FS_ReferencedPakPureChecksums( void );
689 // Returns a space separated string containing the checksums of all loaded
690 // AND referenced pk3 files. Servers with sv_pure set will get this string
691 // back from clients for pure validation
692 
693 void FS_ClearPakReferences( int flags );
694 // clears referenced booleans on loaded pk3s
695 
696 void FS_PureServerSetReferencedPaks( const char *pakSums, const char *pakNames );
697 void FS_PureServerSetLoadedPaks( const char *pakSums, const char *pakNames );
698 // If the string is empty, all data sources will be allowed.
699 // If not empty, only pk3 files that match one of the space
700 // separated checksums will be checked for files, with the
701 // sole exception of .cfg files.
702 
703 qboolean FS_CheckDirTraversal(const char *checkdir);
704 qboolean FS_idPak( char *pak, char *base );
705 qboolean FS_ComparePaks( char *neededpaks, int len, qboolean dlstring );
706 void FS_Rename( const char *from, const char *to );
707 
708 qboolean FS_WriteToTemporaryFile( const void *data, size_t dataLength, char **tempFileName );
709 
710 
711 /*
712 ==============================================================
713 
714 Edit fields and command line history/completion
715 
716 ==============================================================
717 */
718 
719 #define CONSOLE_PROMPT_CHAR ']'
720 #define	MAX_EDIT_LINE		256
721 #define COMMAND_HISTORY		32
722 
723 typedef struct field_s {
724 	int		cursor;
725 	int		scroll;
726 	int		widthInChars;
727 	char	buffer[MAX_EDIT_LINE];
728 } field_t;
729 
730 void Field_Clear( field_t *edit );
731 void Field_AutoComplete( field_t *edit );
732 void Field_CompleteKeyname( void );
733 void Field_CompleteFilename( const char *dir, const char *ext, qboolean stripExt, qboolean allowNonPureFilesOnDisk );
734 void Field_CompleteCommand( char *cmd, qboolean doCommands, qboolean doCvars );
735 
736 /*
737 ==============================================================
738 
739 MISC
740 
741 ==============================================================
742 */
743 
744 #define RoundUp(N, M) ((N) + ((unsigned int)(M)) - (((unsigned int)(N)) % ((unsigned int)(M))))
745 #define RoundDown(N, M) ((N) - (((unsigned int)(N)) % ((unsigned int)(M))))
746 
747 char		*CopyString( const char *in );
748 void		Info_Print( const char *s );
749 
750 void		Com_BeginRedirect (char *buffer, int buffersize, void (*flush)(char *));
751 void		Com_EndRedirect( void );
752 void 		QDECL Com_Printf( const char *fmt, ... );
753 void 		QDECL Com_DPrintf( const char *fmt, ... );
754 void		QDECL Com_OPrintf( const char *fmt, ...); // Outputs to the VC / Windows Debug window (only in debug compile)
755 void 		NORETURN QDECL Com_Error( int code, const char *fmt, ... );
756 void 		NORETURN Com_Quit_f( void );
757 int			Com_EventLoop( void );
758 int			Com_Milliseconds( void );	// will be journaled properly
759 uint32_t	Com_BlockChecksum( const void *buffer, int length );
760 char		*Com_MD5File(const char *filename, int length, const char *prefix, int prefix_len);
761 int      Com_HashKey(char *string, int maxlen);
762 int			Com_Filter(char *filter, char *name, int casesensitive);
763 int			Com_FilterPath(char *filter, char *name, int casesensitive);
764 int			Com_RealTime(qtime_t *qtime);
765 qboolean	Com_SafeMode( void );
766 void		Com_RunAndTimeServerPacket(netadr_t *evFrom, msg_t *buf);
767 
768 void		Com_StartupVariable( const char *match );
769 // checks for and removes command line "+set var arg" constructs
770 // if match is NULL, all set commands will be executed, otherwise
771 // only a set with the exact name.  Only used during startup.
772 
773 
774 extern	cvar_t	*com_developer;
775 extern	cvar_t	*com_dedicated;
776 extern	cvar_t	*com_speeds;
777 extern	cvar_t	*com_timescale;
778 extern	cvar_t	*com_sv_running;
779 extern	cvar_t	*com_cl_running;
780 extern	cvar_t	*com_version;
781 extern	cvar_t	*com_buildScript;		// for building release pak files
782 extern	cvar_t	*com_journal;
783 extern	cvar_t	*com_cameraMode;
784 extern	cvar_t	*com_homepath;
785 #ifndef _WIN32
786 extern	cvar_t	*com_ansiColor;
787 #endif
788 
789 extern	cvar_t	*com_optvehtrace;
790 
791 #ifdef G2_PERFORMANCE_ANALYSIS
792 extern	cvar_t	*com_G2Report;
793 #endif
794 
795 extern	cvar_t	*com_affinity;
796 extern	cvar_t	*com_busyWait;
797 
798 // both client and server must agree to pause
799 extern	cvar_t	*cl_paused;
800 extern	cvar_t	*sv_paused;
801 
802 // com_speeds times
803 extern	int		time_game;
804 extern	int		time_frontend;
805 extern	int		time_backend;		// renderer backend time
806 
807 extern	int		com_frameTime;
808 
809 extern	qboolean	com_errorEntered;
810 
811 
812 extern	fileHandle_t	logfile;
813 extern	fileHandle_t	com_journalFile;
814 extern	fileHandle_t	com_journalDataFile;
815 
816 /*
817 typedef enum {
818 	TAG_FREE,
819 	TAG_GENERAL,
820 	TAG_BOTLIB,
821 	TAG_RENDERER,
822 	TAG_SMALL,
823 	TAG_STATIC
824 } memtag_t;
825 */
826 
827 /*
828 
829 --- low memory ----
830 server vm
831 server clipmap
832 ---mark---
833 renderer initialization (shaders, etc)
834 UI vm
835 cgame vm
836 renderer map
837 renderer models
838 
839 ---free---
840 
841 temp file loading
842 --- high memory ---
843 
844 */
845 
846 #if defined(_DEBUG) && !defined(BSPC)
847 	#define DEBUG_ZONE_ALLOCS
848 #endif
849 
850 /*
851 #ifdef DEBUG_ZONE_ALLOCS
852 	#define Z_TagMalloc(size, tag)			Z_TagMallocDebug(size, tag, #size, __FILE__, __LINE__)
853 	#define Z_Malloc(size)					Z_MallocDebug(size, #size, __FILE__, __LINE__)
854 	#define S_Malloc(size)					S_MallocDebug(size, #size, __FILE__, __LINE__)
855 	void *Z_TagMallocDebug( int size, int tag, char *label, char *file, int line );	// NOT 0 filled memory
856 	void *Z_MallocDebug( int size, char *label, char *file, int line );			// returns 0 filled memory
857 	void *S_MallocDebug( int size, char *label, char *file, int line );			// returns 0 filled memory
858 #else
859 	void *Z_TagMalloc( int size, int tag );	// NOT 0 filled memory
860 	void *Z_Malloc( int size );			// returns 0 filled memory
861 	void *S_Malloc( int size );			// NOT 0 filled memory only for small allocations
862 #endif
863 void Z_Free( void *ptr );
864 void Z_FreeTags( int tag );
865 int Z_AvailableMemory( void );
866 void Z_LogHeap( void );
867 */
868 
869 // later on I'll re-implement __FILE__, __LINE__ etc, but for now...
870 //
871 #ifdef DEBUG_ZONE_ALLOCS
872 void *Z_Malloc  ( int iSize, memtag_t eTag, qboolean bZeroit = qfalse, int iAlign = 4);	// return memory NOT zero-filled by default
873 void *S_Malloc	( int iSize );					// NOT 0 filled memory only for small allocations
874 #else
875 void *Z_Malloc  ( int iSize, memtag_t eTag, qboolean bZeroit = qfalse, int iAlign = 4);	// return memory NOT zero-filled by default
876 void *S_Malloc	( int iSize );					// NOT 0 filled memory only for small allocations
877 #endif
878 void  Z_MorphMallocTag( void *pvBuffer, memtag_t eDesiredTag );
879 void  Z_Validate( void );
880 int   Z_MemSize	( memtag_t eTag );
881 void  Z_TagFree	( memtag_t eTag );
882 void  Z_Free	( void *ptr );
883 int	  Z_Size	( void *pvAddress);
884 void Com_InitZoneMemory(void);
885 void Com_InitZoneMemoryVars(void);
886 void Com_InitHunkMemory(void);
887 void Com_ShutdownZoneMemory(void);
888 void Com_ShutdownHunkMemory(void);
889 
890 void Hunk_Clear( void );
891 void Hunk_ClearToMark( void );
892 void Hunk_SetMark( void );
893 qboolean Hunk_CheckMark( void );
894 void Hunk_ClearTempMemory( void );
895 void *Hunk_AllocateTempMemory( int size );
896 void Hunk_FreeTempMemory( void *buf );
897 int	Hunk_MemoryRemaining( void );
898 void Hunk_Log( void);
899 void Hunk_Trash( void );
900 
901 void Com_TouchMemory( void );
902 
903 // commandLine should not include the executable name (argv[0])
904 void Com_Init( char *commandLine );
905 void Com_Frame( void );
906 void Com_Shutdown( void );
907 
908 
909 /*
910 ==============================================================
911 
912 CLIENT / SERVER SYSTEMS
913 
914 ==============================================================
915 */
916 
917 //
918 // client interface
919 //
920 void CL_InitKeyCommands( void );
921 // the keyboard binding interface must be setup before execing
922 // config files, but the rest of client startup will happen later
923 
924 void CL_Init( void );
925 void CL_Disconnect( qboolean showMainMenu );
926 void CL_Shutdown( void );
927 void CL_Frame( int msec );
928 qboolean CL_GameCommand( void );
929 void CL_KeyEvent (int key, qboolean down, unsigned time);
930 
931 void CL_CharEvent( int key );
932 // char events are for field typing, not game control
933 
934 void CL_MouseEvent( int dx, int dy, int time );
935 
936 void CL_JoystickEvent( int axis, int value, int time );
937 
938 void CL_PacketEvent( netadr_t from, msg_t *msg );
939 
940 void CL_ConsolePrint( const char *text );
941 
942 void CL_MapLoading( void );
943 // do a screen update before starting to load a map
944 // when the server is going to load a new map, the entire hunk
945 // will be cleared, so the client must shutdown cgame, ui, and
946 // the renderer
947 
948 void	CL_ForwardCommandToServer( const char *string );
949 // adds the current command line as a clc_clientCommand to the client message.
950 // things like godmode, noclip, etc, are commands directed to the server,
951 // so when they are typed in at the console, they will need to be forwarded.
952 
953 void CL_ShutdownAll( qboolean shutdownRef );
954 // shutdown all the client stuff
955 
956 void CL_FlushMemory( void );
957 // dump all memory on an error
958 
959 void CL_StartHunkUsers( void );
960 // start all the client stuff using the hunk
961 
962 qboolean CL_ConnectedToRemoteServer( void );
963 // returns qtrue if connected to a server
964 
965 void Key_KeynameCompletion ( void(*callback)( const char *s ) );
966 // for keyname autocompletion
967 
968 void Key_WriteBindings( fileHandle_t f );
969 // for writing the config files
970 
971 void S_ClearSoundBuffer( void );
972 // call before filesystem access
973 
974 void SCR_DebugGraph (float value, int color);	// FIXME: move logging to common?
975 
976 // AVI files have the start of pixel lines 4 byte-aligned
977 #define AVI_LINE_PADDING 4
978 
979 
980 //
981 // server interface
982 //
983 void SV_Init( void );
984 void SV_Shutdown( char *finalmsg );
985 void SV_Frame( int msec );
986 void SV_PacketEvent( netadr_t from, msg_t *msg );
987 int SV_FrameMsec( void );
988 qboolean SV_GameCommand( void );
989 
990 
991 //
992 // UI interface
993 //
994 qboolean UI_GameCommand( void );
995 
996 /* This is based on the Adaptive Huffman algorithm described in Sayood's Data
997  * Compression book.  The ranks are not actually stored, but implicitly defined
998  * by the location of a node within a doubly-linked list */
999 
1000 #define NYT HMAX					/* NYT = Not Yet Transmitted */
1001 #define INTERNAL_NODE (HMAX+1)
1002 
1003 typedef struct nodetype {
1004 	struct	nodetype *left, *right, *parent; /* tree structure */
1005 	struct	nodetype *next, *prev; /* doubly-linked list */
1006 	struct	nodetype **head; /* highest ranked node in block */
1007 	int		weight;
1008 	int		symbol;
1009 } node_t;
1010 
1011 #define HMAX 256 /* Maximum symbol */
1012 
1013 typedef struct huff_s {
1014 	int			blocNode;
1015 	int			blocPtrs;
1016 
1017 	node_t*		tree;
1018 	node_t*		lhead;
1019 	node_t*		ltail;
1020 	node_t*		loc[HMAX+1];
1021 	node_t**	freelist;
1022 
1023 	node_t		nodeList[768];
1024 	node_t*		nodePtrs[768];
1025 } huff_t;
1026 
1027 typedef struct huffman_s {
1028 	huff_t		compressor;
1029 	huff_t		decompressor;
1030 } huffman_t;
1031 
1032 void	Huff_Compress(msg_t *buf, int offset);
1033 void	Huff_Decompress(msg_t *buf, int offset);
1034 void	Huff_Init(huffman_t *huff);
1035 void	Huff_addRef(huff_t* huff, byte ch);
1036 int		Huff_Receive (node_t *node, int *ch, byte *fin);
1037 void	Huff_transmit (huff_t *huff, int ch, byte *fout);
1038 void	Huff_offsetReceive (node_t *node, int *ch, byte *fin, int *offset);
1039 void	Huff_offsetTransmit (huff_t *huff, int ch, byte *fout, int *offset);
1040 void	Huff_putBit( int bit, byte *fout, int *offset);
1041 int		Huff_getBit( byte *fout, int *offset);
1042 
1043 extern huffman_t clientHuffTables;
1044 
1045 #define	SV_ENCODE_START		4
1046 #define SV_DECODE_START		12
1047 #define	CL_ENCODE_START		12
1048 #define CL_DECODE_START		4
1049 
Round(float value)1050 inline int Round(float value)
1051 {
1052 	return((int)floorf(value + 0.5f));
1053 }
1054 
1055 // Persistent data store API
1056 bool PD_Store ( const char *name, const void *data, size_t size );
1057 const void *PD_Load ( const char *name, size_t *size );
1058 
1059 uint32_t ConvertUTF8ToUTF32( char *utf8CurrentChar, char **utf8NextChar );
1060 
1061 #include "sys/sys_public.h"
1062