//-----------------------------------------------------------------------------
//
//  $Logfile:: /Source/ref.h                                                  $
// $Revision:: 2                                                              $
//   $Author:: Burgermac                                                      $
//     $Date:: 12/27/00 5:13 PM                                               $
//
// Copyright (C) 1998 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source is may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
// DESCRIPTION:
//

#ifndef __REF_H__
#define __REF_H__

#ifndef __QCOMMON_H__
#include "qcommon.h"
#endif

//FIXME this should be included in qcommon, but it was checked out
#include "sinmdl.h"

#define	MAX_DLIGHTS		32
#define	MAX_ENTITIES	256
#define	MAX_PARTICLES	4096
#define	MAX_LIGHTSTYLES	256
#define	MAX_TRIANGLES	512

#define POWERSUIT_SCALE		4.0F

#define SHELL_RED_COLOR		0xF2
#define SHELL_GREEN_COLOR	0xD0
#define SHELL_BLUE_COLOR	0xF3

#define SHELL_RG_COLOR		0xDC
#define SHELL_RB_COLOR		0x86
#define SHELL_BG_COLOR		0x78

#define SHELL_WHITE_COLOR	0xD7

typedef struct entity_s
{
	struct model_t		*model;			// opaque type outside refresh

	float	angles[3];

	/*
	** most recent data
	*/
	float	origin[3];		// also used as RF_BEAM's "from"
	int		frame;			// also used as RF_BEAM's diameter

	/*
	** previous data for lerping
	*/
	float	oldorigin[3];	// also used as RF_BEAM's "to"
	int		oldframe;

	/*
	** misc
	*/
	float	backlerp;				// 0.0 = current, 1.0 = old
	int		skinnum;					// also used as RF_BEAM's palette index

	int		lightstyle;				// for flashing entities
	float	alpha;					// ignore if RF_TRANSLUCENT isn't set

	struct image_s	*skin;			// NULL for inline skin
	struct image_s	*damageskin;
	int		flags;
	float			mat[3][3];
	int				parent;
	bone_t			bone;
	int				real_entity_number;
#ifdef _H2INC
	unsigned char	groups[MAX_MODEL_GROUPS];
#else
	byte			groups[MAX_MODEL_GROUPS];
#endif
	int				oldanim;
	int				anim;
	float			scale;
	float			color_r;
	float			color_g;
	float			color_b;
	int				radius;
	int				lightofs;
	int				gravaxis;
} entity_t;

#define ENTITY_FLAGS  68

typedef struct
{
	vec3_t	origin;
	vec3_t	color;
	float	intensity;
} dlight_t;

typedef struct
{
	vec3_t	origin;
	float	color[4];
	unsigned char	flags;
#ifdef _H2INC
	float    amdsize; // added variable size stuff
#else
	float    size; // added variable size stuff
#endif
} particle_t;

#define TRI_TWOSIDED	(1<<2)
#define TRI_MASKED		(1<<3)
#define TRI_ENVMAPPED	(1<<4)
#define TRI_WEAPONMODEL	(1<<5)

//
// TRI_VERT -> x,y,z,s,t,r,g,b
//
#define TRI_VERT_SIZE	8
#define TRI_MAX_VERTS	(3*4)

typedef struct
{
	vec3_t	origin;
	vec3_t	angles;
	void	*texture;
	float	alpha;
	int		flags;
	int		surftype;
	int		num_tris;
	float	verts[TRI_MAX_VERTS][TRI_VERT_SIZE];
} triangle_t;

typedef struct
{
	float		rgb[4];			// 0.0 - 2.0 with alpha
	float		white;			// highest of rgb
	int			rgbvalue;
} lightstyle_t;

typedef struct
{
#ifdef _H2INC
   int         x, y, AMD_width, height;// in virtual screen coordinates
#else
	int			x, y, width, height;// in virtual screen coordinates
#endif
	float		fov_x, fov_y;
	float		vieworg[3];
	float		viewangles[3];
	float		blend[4];			// rgba 0-1 full screen blend
	float		time;				// time is uesed to auto animate
	int			rdflags;			// RDF_UNDERWATER, etc

#ifdef _H2INC
   unsigned char *areabits;        // if not NULL, only areas with set bits will be drawn
#else
	byte		*areabits;			// if not NULL, only areas with set bits will be drawn
#endif

	lightstyle_t	*lightstyles;	// [MAX_LIGHTSTYLES]

	int			num_entities;
	entity_t	*entities;

	int			num_dlights;
	dlight_t	*dlights;

	int			num_particles;
	particle_t	*particles;

	int			num_triangles;
	triangle_t	**triangles;
	qboolean	paused;
	float		fovfactor;
} refdef_t;

#define SIN_API_VERSION 1
#define API_VERSION		(0x40 + SIN_API_VERSION)

