/*--------------------------------------------------------------------------*/
/*		Color 4000 test.													*/
/*--------------------------------------------------------------------------*/

//#define BIOS_INLINE

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
#include <stdio.h>
#include <sys/bios.h>
#include <sys/libwwc.h>
#include <sys/types.h>
#include <fcntl.h>
#include <machine.h>
#include <string.h>

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
#define	RGB_MAKE( rr, gg, bb)	( (rr << 8) | (gg << 4) | bb )

#define	BG_CHR(v,h,p,c)	( ((v) << 15) | ((h) << 14) | ((p)<<9) | (c) )

short bg_chr[32][32];
char font_data[512*0x20];

typedef struct {
	char	fname[64];
} LINE_W;

LINE_W	line[16];
struct stat statbuf;

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

extern	void Hpalet_set00( int );
extern	void Hpalet_set01( int );

static int usehblank,usevblank;
static int palfg;
static int palcnt;
static int exit_fg;

static void far hb_callback( );
static void far vb_callback( );

static char str[64];
void GetExt(char far *name_buf, char far *filename );


static char paletdt[ 0x1000 ];
static char blkpal[ 0x100 ];
static int palettbl[32];

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
// 割り込みハンドラ
int _asm_inline( char near *asm);
#define _CS _asm_inline("\tmov\tax,cs");
#define _DS _asm_inline("\tmov\tax,ds");

/*--------------------------------------------------------------------------*/
//		H-Blank割り込み初期化
/*--------------------------------------------------------------------------*/
void InitHblank( void (far *callback)( ) )
{
	static intvector_t hbl;

	usehblank = FALSE;
	hbl.callback = (void (near *)( ))FP_OFF(callback);
	palfg = 0;

	hbl.cs = _CS;
	hbl.ds = _DS;
	sys_interrupt_set_hook( SYS_INT_HBLANK_COUNTUP, &hbl, NULL);
	timer_enable( TIMER_HBLANK, TIMER_AUTOPRESET, 8);

	usehblank = TRUE;
}

/*--------------------------------------------------------------------------*/
//		V-Blank割り込み初期化
/*--------------------------------------------------------------------------*/
void InitVblank( void (far *callback)( ) )
{
	static intvector_t vbl;

	usevblank = FALSE;
	vbl.callback = (void (near *)( ))FP_OFF(callback);

	vbl.cs = _CS;
	vbl.ds = _DS;
	sys_interrupt_set_hook( SYS_INT_VBLANK_COUNTUP, &vbl, NULL);
	timer_enable( TIMER_VBLANK, TIMER_AUTOPRESET, 1);

	usevblank = TRUE;
}

/*--------------------------------------------------------------------------*/
//		H-Blank割り込み
/*--------------------------------------------------------------------------*/
void far hb_callback( )
{
	int		adrs;

	adrs = palettbl[ palcnt ];

	if (adrs){
		if (palfg == 0) Hpalet_set00( adrs );
		else Hpalet_set01( adrs );
	}

	palcnt++;
	palfg = 1-palfg;
}

/*--------------------------------------------------------------------------*/
//		H-Blank割り込みリセット
/*--------------------------------------------------------------------------*/
void HIntStop( )
{
	if (usehblank == FALSE) return;

	timer_disable( TIMER_HBLANK );
	sys_interrupt_reset_hook( SYS_INT_HBLANK_COUNTUP, NULL );
	usehblank = FALSE;
}

/*--------------------------------------------------------------------------*/
//		V-Blank割り込み終了
/*--------------------------------------------------------------------------*/
void VIntStop( )
{
	if (usevblank == FALSE) return;

	timer_disable( TIMER_VBLANK );
	sys_interrupt_reset_hook( SYS_INT_VBLANK_COUNTUP, NULL );
	usevblank = FALSE;
}

/*--------------------------------------------------------------------------*/
//			V-BLANK割り込み
/*--------------------------------------------------------------------------*/
void far vb_callback( )
{
	int	key;

	palfg = 0;
	palcnt = 2;

	// H-Blankストップ
	HIntStop( );

	// 最初のカラーを転送しておく。
	Hpalet_set00( (int)paletdt );
	Hpalet_set01( (int)paletdt + 0x100 );

	// H-Blankスタート
	InitHblank( hb_callback );

	key = key_press_check( );
	if (key & KEY_START){
		exit_fg = 1;
		return;
	}
}

/*--------------------------------------------------------------------------*/
//		main.
/*--------------------------------------------------------------------------*/
void main(int argc, char *argv[])
{
	int		x,y,c,pno,key;
	int		fd,i,nent,result,cnt;

	// テキストスクリーン初期化
	text_screen_init( );

	chdir("/rom0");
	nent = nument(NULL);

	y = 0;
	cnt = 0;
	for (i=0;i<nent;i++){
		result = getent(NULL,i,&statbuf);
		if (result == E_FS_SUCCESS){
			if (statbuf.count != -1){
				GetExt( str, statbuf.name );
				if (strcmp(str,"c2k") == 0){
					text_put_string( 2, y, statbuf.name);
					strcpy(line[cnt].fname, "/rom0/");
					strcat(line[cnt].fname, statbuf.name );
					cnt++;
					y++;
				}
			}
		}
	}

	y = 0;
	while(1){
		text_put_string(0,y,">");
		key = key_wait( );
		text_put_string(0,y," ");
		if (key & KEY_START) return;

		if (key & KEY_X1){
			y--;
			if (y<0) y = cnt-1;
		}

		if (key & KEY_X3){
			y++;
			if (y >= cnt) y = 0;
		}

		text_put_string(0,17, line[y].fname );


		if (key & KEY_A) break;
	}

	// スクリーン初期化
	display_control( DCM_SCR1 | DCM_BORDER_COLOR );

	// color初期化
	wwc_set_color_mode( COLOR_MODE_16PACKED );

	fd = open( line[y].fname, O_RDONLY ,0 );
	read( fd, (char far *)paletdt, 0x1000);

	read( fd, (char far *)font_data, 32 * 16 * 32);
	close(fd);

	// キャラセット
	wwc_font_set_colordata( 0, 32*16, font_data );

	// ブランクパレット
	for (i=0;i<0x100;i++) blkpal[i] = 0;

	// パレットテーブル
	for (i=0;i<32;i++){
		if (i<16) palettbl[i] = (int)paletdt + 0x100 * i;
		else if (i==16) palettbl[i] = (int)blkpal;
		else palettbl[i] = 0;
	}

	c = 0;
	for (y=0;y<32;y++){
		for (x=0;x<32;x++){
			if (y < 16){
				pno = (x / 4) + (y & 1) * 8;
				bg_chr[y][x] = BG_CHR(0,0, pno, c);
				c++;
			}
			else bg_chr[y][x] = 0;
		}
	}

	screen_set_char( 0, 0,0, 32, 16, bg_chr); 

	exit_fg = 0;

	// V-Blankスタート
	InitVblank( vb_callback );

	while(exit_fg==0);

	VIntStop( );
}

/*----------------------------------------------------------------------------*/
//		パスから拡張子を取り出して返す。
/*----------------------------------------------------------------------------*/
void GetExt(char far *name_buf, char far *filename )
{
	char far *name_pnt;
	char far *str;

	name_pnt = filename;

	// ディレクトリ名、スラッシュ、\マークをスキップ
	while ((str = strchr(name_pnt,'/'))!=NULL) { name_pnt = (++str);}

	// '.'を探してそれ以降を取得。なかったら NULLをセット。
	if ((str = strchr(name_pnt,'.'))!=NULL) strcpy(name_buf,++str);
	else name_buf[0] = '\0';
}

