/*
client.h - primary header for client
Copyright (C) 2009 Uncle Mike

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
*/

#ifndef CLIENT_H
#define CLIENT_H

#include "mathlib.h"
#include "cdll_int.h"
#include "menu_int.h"
#include "mobility_int.h"
#include "cl_entity.h"
#include "com_model.h"
#include "mod_local.h"
#include "pm_defs.h"
#include "pm_movevars.h"
#include "render_api.h"
#include "cdll_exp.h"
#include "screenfade.h"
#include "protocol.h"
#include "netchan.h"
#include "net_api.h"
#include "world.h"
#include "qfont.h"
#include "voice.h"

#define MAX_DEMOS		32
#define MAX_MOVIES		8
#define MAX_CDTRACKS	32
#define MAX_IMAGES		256	// SpriteTextures
#define MAX_EFRAGS		4096
#define MAX_REQUESTS	32

// screenshot types
#define VID_SCREENSHOT	0
#define VID_LEVELSHOT	1
#define VID_MINISHOT	2
#define VID_MAPSHOT		3	// special case for overview layer
#define VID_SNAPSHOT	4	// save screenshot into root dir and no gamma correction

//=============================================================================
typedef struct netbandwithgraph_s
{
	unsigned short client;
	unsigned short players;
	unsigned short entities; // entities bytes, except for players
	unsigned short tentities; // temp entities
	unsigned short sound;
	unsigned short event;
	unsigned short usr;
	unsigned short msgbytes;
	//unsigned short voicebytes; // TODO: enable it someday...
} netbandwidthgraph_t;

typedef struct frame_s
{
	// received from server
	double		receivedtime;	// time message was received, or -1
	double		latency;
	double		time;		// server timestamp

	clientdata_t	client;		// local client private data
	entity_state_t	playerstate[MAX_CLIENTS];
	weapon_data_t	weapondata[64];

	int		num_entities;
	int		first_entity;	// into the circular cl_packet_entities[]

	qboolean		valid;		// cleared if delta parsing was invalid
	netbandwidthgraph_t graphdata;
} frame_t;

typedef struct runcmd_s
{
	double		senttime;
	double		receivedtime;
	float		frame_lerp;

	usercmd_t		cmd;

	qboolean		processedfuncs;
	qboolean		heldback;
	int		sendsize;
} runcmd_t;

#define CMD_BACKUP		MULTIPLAYER_BACKUP	// allow a lot of command backups for very fast systems
#define CMD_MASK		(CMD_BACKUP - 1)

#define CL_UPDATE_MASK	(CL_UPDATE_BACKUP - 1)
extern int CL_UPDATE_BACKUP;

#define INVALID_HANDLE	0xFFFF		// for XashXT cache system

// used by SetUpPlayerPrediction
typedef struct
{
	int movetype;
	int solid;
	int usehull;
	qboolean active;
	vec3_t origin;
	vec3_t angles;
} predicted_player_t;

typedef struct
{
	vec3_t  origin;		// generated by CL_PredictMovement
	vec3_t  viewofs;
	vec3_t  velocity;
	vec3_t  punchangle;
	vec3_t  origins[CMD_BACKUP];
	vec3_t  error;
	vec3_t  lastorigin;
	double  correction_time;
	int     viewmodel;
	int     onground;
	int     waterlevel;
	int     usehull;
	int     moving;
	int     lastground;
} cl_predicted_data_t; // data we got from prediction system

