/*
	文字表示
*/
#include "ot_header.h"

#include "kn_def.h"
#include "kn_main.h"
#include "kn_dynamic.h"
#include "kn_font.h"

/*******************************************************
	FUNCTION
*******************************************************/
#define KN_CC_PRIMC_TEXA 0,0,0,PRIMITIVE,0,0,0,TEXEL0
static Gfx		*makeFontGlist( Gfx *gp, uint font_type, uint font_code, int sx, int uy,
						uint flag,
					    uchar r0, uchar g0, uchar b0,
					    uchar r1, uchar g1, uchar b1,
					    uchar r2, uchar g2, uchar b2,
					    uchar r3, uchar g3, uchar b3, float scale );
Gfx		*makeFontVtxGlist( Gfx *gp, uint wd, uint ht, int sx, int sy,
							   uchar r0, uchar g0, uchar b0,
							   uchar r1, uchar g1, uchar b1,
							   uchar r2, uchar g2, uchar b2,
							   uchar r3, uchar g3, uchar b3, float scale );
Gfx		*makeTimeGlist( Gfx *gp, uint font_type, int ctime, int sx, int sy,
						uint flag,
					    uchar r0, uchar g0, uchar b0,
						uchar r1, uchar g1, uchar b1,
						uchar r2, uchar g2, uchar b2,
						uchar r3, uchar g3, uchar b3 );
Gfx		*makeStrGlist( Gfx *gp, uint font_type, char *str, int sx, int sy,
					   uint flag,
					   uchar r0, uchar g0, uchar b0,
					   uchar r1, uchar g1, uchar b1,
					   uchar r2, uchar g2, uchar b2,
					   uchar r3, uchar g3, uchar b3 );
uint 	codeConvAsc2Font( uint font_type, char asc_code );
void	calcFlashColorType0( void );
void	calcFlashColorType1( void );
void	calcFlashColorType2( void );
void	calcFlashColorType3( void );
void	calcFlashColorType4( void );
void	calcFlashColorType5( void );
void	initKnFont( void );
void	moveKnFont( void );

/*******************************************************
	VARIABLE
*******************************************************/
/* Display List */
extern Gfx dlInitFont[], dlInitShade[];

/* font texture */
extern uchar	tx_main_font[];
extern uchar	tx_small_font[];
extern uchar	tx_select_font[];
extern uint		tx_middle_font[];
//extern uint		tx_rank_font[];
extern uint		tx_speed_font[];

/* 自分のホバー番号 */
extern int		my_hover;

extern sKnPad	mKnPad[];

/* 横幅テーブル */
uchar fontWidthMain[FONT_MAX_NUM_MAIN] = {
	14, 10, 13, 11, 15, 12, 12, 11, 13, 12,
	18, 13, 13, 16, 11, 12, 15, 16,  8, 10,
	15, 12, 24, 16, 17, 13, 17, 15, 12, 16,
	16, 17, 23, 16, 17, 15, 12,  9, 10,  6,
#ifdef CHINA
	   // RF: Added extra line
	24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
	24, 24, 24, 24, 24 
#endif
};
uchar fontWidthSmall[FONT_MAX_NUM_SMALL] = {
	 6,  5,  6,  6,  6,  6,  6,  6,  6,  6,
	 8,  6,  6,  7,  6,  6,  7,  7,  3,  5,
	 7,  5,  8,  7,  8,  6,  8,  7,  5,  7,
	 7,  8,  8,  7,  8,  7,  6,  5,  5,  7,
	 7,  3,
};
uchar fontWidthSelect[FONT_MAX_NUM_SELECT] = {
	10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
	12,  9,  9, 11,  7,  8, 10, 11,  6,  7,
	 8,  8, 15, 11, 12,  9, 13, 10,  8, 10,
	10, 12, 15, 11, 11, 10, 10, 10,  5,  6,
	   10,  5,  1,  8,  8, 10,
#ifdef CHINA
	   11, 11, 11, 11, 11, 11
#endif
};
uchar fontWidthMiddle[FONT_MAX_NUM_MIDDLE] = {
	12, 10, 12, 11, 12, 11, 11, 11, 12, 11,
	 5,  7
};
uchar fontWidthRank[FONT_MAX_NUM_RANK] = {
	12, 10, 12, 11, 12, 11, 11, 10, 12, 11
};
uchar fontWidthSpeed[FONT_MAX_NUM_SPEED] = {
	16, 13, 16, 14, 16, 15, 15, 14, 15, 15,
	13
};
uchar fontWidthGoal[FONT_MAX_NUM_GOAL] = {
	1, 18, 30, 27, 30, 40, 40, 36, 29, 28,		/* ０番はダミー */
};

