/* *****************************************************************************
	Title : font.c
***************************************************************************** */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/bios.h>

#include "font.h"


/* ★グローバル変数		*/
FNTMNG		FntMng;									/* ﾌｫﾝﾄ管理構造体			*/
FNTDFLUSH	FntDFlush[ FNT_DISP_CHRMAX];			/* ﾌｫﾝﾄ表示内容ﾃﾞｰﾀ			*/
char		FntData[ 16];							/* ﾌｫﾝﾄﾃﾞｰﾀ：8Byte=1文字	*/


/* ******************************************************************************
　関　　数	：FntInit
　内　　容	：ASCIIフォント関連の初期化
　表　　記	：void	FntInit( void)
　引　　数	：−
　返　　値	：−
　コメント	：−
　履　　歴	：Ver 1.00	2000/11/18		K.Kimura		初版
****************************************************************************** */
void	FntInit( void)
{
	static	short		i;


	/* ///  ●フォント管理構造体の初期化●  /// */
	memset( &FntMng, 0, sizeof( FNTMNG));
	memset( FntDFlush, 0, ( sizeof( FNTDFLUSH) * FNT_DISP_CHRMAX));
	memset( FntData, 0, ( sizeof( char) * 16));

	FntMng.regNum = 0;
	FntMng.fntAdr = NULL;

	for (i = 0; i < FNT_FONT_NUM; i++)
		FntMng.regChr[ i] = 0;

	for (i = 0; i < (FNT_FONT_NUM / 16); i++)
		FntMng.setFlag[ i] = 0;

	/* ///  モノクロフォント・カラー設定  /// */
	palette_set_color( FNT_PALETTE_NUM, FNT_PALETTE); 
	font_set_color( 0x0003);

}


/* ******************************************************************************
　関　　数	：FntSetFontAddress
　内　　容	：ASCIIフォント関連の初期化
　表　　記	：void	FntSetFontAddress( void far *adr)
　引　　数	：void far	*adr : ﾌｫﾝﾄﾃﾞｰﾀへの先頭ｱﾄﾞﾚｽ
　返　　値	：−
　コメント	：ＡＳＣＩＩフォントデータ（８ｘ８ １２８キャラクタ数限定）の
			：データアドレスを設定します。
			：オリジナルフォントを使用する場合は、最初にアドレスを設定しないと
			：フォントの使用できません。
			：
　履　　歴	：Ver 1.00	2000/11/18		K.Kimura		初版
****************************************************************************** */
void	FntSetFontAddress( char far *adr)
{
	FntMng.fntAdr = adr;							/* ｱﾄﾞﾚｽ設定				*/
}


/* ******************************************************************************
　関　　数	：FntSetRegChrNum
　内　　容	：フォント登録キャラクタ番号の設定
　表　　記	：void	FntSetRegChrNum( u_short st_chr, u_short chr_num)
　引　　数	：u_short	st_chr	: ﾌｫﾝﾄ登録開始ｷｬﾗｸﾀ番号
			：u_short	chr_num	: ﾌｫﾝﾄ登録最大数
　返　　値	：−
　コメント	：フォントデータ登録開始キャラクタ番号と、
　			：そのサイズ（登録最大文字数）を設定します。
			：キャラクタ番号が、いわゆるＶＲＡＭに相当するため、
			：登録されるキャラクタ番号には細心の注意を払う必要があります。
			：
　履　　歴	：Ver 1.00	2000/11/18		K.Kimura		初版
****************************************************************************** */
void	FntSetRegChrNum( u_short st_chr, u_short chr_num)
{
	FntMng.regChrStart	= st_chr;					/* 登録開始ｷｬﾗｸﾀ番号		*/
	FntMng.regChrNum	= chr_num;					/* 登録最大文字数			*/
}


/* ******************************************************************************
　関　　数	：FntPrint
　内　　容	：文字列登録
　表　　記	：void	FntPrint( int scr, u_short x, u_short y, char *str)
　引　　数	：int		scr  : 表示ｽｸﾘｰﾝ画面選択
			：u_short	x,y	 : 画面座標（各0〜31）
			：char		*str : 表示文字列
			：u_short	vm	 : 0b010	.. 水平反転
			：				   0b100	.. 垂直反転
			：				   0b001	.. 縦方向加算
　返　　値	：−
　コメント	：表示ＡＳＣＩＩ文字列の登録を行います。
			：実際の表示は、FntFlush() で行われます。
			：
　履　　歴	：Ver 1.00	2000/11/20		K.Kimura		初版
　			：Ver 2.00	2001/01/09		K.Kimura		ﾊﾟﾚｯﾄ対応
****************************************************************************** */
void	FntPrint( int scr, u_short x, u_short y, char *str, u_short vm, u_short pal)
{
	static	int		i;
	static	u_short	idx, bit;
	static	short	dx, dy;
	static	int		strnum, rnum;
	FNTDFLUSH		*p;


	p = FntDFlush;
	strnum = strlen( str);
	rnum = FntMng.regNum;

	dx = dy = 0;

	if (vm & 0x0001) {
		dy++;
	} else {
		dx++;
	}

	for (i = 0; i < strnum; i++)
	{
		if (rnum < FNT_DISP_CHRMAX)
		{
			/* 表示用として登録可能 */

			p[ rnum].flag = (((y << 5) | x) | (scr << 12) | (vm << 13));
			p[ rnum].code = str[ i];						/* 表示文字情報の格納		*/
			p[ rnum].pal  = (pal << 9);						/* ﾊﾟﾚｯﾄ番号				*/

			idx = (str[ i] / 16);
			bit = (str[ i] % 16);
			FntMng.setFlag[ idx] |= (0x0001 << bit);		/* 登録必要な文字			*/

			x += dx;
			y += dy;

			rnum++;
		}
	}

	FntMng.regNum = rnum;
	FntMng.flag |= FNT_FLAG_DRAW;

}


