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

		パズル「かさねがさね」

						画面

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

#include	"common.h"
#include	"kasane.h"
#include	"screen.h"
#include	"pad.h"


#define		LCD_COL(c0, c1, c2, c3, c4, c5, c6, c7)	\
					((c0) | ((c1) << 4) | ((c2) << 8) | ((c3) << 12)),\
					((c4) | ((c5) << 4) | ((c6) << 8) | ((c7) << 12))
														/* LCD階調 */
#define		PALET_COL(c0, c1, c2, c3)	\
					((c0) | ((c1) << 4) | ((c2) << 8) | ((c3) << 12))
														/* パレット */
#define		FONT_COL(c0, c1)	((c1) | ((c0) << 2))	/* フォント */


#define		FIELD_X		 2				/* 盤の位置 */
#define		FIELD_Y		 1
#define		TITLE_X		20				/* タイトル */
#define		TITLE_Y		 3
#define		KEY_X		20				/* キー操作表示位置 */
#define		KEY_Y		12


/*** キャラクタコード *******/
#define		CHR_SPACE		0x0800				/* 空白 */
#define		CHR_X_CHIP		0x100b				/* 横方向チップ */
#define		CHR_Y_CHIP		0x1206				/* 縦方向チップ */
#define		CHR_FRAME		0x1a08				/* 枠 */
#define		CHR_KEY			0x1c18				/* キー操作 */
#define		CHR_BACK		0x1428				/* 背景 */
#define		CHR_TITLE		0x1e48				/* タイトル */

#define		SPR_CUR_L		(0x0801 | CFM_SPR_UPPER)		/* カーソル */
#define		SPR_CUR_R		(0x0802 | CFM_SPR_UPPER)
#define		SPR_CUR_D		(0x0803 | CFM_SPR_UPPER)
#define		SPR_CUR_U		(0x0804 | CFM_SPR_UPPER)


static
u_int	lcd_color[8] = {0, 1, 3, 5, 8, 11, 13, 15};		/* 画面階調 */

static
u_int	palet_data[] = {				/* パレット */
			PALET_COL(3, 5, 6, 7),			/* 8 */
			PALET_COL(1, 3, 4, 5),
			PALET_COL(0, 1, 2, 3),
			PALET_COL(0, 0, 0, 0),

			PALET_COL(0, 1, 2, 3),			/* 12 */
			PALET_COL(0, 4, 5, 7),
			PALET_COL(0, 3, 5, 7),
			PALET_COL(0, 4, 5, 7)
		};

u_int		spr_no;						/* スプライト枚数 */
int			fade_flag;					/* 画面フェード状態 */
static int	fade_cnt;					/* 画面の明るさ */

static u_short	bg_buf[2][LEN*2][LEN*2];		/* ＢＧ設定用バッファ */


#define	set_sprite(code, x, y)	sprite_set_char_location(spr_no++, code, x, y)
												/* スプライト設定 */

/**************************
    フェードイン・アウト
 **************************/
static
void	set_fade(void)
{
	u_int far*	p;
	u_int	col[2];
	int		i, j;

	if ( fade_flag == 1 ) {					/* フェードイン */
		if ( ++fade_cnt >= FADE_COUNT ) {
			fade_flag = 0;
			fade_cnt = FADE_COUNT;
		}
	}
	else {									/* フェードアウト */
		if ( --fade_cnt <= 0 ) {
			fade_flag = 0;
			fade_cnt =0;
		}
	}
	p = lcd_color;							/* 画面階調 */
	for (i = 0; i < 2; i++) {
		col[i] = 0x0000;
		for (j = 0; j < 16; j += 4) {
			col[i] |= ((*p++)*fade_cnt/FADE_COUNT) << j;
		}
	}
	lcd_set_color(col[0], col[1]);			/* 画面階調設定 */
}

/******************
    システム同期
 ******************/
static
void	v_synch(void)
{
	rand();
	spr_no = 0;						/* スプライト枚数 */
	pad_synch();					/* パッド同期処理 */
	sys_wait(1);					/* 同期待ち */
	if ( fade_flag ) {
		set_fade();					/* フェードイン･アウト */
	}
}


/************************
    横チップ設定
		引数	y = 行
 ************************/