/* font scale */
static float	fontScale = 1.0f;
static short	fontScaleFlag = 0;
/* フォント用ポリゴン文字数 */
int fontVtxNum;
/* フォント */
static uint	fontType = FONT_TYPE_NONE;
static uint fontFlag;
static uint fontR[4], fontG[4], fontB[4];
/* フォントフラッシュ用 */
static sFontFlash mFontFlash;
static sFontFlash mFontFlashInit = {
	0, 0, 0, 2
};

/* セレクトタイプの数字を縦に並べたときの表示座標補正 */
char dxSelectNumber[] = {
	0, 1, 1, 0, 0, 1, 1, 1, 0, 0,
};

/* ====================================================================== */
/*
	文字表示
*/
static Gfx	*makeFontGlist( Gfx *gp, uint font_type, uint font_code, int sx, int sy, uint flag,
					uchar r0, uchar g0, uchar b0,
					uchar r1, uchar g1, uchar b1,
					uchar r2, uchar g2, uchar b2,
					uchar r3, uchar g3, uchar b3, float scale )
{
	register uint 	timg, timg2, wd, dsp_wd, ht, fmt_siz, rect_flag, display_flag;
	register int 	dif_flag;
	register uint 	*timgp;

	/* レクタングルの設定 */
	rect_flag = 1;
	if( flag == FONT_FLAG_SHADE ) rect_flag = 0;
	
	switch( font_type ) {
		case FONT_TYPE_MAIN:
			if( font_code >= FONT_MAX_NUM_MAIN ) font_code = 0;
			wd = FONT_WD_MAIN;
			dsp_wd = (uint)fontWidthMain[font_code];
			ht = FONT_HT_MAIN;
			timg = (uint)(tx_main_font + font_code * wd * ht);
			fmt_siz = 0;	/* ia8 */
			break;
		case FONT_TYPE_SMALL:
			if( font_code >= FONT_MAX_NUM_SMALL ) font_code = 0;
			wd = FONT_WD_SMALL;
			dsp_wd = (uint)fontWidthSmall[font_code];
			ht = FONT_HT_SMALL;
			timg = (uint)(tx_small_font + font_code * wd * ht);
			fmt_siz = 0;	/* ia8 */
			break;
		case FONT_TYPE_SELECT:
			if( font_code >= FONT_MAX_NUM_SELECT ) font_code = 0;
			wd = FONT_WD_SELECT;
			dsp_wd = (uint)fontWidthSelect[font_code];
			ht = FONT_HT_SELECT;
			timg = (uint)(tx_select_font + font_code * wd * ht);
			fmt_siz = 0;	/* ia8 */
			break;
		case FONT_TYPE_MIDDLE:
			if( font_code >= FONT_MAX_NUM_MIDDLE ) font_code = 0;
			wd = FONT_WD_MIDDLE;
			dsp_wd = (uint)fontWidthMiddle[font_code];
			ht = FONT_HT_MIDDLE;
			timg = (uint)(tx_middle_font + font_code * wd * ht);
			fmt_siz = 1;	/* rgba32 */
			break;
		case FONT_TYPE_RANK:
			if( font_code >= FONT_MAX_NUM_RANK ) font_code = 0;
			wd = FONT_WD_RANK;
			dsp_wd = (uint)fontWidthRank[font_code];
			ht = FONT_HT_RANK;
			timg = (uint)(tx_middle_font + font_code * wd * ht);
			fmt_siz = 1;	/* rgba32 */
			break;
		case FONT_TYPE_SPEED:
			if( font_code >= FONT_MAX_NUM_SPEED ) font_code = 0;
			wd = FONT_WD_SPEED;
			dsp_wd = (uint)fontWidthSpeed[font_code];
			ht = FONT_HT_SPEED;
			timg = (uint)(tx_speed_font + font_code * wd * ht);
			fmt_siz = 1;	/* rgba32 */
			break;
	}

	display_flag = 1;
	/* 表示チェック */
	if( sx >= 320 ) display_flag = 0;
	else if( (sx +(int)((float)wd * scale) ) < 0 ) display_flag = 0;
	else if( sy >= 240 ) display_flag = 0;
	else if( (sy+(int)((float)ht * scale) ) < 0 ) display_flag = 0;
	if( display_flag == 0 ) return( gp );

	/* フォントタイプの保存 */
	dif_flag = 0;
	if( fontType != font_type ) {
		dif_flag = 1;
		fontType = font_type;
	}

	if( fmt_siz == 0 ) {
		gDPLoadTextureBlock( gp++, timg, G_IM_FMT_IA, G_IM_SIZ_8b, wd, ht, 0,
			G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD );
	}
	else if( fmt_siz == 1 ) {
		gDPLoadTextureBlock( gp++, timg, G_IM_FMT_RGBA, G_IM_SIZ_32b, wd, ht, 0,
			G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD );
	}

	if( rect_flag == 1 ) {
		gSPScisTextureRectangle( gp++, sx<<2, sy<<2, (sx + (int)wd)<<2, (sy + (int)ht)<<2,
							G_TX_RENDERTILE, 0,0, 1<<10, 1<<10 );
	}
	else {
		gp = makeFontVtxGlist( gp, wd, ht, sx, sy, r0, g0, b0, r1, g1, b1,
							   r2, g2, b2, r3, g3, b3, scale );
	}

	return( gp );
}