// the client_t structure is wiped completely at every
// server map change
typedef struct
{
	int		timeoutcount;

	int		servercount;		// server identification for prespawns
	int		validsequence;		// this is the sequence number of the last good
						// world snapshot/update we got.  If this is 0, we can't
						// render a frame yet
	int		parsecount;		// server message counter
	int		parsecountmod;		// modulo with network window
									
	qboolean		video_prepped;		// false if on new level or new ref dll
	qboolean		audio_prepped;		// false if on new level or new snd dll
	qboolean		force_refdef;		// vid has changed, so we can't use a paused refdef

	int		delta_sequence;		// acknowledged sequence number

	double		mtime[2];			// the timestamp of the last two messages

	int		last_command_ack;
	int		last_incoming_sequence;

	qboolean		force_send_usercmd;
	qboolean		thirdperson;
	qboolean		background;		// not real game, just a background

	uint		checksum;			// for catching cheater maps

	client_data_t	data;			// some clientdata holds

	frame_t		frame;			// received from server
	frame_t		frames[MULTIPLAYER_BACKUP];	// alloced on svc_serverdata
	runcmd_t		commands[MULTIPLAYER_BACKUP];	// each mesage will send several old cmds
	local_state_t	predict[MULTIPLAYER_BACKUP];	// local client state

	double		time;			// this is the time value that the client
						// is rendering at.  always <= cls.realtime
						// a lerp point for other data
	double		oldtime;			// previous cl.time, time-oldtime is used
						// to decay light values and smooth step ups

	float		lerpFrac;			// interpolation value
	float		lerpBack;			// invert interpolation value
	ref_params_t	refdef;			// shared refdef

	char		serverinfo[MAX_INFO_STRING];
	player_info_t	players[MAX_CLIENTS];
	event_state_t	events;

	// predicting stuff
	cl_predicted_data_t predicted;  // generated from CL_PredictMovement

	// server state information
	int		playernum;
	int		maxclients;
	int		movemessages;
	int		num_custombeams;			// server beams count

	char		model_precache[MAX_MODELS][CS_SIZE];
	char		sound_precache[MAX_SOUNDS][CS_SIZE];
	char		event_precache[MAX_EVENTS][CS_SIZE];
	lightstyle_t	lightstyles[MAX_LIGHTSTYLES];

	int		sound_index[MAX_SOUNDS];
	int		decal_index[MAX_DECALS];

	cl_entity_t	*world;
	model_t		*worldmodel;			// pointer to world
	float weaponstarttime;
	int weaponseq;
	int     scr_fov;
	model_t *playermodels[32];
	predicted_player_t predicted_players[MAX_CLIENTS];
	int lostpackets;					// count lost packets and show dialog in menu
} client_t;

/*
==================================================================

the client_static_t structure is persistant through an arbitrary number
of server connections

==================================================================
*/
typedef enum
{
	ca_uninitialized = 0,
	ca_disconnected, 	// not talking to a server
	ca_connecting,	// sending request packets to the server
	ca_connected,	// netchan_t established, waiting for svc_serverdata
	ca_active,	// game views should be displayed
	ca_cinematic,	// playing a cinematic, not connected to a server
} connstate_t;

typedef enum
{
	scrshot_inactive,
	scrshot_normal,	// in-game screenshot
	scrshot_snapshot,	// in-game snapshot
	scrshot_plaque,  	// levelshot
	scrshot_savegame,	// saveshot
	scrshot_demoshot,	// for demos preview
	scrshot_envshot,	// cubemap view
	scrshot_skyshot,	// skybox view
	scrshot_mapshot	// overview layer
} scrshot_t;

// client screen state
typedef enum
{
	CL_LOADING = 1,	// draw loading progress-bar
	CL_ACTIVE,	// draw normal hud
	CL_PAUSED,	// pause when active
	CL_CHANGELEVEL,	// draw 'loading' during changelevel
} scrstate_t;

typedef struct
{
	char		name[32];
	int		number;	// svc_ number
	int		size;	// if size == -1, size come from first byte after svcnum
	pfnUserMsgHook	func;	// user-defined function	
} cl_user_message_t;

typedef void (*pfnEventHook)( event_args_t *args );

typedef struct
{
	char		name[CS_SIZE];
	word		index;	// event index
	pfnEventHook	func;	// user-defined function
} cl_user_event_t;

typedef struct
{
	int		hFontTexture;		// handle to texture
	wrect_t		fontRc[NUM_GLYPHS];		// rectangles
	byte		charWidths[NUM_GLYPHS];
	int		charHeight;
	qboolean		valid;			// all rectangles are valid
} cl_font_t;

typedef struct
{
	// temp handle
	const model_t	*pSprite;			// pointer to current SpriteTexture

	// scissor test
	int		scissor_x;
	int		scissor_y;
	int		scissor_width;
	int		scissor_height;
	qboolean		scissor_test;
	qboolean		adjust_size;		// allow to adjust scale for fonts

	int		cullMode;			// override CULL FACE from TriAPI

	// holds text color
	rgba_t		textColor;
	rgba_t		spriteColor;
	rgba_t		triColor;

	byte		gammaTable[256];
} client_draw_t;

