#include	<stdio.h>
#include	<stdlib.h>
#include	<time.h>

#include	<egb.h>

#include	"tb.h"
#include	"tb_rand.h"
#include	"tb_scn.h"

int		tbTST_egb_clearScreen(void)
{
	int			sec, count = 0;

	tbSCN_clearTestFrame();
	{
		clock_t		clk, clkwk;

		EGB_viewport(EgbPtr,(char *)&TBcfg.frTest);
		sec = TBcfg.looptime;
		clk = clock() + sec * CLOCKS_PER_SEC;
		while ( CHKCLOCK(clk,clkwk) )
		{
			int		color;

			color = GETRNDCOL(count,TBscn.resoptr->maxcol);
			EGB_color(EgbPtr,1, color);
			EGB_partClearScreen(EgbPtr);
			++count;
		}
	}

	/* 結果表示	*/
	{
		int		count_per_sec;

		count_per_sec = (int)( (double)count / (double)sec );
		tb_list_putf(TBcfg.listctrl,
		   "\tEGB  clear screen       \t%5d\n",count_per_sec);
	}
	return (0);
}

typedef struct
{
	unsigned int		sel;
	unsigned int		off;
	unsigned int		xbyte;
	unsigned int		xb;
	unsigned int		yb;
	unsigned int		col0;
	unsigned int		col1;
	unsigned int		col2;
} VRAMFILLPKT;

extern void				_vramfill_dword(VRAMFILLPKT *);
extern void				_vramfill_dword24(VRAMFILLPKT *);
static unsigned int		get_color_dword(unsigned int color, int pixel);

#define	_FXBYTE(_x,_pixel)	(((_x) * (_pixel))>>3)

int		tbTST_dac_clearScreen(void)
{
	int			sec, count = 0;

	tbSCN_clearTestFrame();
	if ( TBscn.resoptr->pixel != 24 )
	{
		clock_t		clk, clkwk;

		sec = TBcfg.looptime;
		clk = clock() + sec * CLOCKS_PER_SEC;
		while ( CHKCLOCK(clk,clkwk) )
		{
			VRAMFILLPKT	pkt;
			int			color;

			color = GETRNDCOL(count,TBscn.resoptr->maxcol);

			pkt.sel   = TBscn.resoptr->sel;
			pkt.off   = TBscn.resoptr->off
			            + _FXBYTE(TBcfg.frTest.x1,TBscn.resoptr->pixel)
			            +   TBcfg.frTest.y1 * TBscn.resoptr->xbyte;
			pkt.xbyte = TBscn.resoptr->xbyte;
			pkt.xb    = _FXBYTE(TBcfg.frTest.x2 - TBcfg.frTest.x1 + 1,TBscn.resoptr->pixel) / 4;
			pkt.yb    =  TBcfg.frTest.y2 - TBcfg.frTest.y1 + 1;
			pkt.col0  = get_color_dword(color,TBscn.resoptr->pixel);

			_vramfill_dword(&pkt);

			++count;
		}
	} else
	{	/* 24ビットフルカラー専用	*/
		clock_t		clk, clkwk;

		sec = TBcfg.looptime;
		clk = clock() + sec * CLOCKS_PER_SEC;
		while ( CHKCLOCK(clk,clkwk) )
		{
			VRAMFILLPKT	pkt;
			int			color;

			color = GETRNDCOL(count,TBscn.resoptr->maxcol);

			pkt.sel   = TBscn.resoptr->sel;
			pkt.off   = TBscn.resoptr->off
			            + _FXBYTE(TBcfg.frTest.x1,TBscn.resoptr->pixel)
			            +   TBcfg.frTest.y1 * TBscn.resoptr->xbyte;
			pkt.xbyte = TBscn.resoptr->xbyte;
			pkt.xb    = _FXBYTE(TBcfg.frTest.x2 - TBcfg.frTest.x1 + 1,TBscn.resoptr->pixel) / (4*3);
			pkt.yb    =  TBcfg.frTest.y2 - TBcfg.frTest.y1 + 1;
			{
				unsigned char	   *dst;
				unsigned char		r, g, b;

				r =  color      & 0xFF;
				g = (color>> 8) & 0xFF;
				b = (color>>16) & 0xFF;
				dst = (unsigned char *)&pkt.col0;
				{
					*dst++ = r;	*dst++ = g;	*dst++ = b;
					*dst++ = r;	*dst++ = g;	*dst++ = b;
					*dst++ = r;	*dst++ = g;	*dst++ = b;
					*dst++ = r;	*dst++ = g;	*dst++ = b;
				}
			}
			_vramfill_dword24(&pkt);

			++count;
		}
	}

	/* 結果表示	*/
	{
		int		count_per_sec;

		count_per_sec = (int)( (double)count / (double)sec );
		tb_list_putf(TBcfg.listctrl,
		   "\tVRAM clear screen       \t%5d\n",count_per_sec);
	}
	return (0);
}

static unsigned int		get_color_dword(unsigned int color, int pixel)
{
	switch ( pixel )
	{
		case 4:
		{
			static unsigned int tbl[16] =
			{
				0x0000_0000, 0x1111_1111, 0x2222_2222, 0x3333_3333,
				0x4444_4444, 0x5555_5555, 0x6666_6666, 0x7777_7777,
				0x8888_8888, 0x9999_9999, 0xAAAA_AAAA, 0xBBBB_BBBB,
				0xCCCC_CCCC, 0xDDDD_DDDD, 0xEEEE_EEEE, 0xFFFF_FFFF,
			};
			return tbl[color];
		}
		case 8:
		{
			register unsigned int	n;

			n = color;
			n |= (n<<8);
			n |= (n<<16);
			return n;
		}
		case 16:
			return color | (color<<16);
		default:
			return color;
	}
}
