/************************************************************************
 * TITLE:         CONVIDEO.S            				*
 * PROJECT:	  JAGUAR MC   						*
 * FUNCTION:      Console Video Driver 					*
 * PROGRAMMER:    Hans-Martin Krober					*
 * DATE:       	  12/95              					*
 *                         						*
 *            COPYRIGHT 1993,1994,1995 Atari U.S. Corporation           *
 *          UNATHORIZED REPRODUCTION, ADAPTATION, DISTRIBUTION,         *
 *          PERFORMANCE OR DISPLAY OF THIS COMPUTER PROGRAM OR          *
 *        THE ASSOCIATED AUDIOVISUAL WORK IS STRICTLY PROHIBITED.       *
 *                          ALL RIGHTS RESERVED.                        *
 *                         						*
 ************************************************************************/

#include "portab.h"
#include "blit.h"
#include "font.h"
#inculde "_vdi.h"
#inculde "scrndef.h"


#define SCREEN_W 320
#define WIDFLAG WID320		/* blitter flags corresponding to OBJWIDTH */
#define LINEY 12		/* number of pixels per line of characters */

/************************************************************************
 *									*
 *	EXTERNAL DATA							*	
 ***                                                                  ***/

EXTERN BYTE	v_screen[];		/* Main video screen buffer 	*/
EXTERN FNThead 	sysfnt[];		/* System font header		*


/************************************************************************
 *									*
 *	GLOBAL DATA							*	
 ***                                                                  ***/

GLOBAL BYTE cv_curs_x;			/* Console Driver X cursor pos	*/
GLOBAL BYTE cv_curs_y;			/* Console Driver Y cursor pos	*/
GLOBAL BYTE cv_buf[2];			/* Console Driver Oubuf buffer	*/

GLOBAL WORD gl_wchar;			/* Width of System Font Char	*/
GLOBAL WORD gl_hchar;			/* Height of System Font Char	*/


/************************************************************************
 *									*
 *	FUNCTIONS							*	
 ***                                                                  ***/


/*
 *	:v_init()
 *	Initialized the Video Interface Driver
 */

	GLOBAL WORD
v_init(VOID)
{
	v_handle 	= 0;
	v_scrn_id 	= 0
	return 0;
}

/*
 *	:v_crtvwk()
 *	Create a virtual workstation
 */

	GLOBAL WORD
v_crtvwk(name, screen, planes, width, height)
	BYTE	*name;
	BYTE	*screen;
	WORD	planes;
	WORD	width;
	WORD	height;
{
	SCREENDEF *s = &v_screen[v_scrn_id];

	if (v_scrn_id >= MAX_VWK)
		return FAILURE;

	s->name 	= name;
	s->devId	= v_scrn_id;
	s->planes	= planes;
	s->xRez		= width;
	s->yRez		= height;
	s->formId	= PIXPACKED;
	s->vidAdr	= screen;

	

	return v_scrn_id++;
}
	WORD
v_opnvwk(in, handle, out)
	WORD in[];
	WORD *handle;
	WORD out[];
{
	ATTRIBUTE *pwk;

	*handle = get_vdihandle();
	
	memcpy((BYTE*)&vdi_wrkst[handle], (BYTE*)vdi_romwrkst);


}


/*
 *	:vc_conout()
 *	Print a character on the screen
 */

	WORD
vc_conout(handle, c)
	WORD handle;
	WORD c;
{
	VWRKSTN p_vwk = &v_vwk[handle];

	switch (c) {
	case CR:
		p_vwk->vc_curs_x  = 0;
		p_vwk->vc_curs_y  += p_vwk->vc_hchar;
		break;
	default:
		p_vwk->vc_outbuf[0] = c;

		
		FNTstr(curs_x, curs_y, outbuf, 
		mscreen, PIXEL16|PITCH1|WIDFLAG, sysfnt, 0x1aff, 0 );

		curs_x += gl_wchar;

		if (curs_x > (cv_/6*6)) {
			curs_x  = 0;
			curs_y += gl_hchar;
		}
		break;
	}
}





	WORD