typedef struct
{
	int		gl_texturenum;	// this is a real texnum

	// scissor test
	int		scissor_x;
	int		scissor_y;
	int		scissor_width;
	int		scissor_height;
	qboolean		scissor_test;

	// holds text color
	rgba_t		textColor;
	rgba_t		picColor;
} gameui_draw_t;

typedef struct
{
	// centerprint stuff
	float		time;
	int		y, lines;
	char		message[2048];
	int		totalWidth;
	int		totalHeight;
} center_print_t;

typedef struct
{
	float		time;
	float		duration;
	float		amplitude;
	float		frequency;
	float		next_shake;
	vec3_t		offset;
	float		angle;
	vec3_t		applied_offset;
	float		applied_angle;
} screen_shake_t;

typedef struct
{
	struct mstudiotex_s	*ptexture;	// array of textures with local copy of remapped textures
	short		numtextures;	// textures count
	short		topcolor;		// cached value
	short		bottomcolor;	// cached value
	model_t		*model;		// for catch model changes
} remap_info_t;

typedef struct
{
	net_response_t		resp;
	double			timeout;
	double			timesend;	// time when request was sent
	net_api_response_func_t	pfnFunc;
	int			flags;	// FNETAPI_MULTIPLE_RESPONSE etc
} net_request_t;

// new versions of client dlls have a single export with all callbacks
typedef void (*CL_EXPORT_FUNCS)( void *pv );

typedef struct
{
	void                 *hInstance;                 // pointer to client.dll
	cldll_func_t         dllFuncs;                   // dll exported funcs
	render_interface_t   drawFuncs;                  // custom renderer support
	mempool_t            *mempool;                   // client edicts pool
	string               mapname;                    // map name
	string               maptitle;                   // display map title
	string               itemspath;                  // path to items description for auto-complete func

	cl_entity_t          *entities;                  // dynamically allocated entity array
	cl_entity_t          *static_entities;           // dynamically allocated static entity array
	remap_info_t         **remap_info;               // store local copy of all remap textures for each entity

	int                  maxEntities;
	int                  maxRemapInfos;              // maxEntities + cl.viewEnt; also used for catch entcount
	int                  numStatics;                 // actual static entity count

	// movement values from server
	movevars_t           movevars;
	movevars_t           oldmovevars;
	playermove_t         *pmove;                     // pmove state

	//int                old_trace_hull;             // used by PM_Push\Pop state
	qboolean             pushed;                     // used by PM_Push\Pop state
	int                  oldviscount;                // used by PM_Push\Pop state
	int                  oldphyscount;               // used by PM_Push\Pop state

	vec3_t               player_mins[MAX_MAP_HULLS]; // 4 hulls allowed
	vec3_t               player_maxs[MAX_MAP_HULLS]; // 4 hulls allowed

	cl_user_message_t    msg[MAX_USER_MESSAGES];     // keep static to avoid fragment memory
	cl_user_event_t      *events[MAX_EVENTS];

	string               cdtracks[MAX_CDTRACKS];     // 32 cd-tracks read from cdaudio.txt

	model_t              sprites[MAX_IMAGES];        // client spritetextures
	int                  load_sequence;              // for unloading unneeded sprites

	client_draw_t        ds;                         // draw2d stuff (hud, weaponmenu etc)
	screenfade_t         fade;                       // screen fade
	screen_shake_t       shake;                      // screen shake
	center_print_t       centerPrint;                // centerprint variables
	SCREENINFO           scrInfo;                    // actual screen info
	ref_overview_t       overView;                   // overView params
	rgb_t                palette[256];               // palette used for particle colors

	client_textmessage_t *titles;                    // title messages, not network messages
	int                  numTitles;

	net_request_t        net_requests[MAX_REQUESTS]; // no reason to keep more

	efrag_t              *free_efrags;               // linked efrags
	cl_entity_t          viewent;                    // viewmodel
} clgame_static_t;