Gfx	*makeFontVtxGlist( Gfx *gp, uint wd, uint ht, int sx, int sy,
					   uchar r0, uchar g0, uchar b0,
					   uchar r1, uchar g1, uchar b1,
					   uchar r2, uchar g2, uchar b2,
					   uchar r3, uchar g3, uchar b3, float scale )
{
	register int	i;
	register float  sc;
	register Vtx_t	*vp;

	for( i = 0 ; i < 4 ; i ++ ) {
		vp = &(pKnDynamic->vtxFont[fontVtxNum + i].v);
		if( i == 1 || i == 3 ) 	{
			vp->ob[0] = sx + (int)((float)wd * scale ) - 1;
			vp->tc[0] = ( wd * 2 + 1 ) << 5;
		}
		else {
			vp->ob[0] = sx;
			vp->tc[0] = ( -1 ) << 5;
		}
		if( i == 2 || i == 3 ) 	{
			vp->ob[1] = sy + (int)((float)ht * scale ) - 1;
			vp->tc[1] = ( ht * 2 ) << 5;
		}
		else {
			vp->ob[1] = sy;
			vp->tc[1] = ( -1 ) << 5;
		}
		vp->ob[2] = 0;
		vp->flag = 0;
		if( i == 0 ) {
			vp->cn[0] = r0;
			vp->cn[1] = g0;
			vp->cn[2] = b0;
		}
		else if( i == 1 ) {
			vp->cn[0] = r1;
			vp->cn[1] = g1;
			vp->cn[2] = b1;
		}
		else if( i == 2 ) {
			vp->cn[0] = r2;
			vp->cn[1] = g2;
			vp->cn[2] = b2;
		}
		else {
			vp->cn[0] = r3;
			vp->cn[1] = g3;
			vp->cn[2] = b3;
		}
		
		vp->cn[3] = 0xff;
	}
    gSPVertex( gp++, &(rspKnDynamic.vtxFont[fontVtxNum]), 4, 0 );
    gSP1Triangle( gp++, 0, 3, 1, 0 );
	gSP1Triangle( gp++, 0, 2, 3, 0 );
	fontVtxNum += 4;
	if( fontVtxNum >= MAX_NUM_FONT_VTX ) fontVtxNum = MAX_NUM_FONT_VTX - 4;

	return( gp );
}

/*=================================================================*/
/*
	タイム表示
*/
/* 初期化あり */
Gfx	*makeTimeGlist( Gfx *gp, uint font_type, int ctime, int sx, int sy,
							uint flag,
						    uchar r0, uchar g0, uchar b0,
							uchar r1, uchar g1, uchar b1,
							uchar r2, uchar g2, uchar b2,
							uchar r3, uchar g3, uchar b3 )
{
	register uint	dspx, dx, min_code, sec_code, min_dx, sec_dx;
	register int 	fig100, fig10, fig1, min, sec, msec;

	/* フラグ処理 */
	gp = makeInitStrGlist( gp, flag, r0, g0, b0, r1, g1, b1, r2, g2, b2, r3, g3, b3 );
	gp = makeTimeGlistSub( gp, font_type, ctime, sx, sy );
	
	return( gp );
}