v_gtext(handle, x, y, txt)
	WORD handle;
	WORD x;
	WORD y;
	BYTE *txt;


int x, int y, char *_str, void *dest, long blitflags, FNThead *fnt, unsigned fgcolor, unsigned bgcolor )
{
	WORD bshift;		/* convert from character to pixel with this shift */
	WORD fwidth;		/* width for the first blit */
	WORD c;			/* character to be blitted */
	LONG count;		/* contents of blitter COUNT register */
	LONG a1pixel;		/* destination address (y,x) */
	LONG cmd;		/* contents of blitter CMD register */
	LONG bits;		/* flag bits for the blitter */
	WORD numblits;		/* number of blits to perform */
	UBYTE *charwidths;	/* points to table of character widths, for proportional fonts */
	UBYTE *str = (UBYTE *)txt;
	LONG bndbox;		/* bounding box of the string we just blitted */


	bitflags = PIXEL16|PITCH1|WIDFLAG;
	dest = mscreen;
	
#if 0
 	switch(fnt->type) {
	case 4: /* 8 bit per pixel, with palette */
		if ((blitflags & 0x38) == PIXEL16) {
			return FNTexpand(x, y, str, (unsigned short *)dest, blitflags, fnt, fgcolor);
		}
		/* else fall through */
	case 3:
		/* plain bitmap image; just blit it as a copy */
		return FNTcopy(x, y, str, dest, blitflags, fnt);
	case 2:
		/* proportional font: find the character width table */
		charwidths = ((unsigned char *)fnt->data)+fnt->res*(long)fnt->height*2;
		break;
	default:
		/* fixed width font; no character width table is necessary */
		charwidths = 0;
		break;
	}
#else
		charwidths = 0;
#endif	

	/* figure out how to access characters in the font */
	/* all characters must be on a byte boundary (hence the	
	   "+7" and "& ~7"). Characters wider than 8 bits will
	   require more than one blit, since bit to pixel expansion
	   doesn't work properly for > 8 pixels wide. (Actually, it
	   does work for multiples of 8, but we don't take advantage
	   of that here.)
	 */
#if 0
	switch(	(fnt->width+7) & ~7 ) {
#else
	switch(	(8+7) & ~7 ) {
#endif
		default: bshift = 0; numblits = 1; break;
		case 16: bshift = 1; numblits = 2; break;
		case 24:
		case 32:
			bshift = 2; numblits = 4; break;
	}

	/* for fixed width fonts, precalculate some blitter parameters
	 * if the width is > 8, we'll blit from 1-8 characters
	 * in the first blit, otherwise we'll do the whole
	 * thing on the first blit
	 */
#if 0
	if (!charwidths) {
		if (fnt->width > 8) {
			/* this weird expression gives 1-8 for the first blit */
			fwidth = 1+((fnt->width-1)&0x7);
		} else {
			fwidth = fnt->width;
		}
		count = (((long)fnt->height) << 16) | fwidth;
	}
#else
		fwidth = 8;
		count = (((long)8) << 16) | fwidth;		

#endif
	a1pixel = (((long)y) << 16L) | (unsigned)x;
	cmd = SRCENX|UPDA1|UPDA2|PATDSEL|BCOMPEN|BKGWREN;

	/*
	 * NOTE:
	 * in < 1 byte/pixel modes, we must shift the color
	 * around to get at least 8 bits of the color register
	 * filled.
	 * Also: in these modes we must enable DSTEN in order to
	 * read write just some of a byte's pixels.
	 */
	bits = blitflags & (PIXEL1|PIXEL2|PIXEL4|PIXEL8|PIXEL16);
	switch(bits) {
	case PIXEL1:
		if (fgcolor) fgcolor = 0xff;
		if (bgcolor) bgcolor = 0xff;
		cmd |= DSTEN;
		break;
	case PIXEL2:
		fgcolor = (fgcolor << 2) | fgcolor;
		bgcolor = (bgcolor << 2) | bgcolor;
		fgcolor = (fgcolor << 4) | fgcolor;
		bgcolor = (bgcolor << 4) | bgcolor;
		cmd |= DSTEN;
		break;
	case PIXEL4:
		fgcolor = (fgcolor << 4) | fgcolor;
		bgcolor = (bgcolor << 4) | bgcolor;
		cmd |= DSTEN;
		break;
	case PIXEL8:
		break;
	default:	/* only 16 bits; we don't support 32 */
		break;
	}

	/* set up the colors */
	*(volatile long *)B_PATD = fgcolor;
	if (bgcolor) {
		*(volatile long *)B_DSTD = bgcolor;
	} else {
		cmd |= DSTEN;
	}

	/* set up the blitter windows */
	/* for bit to pixel expansion, we read the pixels as bytes; this is quirky, but the way the
	 * blitter was designed (if we read the "normal" way, the expansion doesn't work in 1, 2, and
	 * 4 bit per pixel modes)
	 */
#if 0
	A2_BASE = (long)fnt->data;
#else
	A2_BASE = (long)font8x8;
#endif	
	A1_BASE = (long)dest;

#if 0
	A2_FLAGS = XADDPIX|divby8(fnt->blitflags)|PITCH1|PIXEL8;
#else
	A2_FLAGS = XADDPIX|divby8(0x5800)|PITCH1|PIXEL8;
#endif
	A1_FLAGS = XADDPIX|(blitflags & ~XADDINC);

	A2_STEP = 0x0001ffff;		/* the source step is always fixed */
#if 0
	bndbox = ((long)fnt->height) << 16;
#else
	bndbox = ((long)8) << 16;
#endif
	/* now blit it */
	while ( (c = *str++) != 0 ) {
		int blitcount;
#if 0
		if (c < fnt->firstchar || c > fnt->lastchar)
#else
		if (c < 0 || c > 255)
#endif
			c = 0;
		else
#if 0
			c -= fnt->firstchar;
#else
			c -= 0;
#endif

		/* for proportional width fonts, find the character width */
		if (charwidths) {
			fwidth = charwidths[c];
			blitcount = ((fwidth+7)&~7) >> 3;
			if (fwidth > 8) {
				/* this weird expression gives 1-8 for the first blit */
				fwidth = 1+((fwidth-1)&0x7);
			}
			count = (((long)fnt->height) << 16) | fwidth;

			/* for proportional fonts we may have to skip some blits
			 * (the character may have been padded on the left more than other
			 * characters in the font)
			 */
			c = c << bshift;
			if (numblits > blitcount) {
				c += (numblits-blitcount);
			}
			count = (((long)fnt->height) << 16) | fwidth;
		} else {
			blitcount = numblits;
			c = c << bshift;
		}

		A2_PIXEL = c;
		A1_PIXEL = a1pixel;
		B_COUNT = count;

		A1_STEP = 0x00010000L | ((-fwidth) & 0x0000ffffL);
		B_CMD = cmd;

		a1pixel += fwidth;
		bndbox += fwidth;

		if (blitcount > 1) {
			blitcount--;
			/* now blit the remaining 8xn blocks in the
			   character; all these blits will be 8 bits
			   wide
			 */
			c += 1;
		
			A1_STEP = 0x0001fff8L;

			while (blitcount > 0) {
				A2_PIXEL = c;
				A1_PIXEL = a1pixel;
#if 0
				B_COUNT = (((long)fnt->height) << 16) | 8;
#else
				B_COUNT = (((long)8) << 16) | 8;
#endif

				B_CMD = cmd;

				a1pixel += 8;
				c += 1;
				bndbox += 8;
				blitcount--;
			}
		}
	}
	return bndbox;
}