typedef struct
{
	void		*hInstance;		// pointer to client.dll
	UI_FUNCTIONS	dllFuncs;			// dll exported funcs
	mempool_t		*mempool;			// client edicts pool

	cl_entity_t	playermodel;		// uiPlayerSetup drawing model
	player_info_t	playerinfo;		// local playerinfo

	gameui_draw_t	ds;			// draw2d stuff (menu images)
	GAMEINFO		gameInfo;			// current gameInfo
	GAMEINFO		*modsInfo[MAX_MODS];	// simplified gameInfo for MainUI

	ui_globalvars_t	*globals;

	qboolean		drawLogo;			// set to TRUE if logo.avi missed or corrupted
	int		logo_xres;
	int		logo_yres;
	float		logo_length;
	qboolean	use_text_api;
} menu_static_t;

typedef struct
{
	connstate_t	state;
	qboolean		initialized;
	qboolean		changelevel;		// during changelevel
	qboolean		changedemo;		// during changedemo

	// screen rendering information
	float		disable_screen;		// showing loading plaque between levels
						// or changing rendering dlls
						// if time gets > 30 seconds ahead, break it
	int		disable_servercount;	// when we receive a frame and cl.servercount
						// > cls.disable_servercount, clear disable_screen

	qboolean		draw_changelevel;		// draw changelevel image 'Loading...'

	keydest_t		key_dest;

	mempool_t		*mempool;			// client premamnent pool: edicts etc
	
	int		framecount;
	int		quakePort;		// a 16 bit value that allows quake servers
						// to work around address translating routers
						// g-cont. this port allow many copies of engine in multiplayer game
	// connection information
	string		servername;		// name of server from original connect
	netadr_t    serveradr;     // for checking some connectionless packets
	double		connect_time;		// for connection retransmits


	sizebuf_t		datagram;			// unreliable stuff. gets sent in CL_Move about cl_cmdrate times per second.
	byte		datagram_buf[NET_MAX_PAYLOAD];

	netchan_t		netchan;
	int		serverProtocol;		// in case we are doing some kind of version hack
	int		challenge;		// from the server to use for connecting

	float		packet_loss;
	double		packet_loss_recalc_time;

	float		nextcmdtime;		// when can we send the next command packet?                
	int		lastoutgoingcommand;	// sequence number of last outgoing command

	// internal images
	int		oldParticleImage;
	int		fillImage;		// used for emulate FillRGBA to avoid wrong draw-sort
	int		particleImage;		// built-in particle and sparks image
	int		pauseIcon;		// draw 'paused' when game in-pause
	int		loadingBar;		// 'loading' progress bar
	int		glowShell;		// for renderFxGlowShell
	int		tileImage;		// for draw any areas not covered by the refresh
	HSPRITE		hChromeSprite;		// this is a really HudSprite handle, not texnum!
	cl_font_t		creditsFont;		// shared creditsfont

	float		latency;			// rolling average of frame latencey (receivedtime - senttime) values.

	int		num_client_entities;	// cl.maxclients * CL_UPDATE_BACKUP * MAX_PACKET_ENTITIES
	int		next_client_entities;	// next client_entity to use
	entity_state_t	*packet_entities;		// [num_client_entities]

	scrshot_t		scrshot_request;		// request for screen shot
	scrshot_t		scrshot_action;		// in-action
	vec3_t envshot_vieworg;		// envshot position
	int		envshot_viewsize;		// override cvar
	qboolean		envshot_disable_vis;	// disable VIS on server while makes an envshots
	string		shotname;
	// demo loop control
	int		demonum;			// -1 = don't play demos
	int		olddemonum;		// restore playing
	string		demos[MAX_DEMOS];		// when not playing

	// movie playlist
	int		movienum;
	string		movies[MAX_MOVIES];

	// demo recording info must be here, so it isn't clearing on level change
	qboolean		demorecording;
	qboolean		demoplayback;
	qboolean		demowaiting;		// don't record until a non-delta message is received
	qboolean		timedemo;
	string		demoname;			// for demo looping
	double		demotime;			// recording time

	file_t		*demofile;
	file_t		*demoheader;		// contain demo startup info in case we record a demo on this level
	qboolean keybind_changed;
	qboolean splitcompress;			// enabled only on server->client netchan
	qboolean need_save_config;
	qboolean internetservers_wait;	// internetservers is waiting for dns request
	qboolean internetservers_pending;	// internetservers is waiting for dns request
} client_static_t;


	// download info