/* 初期化無し */
Gfx	*makeTimeGlistSub( Gfx *gp, uint font_type, int ctime, int sx, int sy )
{
	register uint	dspx, dx, min_code, sec_code, min_dx, sec_dx;
	register int 	fig100, fig10, fig1, min, sec, msec;

	switch( font_type ) {
		case FONT_TYPE_MAIN:
			dx = FONT_WD_MAIN;
			min_code = 37;
			sec_code = 38;
			min_dx = (uint)fontWidthMain[min_code];
			sec_dx = (uint)fontWidthMain[sec_code];
			break;
		case FONT_TYPE_SMALL:
			dx = FONT_WD_SMALL;
			min_code = 37;
			sec_code = 38;
			min_dx = (uint)fontWidthSmall[min_code];
			sec_dx = (uint)fontWidthSmall[sec_code];
			break;
		case FONT_TYPE_SELECT:
//			dx = FONT_WD_SELECT - 8;
			dx = 10;
			min_code = 38;
			sec_code = 39;
			min_dx = (uint)fontWidthSelect[min_code];
			sec_dx = (uint)fontWidthSelect[sec_code];
			break;
		case FONT_TYPE_MIDDLE:
			dx = FONT_WD_MIDDLE;
			min_code = 10;
			sec_code = 11;
			min_dx = (uint)fontWidthMiddle[min_code];
			sec_dx = (uint)fontWidthMiddle[sec_code];
			break;
		case FONT_TYPE_RANK:
			dx = FONT_WD_RANK;
			min_code = 0;		/* 未定 */
			sec_code = 0;		/* 未定 */
			min_dx = (uint)fontWidthRank[min_code];
			sec_dx = (uint)fontWidthRank[sec_code];
			break;
		case FONT_TYPE_SPEED:
			dx = FONT_WD_SPEED;
			min_code = 0;		/* 未定 */
			sec_code = 0;		/* 未定 */
			min_dx = (uint)fontWidthSpeed[min_code];
			sec_dx = (uint)fontWidthSpeed[sec_code];
			break;
	}
	/* 時間計測 */
	min = (ctime / (20 * 50)) / 60;
	sec = (ctime / (20 * 50)) % 60;
	/* バグ修正 */
//	msec = (float)(ctime % (20 * 50)) / (20 * 50) * 1000.F;
	msec = ctime % 1000;
	
	dspx = sx;
	/* 分 */
	fig1 = min % 10;
	gp = makeFontGlist( gp, font_type, (uint)(fig1), dspx, sy, fontFlag,
						fontR[0], fontG[0], fontB[0], fontR[1], fontG[1], fontB[1],
						fontR[2], fontG[2], fontB[2], fontR[3], fontG[3], fontB[3], 1.0f );
	dspx += dx;
	/* 分マーク */
	gp = makeFontGlist( gp, font_type, min_code, dspx, sy, fontFlag,
						fontR[0], fontG[0], fontB[0], fontR[1], fontG[1], fontB[1],
						fontR[2], fontG[2], fontB[2], fontR[3], fontG[3], fontB[3], 1.0f );
	dspx += min_dx;
	/* 秒 */
	fig1 = sec % 10;
	fig10 = ( sec / 10 ) % 10;
	gp = makeFontGlist( gp, font_type, (uint)(fig10) , dspx, sy, fontFlag,
						fontR[0], fontG[0], fontB[0], fontR[1], fontG[1], fontB[1],
						fontR[2], fontG[2], fontB[2], fontR[3], fontG[3], fontB[3], 1.0f );
	dspx += dx;
	gp = makeFontGlist( gp, font_type, (uint)(fig1), dspx, sy, fontFlag,
						fontR[0], fontG[0], fontB[0], fontR[1], fontG[1], fontB[1],
						fontR[2], fontG[2], fontB[2], fontR[3], fontG[3], fontB[3], 1.0f );
	dspx += dx;
	/* 秒マーク */
	gp = makeFontGlist( gp, font_type, sec_code, dspx, sy, fontFlag,
						fontR[0], fontG[0], fontB[0], fontR[1], fontG[1], fontB[1],
						fontR[2], fontG[2], fontB[2], fontR[3], fontG[3], fontB[3], 1.0f );
	dspx += sec_dx;

	/* コンマ秒 */
	fig1 = msec % 10;
	fig10 = ( msec / 10 ) % 10;
	fig100 = ( msec / 100 ) % 10;
	gp = makeFontGlist( gp, font_type, (uint)(fig100), dspx, sy, fontFlag,
						fontR[0], fontG[0], fontB[0], fontR[1], fontG[1], fontB[1],
						fontR[2], fontG[2], fontB[2], fontR[3], fontG[3], fontB[3], 1.0f );
	dspx += dx;
	gp = makeFontGlist( gp, font_type, (uint)(fig10), dspx, sy, fontFlag,
						fontR[0], fontG[0], fontB[0], fontR[1], fontG[1], fontB[1],
						fontR[2], fontG[2], fontB[2], fontR[3], fontG[3], fontB[3], 1.0f );
	dspx += dx;
	gp = makeFontGlist( gp, font_type, (uint)(fig1), dspx, sy, fontFlag,
						fontR[0], fontG[0], fontB[0], fontR[1], fontG[1], fontB[1],
						fontR[2], fontG[2], fontB[2], fontR[3], fontG[3], fontB[3], 1.0f );
	
	return( gp );
}
/*=================================================================*/
/*
	文字列
*/
/* 初期化用ディスプレイリストを含む */
Gfx	*makeStrGlist( Gfx *gp, uint font_type, char *str, int sx, int sy,
				   uint flag,
				   uchar r0, uchar g0, uchar b0,
				   uchar r1, uchar g1, uchar b1,
				   uchar r2, uchar g2, uchar b2,
				   uchar r3, uchar g3, uchar b3 )
{
	fontScale = 1.0f;
	gp = makeInitStrGlist( gp, flag, r0, g0, b0, r1, g1, b1, r2, g2, b2, r3, g3, b3 );
	fontScaleFlag = 0;
	gp = makeStrGlistSub( gp, font_type, str, sx, sy );

	return( gp );
}