void	set_x_chip(int y)
{
	u_short far*	p;
	int		x;

	p = &bg_buf[0][y*2][0];						/* ＢＧ設定用バッファ */
	for (x = 0; x < x_chip[y].min; x++) {		/* 空白 */
		*(p + LEN*2) = CHR_SPACE;
		*p++         = CHR_SPACE;
	}
	*(p + LEN*2) = CHR_X_CHIP + 8;				/* 左端 */
	*p++         = CHR_X_CHIP;
	x++;
	for (; x < x_chip[y].max - 1; x++) {
		*(p + LEN*2) = CHR_X_CHIP + 9;			/* 間 */
		*p++         = CHR_X_CHIP + 1;
	}
	*(p + LEN*2) = CHR_X_CHIP + 10;				/* 右端 */
	*p++         = CHR_X_CHIP + 2;
	x++;
	for (; x < LEN*2; x++) {					/* 空白 */
		*(p + LEN*2) = CHR_SPACE;
		*p++         = CHR_SPACE;
	}
}

/************************
    縦チップ設定
		引数	x = 列
 ************************/
void	set_y_chip(int x)
{
	u_short far*	p;
	int		y;

	p = &bg_buf[1][0][x*2];						/* ＢＧ設定用バッファ */
	for (y = 0; y < y_chip[x].min; y++) {		/* 空白 */
		*p++ = CHR_SPACE;
		*p   = CHR_SPACE;
		p += LEN*2 - 1;
	}
	*p++ = CHR_Y_CHIP;							/* 上端 */
	*p   = CHR_Y_CHIP + 1;
	p += LEN*2 - 1;
	y++;
	for (; y < y_chip[x].max - 1; y++) {		/* 間 */
		*p++ = CHR_Y_CHIP + 8;
		*p   = CHR_Y_CHIP + 9;
		p += LEN*2 - 1;
	}
	*p++ = CHR_Y_CHIP + 16;						/* 下端 */
	*p   = CHR_Y_CHIP + 17;
	p += LEN*2 - 1;
	y++;
	for (; y < LEN*2; y++) {					/* 空白 */
		*p++ = CHR_SPACE;
		*p   = CHR_SPACE;
		p += LEN*2 - 1;
	}
}

/******************
    カーソル描画
 ******************/
static
void	draw_cursor(void)
{
	int		d;

	if ( cursor_flag < 0 ) {
		return;
	}
	d = cursor_flag ? 0 : 3;
	set_sprite(SPR_CUR_L, FIELD_X*8 - 8 + d,      FIELD_Y*8 + 4 + cursor_y*16);
	set_sprite(SPR_CUR_R, FIELD_X*8 + LEN*16 - d, FIELD_Y*8 + 4 + cursor_y*16);
	set_sprite(SPR_CUR_D, FIELD_X*8 + 4 + cursor_x*16, FIELD_Y*8 - 8 + d);
	set_sprite(SPR_CUR_U, FIELD_X*8 + 4 + cursor_x*16, FIELD_Y*8 + LEN*16 - d);
}

/**************
    画面描画
 **************/
void	draw_screen(void)
{
	static int	page = 0;

	v_synch();							/* 同期待ち */
	screen_set_char(SCREEN2, FIELD_X, FIELD_Y, LEN*2, LEN*2,
													&bg_buf[page][0][0]);
										/* チップ描画 */
	page ^= 0x01;
	draw_cursor();						/* カーソル描画 */
	sprite_set_range(0, spr_no);		/* スプライト表示数設定 */
}


/**************************************
    クリア後の入力待ち
		戻り値	 TRUE : ゲーム続行
				FALSE : ゲーム終了
 **************************************/
Bool	wait_clear(void)
{
	static int	t = 0;
	int		cnt;
	Bool	ret;

	cnt = 0;
	while ( cnt <= FADE_COUNT ) {
		draw_screen();								/* 画面描画 */
		screen_set_scroll(SCREEN1, t/2, 127 - t);	/* 背景スクロール */
		t = (t + 1) % 128;

		if ( cnt == 0 ) {
			if ( get_pad() & KEY_START ) {
				ret = FALSE;
				cnt = 1;
				fade_out();
			}
			else if ( get_push() & (KEY_A | KEY_B) ) {
				ret = TRUE;
				cnt = 1;
				fade_out();
			}
		}
		else {
			cnt++;
		}
	}
	return	ret;
}