extern int		downloadcount;
extern int		downloadfileid;

extern client_t		cl;
extern client_static_t	cls;
extern clgame_static_t	clgame;
extern menu_static_t	menu;

//
// cvars
//
extern convar_t *r_oldparticles;
extern convar_t	*cl_predict;
extern convar_t	*cl_showfps;
extern convar_t *cl_showpos;
extern convar_t	*cl_envshot_size;
extern convar_t	*cl_timeout;
extern convar_t	*cl_charset;
extern convar_t	*cl_nodelta;
extern convar_t	*cl_interp;
extern convar_t	*cl_showerror;
extern convar_t *cl_nosmooth;
extern convar_t *cl_smoothtime;
extern convar_t	*cl_crosshair;
extern convar_t	*cl_testlights;
extern convar_t	*cl_solid_players;
extern convar_t	*cl_idealpitchscale;
extern convar_t	*cl_allow_levelshots;
extern convar_t	*cl_allow_fragment;
extern convar_t	*cl_lightstyle_lerping;
extern convar_t	*cl_draw_particles;
extern convar_t	*cl_levelshot_name;
extern convar_t	*cl_draw_beams;
extern convar_t *cl_cmdrate;
extern convar_t	*cl_lw;
extern convar_t *cl_trace_events;
extern convar_t *cl_trace_stufftext;
extern convar_t *cl_trace_messages;
extern convar_t	*cl_sprite_nearest;
extern convar_t *cl_updaterate;
extern convar_t *r_bmodelinterp;
extern convar_t *hud_scale;
extern convar_t	*scr_centertime;
extern convar_t	*scr_viewsize;
extern convar_t	*scr_download;
extern convar_t	*scr_loading;
extern convar_t	*scr_dark;	// start from dark
extern convar_t	*userinfo;
extern convar_t	*hltv;
extern convar_t *m_ignore;
extern convar_t *hud_utf8;
extern convar_t *vgui_utf8;
extern convar_t *ui_renderworld;


//=============================================================================

void CL_SetLightstyle( int style, const char* s, float f );
void CL_RunLightStyles( void );

void CL_AddEntities( void );
void CL_DecayLights( void );

//=================================================

//
// cl_cmds.c
//
void CL_Quit_f( void );
void CL_ScreenShot_f( void );
void CL_SnapShot_f( void );
void CL_PlayCDTrack_f( void );
void CL_MP3Command_f( void );
void CL_EnvShot_f( void );
void CL_SkyShot_f( void );
void CL_SaveShot_f( void );
void CL_DemoShot_f( void );
void CL_LevelShot_f( void );
void CL_SetSky_f( void );
void SCR_Viewpos_f( void );
void SCR_TimeRefresh_f( void );

//
// cl_main.c
//
void CL_Init( void );
void CL_SendCommand( void );
void CL_Disconnect_f( void );
void CL_ProcessFile( qboolean successfully_received, const char *filename );
void CL_WriteUsercmd( sizebuf_t *msg, int from, int to );
void CL_GetChallengePacket( void );
void CL_PingServers_f( void );
void CL_ClearState( void );

//
// cl_demo.c
//
void CL_StartupDemoHeader( void );
void CL_DrawDemoRecording( void );
void CL_WriteDemoUserCmd( int cmdnumber );
void CL_WriteDemoMessage( qboolean startup, int start, sizebuf_t *msg );
void CL_WriteDemoUserMessage( const byte *buffer, size_t size );
qboolean CL_DemoReadMessage( byte *buffer, size_t *length );
void CL_WriteDemoJumpTime( void );
void CL_CloseDemoHeader( void );
void CL_StopPlayback( void );
void CL_StopRecord( void );
void CL_PlayDemo_f( void );
void CL_StartDemos_f( void );
void CL_Demos_f( void );
void CL_DeleteDemo_f( void );
void CL_Record_f( void );
void CL_Stop_f( void );
void CL_FreeDemo( void );