Gfx	*makeStrGlistS( Gfx *gp, uint font_type, char *str, int sx, int sy,
				   uint flag,
				   uchar r0, uchar g0, uchar b0,
				   uchar r1, uchar g1, uchar b1,
				   uchar r2, uchar g2, uchar b2,
				   uchar r3, uchar g3, uchar b3, float scale )
{
	fontScale = scale;
	gp = makeInitStrGlist( gp, flag, r0, g0, b0, r1, g1, b1, r2, g2, b2, r3, g3, b3 );
	fontScaleFlag = 1;
	gp = makeStrGlistSub( gp, font_type, str, sx, sy );

	return( gp );
}

/* 初期化用ディスプレイリストを含まない */
Gfx	*makeInitStrGlist( Gfx *gp, uint flag,
				   uchar r0, uchar g0, uchar b0,
				   uchar r1, uchar g1, uchar b1,
				   uchar r2, uchar g2, uchar b2,
				   uchar r3, uchar g3, uchar b3 )
{
	/* パラメータセット */
	fontType = FONT_TYPE_NONE;
	fontFlag = flag;
	fontScaleFlag = 0;
	fontR[0] = r0; fontG[0] = g0; fontB[0] = b0;
	fontR[1] = r1; fontG[1] = g1; fontB[1] = b1;
	fontR[2] = r2; fontG[2] = g2; fontB[2] = b2;
	fontR[3] = r3; fontG[3] = g3; fontB[3] = b3;

	/* フラグ処理 */
	switch( flag ) {
		case FONT_FLAG_FLASH:
			gSPDisplayList( gp++, dlInitFont );
			gDPSetCombineMode( gp++, KN_CC_PRIMC_TEXA, KN_CC_PRIMC_TEXA );
			gDPSetPrimColor( gp++, 0, 0, r0, g0, b0, 255 );
			break;
		case FONT_FLAG_SHADE:
			gSPDisplayList( gp++, dlInitShade );
			gSPMatrix( gp++, &(rspKnDynamic.mtxFontProj),
					   G_MTX_PROJECTION | G_MTX_LOAD | G_MTX_NOPUSH );
			gSPMatrix( gp++, &automatic.e_MT,
					   G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_NOPUSH );
			break;
		case FONT_FLAG_FLASH_0:
		case FONT_FLAG_FLASH_1:
		case FONT_FLAG_FLASH_2:
		case FONT_FLAG_FLASH_3:
		case FONT_FLAG_FLASH_4:
		case FONT_FLAG_FLASH_5:
			gSPDisplayList( gp++, dlInitFont );
			gDPSetCombineMode( gp++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM );
			mFontFlash.moveFlag = 1;
			switch( flag ) {
				case FONT_FLAG_FLASH_0:
					calcFlashColorType0();
					break;
				case FONT_FLAG_FLASH_1:
					calcFlashColorType1();
					break;
				case FONT_FLAG_FLASH_2:
					calcFlashColorType2();
					break;
				case FONT_FLAG_FLASH_3:
					calcFlashColorType3();
					break;
				case FONT_FLAG_FLASH_4:
					calcFlashColorType4();
					break;
				case FONT_FLAG_FLASH_5:
					calcFlashColorType5();
					break;
		}
			gDPSetPrimColor( gp++, 0, 0,
							 (uint)mFontFlash.r, (uint)mFontFlash.g, (uint)mFontFlash.b, 255 );
			break;
		case FONT_FLAG_COLOR:
			gSPDisplayList( gp++, dlInitFont );
			gDPSetCombineMode( gp++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM );
			gDPSetPrimColor( gp++, 0, 0, r0, g0, b0, 255 );
			break;
		case FONT_FLAG_ALPHA:
			gSPDisplayList( gp++, dlInitFont );
			gDPSetCombineMode( gp++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM );
			gDPSetPrimColor( gp++, 0, 0, 255, 255, 255, r0 );
			break;

		default:
			gSPDisplayList( gp++, dlInitFont );
			break;
	}
	
	return( gp );
}