/************************************
    背景描画
		引数	pat = パターン番号
 ************************************/
void	draw_back(u_int pat)
{
	int		i, j;

	pat = CHR_BACK + pat*4;						/* 背景パターンキャラクタ */
	for (i = 0; i < SCREEN_CHAR_HEIGHT; i++) {
		for (j = 0; j < SCREEN_CHAR_WIDTH; j++) {
			screen_fill_char(SCREEN1, j, i, 1, 1, pat + (j % 4) + (i % 4)*8);
												/* キャラクタ設定 */
		}
	}
}

/******************
    枠などの描画
 ******************/
static
void	draw_frame(void)
{
	u_short		code;
	int			x, y;

	screen_fill_char(SCREEN2, 0, 0, SCREEN_CHAR_WIDTH, SCREEN_CHAR_HEIGHT, CHR_SPACE);
													/* 画面クリア */

													/* 枠描画 */
	screen_fill_char(SCREEN2, FIELD_X - 1,      FIELD_Y - 1,     1, 1, CHR_FRAME);
	screen_fill_char(SCREEN2, FIELD_X + LEN*2 , FIELD_Y - 1,     1, 1, CHR_FRAME + 1);
	screen_fill_char(SCREEN2, FIELD_X - 1,      FIELD_Y + LEN*2, 1, 1, CHR_FRAME + 8);
	screen_fill_char(SCREEN2, FIELD_X + LEN*2 , FIELD_Y + LEN*2, 1, 1, CHR_FRAME + 9);
	screen_fill_char(SCREEN2, FIELD_X, FIELD_Y - 1,    LEN*2, 1, CHR_FRAME + 2);
	screen_fill_char(SCREEN2, FIELD_X, FIELD_Y +LEN*2, LEN*2, 1, CHR_FRAME + 2);
	screen_fill_char(SCREEN2, FIELD_X - 1,     FIELD_Y, 1, LEN*2, CHR_FRAME + 10);
	screen_fill_char(SCREEN2, FIELD_X + LEN*2, FIELD_Y, 1, LEN*2, CHR_FRAME + 10);

	code = CHR_TITLE;								/* タイトル */
	for (y = 0; y < 5; y++) {
		for (x = 0; x < 8; x++) {
			screen_fill_char(SCREEN2, TITLE_X + x, TITLE_Y + y, 1, 1, code++);
		}
	}

	code = CHR_KEY;									/* キー操作表示 */
	for (x = 0; x < 8; x++) {
		screen_fill_char(SCREEN2, KEY_X + x, KEY_Y,     1, 1, code);
		screen_fill_char(SCREEN2, KEY_X + x, KEY_Y + 2, 1, 1, code + 8);
		code++;
	}
}

/********************************
    画面初期化
		引数	res = リソース
		戻り値	次のリソース
 ********************************/
res_t far*	init_screen(res_t far* res)
{
	int		i;

	lcd_off();										/* 画面ＯＦＦ */

	display_control(DCM_SCR1 | DCM_SCR2 | DCM_SPR);	/* ディスプレイ設定 */
	screen_set_scroll(SCREEN1, 0, 0);				/* スクロール値初期化 */
	screen_set_scroll(SCREEN2, 0, 0);

	lcd_set_color(0x0000, 0x0000);					/* 画面階調初期化 */
	fade_flag = 0;
	fade_cnt = 0;

	font_set_colordata(0x0000,
			 ((res_image_t far*)res)->width*((res_image_t far*)res)->height,
									(char far*)res + sizeof(res_image_t));
													/* キャラクタ定義 */
	res = (res_t far*)((char far*)res + (res->size << 4));

	for (i = 0; i < sizeof(palet_data)/sizeof(u_int); i++) {
		palette_set_color(i + 8, palet_data[i]);	/* パレット設定 */
	}

	draw_frame();									/* 枠などの描画 */
	lcd_on();										/* 画面ＯＮ */

	return	res;
}

/*************** End of File ********************************************/