/* ******************************************************************************
　関　　数	：FntFlush
　内　　容	：文字列表示
　表　　記	：void	FntFlush( void)
　引　　数	：−
　返　　値	：−
　コメント	：表示ＡＳＣＩＩ文字列の表示を行います。
			：FntPrint で表示すべき全ての文字登録を行った後にコールします。
			：１Ｖで一回のコールとなります。
			：
　履　　歴	：Ver 1.00	2000/11/20		K.Kimura		初版
			：Ver 2.00	2000/12/18		K.Kimura		登録文字列に対応
****************************************************************************** */
void	FntFlush( void)
{
	static	int			i;
	static	u_short		idx, bit;
	static	int			num;
	static	char far	*dp;


	/* ///  ■描画必要？チェック■  /// */
	if ((FntMng.flag & FNT_FLAG_DRAW) == 0)
		return;

	num = 0;

	/* ///  ■文字の登録■  /// */
	for (i = 0; i < FNT_FONT_NUM; i++)
	{
		idx = ( i / 16);
		bit = ( i % 16);

		if ((FntMng.setFlag[ idx] & (0x0001 << bit)) == 0)
			continue;

		if (num < FNT_REG_CHRMAX)
		{
			/* ///  ＶＲＡＭ設定  /// */
			if (FntMng.fntAdr == NULL)
			{
				/* 登録文字列から（画面モードは、横画面専用） */
				text_get_fontdata( i, FntData);
				font_set_monodata(( FntMng.regChrStart + num), 1, FntData);
			}
			else
			{
				/* メモリ常駐データから（画面モードは、データ次第） */
				dp = FntMng.fntAdr + ( 16 * i);
				memcpy( FntData, dp, 16); 
				font_set_colordata(( FntMng.regChrStart + num), 1, FntData);
			}

			FntMng.regChr[ i] = ( FntMng.regChrStart + num);
			num++;
		}
		else
		{
			break;										/* 登録文字数ｵｰﾊﾞｰ		*/
		}
	}

	if (num > 0)
	{
		fntDispStringAll();								/* 全ての登録ﾌｫﾝﾄを表示	*/
	}

	/* 次回用に初期化 */
	FntMng.regNum = 0;
	FntMng.flag &= ~FNT_FLAG_DRAW;						/* 描画ﾌﾗｸﾞ初期化		*/

	for (i = 0; i < (FNT_FONT_NUM / 16); i++)
		FntMng.setFlag[ i] = 0;

	for (i = 0; i < FNT_FONT_NUM; i++)
		FntMng.regChr[ i] = 0;

}


/* ******************************************************************************
　関　　数	：fntDispStringAll
　内　　容	：登録文字列の表示
　表　　記	：void	fntDispStringAll( void)
　引　　数	：−
　返　　値	：−
　コメント	：
			：
　履　　歴	：Ver 1.00	2000/11/20		K.Kimura		初版
****************************************************************************** */
void	fntDispStringAll( void)
{
	static	int		i;
	static	u_short	pal;
	static	int		cnum, code, flag;
	static	int		scr, x, y;
	static	u_short	data;
	FNTDFLUSH		*p;



	p = FntDFlush;

	/* ///  ■登録文字の表示■  /// */
	for (i = 0; i < FntMng.regNum; i++)
	{
		code = p[ i].code;
		flag = p[ i].flag;
		pal  = p[ i].pal;
		cnum = FntMng.regChr[ code];

		/*  < flag内容 >
			bit  0.. 4	: X座標
			bit  5.. 9	: Y座標
			bit 12		: 表示スクリーン 0, 1
			bit 13		: 縦方向加算
			bit 14		: 水平反転
			bit 15		: 垂直反転
		*/

		x = ( flag & 0x001f);
		y = (( flag >> 5) & 0x001f);
		scr = (( flag >> 12) & 0x0001);
		data = ((flag & 0xc000) | pal | cnum);

		/* ///  文字列表示  /// */
		screen_set_char( scr, x, y, 1, 1, &data);
	}

}


