/************************************************************************/
/* TITLE	: PACK.C						*/
/* Function	: Process the Given Pack of Symbols			*/ 
/*									*/
/* Project #	: JAGUAR CD+G						*/
/* Programmer	: Pradip K Fatehpuria	11/10/93			*/
/*									*/
/* COPYRIGHT(c) 1992,1993 Atari Computer Corporation			*/
/* UNATHORIZED REPRODUCTION, ADAPTATION, DISTRIBUTION, PERFORMANCE OR	*/
/* DISPLAY OF THIS COMPUTER PROGRAM OR THE ASSOCIATED AUDIOVISUAL WORK	*/
/* IS STRICTLY PROHIBITED.						*/
/* ALL RIGHTS RESERVED.							*/
/************************************************************************/

#include	"defs.h"
#include	"packbind.h"

/* -------------------------------------------------------------------- */

#define	PACK_ZERO		0x0000
#define	PACK_LINEGRAPHICS	0x0008
#define	PACK_TVGRAPHICS		0x0009
#define	PACK_EXTTVGRAPHICS	0x000A
#define	PACK_MIDI		0x0018
#define	PACK_USER		0x0038

/* -------------------------------------------------------------------- */

extern	unsigned short	*TvColTbl;

extern	unsigned short	CDGword[];

/* -------------------------------------------------------------------- */

short	BldObFlag = FALSE;

/* The Channel Number the user wants to view */

short	TvChnlNo = 0;		/* Current Channel Number */

/* Line Graphics Colour Table */

unsigned short	LnColTbl[] =
	{
	LINECOL_BLACK	,
	LINECOL_BLUE	,
	LINECOL_GREEN	,
	LINECOL_CYAN	,
	LINECOL_RED	,
	LINECOL_MAGENTA	,
	LINECOL_YELLOW	,
	LINECOL_WHITE		
	};

/* Current Pack being processed */

unsigned short	*CurPack;

/* What type of graphcs are being displayed ? */

short	CDGType = 0x0000;

/* Whether WRITE FONT (FALSE) or XOR FONT (TRUE) */

short	XORFlag = FALSE;

/* Scroll variable from LINE and Tv graphics modes */

short	lnPH = 0;		/* Horizontal Screen Pointer for LINE-Graphics */
short	lnPV = 0;		/* Vertical Screen Pointer for LINE-Graphics */

short	lnCOPH = 0;		/* Horizontal shift (left or right) in LINE-Graphics */
short	lnCOPV = 0;		/* Vertical shift (up or down) in LINE-Graphics */

short	tvPH = 0;		/* Horizontal Screen Pointer for TV-Graphics */
short	tvPV = 0;		/* Vertical Screen Pointer for TV-Graphics */

short	tvCOPH = 0;		/* Horizontal shift (left or right) in TV-Graphics */
short	tvCOPV = 0;		/* Vertical shift (up or down) in TV-Graphics */

/* Scroll Type and Preset Color for Scroll with Preset */

short	ScrlType = FALSE;	/* scroll with copy (TRUE) or preset (FALSE) */

unsigned short	ScrlColr = 0;	/* Background Colour in Font */

/* Border preset colours */

short	BrdColNo = 0;		/* Preset Border Colour */

/* number of packets processed */

long	PackCount = 0L;

/* -------------------------------------------------------------------- */

unsigned char	mess[200];

/* -------------------------------------------------------------------- */

static	unsigned short	TvColRed[ 256 ];
static	unsigned short	TvColGrn[ 256 ];
static	unsigned short	TvColBlu[ 256 ];
static	unsigned short	TransFac[ 256 ];

/************************************************************************/
/************************************************************************/

/* -----------------------------------------------------------------------
 * Process the four packets collected from the CD
 */

void	procsub()
{
register unsigned short	*pack;
register short	i;

	for (pack = CDGword, i = 0 ; i < 4 ; i++, pack += 24)
	{
		PackCount ++;
		procpack(pack);
	}
	return;
}

/************************************************************************/
/************************************************************************/

/* -----------------------------------------------------------------------
 * Process the current pack received from the CD+G player
 */