//
// these are the functions exported by the refresh module
//
typedef struct
{
	// if api_version is different, the dll cannot be used
	int		api_version;

	// called when the library is loaded (0 : OK, -1 : fail)
	int	(*Init) (void *hinstance, void *wndproc);

	// called before the library is unloaded
	void	(*Shutdown) (void);

	// All data that will be used in a level should be
	// registered before rendering any frames to prevent disk hits,
	// but they can still be registered at a later time
	// if necessary.
	//
	// EndRegistration will free any remaining data that wasn't registered.
	// Any model_t or skin_s pointers from before the BeginRegistration
	// are no longer valid after EndRegistration.
	//
	// Skins and images need to be differentiated, because skins
	// are flood filled to eliminate mip map edge errors, and pics have
	// an implicit "pics/" prepended to the name. (a pic name that starts with a
	// slash will not use the "pics/" prefix or the ".pcx" postfix)
	void	(*BeginRegistration) (const char *map, csurface_t *surfaces);
	struct model_t *(*RegisterModel) (const char *name);
	struct image_s *(*RegisterSkin) (const char *name);
	struct image_s *(*RegisterPic) (const char *name);
	void	(*SetSky) (const char *name, float rotate, vec3_t axis);
	void	(*EndRegistration) (void);

	void	(*RenderFrame) (refdef_t *fd);

	void	(*DrawGetPicSize) (int *w, int *h, const char *name);	// will return 0 0 if not found
	void	(*DrawPic) (int x, int y, const char *name);
	void	(*DrawStretchPic) (int x, int y, int w, int h, const char *name);
	void	(*DrawChar) (int x, int y, int c);
	void	(*DrawTileClear) (int x, int y, int w, int h, const char *name);
	void	(*DrawFill) (int x, int y, int w, int h, float r, float g, float b);
	void	(*DrawFadeScreen) (float r, float g, float b, float a);
   //
   // this should clear the frame buffer in case the cinematic does letter box stuff
   //
	void	(*BeginCinematic) (void);
   //
   // this should restore anything setup by BeginCinematic
   //
	void	(*EndCinematic) (void);
   //
   // this should render to the frame buffer as directly as possible
   // it also performs resizing if necessary
   //
	void	(*DrawCinematicFrame) (int x, int y, int w, int h, int cols, int rows, int pitch, unsigned short *data);

	/*
	** video mode and refresh state management entry points
	*/
	void	(*CinematicSetPalette)( const unsigned char *palette);	// NULL = game palette
	void	(*BeginFrame)( float camera_separation );
	void	(*EndFrame) (void);

	void	(*AppActivate)( qboolean activate );

	// SIN model stuff
	int		(*SINMDL_GetDefHandle)( struct model_t * mdl );
	void	(*DrawChar3D) (float x, float y, int c, int rows, int cols, float r, float g, float b, float a);
	void	(*FlushChar3D) (float r, float g, float b, float a); /* FS */
	void	(*DrawPic3D) (float x, float y, const char *picn, float scalex, float scaley, float r, float g, float b, float a);
	void	(*DrawFill3D) (float x, float y, float w, float h, float r, float g, float b, float a);
	void	(*DrawAltFill3D) (float x, float y, float w, float h, float r, float g, float b, float a);
	void	(*DrawStretchPic3D) (float x, float y, float w, float h, const char *picn, float r, float g, float b, float a);
	void	(*DrawTilePic3D) (float x, float y, float w, float h, const char *picn, float r, float g, float b, float a);
	// SIN triangle stuff
	// returns actual count of tris
	int		(*TesselateModel)( entity_t * ent, triangle_t * tris, int max_tris, int min_size, int max_size, int flags,const vec3_t origin );
	// lightmap modification
	void	(*BurnLightmap)( vec3_t start, vec3_t dir, int amount );
	// numframes in entity
	int		(*GetNumFrames)( entity_t * ent );

#ifdef __A3D_GEOM
	void (*A3D_RenderGeometry) (void *pA3D, void *pGeom, void *pMat, void *pGeomStatus);
#endif
} refexport_t;

#ifndef _H2INC
//
// these are the functions imported by the refresh module
//
typedef struct
{
	void	(*Sys_Error) (int err_level, const char *str, ...) __fp_attribute__((__noreturn__, __format__(__printf__,2,3)));

	void	(*Cmd_AddCommand) (const char *name, void(*cmd)(void));
	void	(*Cmd_RemoveCommand) (const char *name);
	int		(*Cmd_Argc) (void);
	const char	*(*Cmd_Argv) (int i);
	void	(*Cmd_ExecuteText) (int exec_when, const char *text);

	void	(*Con_Printf) (int print_level, const char *str, ...) __fp_attribute__((__format__(__printf__,2,3)));
	void	(*SCR_CenterPrintf) (const char *str, ...) __fp_attribute__((__format__(__printf__,1,2)));

	// files will be memory mapped read only
	// the returned buffer may be part of a larger pak file,
	// or a discrete file from anywhere in the quake search path
	// a -1 return means the file does not exist
	// NULL can be passed for buf to just determine existance
	int		(*FS_LoadFile) (const char *name, void **buf);
	void	(*FS_FreeFile) (void *buf);

	// gamedir will be the current directory that generated
	// files should be stored to, ie: "f:\quake\id1"
	const char *(*FS_Gamedir) (void);
	const char *(*FS_Playerdir) (void);

	cvar_t	*(*Cvar_Get) (const char *name, const char *value, int flags);
	cvar_t	*(*Cvar_Set)( const char *name, const char *value );
	void	 (*Cvar_SetValue)( const char *name, float value );

	qboolean	(*Vid_GetModeInfo)( int *width, int *height, int mode );
	void		(*Vid_MenuInit)( void );
	void		(*Vid_NewWindow)( int width, int height );

	// SIN model stuff, have to put this here, because both
	// the client and the server need this info
	dsinanim_t		*(*SINMDL_GetAnim) ( int index );
	dsinbasemdl_t	*(*SINMDL_GetBaseModel) ( int index );
	dsinmdl_t		*(*SINMDL_GetDef) ( int index );
	void			(*SINMDL_FreeDef) ( int index );

	int				(*SINMDL_RegisterDef) ( const char * path );

	// This is to allow the renderer to call the client to process
	// the console output.
	void			(*CONSOLE_Process) (const char *name);

	debugline_t		**DebugLines;
	int				*numDebugLines;

	void			(*Cvar_SetDescription) (const char *var_name, const char *description); /* FS */
} refimport_t;
#endif


// this is the only function actually exported at the linker level
typedef	refexport_t	(*GetRefAPI_t) (refimport_t);

#endif // __QCOMMON_H__
