#include	<stdio.h>
#include	<stdlib.h>
#include	<time.h>

#include	<egb.h>

#include	"tb.h"
#include	"tb_scn.h"

void	   *EgbPtr = NULL;
TBSCN		TBscn;

typedef struct
{
	int		numPage;
	int		md[2];
} MODEPARA;

typedef struct
{
	int		numPage;
	int		pixel[2];
} COLORPARA;


/*************************************************************************
*	画面の初期化（CRTC設定）
*************************************************************************/

int		tbSCN_initCrtc(int pixel, int flagHR)
{
	int				handle, numPage;
	RESOLUTION		resobuf[2];

	if ( EgbPtr == NULL )
	{
		if ( (EgbPtr = CALLOC(1,EgbWorkSize)) == NULL )
			return (-1);
		EGB_init(EgbPtr, EgbWorkSize );
	} else
	{
		int				page;

		EGB_displayPage(EgbPtr,1,0);
		for ( page = 0; page < TBscn.numPage; ++page )
		{
			EGB_writePage(EgbPtr,page);
			EGB_color(EgbPtr,1,0);
			EGB_clearScreen(EgbPtr);
		}
	}

	if ( !flagHR )
	{	/* 中解像度	*/
		MODEPARA		mode;

		switch ( pixel )
		{
			case  4:
				mode.numPage   = 2;
				mode.md[0]     = 3;
				mode.md[1]     = 3;
				break;

			case  8:
				mode.numPage   =  1;
				mode.md[0]     = 12;
				break;

			case 16:
				mode.numPage   =  2;
				mode.md[0]     = 10;
				mode.md[1]     = 10;
				break;

			default:
				return (-1);
		}
		numPage = mode.numPage;
		handle = EGB_getResolutionMode(&mode,resobuf);
		if ( handle < 0 )
			return (-1);
	} else
	{	/* 高解像度（フルカラーを含む）	*/
		const int		video = 0;
		COLORPARA		color;

		switch ( pixel )
		{
			case  4:
				color.numPage  = 2;
				color.pixel[0] = 4;
				color.pixel[1] = 4;
				handle = EGB_getResolutionMax(video, &color, resobuf);
				if ( handle < 0 || resobuf[0].dx <= 640 || resobuf[0].dy <= 480 )
					return (-1);
				break;

			case  8:
				color.numPage  = 1;
				color.pixel[0] = 8;
				handle = EGB_getResolutionMax(video, &color, resobuf);
				if ( handle < 0 || resobuf[0].dx <= 640 || resobuf[0].dy <= 480 )
					return (-1);
				break;

			case 16:
				color.numPage  = 2;
				color.pixel[0] = 16;
				color.pixel[1] = 16;
				handle = EGB_getResolutionMax(video, &color, resobuf);
				if ( handle < 0 || resobuf[0].dx <= 320 || resobuf[0].dy <= 240 )
					return (-1);
				break;

			case 24:
				color.numPage  = 1;
				color.pixel[0] = 24;
				handle = EGB_getResolutionMax(video, &color, resobuf);
				if ( handle < 0 )
					return (-1);
				break;
			default:
				return (-1);
		}
		numPage = color.numPage;
	}
	if ( EGB_resolutionHandle( EgbPtr , 0,  handle ) < 0 )
		return (-1);
	EGB_displayPage(EgbPtr,1,0);
	{
		clock_t		clk, clkwk;

		clk = clock() + CLOCKS_PER_SEC * 20 / 100;
		while ( CHKCLOCK(clk,clkwk) )
			;
	}

	/* 解像度情報の設定	*/
	{
		int				page;
		RESOLUTION	   *reso;;

		TBscn.numPage = numPage;
		for ( page = 0; page < numPage; ++page )
		{
			reso = resobuf + page;

			TBscn.reso[page].pixel   =                reso->pixel  ;
			TBscn.reso[page].maxcol  = (1 << ((reso->pixel == 16) ? 15 : reso->pixel)) - 1;
			TBscn.reso[page].sel     =                reso->segment;
			TBscn.reso[page].off     = (unsigned int) reso->offset ;
			TBscn.reso[page].xbyte   =                reso->byte   ;

			TBscn.reso[page].v.xs    =                reso->vx     ;
			TBscn.reso[page].v.ys    =                reso->vy     ;
			TBscn.reso[page].v.fr.x1 = 0;
			TBscn.reso[page].v.fr.y1 = 0;
			TBscn.reso[page].v.fr.x2 = reso->vx - 1;
			TBscn.reso[page].v.fr.y2 = reso->vy - 1;

			TBscn.reso[page].d.xs    =                reso->dx     ;
			TBscn.reso[page].d.ys    =                reso->dy     ;
			TBscn.reso[page].d.fr.x1 = 0;
			TBscn.reso[page].d.fr.y1 = 0;
			TBscn.reso[page].d.fr.x2 = reso->dx - 1;
			TBscn.reso[page].d.fr.y2 = reso->dy - 1;

			if ( pixel == 16 )
			{	/* 32,768色画面は画面の拡大率を設定する	*/
				EGB_writePage(EgbPtr,page);
				EGB_displayStart(EgbPtr, 0, 0, 0);	/* 表示開始位置		*/
				EGB_displayStart(EgbPtr, 1, 0, 0);	/* 仮想画面中の移動	*/
				EGB_displayStart(EgbPtr, 2, 2, 2);	/* 画面の拡大		*/
				EGB_displayStart(EgbPtr, 3, reso->dx, reso->dy);
													/* 画面の大きさ		*/
			}
		}

		TBscn.page = 0;
		TBscn.resoptr = TBscn.reso + TBscn.page;
		EGB_writePage(EgbPtr, TBscn.page);
	}
	EGB_displayPage(EgbPtr,0,3);

	return (0);
}