void	procpack(pack)
unsigned short	*pack;
{
static	unsigned short	func_items[] =
	{
	PACK_ZERO		,
	PACK_LINEGRAPHICS	,
	PACK_TVGRAPHICS		,
	PACK_EXTTVGRAPHICS	,
	PACK_MIDI		,
	PACK_USER		,
	-1
	};
static	void	(*func_table[])( void ) =
	{
	proczero	,
	procline	,
	proctv		,
	procextv	,
	procmidi	,
	procuser
	};

	CurPack = pack;
	procfunc(CurPack[0], func_items, func_table);
	return;
}

/* -----------------------------------------------------------------------
 */

void	procfunc(item, itemlist, funclist)
register unsigned short	item;
register unsigned short	itemlist[];
void	(*funclist[])( void );
{
register short	i;

	for (i = 0 ; itemlist[i] != -1 ; i++)
	{
		if (itemlist[i] != item)
			continue;

		(*funclist[i])();
		return;
	}
	return;
}

/************************************************************************/
/************************************************************************/

/* -----------------------------------------------------------------------
 * Load the CLUT Colour table given the starting position in table and 
 * the current pack.
 *
 * This routine loads a 12 bit colour composition as used in TV-grapics
 * and converts it to a 16 bit colour by extrapolating the intensity of
 * RGB components.
 *
 * 16 bit RGB color format : RRRR RBBB BBGG GGGG
 */

void	ldclut1(colno)
register short	colno;
{
register unsigned short	*pack = CurPack;
register unsigned short	color;
register unsigned short	newcol;
register short	i;

	for (i = 4 ; i < 20 ; i++)
	{
		color = pack[i++];

		TvColRed[ colno ] = ((color >> 1) & 0x001E);
		TvColGrn[ colno ] = ((color << 4) & 0x0020);

		color = pack[i];

		TvColGrn[ colno ] = ((color >> 2) & 0x000C);
		TvColBlu[ colno ] = ((color << 1) & 0x001E);

		newcol = 0x0000;
		newcol |= ((TvColRed[ colno ] << 11) & 0xF800);
		newcol |= ((TvColBlu[ colno ] <<  6) & 0x07C0);
		newcol |= ((TvColGrn[ colno ]      ) & 0x003F);

		TvColTbl[ colno ++ ] = newcol;
	}
	return;
}

/* -----------------------------------------------------------------------
 * Load the additional 2 bits of each colour given the starting position
 * in table and the current pack.
 *
 * This routine adds aditional low order bits to the colour table as
 * prepared above.
 */

void	ldclut2(colno)
register short	colno;
{
register unsigned short	*pack = CurPack;
register unsigned short	color;
register unsigned short	newcol;
register short	i;

	for (i = 4 ; i < 20 ; i++)
	{
		color = pack[i];

		TvColRed[ colno ] |= ((color >> 5) & 0x0001);
		TvColGrn[ colno ] |= ((color >> 2) & 0x0003);
		TvColBlu[ colno ] |= ((color >> 1) & 0x0001);

		newcol = 0x0000;
		newcol |= ((TvColRed[ colno ] << 11) & 0xF800);
		newcol |= ((TvColBlu[ colno ] <<  6) & 0x07C0);
		newcol |= ((TvColGrn[ colno ]      ) & 0x003F);

		TvColTbl[ colno ++ ] = newcol;
	}
	return;
}

/* -----------------------------------------------------------------------
 * Load the transparency factor for different color components and update
 * the colour table
 */

void	ldtrans()
{
register unsigned short	*pack = CurPack;
register unsigned short	factor;
register unsigned short	newcol;
register unsigned short	red, grn, blu;
register short	i;

	for (i = 0 ; i < 16 ; i++)
	{
		factor = pack[i+4];

		red = (TvColRed[i] & (31 - ((factor >> 1) & 0x001F)));
		grn = (TvColGrn[i] & (63 - ((factor     ) & 0x002F)));
		blu = (TvColBlu[i] & (31 - ((factor >> 1) & 0x001F)));

		newcol = 0x0000;
		newcol |= ((red << 11) & 0xF800);
		newcol |= ((grn <<  6) & 0x07C0);
		newcol |= ((blu      ) & 0x003F);

		TvColTbl[i] = newcol;
	}
	return;
}

/************************************************************************/
/*	END OF FILE							*/
/************************************************************************/