//
// cl_events.c
//
void CL_ParseEvent( sizebuf_t *msg );
void CL_ParseReliableEvent( sizebuf_t *msg );
void CL_SetEventIndex( const char *szEvName, int ev_index );
void CL_QueueEvent( int flags, int index, float delay, event_args_t *args );
void CL_PlaybackEvent( int flags, const edict_t *pInvoker, word eventindex, float delay, const vec3_t origin,
                       const vec3_t angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 );
void CL_RegisterEvent( int lastnum, const char *szEvName, pfnEventHook func );
word CL_EventIndex( const char *name );
const char *CL_IndexEvent( word index );
void CL_ResetEvent( event_info_t *ei );
void CL_FireEvents( void );

//
// cl_game.c
//
void CL_UnloadProgs( void );
qboolean CL_LoadProgs( const char *name );
void CL_ParseUserMessage( sizebuf_t *msg, int svc_num );
void CL_LinkUserMessage( char *pszName, const int svc_num, int iSize );
void CL_ParseTextMessage( sizebuf_t *msg );
void CL_DrawHUD( int state );
void CL_GetMousePosition ( int *x, int *y );
void CL_InitEdicts( void );
void CL_FreeEdicts( void );
void CL_ClearWorld( void );
void CL_DrawCenterPrint( void );
void CL_FreeEntity( cl_entity_t *pEdict );
void CL_CenterPrint( const char *text, float y );
void CL_TextMessageParse( byte *pMemFile, int fileSize );
client_textmessage_t *CL_TextMessageGet( const char *pName );
int pfnDecalIndexFromName( const char *szDecalName );
int pfnIndexFromTrace( struct pmtrace_s *pTrace );
int CL_FindModelIndex( const char *m );
HSPRITE pfnSPR_Load( const char *szPicName );
HSPRITE pfnSPR_LoadExt( const char *szPicName, uint texFlags );
void SPR_AdjustSize( float *x, float *y, float *w, float *h );
void TextAdjustSize( int *x, int *y, int *w, int *h );
void TextAdjustSizeReverse( int *x, int *y, int *w, int *h );
void PicAdjustSize( float *x, float *y, float *w, float *h );
void CL_PlayerTrace( const vec3_t start, const vec3_t end, int traceFlags, int ignore_pe, pmtrace_t *tr );
void CL_PlayerTraceExt( const vec3_t start, const vec3_t end, int traceFlags, int (*pfnIgnore)( physent_t *pe ), pmtrace_t *tr );
void CL_SetTraceHull( int hull );
void CL_FillRGBA( int x, int y, int width, int height, int r, int g, int b, int a );
void CL_FillRGBABlend( int x, int y, int width, int height, int r, int g, int b, int a );


_inline cl_entity_t *CL_EDICT_NUM( int n )
{
	if( !clgame.entities )
		return NULL;
	if(( n >= 0 ) && ( n < clgame.maxEntities ))
		return clgame.entities + n;

	Host_Error( "CL_EDICT_NUM: bad number %i\n", n );
	return NULL;	
}

extern rgba_t g_color_table[8];

//
// cl_parse.c
//
void CL_ParseServerMessage( sizebuf_t *msg );
void CL_ParseTempEntity( sizebuf_t *msg );
qboolean CL_DispatchUserMessage( const char *pszName, int iSize, void *pbuf );
int CL_ParseScreenShake( const char *pszName, int iSize, void *pbuf );
int CL_ParseScreenFade( const char *pszName, int iSize, void *pbuf );

//
// cl_scrn.c
//
void SCR_VidInit( void );
void SCR_TileClear( void );
void SCR_AddDirtyPoint( int x, int y );
void SCR_InstallParticlePalette( void );
void SCR_EndLoadingPlaque( void );
void SCR_RebuildGammaTable( void );
void SCR_RegisterTextures( void );
void SCR_LoadCreditsFont( void );
void SCR_MakeScreenShot( void );
void SCR_MakeLevelShot( void );
void SCR_NetSpeeds( void );
void SCR_RSpeeds( void );
void SCR_DrawFPS( void );
void SCR_DrawPos( void );

//
// cl_netgraph.c
//
void SCR_DrawNetGraph( void );
void CL_InitNetgraph( void );

//
// cl_view.c
//