/*************************************************************************
*	テストフレームの描画
*************************************************************************/

#define	ADJX32(_n)	((((_n) + 15) / 32) * 32)	/* 32の倍数に	*/

int		tbSCN_setTestFrame(void)
{
	if ( TBcfg.flags & TBFLAGS_MAXSCREEN )
	{	/* 最大解像度でテスト	*/
		TBcfg.xsTest    = TBscn.resoptr->d.xs;
		TBcfg.ysTest    = TBscn.resoptr->d.ys;
	}
	{
		TBcfg.frTest.x1 = ADJX32( (TBscn.resoptr->d.fr.x1 + TBscn.resoptr->d.fr.x2 - TBcfg.xsTest) / 2 );
		TBcfg.frTest.y1 =         (TBscn.resoptr->d.fr.y1 + TBscn.resoptr->d.fr.y2 - TBcfg.ysTest) / 2;
		TBcfg.frTest.x2 = TBcfg.frTest.x1 + TBcfg.xsTest - 1;
		TBcfg.frTest.y2 = TBcfg.frTest.y1 + TBcfg.ysTest - 1;
	}

/*	EGB_viewport(EgbPtr,(char *)&TBcfg.frTest);*/
	EGB_color(EgbPtr,1,0);
	EGB_clearScreen(EgbPtr);

	{
		struct
		{
			short	x1, y1, x2, y2;
		} para;

		EGB_paintMode( EgbPtr, 0x002 );
		EGB_writeMode( EgbPtr, PSET );

		para.x1 = TBcfg.frTest.x1 - 1;
		para.y1 = TBcfg.frTest.y1 - 1;
		para.x2 = TBcfg.frTest.x2 + 1;
		para.y2 = TBcfg.frTest.y2 + 1;
		EGB_color( EgbPtr, 0, 0);
		EGB_rectangle( EgbPtr, (char *)&para );

		para.x1 = TBcfg.frTest.x1 - 2;
		para.y1 = TBcfg.frTest.y1 - 2;
		para.x2 = TBcfg.frTest.x2 + 2;
		para.y2 = TBcfg.frTest.y2 + 2;
		EGB_color( EgbPtr, 0, TBscn.resoptr->maxcol);
		EGB_rectangle( EgbPtr, (char *)&para );
	}

	return (0);
}

void		tbSCN_clearTestFrame(void)
{
	EGB_viewport(EgbPtr,(char *)&TBcfg.frTest);
	EGB_color(EgbPtr,1,0);
	EGB_partClearScreen(EgbPtr);
}