Gfx	*makeStrGlistSub( Gfx *gp, uint font_type, char *str, int sx, int sy )
{
	register char	*sp;
	register uint	code;
	register float	sc;
	register int 	dspx, space_dx, dx;


	// RF: PUT FONT STUFF HERE
	sp = str;
	dspx = sx;
	while( 1 ) {
		if( *sp == 0x00 ) break;

		/* ASCII -> CHAR CODE */
		code = codeConvAsc2Font( font_type, *sp );
		switch( font_type ) {
			case FONT_TYPE_MAIN:
				dx = (int)fontWidthMain[code];
				space_dx = (int)FONT_SPACE_WD_MAIN;
				break;
			case FONT_TYPE_SMALL:
				dx = (int)fontWidthSmall[code];
				space_dx = (int)FONT_SPACE_WD_SMALL;
				break;
			case FONT_TYPE_SELECT:
				dx = (int)fontWidthSelect[code];
				space_dx = (int)FONT_SPACE_WD_SELECT;
				break;
			case FONT_TYPE_MIDDLE:
				dx = (int)fontWidthMiddle[code];
				space_dx = (int)FONT_SPACE_WD_MIDDLE;
				break;
			case FONT_TYPE_RANK:
				dx = (int)fontWidthRank[code];
				space_dx = (int)FONT_SPACE_WD_RANK;
				break;
			case FONT_TYPE_SPEED:
				dx = (int)fontWidthSpeed[code];
				space_dx = (int)FONT_SPACE_WD_SPEED;
				break;
			case FONT_TYPE_GOAL:
				dx = (int)fontWidthGoal[code];
				space_dx = (int)FONT_SPACE_WD_GOAL;
				break;
		}

		if( code == FONT_CODE_SPACE ) {
			if( fontScaleFlag ) dspx += ( space_dx * fontScale );
			else dspx += space_dx;
		}
		else {
			if( fontScaleFlag ) sc = fontScale;
			else sc = 1.0f;
			gp = makeFontGlist( gp, font_type, (uint)(code), dspx, sy, fontFlag,
								fontR[0], fontG[0], fontB[0],
								fontR[1], fontG[1], fontB[1],
								fontR[2], fontG[2], fontB[2],
								fontR[3], fontG[3], fontB[3], sc );
			if( fontScaleFlag ) dspx += (int)( (float)dx * fontScale);
			else dspx += dx;
		}
		sp ++;
	}

	return( gp );
}

/* アスキーコードをフォントコードに変換 */
uint codeConvAsc2Font( uint font_type, char asc_code )
{
	register uint font_code;

	font_code = 0;
	/* 数字 */
	if( ( asc_code >= 0x30 ) && ( asc_code <= 0x39 ) ) {
		font_code = (uint)(asc_code - 0x30);
	}
	else if (  asc_code >= 0x71  && asc_code <=0x7E ) {
	   if ( font_type == FONT_TYPE_MAIN )
	   {
	      font_code = (uint) ( 40 + asc_code - 0x71); //xxx
	   } else if ( font_type == FONT_TYPE_SELECT )
	   {
	      font_code = (uint) ( 46 + asc_code - 0x71); //xxx	      
	   }
	}
	/* アルファベット */
	else if( ( asc_code >= 0x41 ) && ( asc_code <= 0x5a ) ) {
		switch( font_type ) {
			case FONT_TYPE_MAIN:
			case FONT_TYPE_SMALL:
			case FONT_TYPE_SELECT:
				font_code = (uint)(asc_code - 0x41 + 10);
				break;
			default:
				font_code = 0;
				break;
		}
	}
	/* 記号 */
	else if( asc_code == 0x2f ) {	/* / */
		switch( font_type ) {
			case FONT_TYPE_SPEED:
				font_code = 10;
				break;
			case FONT_TYPE_SELECT:
				font_code = 40;
				break;
			default:
				font_code = 0;
				break;
		}
	}
	else if( asc_code == 0x2d ) {	/* - */
		switch( font_type ) {
			case FONT_TYPE_MAIN:
			case FONT_TYPE_SMALL:
				font_code = 36;
				break;
			case FONT_TYPE_SELECT:
				font_code = 37;
				break;
			default:
				font_code = 0;
				break;
		}
	}
	else if( asc_code == 0x27 ) {	/* ' */
		switch( font_type ) {
			case FONT_TYPE_MAIN:
			case FONT_TYPE_SMALL:
				font_code = 37;
				break;
			case FONT_TYPE_SELECT:
				font_code = 38;
				break;
			case FONT_TYPE_MIDDLE:
				font_code = 10;
				break;
			default:
				font_code = 0;
				break;
		}
	}
	else if( asc_code == 0x40 ) {	/* " */
		switch( font_type ) {
			case FONT_TYPE_MAIN:
			case FONT_TYPE_SMALL:
				font_code = 38;
				break;
			case FONT_TYPE_SELECT:
				font_code = 39;
				break;
			case FONT_TYPE_MIDDLE:
				font_code = 11;
				break;
			default:
				font_code = 0;
				break;
		}
	}
	else if( asc_code == 0x26 ) {	/* & */
		switch( font_type ) {
			case FONT_TYPE_SELECT:
				font_code = 36;
				break;
			default:
				font_code = 0;
				break;
		}
	}
	else if( asc_code == 0x2e ) {	/* . */
		switch( font_type ) {
			case FONT_TYPE_MAIN:
				font_code = 39;
				break;
			case FONT_TYPE_SELECT:
				font_code = 41;
				break;
			case FONT_TYPE_SMALL:
				font_code = 41;
				break;
			default:
				font_code = 0;
				break;
		}
	}
	else if( asc_code == 0x7c ) {	/* | */
		switch( font_type ) {
			case FONT_TYPE_SELECT:
				font_code = 42;
				break;
			default:
				font_code = 0;
				break;
		}
	}
	else if( asc_code == 0x3c ) {	/* < */
		switch( font_type ) {
			case FONT_TYPE_SELECT:
				font_code = 43;
				break;
			default:
				font_code = 0;
				break;
		}
	}
	else if( asc_code == 0x3e ) {	/* > */
		switch( font_type ) {
			case FONT_TYPE_SELECT:
				font_code = 44;
				break;
			default:
				font_code = 0;
				break;
		}
	}
	else if( asc_code == 0x0a ) {	/* x */
		switch( font_type ) {
			case FONT_TYPE_SMALL:
				font_code = 40;
				break;
			default:
				font_code = 0;
				break;
		}
	}
	else if( asc_code == 0x2b ) {	/* + */
		switch( font_type ) {
			case FONT_TYPE_SELECT:
				font_code = 45;
				break;
			default:
				font_code = 0;
				break;
		}
	}
	else if( asc_code == 0x20 ) {	/* SPACE */
		font_code = FONT_CODE_SPACE;
	}
	
	return( font_code );
}