void V_Init (void);
void V_Shutdown( void );
qboolean V_PreRender( void );
void V_PostRender( void );
void V_RenderView( void );
void V_SetupOverviewState( void );
void V_ProcessOverviewCmds( usercmd_t *cmd );
void V_MergeOverviewRefdef( ref_params_t *fd );
void V_ProcessShowTexturesCmds( usercmd_t *cmd );
void V_WriteOverviewScript( void );

//
// cl_pmove.c
//
void CL_SetSolidEntities( void );
void CL_SetSolidPlayers( int playernum );
void CL_InitClientMove( void );
void CL_PredictMovement( void );
void CL_CheckPredictionError( void );
qboolean CL_IsPredicted( void );
int CL_TruePointContents( const vec3_t p );
int CL_PointContents( const vec3_t p );
int CL_WaterEntity( const vec3_t rgflPos );
cl_entity_t *CL_GetWaterEntity( const vec3_t rgflPos );
void CL_SetupPMove( playermove_t *pmove, const local_state_t *from, const usercmd_t *ucmd, const qboolean runfuncs, const double time );
pmtrace_t CL_TraceLine( const vec3_t start, const vec3_t end, int flags );
void CL_ClearPhysEnts( void );
void CL_PushPMStates( void );
void CL_PopPMStates( void );
void CL_SetUpPlayerPrediction( int dopred, int bIncludeLocalClient );

//
// cl_studio.c
//
void CL_InitStudioAPI( void );

//
// cl_frame.c
//
typedef struct channel_s  channel_t;
int CL_ParsePacketEntities( sizebuf_t *msg, qboolean delta );
qboolean CL_AddVisibleEntity( cl_entity_t *ent, int entityType );
void CL_UpdateStudioVars( cl_entity_t *ent, entity_state_t *newstate, qboolean noInterp );
qboolean CL_GetEntitySpatialization( channel_t *ch );
qboolean CL_UpdateEntityFields( cl_entity_t *ent );
void CL_ComputePlayerOrigin( cl_entity_t* ent );
qboolean CL_IsPlayerIndex( int idx );
void CL_SetIdealPitch( void );

//
// cl_remap.c
//
remap_info_t *CL_GetRemapInfoForEntity( cl_entity_t *e );
void CL_AllocRemapInfo( int topcolor, int bottomcolor );
void CL_FreeRemapInfo( remap_info_t *info );
void R_StudioSetRemapColors( int top, int bottom );
void CL_UpdateRemapInfo( int topcolor, int bottomcolor );
void CL_ClearAllRemaps( void );

//
// cl_tent.c
//
int CL_AddEntity( int entityType, cl_entity_t *pEnt );
void CL_WeaponAnim( int iAnim, int body );
void CL_WeaponAnim2( int iAnim, int body, float framerate );
void CL_ClearEffects( void );
void CL_ClearEfrags( void );
void CL_TestLights( void );
void CL_DrawParticlesExternal( const vec3_t vieworg, const vec3_t fwd, const vec3_t rt, const vec3_t up, uint clipFlags );
void CL_FireCustomDecal( int textureIndex, int entityIndex, int modelIndex, const vec3_t pos, int flags, float scale );
void CL_DecalShoot( int textureIndex, int entityIndex, int modelIndex, const vec3_t pos, int flags );
void CL_PlayerDecal( int textureIndex, int entityIndex, const vec3_t pos );
void CL_InitParticles( void );
void CL_ClearParticles( void );
void CL_FreeParticles( void );
void CL_DrawParticles( void );
void CL_InitTempEnts( void );
void CL_ClearTempEnts( void );
void CL_FreeTempEnts( void );
void CL_AddTempEnts( void );
void CL_InitViewBeams( void );
void CL_ClearViewBeams( void );
void CL_FreeViewBeams( void );
void CL_DrawBeams( int fTrans );
void CL_AddCustomBeam( cl_entity_t *pEnvBeam );
void CL_KillDeadBeams( cl_entity_t *pDeadEntity );
void CL_ParseViewBeam( sizebuf_t *msg, int beamType );
void CL_RegisterMuzzleFlashes( void );
void CL_ReadPointFile_f( void );
void CL_ReadLineFile_f( void );

