1 /*
2 ===========================================================================
3 
4 Return to Castle Wolfenstein multiplayer GPL Source Code
5 Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
6 
7 This file is part of the Return to Castle Wolfenstein multiplayer GPL Source Code (“RTCW MP Source Code”).
8 
9 RTCW MP Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13 
14 RTCW MP Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with RTCW MP Source Code.  If not, see <http://www.gnu.org/licenses/>.
21 
22 In addition, the RTCW MP Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the RTCW MP Source Code.  If not, please request a copy in writing from id Software at the address below.
23 
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25 
26 ===========================================================================
27 */
28 
29 // client.h -- primary header for client
30 
31 #include "../qcommon/q_shared.h"
32 #include "../qcommon/qcommon.h"
33 #include "../renderer/tr_public.h"
34 #include "../ui/ui_public.h"
35 #include "keys.h"
36 #include "snd_public.h"
37 #include "../cgame/cg_public.h"
38 #include "../game/bg_public.h"
39 
40 #ifdef USE_CURL
41 #include "cl_curl.h"
42 #endif /* USE_CURL */
43 
44 #ifdef USE_VOIP
45 #ifdef USE_LOCAL_HEADERS
46   #include "../opus-1.2.1/include/opus.h"
47   #include "../opusfile-0.9/include/opusfile.h"
48 #else
49   #include <opus/opus.h>
50   #include <opus/opusfile.h>
51 #endif
52 #endif
53 
54 // file full of random crap that gets used to create cl_guid
55 #define QKEY_FILE "wkey"
56 #define QKEY_SIZE 2048
57 
58 #define	RETRANSMIT_TIMEOUT	3000	// time between connection packet retransmits
59 
60 #define LIMBOCHAT_WIDTH		140     // NERVE - SMF
61 #define LIMBOCHAT_HEIGHT	7       // NERVE - SMF
62 
63 // snapshots are a view of the server at a given time
64 typedef struct {
65 	qboolean valid;                 // cleared if delta parsing was invalid
66 	int snapFlags;                  // rate delayed and dropped commands
67 
68 	int serverTime;                 // server time the message is valid for (in msec)
69 
70 	int messageNum;                 // copied from netchan->incoming_sequence
71 	int deltaNum;                   // messageNum the delta is from
72 	int ping;                       // time from when cmdNum-1 was sent to time packet was reeceived
73 	byte areamask[MAX_MAP_AREA_BYTES];                  // portalarea visibility bits
74 
75 	int cmdNum;                     // the next cmdNum the server is expecting
76 	playerState_t ps;                       // complete information about the current player at this time
77 
78 	int numEntities;                        // all of the entities that need to be presented
79 	int parseEntitiesNum;                   // at the time of this snapshot
80 
81 	int serverCommandNum;                   // execute all commands up to this before
82 											// making the snapshot current
83 } clSnapshot_t;
84 
85 
86 
87 /*
88 =============================================================================
89 
90 the clientActive_t structure is wiped completely at every
91 new gamestate_t, potentially several times during an established connection
92 
93 =============================================================================
94 */
95 
96 typedef struct {
97 	int p_cmdNumber;            // cl.cmdNumber when packet was sent
98 	int p_serverTime;           // usercmd->serverTime when packet was sent
99 	int p_realtime;             // cls.realtime when packet was sent
100 } outPacket_t;
101 
102 // the parseEntities array must be large enough to hold PACKET_BACKUP frames of
103 // entities, so that when a delta compressed message arives from the server
104 // it can be un-deltad from the original
105 #define  MAX_PARSE_ENTITIES  ( PACKET_BACKUP * MAX_SNAPSHOT_ENTITIES )
106 
107 extern int g_console_field_width;
108 
109 typedef struct {
110 	int timeoutcount;               // it requres several frames in a timeout condition
111 									// to disconnect, preventing debugging breaks from
112 									// causing immediate disconnects on continue
113 	clSnapshot_t snap;              // latest received from server
114 
115 	int serverTime;                 // may be paused during play
116 	int oldServerTime;              // to prevent time from flowing bakcwards
117 	int oldFrameServerTime;         // to check tournament restarts
118 	int serverTimeDelta;            // cl.serverTime = cls.realtime + cl.serverTimeDelta
119 									// this value changes as net lag varies
120 	qboolean extrapolatedSnapshot;      // set if any cgame frame has been forced to extrapolate
121 	// cleared when CL_AdjustTimeDelta looks at it
122 	qboolean newSnapshots;          // set on parse of any valid packet
123 
124 	gameState_t gameState;          // configstrings
125 	char mapname[MAX_QPATH];        // extracted from CS_SERVERINFO
126 
127 	int parseEntitiesNum;           // index (not anded off) into cl_parse_entities[]
128 
129 	int mouseDx[2], mouseDy[2];         // added to by mouse events
130 	int mouseIndex;
131 	int joystickAxis[MAX_JOYSTICK_AXIS];            // set by joystick events
132 
133 	// cgame communicates a few values to the client system
134 	int cgameUserCmdValue;              // current weapon to add to usercmd_t
135 	int cgameUserHoldableValue;         // current holdable item to add to usercmd_t	//----(SA)	added
136 	float cgameSensitivity;
137 	int cgameMpSetup;                   // NERVE - SMF
138 	int cgameMpIdentClient;             // NERVE - SMF
139 	vec3_t cgameClientLerpOrigin;       // DHM - Nerve
140 
141 	// cmds[cmdNumber] is the predicted command, [cmdNumber-1] is the last
142 	// properly generated command
143 	usercmd_t cmds[CMD_BACKUP];     // each mesage will send several old cmds
144 	int cmdNumber;                  // incremented each frame, because multiple
145 									// frames may need to be packed into a single packet
146 
147 	outPacket_t outPackets[PACKET_BACKUP];  // information about each packet we have sent out
148 
149 	// the client maintains its own idea of view angles, which are
150 	// sent to the server each frame.  It is cleared to 0 upon entering each level.
151 	// the server sends a delta each frame which is added to the locally
152 	// tracked view angles to account for standing on rotating objects,
153 	// and teleport direction changes
154 	vec3_t viewangles;
155 
156 	int serverId;                   // included in each client message so the server
157 									// can tell if it is for a prior map_restart
158 	// big stuff at end of structure so most offsets are 15 bits or less
159 	clSnapshot_t snapshots[PACKET_BACKUP];
160 
161 	entityState_t entityBaselines[MAX_GENTITIES];   // for delta compression when not in previous frame
162 
163 	entityState_t parseEntities[MAX_PARSE_ENTITIES];
164 
165 	// NERVE - SMF
166 	char limboChatMsgs[LIMBOCHAT_HEIGHT][LIMBOCHAT_WIDTH * 3 + 1];
167 	int limboChatPos;
168 
169 	qboolean corruptedTranslationFile;
170 	char translationVersion[MAX_STRING_TOKENS];
171 	// -NERVE - SMF
172 } clientActive_t;
173 
174 extern clientActive_t cl;
175 
176 /*
177 =============================================================================
178 
179 the clientConnection_t structure is wiped when disconnecting from a server,
180 either to go to a full screen console, play a demo, or connect to a different server
181 
182 A connection can be to either a server through the network layer or a
183 demo through a file.
184 
185 =============================================================================
186 */
187 
188 #define MAX_TIMEDEMO_DURATIONS	4096
189 
190 typedef struct {
191 
192 	connstate_t	state;				// connection status
193 
194 	int clientNum;
195 	int lastPacketSentTime;                 // for retransmits during connection
196 	int lastPacketTime;                     // for timeouts
197 
198 	char		servername[MAX_OSPATH];		// name of server from original connect (used by reconnect)
199 	netadr_t serverAddress;
200 	int connectTime;                        // for connection retransmits
201 	int connectPacketCount;                 // for display on connection dialog
202 	char serverMessage[MAX_STRING_TOKENS];          // for display on connection dialog
203 
204 	int challenge;                          // from the server to use for connecting
205 	int checksumFeed;                       // from the server for checksum calculations
206 
207 	int onlyVisibleClients;                 // DHM - Nerve
208 
209 	// these are our reliable messages that go to the server
210 	int reliableSequence;
211 	int reliableAcknowledge;                // the last one the server has executed
212 	char reliableCommands[MAX_RELIABLE_COMMANDS][MAX_TOKEN_CHARS];
213 
214 	// server message (unreliable) and command (reliable) sequence
215 	// numbers are NOT cleared at level changes, but continue to
216 	// increase as long as the connection is valid
217 
218 	// message sequence is used by both the network layer and the
219 	// delta compression layer
220 	int serverMessageSequence;
221 
222 	// reliable messages received from server
223 	int serverCommandSequence;
224 	int lastExecutedServerCommand;              // last server command grabbed or executed with CL_GetServerCommand
225 	char serverCommands[MAX_RELIABLE_COMMANDS][MAX_TOKEN_CHARS];
226 
227 	// file transfer from server
228 	fileHandle_t download;
229 	char downloadTempName[MAX_OSPATH];
230 	char downloadName[MAX_OSPATH];
231 #ifdef USE_CURL
232 	qboolean	cURLEnabled;
233 	qboolean	cURLUsed;
234 	qboolean	cURLDisconnected;
235 	char		downloadURL[MAX_OSPATH];
236 	CURL		*downloadCURL;
237 	CURLM		*downloadCURLM;
238 #endif /* USE_CURL */
239 	int		sv_allowDownload;
240 	char		sv_dlURL[MAX_CVAR_VALUE_STRING];
241 	int downloadNumber;
242 	int downloadBlock;          // block we are waiting for
243 	int downloadCount;          // how many bytes we got
244 	int downloadSize;           // how many bytes we got
245 	char downloadList[MAX_INFO_STRING];        // list of paks we need to download
246 	qboolean downloadRestart;       // if true, we need to do another FS_Restart because we downloaded a pak
247 
248 	// demo information
249 	char demoName[MAX_QPATH];
250 	qboolean demorecording;
251 	qboolean demoplaying;
252 	qboolean demowaiting;       // don't record until a non-delta message is received
253 	qboolean firstDemoFrameSkipped;
254 	fileHandle_t demofile;
255 
256 	qboolean waverecording;
257 	fileHandle_t wavefile;
258 	int wavetime;
259 
260 	int timeDemoFrames;             // counter of rendered frames
261 	int timeDemoStart;              // cls.realtime before first frame
262 	int timeDemoBaseTime;           // each frame will be at this time + frameNum * 50
263 	int			timeDemoLastFrame;// time the last frame was rendered
264 	int			timeDemoMinDuration;	// minimum frame duration
265 	int			timeDemoMaxDuration;	// maximum frame duration
266 	unsigned char	timeDemoDurations[ MAX_TIMEDEMO_DURATIONS ];	// log of frame durations
267 
268 	float	aviVideoFrameRemainder;
269 	float	aviSoundFrameRemainder;
270 
271 #ifdef USE_VOIP
272 	qboolean voipEnabled;
273 	qboolean voipCodecInitialized;
274 
275 	// incoming data...
276 	// !!! FIXME: convert from parallel arrays to array of a struct.
277 	OpusDecoder *opusDecoder[MAX_CLIENTS];
278 	byte voipIncomingGeneration[MAX_CLIENTS];
279 	int voipIncomingSequence[MAX_CLIENTS];
280 	float voipGain[MAX_CLIENTS];
281 	qboolean voipIgnore[MAX_CLIENTS];
282 	qboolean voipMuteAll;
283 
284 	// outgoing data...
285 	// if voipTargets[i / 8] & (1 << (i % 8)),
286 	// then we are sending to clientnum i.
287 	uint8_t voipTargets[(MAX_CLIENTS + 7) / 8];
288 	uint8_t voipFlags;
289 	OpusEncoder *opusEncoder;
290 	int voipOutgoingDataSize;
291 	int voipOutgoingDataFrames;
292 	int voipOutgoingSequence;
293 	byte voipOutgoingGeneration;
294 	byte voipOutgoingData[1024];
295 	float voipPower;
296 #endif
297 
298 #ifdef LEGACY_PROTOCOL
299 	qboolean compat;
300 #endif
301 
302 	// big stuff at end of structure so most offsets are 15 bits or less
303 	netchan_t netchan;
304 } clientConnection_t;
305 
306 extern clientConnection_t clc;
307 
308 /*
309 ==================================================================
310 
311 the clientStatic_t structure is never wiped, and is used even when
312 no client connection is active at all
313 (except when CL_Shutdown is called)
314 ==================================================================
315 */
316 
317 typedef struct {
318 	netadr_t adr;
319 	int start;
320 	int time;
321 	char info[MAX_INFO_STRING];
322 } ping_t;
323 
324 typedef struct {
325 	netadr_t adr;
326 	char hostName[MAX_NAME_LENGTH];
327 	char mapName[MAX_NAME_LENGTH];
328 	char game[MAX_NAME_LENGTH];
329 	int netType;
330 	int gameType;
331 	int clients;
332 	int maxClients;
333 	int minPing;
334 	int maxPing;
335 	int ping;
336 	qboolean visible;
337 	int allowAnonymous;
338 	int friendlyFire;               // NERVE - SMF
339 	int maxlives;                   // NERVE - SMF
340 	int tourney;                    // NERVE - SMF
341 	int punkbuster;                 // DHM - Nerve
342 	int antilag;         // TTimo
343 	char gameName[MAX_NAME_LENGTH];         // Arnout
344 	int			g_humanplayers;
345 	int			g_needpass;
346 } serverInfo_t;
347 
348 #define MAX_AUTOUPDATE_SERVERS  5
349 typedef struct {
350 
351 	qboolean cddialog;              // bring up the cd needed dialog next frame
352 
353 	// when the server clears the hunk, all of these must be restarted
354 	qboolean rendererStarted;
355 	qboolean soundStarted;
356 	qboolean soundRegistered;
357 	qboolean uiStarted;
358 	qboolean cgameStarted;
359 
360 	int framecount;
361 	int frametime;                  // msec since last frame
362 
363 	int realtime;                   // ignores pause
364 	int realFrametime;              // ignoring pause, so console always works
365 
366 	int numlocalservers;
367 	serverInfo_t localServers[MAX_OTHER_SERVERS];
368 
369 	int numglobalservers;
370 	serverInfo_t globalServers[MAX_GLOBAL_SERVERS];
371 	// additional global servers
372 	int numGlobalServerAddresses;
373 	netadr_t globalServerAddresses[MAX_GLOBAL_SERVERS];
374 
375 	int numfavoriteservers;
376 	serverInfo_t favoriteServers[MAX_OTHER_SERVERS];
377 
378 	int pingUpdateSource;       // source currently pinging or updating
379 
380 	// update server info
381 	netadr_t updateServer;
382 	char updateChallenge[MAX_TOKEN_CHARS];
383 	char updateInfoString[MAX_INFO_STRING];
384 
385 	netadr_t authorizeServer;
386 
387 	netadr_t rconAddress;
388 
389 	// DHM - Nerve :: Auto-update Info
390 	char autoupdateServerNames[MAX_AUTOUPDATE_SERVERS][MAX_QPATH];
391 	netadr_t autoupdateServer;
392 
393 	// rendering info
394 	glconfig_t glconfig;
395 	qhandle_t charSetShader;
396 	qhandle_t whiteShader;
397 	qhandle_t consoleShader;
398 	qhandle_t consoleShader2;   //----(SA)	added
399 } clientStatic_t;
400 
401 extern clientStatic_t cls;
402 
403 extern	char		cl_oldGame[MAX_QPATH];
404 extern	qboolean	cl_oldGameSet;
405 
406 //=============================================================================
407 
408 extern vm_t            *cgvm;   // interface to cgame dll or vm
409 extern vm_t            *uivm;   // interface to ui dll or vm
410 extern refexport_t re;          // interface to refresh .dll
411 
412 
413 //
414 // cvars
415 //
416 extern cvar_t  *cl_nodelta;
417 extern cvar_t  *cl_debugMove;
418 extern cvar_t  *cl_noprint;
419 extern cvar_t  *cl_timegraph;
420 extern cvar_t  *cl_maxpackets;
421 extern cvar_t  *cl_packetdup;
422 extern cvar_t  *cl_shownet;
423 extern cvar_t  *cl_shownuments;             // DHM - Nerve
424 extern cvar_t  *cl_visibleClients;          // DHM - Nerve
425 extern cvar_t  *cl_showSend;
426 extern cvar_t  *cl_showServerCommands;      // NERVE - SMF
427 extern cvar_t  *cl_timeNudge;
428 extern cvar_t  *cl_showTimeDelta;
429 extern cvar_t  *cl_freezeDemo;
430 
431 extern cvar_t  *cl_showPing;
432 
433 extern cvar_t  *cl_yawspeed;
434 extern cvar_t  *cl_pitchspeed;
435 extern cvar_t  *cl_run;
436 extern cvar_t  *cl_anglespeedkey;
437 
438 extern cvar_t  *cl_recoilPitch;     // RF
439 
440 extern cvar_t  *cl_bypassMouseInput;    // NERVE - SMF
441 
442 extern cvar_t  *cl_sensitivity;
443 extern cvar_t  *cl_freelook;
444 
445 extern cvar_t  *cl_mouseAccel;
446 extern	cvar_t	*cl_mouseAccelOffset;
447 extern	cvar_t	*cl_mouseAccelStyle;
448 extern cvar_t  *cl_showMouseRate;
449 
450 extern cvar_t  *m_pitch;
451 extern cvar_t  *m_yaw;
452 extern cvar_t  *m_forward;
453 extern cvar_t  *m_side;
454 extern cvar_t  *m_filter;
455 
456 extern	cvar_t	*j_pitch;
457 extern	cvar_t	*j_yaw;
458 extern	cvar_t	*j_forward;
459 extern	cvar_t	*j_side;
460 extern	cvar_t	*j_up;
461 extern	cvar_t	*j_pitch_axis;
462 extern	cvar_t	*j_yaw_axis;
463 extern	cvar_t	*j_forward_axis;
464 extern	cvar_t	*j_side_axis;
465 extern	cvar_t	*j_up_axis;
466 
467 extern cvar_t  *cl_timedemo;
468 extern	cvar_t	*cl_aviFrameRate;
469 extern	cvar_t	*cl_aviMotionJpeg;
470 
471 extern cvar_t  *cl_activeAction;
472 
473 extern cvar_t  *cl_allowDownload;
474 extern  cvar_t  *cl_downloadMethod;
475 extern cvar_t  *cl_conXOffset;
476 extern cvar_t  *cl_inGameVideo;
477 
478 extern	cvar_t	*cl_lanForcePackets;
479 extern	cvar_t	*cl_autoRecordDemo;
480 
481 extern	cvar_t	*cl_consoleKeys;
482 
483 #ifdef USE_MUMBLE
484 extern	cvar_t	*cl_useMumble;
485 extern	cvar_t	*cl_mumbleScale;
486 #endif
487 
488 #ifdef USE_VOIP
489 // cl_voipSendTarget is a string: "all" to broadcast to everyone, "none" to
490 //  send to no one, or a comma-separated list of client numbers:
491 //  "0,7,2,23" ... an empty string is treated like "all".
492 extern	cvar_t	*cl_voipUseVAD;
493 extern	cvar_t	*cl_voipVADThreshold;
494 extern	cvar_t	*cl_voipSend;
495 extern	cvar_t	*cl_voipSendTarget;
496 extern	cvar_t	*cl_voipGainDuringCapture;
497 extern	cvar_t	*cl_voipCaptureMult;
498 extern	cvar_t	*cl_voipShowMeter;
499 extern	cvar_t	*cl_voip;
500 
501 // 20ms at 48k
502 #define VOIP_MAX_FRAME_SAMPLES		( 20 * 48 )
503 
504 // 3 frame is 60ms of audio, the max opus will encode at once
505 #define VOIP_MAX_PACKET_FRAMES		3
506 #define VOIP_MAX_PACKET_SAMPLES		( VOIP_MAX_FRAME_SAMPLES * VOIP_MAX_PACKET_FRAMES )
507 #endif
508 
509 extern cvar_t  *cl_missionStats;
510 extern cvar_t  *cl_waitForFire;
511 
512 // NERVE - SMF - localization
513 extern cvar_t  *cl_language;
514 // -NERVE - SMF
515 
516 //=================================================
517 
518 //
519 // cl_main
520 //
521 
522 void CL_Init( void );
523 void CL_AddReliableCommand(const char *cmd, qboolean isDisconnectCmd);
524 
525 void CL_StartHunkUsers( qboolean rendererOnly );
526 
527 #ifndef UPDATE_SERVER
528 void CL_CheckAutoUpdate( void );
529 void CL_GetAutoUpdate( void );
530 #endif
531 
532 void CL_Disconnect_f( void );
533 void CL_GetChallengePacket( void );
534 void CL_Vid_Restart_f( void );
535 void CL_Snd_Restart_f( void );
536 void CL_StartDemoLoop( void );
537 void CL_NextDemo( void );
538 void CL_ReadDemoMessage( void );
539 void CL_StopRecord_f(void);
540 
541 void CL_InitDownloads( void );
542 void CL_NextDownload( void );
543 
544 void CL_GetPing( int n, char *buf, int buflen, int *pingtime );
545 void CL_GetPingInfo( int n, char *buf, int buflen );
546 void CL_ClearPing( int n );
547 int CL_GetPingQueueCount( void );
548 
549 void CL_ShutdownRef( void );
550 void CL_InitRef( void );
551 qboolean CL_CDKeyValidate( const char *key, const char *checksum );
552 int CL_ServerStatus( char *serverAddress, char *serverStatusString, int maxLen );
553 
554 qboolean CL_CheckPaused(void);
555 
556 void CL_AddToLimboChat( const char *str );                  // NERVE - SMF
557 qboolean CL_GetLimboString( int index, char *buf );         // NERVE - SMF
558 
559 // NERVE - SMF - localization
560 void CL_InitTranslation(void);
561 void CL_SaveTransTable(const char *fileName, qboolean newOnly);
562 void CL_ReloadTranslation(void);
563 void CL_TranslateString( const char *string, char *dest_buffer );
564 const char* CL_TranslateStringBuf( const char *string ); // TTimo
565 // -NERVE - SMF
566 
567 void CL_OpenURL( const char *url ); // TTimo
568 
569 //
570 // cl_input
571 //
572 typedef struct {
573 	int down[2];                // key nums holding it down
574 	unsigned downtime;          // msec timestamp
575 	unsigned msec;              // msec down this frame if both a down and up happened
576 	qboolean active;            // current state
577 	qboolean wasPressed;        // set when down, not cleared when up
578 } kbutton_t;
579 
580 typedef enum {
581 	KB_LEFT,
582 	KB_RIGHT,
583 	KB_FORWARD,
584 	KB_BACK,
585 	KB_LOOKUP,
586 	KB_LOOKDOWN,
587 	KB_MOVELEFT,
588 	KB_MOVERIGHT,
589 	KB_STRAFE,
590 	KB_SPEED,
591 	KB_UP,
592 	KB_DOWN,
593 	KB_BUTTONS0,
594 	KB_BUTTONS1,
595 	KB_BUTTONS2,
596 	KB_BUTTONS3,
597 	KB_BUTTONS4,
598 	KB_BUTTONS5,
599 	KB_BUTTONS6,
600 	KB_BUTTONS7,
601 	KB_WBUTTONS0,
602 	KB_WBUTTONS1,
603 	KB_WBUTTONS2,
604 	KB_WBUTTONS3,
605 	KB_WBUTTONS4,
606 	KB_WBUTTONS5,
607 	KB_WBUTTONS6,
608 	KB_WBUTTONS7,
609 	KB_MLOOK,
610 	KB_KICK,
611 	NUM_BUTTONS
612 } kbuttons_t;
613 
614 
615 void CL_ClearKeys( void );
616 
617 void CL_InitInput( void );
618 void CL_ShutdownInput( void );
619 void CL_SendCmd( void );
620 void CL_ClearState( void );
621 void CL_ReadPackets( void );
622 
623 void CL_WritePacket( void );
624 void IN_CenterView( void );
625 void IN_Notebook( void );
626 void IN_Help( void );
627 
628 //----(SA) salute
629 void IN_Salute( void );
630 //----(SA)
631 
632 void CL_VerifyCode( void );
633 
634 float CL_KeyState( kbutton_t *key );
635 int Key_StringToKeynum( char *str );
636 char *Key_KeynumToString( int keynum, qboolean bTranslate );
637 
638 //
639 // cl_parse.c
640 //
641 extern int cl_connectedToPureServer;
642 extern int cl_connectedToCheatServer;
643 
644 #ifdef USE_VOIP
645 void CL_Voip_f( void );
646 #endif
647 
648 void CL_SystemInfoChanged( void );
649 void CL_ParseServerMessage( msg_t *msg );
650 
651 //====================================================================
652 
653 void    CL_UpdateInfoPacket( netadr_t from );       // DHM - Nerve
654 
655 void    CL_ServerInfoPacket( netadr_t from, msg_t *msg );
656 void    CL_LocalServers_f( void );
657 void    CL_GlobalServers_f( void );
658 void    CL_FavoriteServers_f( void );
659 void    CL_Ping_f( void );
660 qboolean CL_UpdateVisiblePings_f( int source );
661 
662 
663 //
664 // console
665 //
666 void Con_DrawCharacter( int cx, int line, int num );
667 
668 void Con_CheckResize( void );
669 void Con_Init( void );
670 void Con_Shutdown( void );
671 void Con_Clear_f( void );
672 void Con_ToggleConsole_f( void );
673 void Con_DrawNotify( void );
674 void Con_ClearNotify( void );
675 void Con_RunConsole( void );
676 void Con_DrawConsole( void );
677 void Con_PageUp( void );
678 void Con_PageDown( void );
679 void Con_Top( void );
680 void Con_Bottom( void );
681 void Con_Close( void );
682 
683 void CL_LoadConsoleHistory( void );
684 void CL_SaveConsoleHistory( void );
685 
686 //
687 // cl_scrn.c
688 //
689 void    SCR_Init( void );
690 void    SCR_UpdateScreen( void );
691 
692 void	SCR_DebugGraph (float value);
693 
694 int     SCR_GetBigStringWidth( const char *str );   // returns in virtual 640x480 coordinates
695 
696 void    SCR_AdjustFrom640( float *x, float *y, float *w, float *h );
697 void    SCR_FillRect( float x, float y, float width, float height,
698 					  const float *color );
699 void    SCR_DrawPic( float x, float y, float width, float height, qhandle_t hShader );
700 void    SCR_DrawNamedPic( float x, float y, float width, float height, const char *picname );
701 
702 void	SCR_DrawBigString( int x, int y, const char *s, float alpha, qboolean noColorEscape );			// draws a string with embedded color control characters with fade
703 void	SCR_DrawBigStringColor( int x, int y, const char *s, vec4_t color, qboolean noColorEscape );	// ignores embedded color control characters
704 void	SCR_DrawSmallStringExt( int x, int y, const char *string, float *setColor, qboolean forceColor, qboolean noColorEscape );
705 void    SCR_DrawSmallChar( int x, int y, int ch );
706 
707 
708 //
709 // cl_cin.c
710 //
711 
712 void CL_PlayCinematic_f( void );
713 void SCR_DrawCinematic( void );
714 void SCR_RunCinematic( void );
715 void SCR_StopCinematic( void );
716 int CIN_PlayCinematic( const char *arg0, int xpos, int ypos, int width, int height, int bits );
717 e_status CIN_StopCinematic( int handle );
718 e_status CIN_RunCinematic( int handle );
719 void CIN_DrawCinematic( int handle );
720 void CIN_SetExtents( int handle, int x, int y, int w, int h );
721 void CIN_SetLooping( int handle, qboolean loop );
722 void CIN_UploadCinematic( int handle );
723 void CIN_CloseAllVideos( void );
724 
725 //
726 // cl_cgame.c
727 //
728 void CL_InitCGame( void );
729 void CL_ShutdownCGame( void );
730 qboolean CL_GameCommand( void );
731 void CL_CGameRendering( stereoFrame_t stereo );
732 void CL_SetCGameTime( void );
733 void CL_FirstSnapshot( void );
734 void CL_ShaderStateChanged( void );
735 void CL_UpdateLevelHunkUsage( void );
736 //
737 // cl_ui.c
738 //
739 void CL_InitUI( void );
740 void CL_ShutdownUI( void );
741 int Key_GetCatcher( void );
742 void Key_SetCatcher( int catcher );
743 void LAN_LoadCachedServers( void );
744 void LAN_SaveServersToCache( void );
745 
746 //
747 // cl_net_chan.c
748 //
749 void CL_Netchan_Transmit( netchan_t *chan, msg_t* msg ); //int length, const byte *data );
750 qboolean CL_Netchan_Process( netchan_t *chan, msg_t *msg );
751 
752 //
753 // cl_avi.c
754 //
755 qboolean CL_OpenAVIForWriting( const char *filename );
756 void CL_TakeVideoFrame( void );
757 void CL_WriteAVIVideoFrame( const byte *imageBuffer, int size );
758 void CL_WriteAVIAudioFrame( const byte *pcmBuffer, int size );
759 qboolean CL_CloseAVI( void );
760 qboolean CL_VideoRecording( void );
761 
762 //
763 // cl_main.c
764 //
765 void CL_WriteDemoMessage ( msg_t *msg, int headerBytes );
766 
767