/*=================================================================*/
/*
	フラッシュカラー計算
*/
/* タイプ０ */
void calcFlashColorType0( void )
{
	switch( mFontFlash.stat ) {
		case 0:
			mFontFlash.r = 255;
			mFontFlash.g = (uint)( 255.0f * (float)mFontFlash.count0 / (float)mFontFlash.count1 );
			mFontFlash.b = 0;
			break;
		case 1:
			mFontFlash.r = 255;
			mFontFlash.g = 255;
			mFontFlash.b = (uint)( 255.0f * (float)mFontFlash.count0 / (float)mFontFlash.count1 );
			break;
		case 2:
			mFontFlash.r = 255;
			mFontFlash.g = 255;
			mFontFlash.b = (uint)(255.0f * (float)(mFontFlash.count1-mFontFlash.count0)
					/ (float)mFontFlash.count1 );
			break;
		case 3:
			mFontFlash.r = 255;
			mFontFlash.g = (uint)(255.0f * (float)(mFontFlash.count1-mFontFlash.count0)
					/ (float)mFontFlash.count1 );
			mFontFlash.b = 0;
			break;
	}
}
/* タイプ１ */
void calcFlashColorType1( void )
{
	switch( mFontFlash.stat ) {
		case 0:
			mFontFlash.r = (uint)( 255.0f * (float)mFontFlash.count0 / (float)mFontFlash.count1 );
			mFontFlash.g = 0;
			mFontFlash.b = 0;
			break;
		case 1:
			mFontFlash.r = 255;
			mFontFlash.g = (uint)( 255.0f * (float)mFontFlash.count0 / (float)mFontFlash.count1 );
			mFontFlash.b = 0;
			break;
		case 2:
			mFontFlash.r = 255;
			mFontFlash.g = (uint)(255.0f * (float)(mFontFlash.count1-mFontFlash.count0)
						/ (float)mFontFlash.count1 );
			mFontFlash.b = 0;
			break;
		case 3:
			mFontFlash.r = (uint)(255.0f * (float)(mFontFlash.count1-mFontFlash.count0)
						/ (float)mFontFlash.count1 );
			mFontFlash.g = 0;
			mFontFlash.b = 0;
			break;
	}
}
/* タイプ２ */
void calcFlashColorType2( void )
{
	switch( mFontFlash.stat ) {
		case 0:
			mFontFlash.r = (uint)( 255.0f * (float)mFontFlash.count0 / (float)mFontFlash.count1 );
			mFontFlash.g = 255;
			mFontFlash.b = 0;
			break;
		case 1:
			mFontFlash.r = 255;
			mFontFlash.g = 255;
			mFontFlash.b = (uint)( 255.0f * (float)mFontFlash.count0 / (float)mFontFlash.count1 );
			break;
		case 2:
			mFontFlash.r = 255;
			mFontFlash.g = 255;
			mFontFlash.b = (uint)(255.0f * (float)(mFontFlash.count1-mFontFlash.count0)
						/ (float)mFontFlash.count1 );
			break;
		case 3:
			mFontFlash.r = (uint)(255.0f * (float)(mFontFlash.count1-mFontFlash.count0)
						/ (float)mFontFlash.count1 );
			mFontFlash.g = 255;
			mFontFlash.b = 0;
			break;
	}
}
/* タイプ３ */
void calcFlashColorType3( void )
{
	switch( mFontFlash.stat ) {
		case 0:
			mFontFlash.r = 0;
			mFontFlash.g = (uint)( 255.0f * (float)mFontFlash.count0 / (float)mFontFlash.count1 );
			mFontFlash.b = 0;
			break;
		case 1:
			mFontFlash.r = (uint)( 255.0f * (float)mFontFlash.count0 / (float)mFontFlash.count1 );
			mFontFlash.g = 255;
			mFontFlash.b = 0;
			break;
		case 2:
			mFontFlash.r = (uint)(255.0f * (float)(mFontFlash.count1-mFontFlash.count0)
						/ (float)mFontFlash.count1 );
			mFontFlash.g = 255;
			mFontFlash.b = 0;
			break;
		case 3:
			mFontFlash.r = 0;
			mFontFlash.g = (uint)(255.0f * (float)(mFontFlash.count1-mFontFlash.count0)
						/ (float)mFontFlash.count1 );
			mFontFlash.b = 0;
			break;
	}
}
/* タイプ４ */
void calcFlashColorType4( void )
{
	switch( mFontFlash.stat ) {
		case 0:
			mFontFlash.r = 255;
			mFontFlash.g = (uint)( 128.0f * (float)(mFontFlash.count1-mFontFlash.count0) / (float)mFontFlash.count1 );
			mFontFlash.b = 255;
			break;
		case 1:
			mFontFlash.r = 255;
			mFontFlash.g = 0;
			mFontFlash.b = (uint)( 255.0f * (float)(mFontFlash.count1-mFontFlash.count0) / (float)mFontFlash.count1 );
			break;
		case 2:
			mFontFlash.r = 255;
			mFontFlash.g = 0;
			mFontFlash.b = (uint)( 255.0f * (float)mFontFlash.count0 / (float)mFontFlash.count1 );
			break;
		case 3:
			mFontFlash.r = 255;
			mFontFlash.g = (uint)( 128.0f * (float)mFontFlash.count0 / (float)mFontFlash.count1 );
			mFontFlash.b = 255;
			break;
	}
}
/* タイプ５ */
void calcFlashColorType5( void )
{
	switch( mFontFlash.stat ) {
		case 0:
		case 2:
			mFontFlash.r = 128 +
				(uint)( 127.0f * (float)mFontFlash.count0 / (float)mFontFlash.count1 );
			mFontFlash.g = 255;
			mFontFlash.b = 128 +
				(uint)( 127.0f * (float)mFontFlash.count0 / (float)mFontFlash.count1 );
			break;
		case 1:
		case 3:
			mFontFlash.r = 128 + (uint)(127.0f * (float)(mFontFlash.count1-mFontFlash.count0)
						/ (float)mFontFlash.count1 );
			mFontFlash.g = 255;
			mFontFlash.b = 128 +  (uint)(127.0f * (float)(mFontFlash.count1-mFontFlash.count0)
						/ (float)mFontFlash.count1 );
			break;

	}
}