//
// console.c
//
extern convar_t *con_fontsize;
qboolean Con_Visible( void );
void Con_Init( void );
void Con_VidInit( void );
void Con_ToggleConsole_f( void );
void Con_ClearNotify( void );
void Con_DrawDebug( void );
void Con_RunConsole( void );
void Con_DrawConsole( void );
void Con_DrawVersion( void );
int Con_UtfProcessChar( int in );
int Con_UtfProcessCharForce( int in );
int Con_UtfMoveLeft( char *str, int pos );
int Con_UtfMoveRight( char *str, int pos, int length );
void Con_DrawStringLen( const char *pText, int *length, int *height );
int Con_DrawString( int x, int y, const char *string, rgba_t setColor );
int Con_DrawCharacter( int x, int y, int number, rgba_t color );
void Con_DrawCharacterLen( int number, int *width, int *height );
void Con_DefaultColor( int r, int g, int b );
void Con_InvalidateFonts( void );
void Con_SetFont( int fontNum );
void Con_CharEvent( int key );
void Con_RestoreFont( void );
void Key_Console( int key );
void Key_Message( int key );
void Con_Close( void );
void Con_PageUp( int lines );
void Con_PageDown( int lines );
void Con_Bottom( void );

//
// s_main.c
//
void S_StreamRawSamples( int samples, int rate, int width, int channels, const byte *data );
void S_StartBackgroundTrack( const char *intro, const char *loop, int position );
void S_StopBackgroundTrack( void );
void S_StreamSetPause( int pause );
void S_StartStreaming( void );
void S_StopStreaming( void );
void S_BeginRegistration( void );
sound_t S_RegisterSound( const char *sample );
void S_EndRegistration( void );
void S_RestoreSound( const vec3_t pos, int ent, int chan, sound_t handle, float fvol, float attn, int pitch, int flags, double sample, double end, int wordIndex );
void S_StartSound( vec3_t pos, int ent, int chan, sound_t sfx, float vol, float attn, int pitch, int flags );
void S_AmbientSound( const vec3_t pos, int ent, sound_t handle, float fvol, float attn, int pitch, int flags );
void S_FadeClientVolume( float fadePercent, float fadeOutSeconds, float holdTime, float fadeInSeconds );
void S_FadeMusicVolume( float fadePercent );
void S_StartLocalSound( const char *name, float volume, qboolean reliable );
void S_RenderFrame( struct ref_params_s *fd );
void S_ExtraUpdate( void );

//
// cl_menu.c
//
void UI_UnloadProgs( void );
qboolean UI_LoadProgs( void );
void UI_UpdateMenu( float realtime );
void UI_KeyEvent( int key, qboolean down );
void UI_MouseMove( int x, int y );
void UI_SetActiveMenu( qboolean fActive );
void UI_AddServerToList( netadr_t adr, const char *info );
void UI_GetCursorPos( int *pos_x, int *pos_y );
void UI_SetCursorPos( int pos_x, int pos_y );
void UI_ShowCursor( qboolean show );
qboolean UI_CreditsActive( void );
void UI_CharEvent( int key );
qboolean UI_MouseInRect( void );
qboolean UI_IsVisible( void );
void UI_AddTouchButtonToList( const char *name, const char *texture, const char *command, unsigned char *color, int flags );
int UI_HandleMessageMode_f(void);
void pfnPIC_Set( HIMAGE hPic, int r, int g, int b, int a );
void pfnPIC_Draw( int x, int y, int width, int height, const wrect_t *prc );
void pfnPIC_DrawTrans( int x, int y, int width, int height, const wrect_t *prc );
void pfnPIC_DrawHoles( int x, int y, int width, int height, const wrect_t *prc );
void pfnPIC_DrawAdditive( int x, int y, int width, int height, const wrect_t *prc );

//
// cl_mobile.c
//
void Mobile_Init( void );
void Mobile_Shutdown( void );

//
// cl_video.c
//
void SCR_InitCinematic( void );
void SCR_FreeCinematic( void );
qboolean SCR_PlayCinematic( const char *name );
qboolean SCR_DrawCinematic( void );
qboolean SCR_NextMovie( void );
void SCR_RunCinematic( void );
void SCR_StopCinematic( void );
void CL_PlayVideo_f( void );

#endif//CLIENT_H