/*=================================================================*/
/*
	初期化
*/
void initKnFont( void )
{
	mFontFlash = mFontFlashInit;
}
/*=================================================================*/
/*
	フォントメイン
*/
void moveKnFont( void )
{
	if( mFontFlash.moveFlag ) {
		mFontFlash.count0 ++;
		if( mFontFlash.count0 >= mFontFlash.count1 ) {
			mFontFlash.count0 = 0;
			mFontFlash.stat ++;
			if( mFontFlash.stat == 4 ) {
				mFontFlash.stat = 0;
			}
		}
	}
}
/*=================================================================*/
/*
	数字の桁揃え表示（３桁まで）
*/
#define MAX_NUM_FIG		3
Gfx	*makeNumberGlistSub( Gfx *gp, uint font_type, int value, int sx, int sy )
{
	int		i, j;
	int		fig[MAX_NUM_FIG], work, dx, f;
	uchar	*width_p;
	char	str_work[10];
	
	if( font_type == FONT_TYPE_MAIN ) width_p = fontWidthMain;
	else if( font_type == FONT_TYPE_SELECT ) width_p = fontWidthSelect;
	else width_p = fontWidthSmall;


	sprintf( str_work, "%d", value );

	work = value;
	for( i = 0 ; i < MAX_NUM_FIG ; i ++ ) {
		fig[i] = work % 10;
		work /= 10;
	}
	dx = 0;
	for( i = 1 ; i < MAX_NUM_FIG ; i ++ ) {
		if( fig[i] ) {
			dx -= (int)*( width_p + fig[i] );
		}
		else {
			f = 0;
			for( j = i + 1; j < MAX_NUM_FIG ; j ++ ) {
				if( fig[j] ) {
					f = 1;
					break;
				}
			}
			if( f == 0 ) break;
			else dx -= (int)*( width_p + fig[i] );
		}
	}

	gp = makeStrGlistSub( gp, font_type, str_work, sx + dx, sy );
	
	return( gp );
}
