/******************************************************************************

		WAVE RACE 64

		File		: enstatus.c
		Description	: endo's display status program
		Date		: 1996
		Author		: T.Endo

******************************************************************************/

/* Draw Indicator EnemyMark StartSignal */

#define EN_DSPRESULT_FLAG

#include "ot_header.h"
#include "ot_sub.h"
#include "ot_newton.h"
#include "dai_anim_data.h"
#include "ot_hover.h"
#include "ot_sea.h"
#include "ot_letter.h"
#include "ot_menu.h"

#include "sot_world.h"

#include "hjm_camera.h"

#include "kn_def.h"
#include "kn_main.h"
#include "kn_font.h"
#include "kn_ctitle.h"

#include "endefine.h"
#include "enstatus.h"
#include "enchkcrs.h"
#include "ensetcrs.h"
#include "enmain.h"
#include "enbuoy.h"
#include "enmath.h"
#include "endraw.h"

/******************************************************************************
	define constants
******************************************************************************/

#define MINIMAP_WD	64
#define MINIMAP_HT	64
#define MINIMAP_X	24
#define MINIMAP_Y	80

#define SIGNAL_INIT_Y1	100
#define SIGNAL_INIT_Y2	50

#define FLASH_FRAME	2
#define FLASH_FRAME_LAP	3

#define	LAP_MSG_FRAME		40
#define BEST_LAP_MSG_FRAME	20

#define PASS_MSG_MISS	1
#define PASS_MSG_UP	2
#define PASS_MSG_DOWN	3

#define FRAME_MSG_MISS	8
#define FRAME_MSG_UP	12
#define FRAME_MSG_DOWN	8

#define CHASE_PATTERN	8

#define LAP_DSP_MAX	3

#define REVERSE_FRAME	40

/******************************************************************************
 	structures
******************************************************************************/

/******************************************************************************
	external variables
******************************************************************************/

extern uint	tx_lap[];
extern uint	tx_rank[];
extern uint	tx_speed[];
extern uint	tx_speed_km[];
extern uint	tx_power[];
extern uint	tx_power_mark[];
extern uint	tx_miss_mark[];
extern uint	tx_buoy_mark1[];
extern uint	tx_buoy_mark2[];

extern ushort	tx_face_back1[];
extern ushort	tx_face_back2[];
extern ushort	tx_face_back3[];
extern ushort	tx_face_back4[];
extern ushort	tx_face_back_bt[];
extern ushort	tx_face_1_1p[];
extern ushort	tx_face_1_2p[];
extern ushort	tx_face_2_1p[];
extern ushort	tx_face_2_2p[];
extern ushort	tx_face_3_1p[];
extern ushort	tx_face_3_2p[];
extern ushort	tx_face_4_1p[];
extern ushort	tx_face_4_2p[];
extern uchar	tx_back_enemy[];

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 uchar	tx_arrow_up[];
extern uchar	tx_lap_rank[];

/* score attack */
extern uint	tx_sc_time_mark[];
extern uint	tx_sc_score_mark[];
extern uint	tx_score_a[];
extern uint	tx_time_a[];
extern uint	tx_speed2[];
extern uchar	tx_sc_time[];
extern uchar	tx_sc_action[];
extern uchar	tx_sc_ring[];
extern uchar	tx_score_b[];
extern uchar	tx_time_b[];

extern ushort	sig_green_on_txt[];
extern ushort	sig_green_off_txt[];
extern ushort	sig_red_on_txt[];
extern ushort	sig_red_off_txt[];
extern Gfx	signal_model[];
extern Gfx	signal_model0[];
extern Gfx	signal_model1[];
extern Gfx	signal_model2[];
extern Gfx	signal_model3[];

extern Gfx	arrow_model[];

extern Gfx	gfx_init_indicator[];
extern Gfx	gfx_init_start_signal[];

#ifndef EN_DSPRESULT_FLAG
extern Gfx	gfx_init_pass_message[];
#else
extern Gfx	gfx_init_vs_result[];
#endif

extern Gfx	gfx_init_lap_time[];
extern Gfx	gfx_init_rank_face[];
extern Gfx	gfx_init_rank_face_2p[];
extern Gfx	gfx_init_enemy_mark[];
extern Gfx	gfx_enemy_mark[];

extern Gfx	gfx_miss_msg[];
extern Gfx	gfx_p_up_msg[];
extern Gfx	gfx_p_down_msg[];
extern Gfx	gfx_maxpower_msg[];

extern Vp	vp_normal;
extern Vp	vp_indicator0;
extern Vp	vp_indicator1;
extern Vp	vp_indicator2;
extern Vp	vp_start_signal0;
extern Vp	vp_start_signal1;
extern Vp	vp_start_signal2;

extern uint	tx_test[];
extern uint	tx_test2[];

#ifdef EN_DSPRESULT_FLAG
/* vs result (US) */
extern uint	tx_vs_won[];
extern uint	tx_vs_lost[];
extern uint	tx_vs_draw[];
#endif

/******************************************************************************
	variables
******************************************************************************/
int	fdrawmap = 0;

int	cstart_signal;
int	cextend_msg;
int	fbest_lap_msg;
int	frank_zoom;
int	clast_lap_flash;
int	fstatus_move;

#ifdef EN_DSPRESULT_FLAG
int	fvs_result_draw;
#endif

int	en_flash_r1, en_flash_g1, en_flash_b1;	/* K-R-Y-R-K */
int	en_flash_r2, en_flash_g2, en_flash_b2;	/* k-G-Y-G-K */
int	en_flash_r3, en_flash_g3, en_flash_b3;	/* P-R-R-R-P */
int	en_flash_r4, en_flash_g4, en_flash_b4;	/* G-W-G-W-G */

Scoremsg	scoremsg[SCORE_MSG_MAX];

/*---------------------------------------------------------------------------*/
static int	fghost;

/*---------------------------------------------------------------------------*/
static int	scrofs1, scrofs2;

/*---------------------------------------------------------------------------*/
static char	fstart_power[MACHINE_MAX];
static int	crsout_time;

/*---------------------------------------------------------------------------*/
#ifndef ROM_FLAG

static u64	dummy_aligner = 0;
static ushort	tx_minimap[MINIMAP_WD * MINIMAP_HT] = { 0 };

static int	minimapx[MINIMAP_WD], minimapy[MINIMAP_WD];

static int	machine_color[][3] = {
	{ 255, 255, 255 },
	{ 255,  64,  64 },
	{ 255, 255,   0 },
	{  64,  64, 255 },
	{ 255,  64, 255 },
	{  64, 255, 255 },
};

#endif

/*---------------------------------------------------------------------------*/
static int	tflash_lap[SIMPLAY_MAX], iflash_lap[SIMPLAY_MAX], cflash_lap[SIMPLAY_MAX];
static int	tbest_lap_msg, ibest_lap_msg, cbest_lap_msg;

/*---------------------------------------------------------------------------*/
/* enemy mark */
typedef struct {
	float	px, py;
	float	ag;
	int	ct, fg;
} Enemymark;

Enemymark enemymark[SIMPLAY_MAX][BOAT_MAX];

/*---------------------------------------------------------------------------*/
/* pass message */
static int	cflash_pow, iflash_pow;

typedef struct {
	float	px, py;
	float	vx, vy;
	float	sc;
	int	ct, fg;
} Passmsg;

Passmsg	passmsg[SIMPLAY_MAX][PASS_MSG_MAX];

static uchar flash_col_pow1a[][3] = {	/* W-Y-G-Y-W */
	{ 255, 255, 255 },
	{ 255, 255,   0 },
	{   0, 255,   0 },
	{ 255, 255,   0 },
	{ 255, 255, 255 },
};

static uchar flash_col_pow1b[][3] = {	/* Y-G-K-G-Y */
	{ 255, 255,   0 },
	{   0, 255,   0 },
	{   0,   0,   0 },
	{   0, 255,   0 },
	{ 255, 255,   0 },
};

static uchar flash_col_pow2a[][3] = {	/* W-Y-R-Y-W */
	{ 255, 255, 255 },
	{ 255, 255,   0 },
	{ 255,   0,   0 },
	{ 255, 255,   0 },
	{ 255, 255, 255 },
};

static uchar flash_col_pow2b[][3] = {	/* Y-R-K-R-Y */
	{ 255, 128,   0 },
	{ 255,   0,   0 },
	{   0,   0,   0 },
	{ 255,   0,   0 },
	{ 255, 128,   0 },
};

static Vtx vtx_miss_msg_init[] = {
	{ -32, -10, 0,	0,	  0 << 6,  0 << 6,	255, 255,   0, 255 },
	{  32, -10, 0,	0,	 64 << 6,  0 << 6,	255, 255,   0, 255 },
	{ -32,  10, 0,	0,	  0 << 6, 20 << 6,	255, 120,   0, 255 },
	{  32,  10, 0,	0,	 64 << 6, 20 << 6,	255, 120,   0, 255 },
};

static Vtx vtx_p_up_msg_init[] = {
	{ -128, -20, 0,	0,	  0 << 6,  0 << 6,	255, 255,   0, 255 },
	{    0, -20, 0,	0,	128 << 6,  0 << 6,	255, 255,   0, 255 },
	{ -128,   0, 0,	0,	  0 << 6, 20 << 6,	  0, 255,   0, 255 },
	{    0,   0, 0,	0,	128 << 6, 20 << 6,	  0, 255,   0, 255 },
};

static Vtx vtx_p_down_msg_init[] = {
	{ -84, -10, 0,	0,	  0 << 6,  0 << 6,	255, 255,   0, 255 },
	{  84, -10, 0,	0,	168 << 6,  0 << 6,	255, 255,   0, 255 },
	{ -84,  10, 0,	0,	  0 << 6, 20 << 6,	255, 120,   0, 255 },
	{  84,  10, 0,	0,	168 << 6, 20 << 6,	255, 120,   0, 255 },
};

static Vtx vtx_maxpower_msg_init[] = {
	{ -144, -20, 0,	0,	  0 << 6,  0 << 6,	255, 255,   0, 255 },
	{    0, -20, 0,	0,	144 << 6,  0 << 6,	255, 255,   0, 255 },
	{ -144,   0, 0,	0,	  0 << 6, 20 << 6,	  0, 255,   0, 255 },
	{    0,   0, 0,	0,	144 << 6, 20 << 6,	  0, 255,   0, 255 },
};

/*---------------------------------------------------------------------------*/
static int	laptime_fig[7];
static char	strbuf[16];
static int	fstart_signal, start_signal_y, start_signal_y0;

/*---------------------------------------------------------------------------*/
static int	iflash_sc, cflash_sc;

/*---------------------------------------------------------------------------*/
static int	iflash;
static int	cflash;
static int	flash_color1[][3] = {
	{   0,   0,   0 },
	{ 255,   0,   0 },
	{ 255, 255,   0 },
	{ 255,   0,   0 },
	{   0,   0,   0 },
};

static int	flash_color2[][3] = {
	{   0,   0,   0 },
	{   0, 255,   0 },
	{ 255, 255,   0 },
	{   0, 255,   0 },
	{   0,   0,   0 },
};

static int	flash_color3[][3] = {
	{ 255, 128, 128 },
	{ 255, 190, 190 },
	{ 255, 255, 255 },
	{ 255, 190, 190 },
	{ 255, 128, 128 },
};

static int	flash_color4[][3] = {
	{ 128, 255, 128 },
	{ 190, 255, 190 },
	{ 255, 255, 255 },
	{ 190, 255, 190 },
	{ 128, 255, 128 },
};

/*---------------------------------------------------------------------------*/
static u16	perspNorm;

/*---------------------------------------------------------------------------*/
/* rank face */
typedef struct {
	int	px, py;
	int	dx, dy;
	int	cy;
} Rankface;

static Rankface rankface[SIMPLAY_MAX][BOAT_MAX];

static int	face_ofs[BOAT_MAX], face_ofs_dst[BOAT_MAX], face_ofs_v[BOAT_MAX];

static ushort	*face_tbl[] = {
	tx_face_1_1p, tx_face_2_1p, tx_face_3_1p, tx_face_4_1p, 
	tx_face_1_2p, tx_face_2_2p, tx_face_3_2p, tx_face_4_2p, 
};

static int	srank_zoom, srank_zoom_dst;

#ifdef EN_DSPRESULT_FLAG
/*---------------------------------------------------------------------------*/
/* vs result */
static int	fvs_result[SIMPLAY_MAX], cvs_result[SIMPLAY_MAX];
#endif

/*---------------------------------------------------------------------------*/
/* debug */
static int	ffirstinit = 1;
static int	stw0 = 0, stw1 = 0;

/******************************************************************************
	set flash color
******************************************************************************/
void SetFlashColor(void)
{
	int	i;
	float	f, g;

	f = (float)(FLASH_FRAME - cflash) / (float)FLASH_FRAME;
	g = 1.F - f;
	
	en_flash_r1 = flash_color1[iflash][0] * f + flash_color1[iflash + 1][0] * g;
	en_flash_g1 = flash_color1[iflash][1] * f + flash_color1[iflash + 1][1] * g;
	en_flash_b1 = flash_color1[iflash][2] * f + flash_color1[iflash + 1][2] * g;
		
	en_flash_r2 = flash_color2[iflash][0] * f + flash_color2[iflash + 1][0] * g;
	en_flash_g2 = flash_color2[iflash][1] * f + flash_color2[iflash + 1][1] * g;
	en_flash_b2 = flash_color2[iflash][2] * f + flash_color2[iflash + 1][2] * g;
		
	if (frank_process) {
		i = 0;
		f = 1.F;
		g = 0.F;
	}
	else
		i = iflash;

	en_flash_r3 = flash_color3[i][0] * f + flash_color3[i + 1][0] * g;
	en_flash_g3 = flash_color3[i][1] * f + flash_color3[i + 1][1] * g;
	en_flash_b3 = flash_color3[i][2] * f + flash_color3[i + 1][2] * g;
		
	en_flash_r4 = flash_color4[i][0] * f + flash_color4[i + 1][0] * g;
	en_flash_g4 = flash_color4[i][1] * f + flash_color4[i + 1][1] * g;
	en_flash_b4 = flash_color4[i][2] * f + flash_color4[i + 1][2] * g;
		
	if (pause_mode == PAUSE_MODE_OFF && ++cflash >= FLASH_FRAME) {
		cflash = 0;
		iflash = ++iflash & 3;
	}
}

/******************************************************************************
	init game status
******************************************************************************/
void InitGameStatus(void)
{
	int	i, j, k, n;

/*---------------------------------------------------------------------------*/
/* first init */
	if (ffirstinit) {
		ffirstinit = 0;
#if MENU_SW
#if 0
		entry_menu(1, 11, 1, "STW0", 20, 1, MENU_TYPE_INT, 5, 0, &stw0, &int_min, &int_max);
		entry_menu(1, 11, 2, "STW1", 20, 2, MENU_TYPE_INT, 5, 0, &stw1, &int_min, &int_max);
#endif
#endif
	}


/*---------------------------------------------------------------------------*/
/* flash color */
	SetFlashColor();

/*---------------------------------------------------------------------------*/
/* scroll */
	fstatus_move = scrofs1 = scrofs2 = 0;

/*---------------------------------------------------------------------------*/
/* passmsg */
	for (i = 0; i < SIMPLAY_MAX; i++) {
		for (j = 0; j < PASS_MSG_MAX; j++) {
			passmsg[i][j].fg = passmsg[i][j].ct = 0;
			passmsg[i][j].px = passmsg[i][j].py = 
			passmsg[i][j].vx = passmsg[i][j].vy = 0.F;
		}
	}

	for (k = 0; k < 2; k++) {
		for (i = 0; i < 4; i++) {
			endynamic[k].vtx_miss_msg[i] = vtx_miss_msg_init[i];
			endynamic[k].vtx_p_up_msg[i] = vtx_p_up_msg_init[i];
			endynamic[k].vtx_p_down_msg[i] = vtx_p_down_msg_init[i];
			endynamic[k].vtx_maxpower_msg[i] = vtx_maxpower_msg_init[i];
		}
	}

/*---------------------------------------------------------------------------*/
/* start signal */
	fstart_signal = 0;
	cstart_signal = (3 + 1) * SIGNAL_SEC;
	if (ncourse == NCOURSE_PARK || game_kind == GAME_KIND_SCORE)
		k = 1;
	else
		k = 0;
	for (i = 0; i < boat_max; i++)
		fstart_power[i] = k;
	start_signal_y0 = players == 1 ? SIGNAL_INIT_Y1 : SIGNAL_INIT_Y2;
	if (game_kind == GAME_KIND_ATTACK || game_kind == GAME_KIND_SCORE)
		start_signal_y = 0;
	else
		start_signal_y = start_signal_y0;

/*---------------------------------------------------------------------------*/
/* lap time flashing */
	iflash = cflash = iflash_pow = cflash_pow = 0;
	fbest_lap_msg = tbest_lap_msg = ibest_lap_msg = cbest_lap_msg = 0;
	for (i = 0; i < SIMPLAY_MAX; i++)
		tflash_lap[i] = iflash_lap[i] = cflash_lap[i] = 0;
	clast_lap_flash = 0;

/*---------------------------------------------------------------------------*/
/* rank face */
	for (n = 0; n < players; n++) {
		for (i = 0; i < boat_max; i++) {
			rankface[n][i].dy = chkcrs[i].rank * 24;
		}
		for (i = 0; i < boat_max; i++) {
			if (players == 1) {
				if (chkcrs[i].rank > chkcrs[my_hover].rank)
					rankface[n][i].dy += 4;
			}
			else if (n == 0) {
				if (chkcrs[i].rank > chkcrs[my_hover].rank)
					rankface[n][i].dy += 4;
			}
			else if (chkcrs[i].rank > chkcrs[your_hover].rank)
				rankface[n][i].dy += 4;
		}
		for (i = 0; i < boat_max; i++) {
			rankface[n][i].px = rankface[n][i].dx = rankface[n][i].cy = 0;
			rankface[n][i].py = rankface[n][i].dy;
		}
	}

	for (i = 0; i < BOAT_MAX; i++) {
		face_ofs[i] = face_ofs_dst[i] = 0;
		face_ofs_v[i] = 1;
	}

/*---------------------------------------------------------------------------*/
/* score msg */
	for (i = 0; i < SCORE_MSG_MAX; i++)
		scoremsg[i].fg = 0;
	cextend_msg = 0;

/*---------------------------------------------------------------------------*/
/* rank zoom */
	frank_zoom = 0;
	srank_zoom = srank_zoom_dst = 0;

/*---------------------------------------------------------------------------*/
/* enemy mark */
	for (n = 0; n < players; n++) {
		for (i = 0; i < BOAT_MAX; i++) {
			enemymark[n][i].fg = enemymark[n][i].ct = 0;
			enemymark[n][i].px = enemymark[n][i].py = enemymark[n][i].ag = 0.F;
		}
	}

/*---------------------------------------------------------------------------*/
/* crsout time */
	if (game_kind != GAME_KIND_SCORE && ncourse == NCOURSE_PARK)
		crsout_time = (10 + 1) * FRAME_SEC - 1;
	else
		crsout_time = (5 + 1) * FRAME_SEC - 1;

#ifdef EN_DSPRESULT_FLAG
/*---------------------------------------------------------------------------*/
/* vs result */
	fvs_result_draw = 0;
	for (i = 0; i < SIMPLAY_MAX; i++)
		fvs_result[i] = 0;
#endif

}


/******************************************************************************
	set projection matrix
******************************************************************************/
void SetProjectionMatrix(void)
{
	Mtxf	mf;

	make_SCRmatrix(&pendynamic->mtx_persp, &perspNorm,
		24.F, (float)SCREEN_WD / SCREEN_HT,
		16.F, 4096.F, 0.F, 0.F);
	make_LOOKmatrix(&pendynamic->mtx_lookat, &mf,
		0.F, 512.F, 1500.F,
		0.F, 0.F, 0.F,
		0.F, 1.F, 0.F);
	guOrtho(&pendynamic->mtx_ortho,
		-(float)SCREEN_WD / 2.F, (float)SCREEN_WD / 2.F,
		-(float)SCREEN_HT / 2.F, (float)SCREEN_HT / 2.F,
		-1024.F, 1024.F, 1.F);
	guOrtho(&pendynamic->mtx_ortho2,
		0.F, (float)SCREEN_WD,
		(float)SCREEN_HT, 0.F,
		-1024.F, 1024.F, 1.F);
}


/******************************************************************************
	do indicator
******************************************************************************/

void DoIndicator(void)
{
	int	i, j, k, n, ibnext, fgook, fdisp, fring, fnoarw;
	float	f, fcos, fsin, thang, fsin_l, fsin_r;
	float	fx, fz, gx, gz, gl;
	Camera	*pcamera;
	Boat	*pboat;
	Chkcrs	*pchkcrs;
	Buoy	*pbuoy;
	Crsobj	*pcrsobj;

	for (n = 0; n < players; n++) {
		if (n == 0) {
			pcamera = &camera[my_camera];
			pboat   = &hover[my_hover];
			pchkcrs = &chkcrs[my_hover];
		}
		else {
			pcamera = &camera[your_camera];
			pboat   = &hover[your_hover];
			pchkcrs = &chkcrs[your_hover];
		}

#if 0
		fx = pboat->obj.Zx;
		fz = pboat->obj.Zz;
#endif
		fx = pcamera->camera_fx;
		fz = pcamera->camera_fz;
		if ((f = LENGTH2(fx, fz)) > 0.F) {
			fx /= f;
			fz /= f;
		}
		
#if 0
		if (pchkcrs->lap == pchkcrs->rlap)
			ibnext = pchkcrs->ibnext;
		else
			ibnext = ngoalbuoy;
#endif

		if (pchkcrs->ftryagain)
			ibnext = pchkcrs->ibnext;
		else if (pchkcrs->ibrail == pchkcrs->ibnext &&
		    pchkcrs->rlap == pchkcrs->lap) {
			ibnext = pchkcrs->ibnext;
			pbuoy = &buoy[ibnext];
			f = (pboat->obj.gpx - pbuoy->px) * pbuoy->fx +
			    (pboat->obj.gpz - pbuoy->pz) * pbuoy->fz;
			if (f > 0.F)
				ibnext = pbuoy->c1;
		}
		else {
			ibnext = pchkcrs->ibrail;
			pbuoy = &buoy[ibnext];
			f = (pboat->obj.gpx - pbuoy->px) * pbuoy->fx +
			    (pboat->obj.gpz - pbuoy->pz) * pbuoy->fz;
			if (f > -256.F)
				ibnext = pbuoy->c1;
		}
	
		pbuoy = &buoy[ibnext];
		gx = pbuoy->px - pcamera->camera_px;
		gz = pbuoy->pz - pcamera->camera_pz;
		if ((gl = LENGTH2(gx, gz)) > 0.F) {
			gx /= gl;
			gz /= gl;
		}
/*		printf("%8.2f\n", gl);	*/

		if (pbuoy->tp == 0 && !pchkcrs->idc_cnt2) {
/*		if (pbuoy->tp == 0) {	*/
			fcos = pbuoy->fx * fx + pbuoy->fz * fz;
			fsin = pbuoy->fx * gz - pbuoy->fz * gx;
/*			printf("sc: %6.2f %6.2f\n", fcos, fsin);	*/
#if 0
			fgook = (pbuoy->type == BUOY_KD_RIGHT && fsin < 0.F) ||
		 		(pbuoy->type == BUOY_KD_LEFT  && fsin > 0.F) ||
				pbuoy->type == BUOY_KD_CENTER;
			if (fcos < 0.F)
				fgook = 0;
#endif
			if ((pbuoy->type == BUOY_KD_RIGHT && fsin > 0.F) ||
			    (pbuoy->type == BUOY_KD_LEFT  && fsin < 0.F) ||
			    fcos < 0.F)
				fgook = 0;
			else
				fgook = 1;
		}
		else
			fgook = 0;

		thang = 0.7F;
	
		fcos = fx * gx + fz * gz;
		fsin = fx * gz - fz * gx;	/* right , > 0 */
		pchkcrs->idc_dst = acos(fcos);
		if (fsin > 0.F)
			pchkcrs->idc_dst = 360 - pchkcrs->idc_dst;
	
		j = DEFA(pchkcrs->idc_dst, pchkcrs->idc_cur);
#if 1
		if ((k = j / 8) < 2)
			k = 2;
#endif
		if (j <= k)
			pchkcrs->idc_cur = pchkcrs->idc_dst;
		else
			pchkcrs->idc_cur += SGNA(pchkcrs->idc_dst, pchkcrs->idc_cur) * k;
	
		/* at gate */
		if (fcos < thang && pbuoy->tp == 1) {
			gx = pbuoy->lpx - pcamera->camera_px;
			gz = pbuoy->lpz - pcamera->camera_pz;
			if ((gl = LENGTH2(gx, gz)) > 0.F) {
				gx /= gl;
				gz /= gl;
			}
			fsin_l = fx * gz - fz * gx;
			if ((fcos = fx * gx + fz * gz) < thang) {
				gx = pbuoy->rpx - pcamera->camera_px;
				gz = pbuoy->rpz - pcamera->camera_pz;
				if ((gl = LENGTH2(gx, gz)) > 0.F) {
					gx /= gl;
					gz /= gl;
				}
				fsin_r = fx * gz - fz * gx;
				if (fsin_l < 0.F && fsin_r > 0.F)
					fcos = 1.F;
				else
					fcos = fx * gx + fz * gz;
			}	
		}

#if 0
		fdisp = (fcos < thang && (gl > 1024.F || !fgook)) || gl > 3072.F ||
			pchkcrs->ftryagain || pchkcrs->fcrsout; 
#endif
		fdisp = fcos < thang && (gl > 2048.F || !fgook);
		if (pchkcrs->fincave)
			fdisp = 0;

		fnoarw = ChkNoArrowArea(pcamera->camera_px, pcamera->camera_pz);
		if (fnoarw) {
			fdisp = 0;
/*			printf("no arrow area\n");	*/
		}

/*		printf("id: %8.2f %8.0f %8d %8d\n", fcos, gl, fgook, ibnext);	*/

		/*---------------------------------------------------------------------------*/
		/* score attack special */
		if (game_kind == GAME_KIND_SCORE) {
			fring = 0;
			for (i = 0; i < nofcrsobj; i++) {
				pcrsobj = &crsobj[i];
				if (pcrsobj->kd != CRSOBJ_KD_RING)
					continue;
				gx = pcrsobj->px - pcamera->camera_px;
				gz = pcrsobj->pz - pcamera->camera_pz;
				if ((gl = LENGTH2(gx, gz)) > 0.F) {
					gx /= gl;
					gz /= gl;
				}
				if (fx * gx + fz * gz >= thang && gl < 4096.F) {
					fring = 1;
					break;
				}
			}
			if (fring)
				fdisp = 0;
		}

		/*---------------------------------------------------------------------------*/
		/* force display */
		if (pchkcrs->ftryagain || pchkcrs->fcrsout || pchkcrs->creverse >= REVERSE_FRAME)
			fdisp = 1;

		/*---------------------------------------------------------------------------*/
		/* force no display */
		if (game_kind != GAME_KIND_SCORE && ncourse == NCOURSE_PARK)
			fdisp = 0;

		if (fdisp && reverseRunFlag && ncourse == NCOURSE_3 && pchkcrs->lap >= 2) {
			gx = pboat->obj.gpx - (-2500.F);
			gz = pboat->obj.gpz -   2800.F;
			if (gx * gx + gz * gz < 700.F * 700.F) {
				fdisp = 0;
/*				printf("no indicator\n");	*/
			}
		}

		/*---------------------------------------------------------------------------*/
		if (fdisp) {
			if (pchkcrs->idc_cnt < 0x7fffffff)
				pchkcrs->idc_cnt++;
		}
		else
			pchkcrs->idc_cnt = 0;
		
		if (pchkcrs->idc_cnt >= 4 * 2 || pchkcrs->idc_cnt3 > 1) {
			if (pchkcrs->idc_cnt3 == 0)
				pchkcrs->idc_cnt3 = 8;
			if (pchkcrs->idc_cnt2 < 4)
				pchkcrs->idc_cnt2++;
			if (pchkcrs->idc_cnt3 > 1)
				pchkcrs->idc_cnt3--;
		}
		else if (pchkcrs->idc_cnt3 == 0) {
			if (pchkcrs->idc_cnt2 > 0)
				pchkcrs->idc_cnt2--;
		}
		else
			pchkcrs->idc_cnt3--;

		/*---------------------------------------------------------------------------*/
		/* reverse */
		fx = pboat->obj.Zx;
		fz = pboat->obj.Zz;
		if ((f = LENGTH2(fx, fz)) > 0.F) {
			fx /= f;
			fz /= f;
		}
		gx = pbuoy->px - pboat->obj.gpx;
		gz = pbuoy->pz - pboat->obj.gpz;
		if ((f = LENGTH2(gx, gz)) > 0.F) {
			gx /= f;
			gz /= f;
		}
		fcos = fx * gx + fz * gz;
		f = acos(fcos);
			

		if (f >= 100.F && pboat->body_speed * KM_H >= 10.F &&
		    !ChkNoArrowArea(pboat->obj.gpx, pboat->obj.gpz) &&
		    ncourse != NCOURSE_PARK) {
			if (pchkcrs->creverse < 0x7fffffff)
				pchkcrs->creverse++;
		}
		else
			pchkcrs->creverse = 0;

/*		printf("rv: %8.2f %8d\n", f, pchkcrs->creverse);	*/

#if 0
		k = pchkcrs->idc_cur - 180;
		if (fdisp && ABS(k) <= 80 && pboat->body_speed * KM_H >= 10.F &&
		    pcamera->game_camera_round_mode == GCRM_NORMAL) {
			if (pchkcrs->creverse < 0x7fffffff)
				pchkcrs->creverse++;
		}
		else
			pchkcrs->creverse = 0;
#endif

		if (pchkcrs->creverse >= REVERSE_FRAME && (pchkcrs->creverse % 20) == 0 &&
		    signal_mode == SIGNAL_MODE_RACE) {
			Na_SystemSound(NA_SYS_REVERSE, n);
/*			printf("se\n");	*/
		}
	}
	
/*	printf("id: %8d%8d\n", pchkcrs->idc_cnt, pchkcrs->idc_cur);	*/
	
/*	printf("c3: %d\n", chkcrs[my_hover].idc_cnt3);	*/
}
	
/******************************************************************************
	draw indicator
******************************************************************************/

void DrawIndicator(Gfx **ppgfx)
{
	int	n, falpha;
	Gfx	*pgfx = *ppgfx;
	Chkcrs	*pchkcrs;

/*---------------------------------------------------------------------------*/
/* init RCP */
	gSPDisplayList(pgfx++, gfx_init_indicator);
	gSPPerspNormalize(pgfx++, perspNorm);

/*---------------------------------------------------------------------------*/
/* draw */
#define G_CC_INDICATOR	0, 0, 0, SHADE,  0, 0, 0, PRIMITIVE

	for (n = 0; n < players; n++) {
		if (n == 0)
			pchkcrs = &chkcrs[my_hover];
		else
			pchkcrs = &chkcrs[your_hover];
		
/*		falpha = pchkcrs->idc_cnt2 * 96 / 4;	*/
		falpha = pchkcrs->idc_cnt2 * 255 / 4;
/*		printf("ia: %8d\n", falpha);	*/
	
		if (falpha > 0 && !pchkcrs->ffinish && !pchkcrs->fretire) { 
			if (players == 1) {
				gSPViewport(pgfx++, &vp_indicator0);
			}
			else {
				if (n == 0) {
					gSPViewport(pgfx++, &vp_indicator1);
				}
				else {
					gSPViewport(pgfx++, &vp_indicator2);
				}
			}

			gDPPipeSync(pgfx++);
			if (pchkcrs->creverse >= REVERSE_FRAME && (pchkcrs->creverse % 20) == 0) {
				gDPSetCombineMode(pgfx++, G_CC_PRIMITIVE, G_CC_PRIMITIVE);
			}
			else {
				gDPSetCombineMode(pgfx++, G_CC_INDICATOR, G_CC_INDICATOR);
			}

		 	egRotate(&pendynamic->mtx_model[ienmtxmdl], pchkcrs->idc_cur, 0.F, 1.F, 0.F);
			gSPMatrix(pgfx++, &rsp_endynamic.mtx_model[ienmtxmdl++], G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_PUSH);
			gDPPipeSync(pgfx++);
			gDPSetPrimColor(pgfx++, 0, 0,  255, 150, 150, falpha);
			if (falpha < 255) {
				gDPSetRenderMode(pgfx++, G_RM_AA_XLU_SURF, G_RM_AA_XLU_SURF2);
			}
			else {
				gDPSetRenderMode(pgfx++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2);
			}
			gSPDisplayList(pgfx++, arrow_model);
			gSPPopMatrix(pgfx++, G_MTX_MODELVIEW);
		}
	}

/*---------------------------------------------------------------------------*/
/* restore */
	gSPViewport(pgfx++, &vp_normal);
	gSPMatrix(pgfx++, &dynamic.projection_MT, G_MTX_PROJECTION | G_MTX_LOAD | G_MTX_NOPUSH);
	gSPMatrix(pgfx++, &dynamic.viewing_MT, G_MTX_PROJECTION | G_MTX_MUL | G_MTX_NOPUSH);
	gSPPerspNormalize(pgfx++, camera[my_camera].perspNorm);


/*---------------------------------------------------------------------------*/
/* end */
	*ppgfx = pgfx;
	
/*	printf("c3: %d\n", chkcrs[my_hover].idc_cnt3);	*/
}
	
/******************************************************************************
	do start signal
******************************************************************************/

void DoStartSignal(void)
{
	int	i, j;

	if (signal_mode == SIGNAL_MODE_ON || signal_mode == SIGNAL_MODE_ZERO) {
#ifndef ROM_FLAG
		if (signal_mode == SIGNAL_MODE_ON && (pad[pad_no[0]].hold & Z_TRIG) && (pad[pad_no[0]].trig & A_BUTTON)) {
			start_signal_y = 0;
			cstart_signal = SIGNAL_SEC + 1;
			chkcrs[my_hover].passpnt = PASSPNT_MAX;
			chkcrs[my_hover].tbpass = chkcrs[my_hover].fpowmsg = 1;
			fstart_power[my_hover] = 1;
		}
#endif
		if (fstart_signal == 0) {
			if ((start_signal_y -= 3) <= 0) {
				start_signal_y = 0;
				fstart_signal = 1;
			}
		}
		else {
			if (cstart_signal % SIGNAL_SEC == 0) {
				if (signal_mode != SIGNAL_MODE_ZERO) {
					Na_SystemSound(NA_SYS_SIGNAL1, cstart_signal / SIGNAL_SEC - 1);
				}
				else {
					Na_SystemSound(NA_SYS_SIGNAL2, 0);
				}
			}
			j = cstart_signal - SIGNAL_SEC;
			j = ABS(j);
			if (j < SIGNAL_SEC) {
				for (i = 0; i < boat_max; i++) {
					if (hover[i].controller.trig & ACCEL_BT && fstart_power[i] == 0) {
						if (j <= SIGNAL_TIMING_A)
							chkcrs[i].passpnt = PASSPNT_MAX;
						else if (j <= SIGNAL_TIMING_B)
							chkcrs[i].passpnt = 4;
						else if (j <= SIGNAL_TIMING_C)
							chkcrs[i].passpnt = 3;
						else if (j <= SIGNAL_TIMING_D)
							chkcrs[i].passpnt = 2;
						else if (j <= SIGNAL_TIMING_E)
							chkcrs[i].passpnt = 1;
						if (j <= SIGNAL_TIMING_E)
							chkcrs[i].tbpass = chkcrs[i].fpowmsg = 1;
						fstart_power[i] = 1;
					}
				}
			}
#if 0
			if ((cstart_signal -= 1) == SIGNAL_SEC) {
				signal_mode = SIGNAL_MODE_ZERO;
				ftime_stop = 0;
			}
			else if (cstart_signal == 0) {
				signal_mode = SIGNAL_MODE_RACE;
				fstart_signal = 2;
			}
#endif
			cstart_signal -= 1;
			if (cstart_signal == SIGNAL_SEC) {
				signal_mode = SIGNAL_MODE_ZERO;
				ftime_stop = 0;
			}
			else if (cstart_signal <= 0) {
				signal_mode = SIGNAL_MODE_RACE;
				fstart_signal = 2;
			}
		}
	}
	else if (fstart_signal == 2) {
		if (pause_mode == PAUSE_MODE_OFF)
			if ((start_signal_y += 6) >= start_signal_y0)
				fstart_signal = 0;
	}

#if 0
	printf("cs: %8d,%8d%8d,%8d%8d\n",
		signal_mode, cstart_signal, fstart_signal, start_signal_y, start_signal_y0);
#endif

/*	printf("cs: %d %d\n", fstart_power[my_hover], chkcrs[my_hover].passpnt);	*/
}

/******************************************************************************
	draw start signal
******************************************************************************/

void DrawStartSignal(Gfx **ppgfx)
{
	int	i, n;
	float	ang;
	ushort	*ptex0, *ptex1, *ptex2, *ptex3; 
	Gfx	*pgfx = *ppgfx;
	Mtxf	mf;

/*---------------------------------------------------------------------------*/
/* calc */
	if ((n = (cstart_signal - 1) / SIGNAL_SEC) < 0)
		n = 0;
	if (fstart_signal == 0)
		n = 4;

	if (n > 0 && n <= 3)
		ptex0 = sig_red_on_txt;
	else
		ptex0 = sig_red_off_txt;
	
	if (n > 0 && n <= 2)
		ptex1 = sig_red_on_txt;
	else
		ptex1 = sig_red_off_txt;
	
	if (n == 1)
		ptex2 = sig_red_on_txt;
	else
		ptex2 = sig_red_off_txt;
	
	if (n == 0)
		ptex3 = sig_green_on_txt;
	else
		ptex3 = sig_green_off_txt;
	

/*---------------------------------------------------------------------------*/
/* init RCP */
	gSPDisplayList(pgfx++, gfx_init_start_signal);
	make_SCRmatrix(&pendynamic->mtx_model[ienmtxmdl], &perspNorm,
		120.F, (float)SCREEN_WD / SCREEN_HT,
		16.F, 1024.F, 0.F, 0.F);
	gSPMatrix(pgfx++, &rsp_endynamic.mtx_model[ienmtxmdl++], G_MTX_PROJECTION | G_MTX_LOAD | G_MTX_NOPUSH);
	make_LOOKmatrix(&pendynamic->mtx_model[ienmtxmdl], &mf,
		0.F, 0.F, 60.F + (players == 2) * 20.F,
		0.F, 0.F, 0.F,
		0.F, 1.F, 0.F);
	gSPMatrix(pgfx++, &rsp_endynamic.mtx_model[ienmtxmdl++], G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_NOPUSH);
	gSPPerspNormalize(pgfx++, perspNorm);

/*---------------------------------------------------------------------------*/
/* draw */
	egTranslate(&pendynamic->mtx_model[ienmtxmdl], 0.F, start_signal_y, 0.F);
	gSPMatrix(pgfx++, &rsp_endynamic.mtx_model[ienmtxmdl++], G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_NOPUSH);

	ang = (float)start_signal_y / SIGNAL_INIT_Y1 * 120.F;
	if (fstart_signal == 2)
		ang = -ang;
	egRotate(&pendynamic->mtx_model[ienmtxmdl], ang, 0.F, 1.F, 0.F);
	gSPMatrix(pgfx++, &rsp_endynamic.mtx_model[ienmtxmdl++], G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_NOPUSH);

	for (i = 0; i < players; i++) {
		if (players == 1) {
			gSPViewport(pgfx++, &vp_start_signal0);
		}
		else if (i == 0) {
			gSPViewport(pgfx++, &vp_start_signal1);
		}
		else {
			gDPPipeSync(pgfx++);
			gDPSetScissor(pgfx++, G_SC_NON_INTERLACE,
				DISPLAY_X1_2P, DISPLAY_Y1_2P, 
				DISPLAY_X2_2P, DISPLAY_Y2_2P);
			gSPViewport(pgfx++, &vp_start_signal2);
		}
		gDPLoadTextureBlock(pgfx++, ptex0, G_IM_FMT_RGBA, G_IM_SIZ_16b, 32, 32, 0,
			G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
		gSPDisplayList(pgfx++, signal_model0);
		gDPLoadTextureBlock(pgfx++, ptex1, G_IM_FMT_RGBA, G_IM_SIZ_16b, 32, 32, 0,
			G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
		gSPDisplayList(pgfx++, signal_model1);
		gDPLoadTextureBlock(pgfx++, ptex2, G_IM_FMT_RGBA, G_IM_SIZ_16b, 32, 32, 0,
			G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
		gSPDisplayList(pgfx++, signal_model2);
		gDPLoadTextureBlock(pgfx++, ptex3, G_IM_FMT_RGBA, G_IM_SIZ_16b, 32, 32, 0,
			G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
		gSPDisplayList(pgfx++, signal_model3);
	}

/*---------------------------------------------------------------------------*/
/* restore */
	gSPViewport(pgfx++, &vp_normal);
	if (players == 2) {
		gDPPipeSync(pgfx++);
		gDPSetScissor(pgfx++, G_SC_NON_INTERLACE,
			DISPLAY_X1_1P, DISPLAY_Y1_1P, DISPLAY_X2_2P, DISPLAY_Y2_2P);
	}
	gSPMatrix(pgfx++, &dynamic.projection_MT, G_MTX_PROJECTION | G_MTX_LOAD | G_MTX_NOPUSH);
	gSPMatrix(pgfx++, &dynamic.viewing_MT, G_MTX_PROJECTION | G_MTX_MUL | G_MTX_NOPUSH);
	gSPPerspNormalize(pgfx++, camera[my_camera].perspNorm);


/*---------------------------------------------------------------------------*/
/* end */
	*ppgfx = pgfx;
	
}

/******************************************************************************
	do power message
******************************************************************************/

void DoPowerMsg(void)
{
	int	i, k, n, ix, iy;
	Chkcrs	*pchkcrs;
	Passmsg	*ppassmsg;

/*---------------------------------------------------------------------------*/
/* position */
	for (n = 0; n < players; n++) {
		if (n == 0)
			pchkcrs = &chkcrs[my_hover];
		else
			pchkcrs = &chkcrs[your_hover];

		/*---------------------------------------------------------------------------*/
		/* appear */
		if (pchkcrs->tbpass && !(passmsg[n][0].fg && pchkcrs->fmiss_over)) {
			iflash_pow = cflash_pow = 0;

			if (pchkcrs->tbpass == 1 &&
			    (pchkcrs->fpowmsg || passmsg[n][1].fg == PASS_MSG_DOWN)) {
				/*---------------------------------------------------------------------------*/
				/* power up */

				if (passmsg[n][1].fg == PASS_MSG_DOWN) {
					passmsg[n][1].fg = 0;
					pchkcrs->passpnt = 1;
				}
				ppassmsg = &passmsg[n][2];
				ppassmsg->fg = PASS_MSG_UP;
				if (players == 1)
					ppassmsg->sc = 1.F;
				else
					ppassmsg->sc = 0.7F;
				ppassmsg->vx = 64.F * ppassmsg->sc;
				ppassmsg->vy = 10.F * ppassmsg->sc;

				if (players == 1) {
					ppassmsg->px = DISPLAY_X1 + 292.F;
					ppassmsg->py = DISPLAY_Y1 + 186.F;
				}
				else if (n == 0) {
					ppassmsg->px = DISPLAY_X1_1P + 292;
					ppassmsg->py = DISPLAY_Y1_1P + 93.F;
				}
				else {
					ppassmsg->px = DISPLAY_X1_2P + 292;
					ppassmsg->py = DISPLAY_Y1_2P + 93.F;
				}

#if 0
				if (pchkcrs->passpnt >= PASSPNT_MAX)
					ppassmsg->px -= 6.F;				
#endif
				if (pchkcrs->passpnt < PASSPNT_MAX)
					ppassmsg->ct = FRAME_MSG_UP;
				else
					ppassmsg->ct = 0;
			}
			else if (pchkcrs->tbpass == 2 && pchkcrs->miss_sum <= miss_limit) {
				/*---------------------------------------------------------------------------*/
				/* miss */

				ppassmsg = &passmsg[n][0];
				ppassmsg->fg = PASS_MSG_MISS;
				if (pchkcrs->passpnt >= PASSPNT_MAX)
					passmsg[n][2].fg = 0;
				
				if (players == 1) {
					ppassmsg->px = DISPLAY_X1 + 152.F;
					ppassmsg->py = DISPLAY_Y1 + 72.F - 15;
					ix = DISPLAY_X1 + 48 + (miss_limit - pchkcrs->miss_sum) * 14 + 6;
					iy = DISPLAY_Y1 + 185 + 6;
				}
				else if (n == 0) {
					ppassmsg->px = DISPLAY_X1_1P + 152.F;
					ppassmsg->py = DISPLAY_Y1_1P + 24.F;
					ix = DISPLAY_X1_1P + 16 + (miss_limit - pchkcrs->miss_sum) * 14 + 6;
					iy = DISPLAY_Y1_1P + 92 + 6;
				}
				else {
					ppassmsg->px = DISPLAY_X1_2P + 152.F;
					ppassmsg->py = DISPLAY_Y1_2P + 24.F;
					ix = DISPLAY_X1_2P + 16 + (miss_limit - pchkcrs->miss_sum) * 14 + 6;
					iy = DISPLAY_Y1_2P + 92 + 6;
				}
				ppassmsg->ct = FRAME_MSG_MISS + 8;
				ppassmsg->vx = (ix - ppassmsg->px) / (float)FRAME_MSG_MISS;
				ppassmsg->vy = (iy - ppassmsg->py) / (float)FRAME_MSG_MISS;


				/*---------------------------------------------------------------------------*/
				/* power down */
				if (pchkcrs->passpnt > 0 && passmsg[n][1].fg != PASS_MSG_DOWN) {
					ppassmsg = &passmsg[n][1];
					ppassmsg->fg = PASS_MSG_DOWN;
					if (players == 1) {
						ppassmsg->px = DISPLAY_X1 + 152.F;
						ppassmsg->py = DISPLAY_Y1 + 72.F + 24.F + 5;
						ix = DISPLAY_X1 + 180 + 10;
						iy = DISPLAY_Y1 + 187 + 4;
					}
					else if (n == 0) {
						ppassmsg->px = DISPLAY_X1_1P + 152.F;
						ppassmsg->py = DISPLAY_Y1_1P + 66.F;
#if LOCALE==CHINA
						ix = DISPLAY_X1_1P + 180;
#else
						ix = DISPLAY_X1_1P + 180 + 10;
#endif

						iy = DISPLAY_Y1_1P + 94 + 4;
					}
					else {
						ppassmsg->px = DISPLAY_X1_2P + 152.F;
						ppassmsg->py = DISPLAY_Y1_2P + 66.F;
#if LOCALE==CHINA
						ix = DISPLAY_X1_1P + 180;
#else
						ix = DISPLAY_X1_2P + 180 + 10;
#endif
						iy = DISPLAY_Y1_2P + 94 + 4;
					}
					ppassmsg->ct = FRAME_MSG_DOWN + 8;
					ppassmsg->vx = (ix - ppassmsg->px) / (float)FRAME_MSG_DOWN;
					ppassmsg->vy = (iy - ppassmsg->py) / (float)FRAME_MSG_DOWN;
					ppassmsg->sc = 1.F;
				}
			}
		}
		
		/*---------------------------------------------------------------------------*/
		/* move */
		
		for (i = 0; i < 3; i++) {
			ppassmsg = &passmsg[n][i];
			if (ppassmsg->fg) {
				if (ppassmsg->fg == PASS_MSG_MISS) {
					if (ppassmsg->ct <= FRAME_MSG_MISS) {
						ppassmsg->px += ppassmsg->vx;
						ppassmsg->py += ppassmsg->vy;
					}
					if ((ppassmsg->sc = ((float)ppassmsg->ct + 0.5F) / ((float)FRAME_MSG_MISS + 0.5F)) > 1.F)
						ppassmsg->sc = 1.F;

					if (--ppassmsg->ct < 0) {
						ppassmsg->fg = 0;
						if (pchkcrs->fmiss_over)
							SetRetire(pchkcrs);
					}
				}
				else if (ppassmsg->fg == PASS_MSG_DOWN) {
					if (ppassmsg->ct <= FRAME_MSG_DOWN) {
						ppassmsg->px += ppassmsg->vx;
						ppassmsg->py += ppassmsg->vy;
					}
					if ((ppassmsg->sc = ((float)ppassmsg->ct + 0.5F) / ((float)FRAME_MSG_MISS + 0.5F)) > 1.F)
						ppassmsg->sc = 1.F;

					if (--ppassmsg->ct < 0) {
						ppassmsg->fg = 0;
						pchkcrs->passpnt = 0;
					}
				}
				else if (ppassmsg->fg == PASS_MSG_UP) {
					if (pchkcrs->passpnt < PASSPNT_MAX) {
						if (--ppassmsg->ct < 0)
							ppassmsg->fg = 0;
					}
					else {
						if (ppassmsg->ct < 255)
							ppassmsg->ct++;
						if (ppassmsg->ct >= 20)
							if ((ppassmsg->sc -= .08F) < 0.7F)
								ppassmsg->sc = 0.7F;
					}
				}
			}
		}
	}



}

/******************************************************************************
	draw power message
******************************************************************************/

void DrawPowerMsg(Gfx **ppgfx)
{
	int	i, j, n;
	int	r1, g1, b1;
	int	r2, g2, b2;
	float	f, g;
	uchar	(*col1)[3], (*col2)[3];
	Vtx_t	*pvtx;
	Gfx	*pgfx = *ppgfx;
	Passmsg	*ppassmsg;
	Chkcrs	*pchkcrs;

/*---------------------------------------------------------------------------*/
/* flash color */
	f = (float)(FLASH_FRAME - cflash_pow) / (float)FLASH_FRAME;
	g = 1.F - f;

	for (i = 0; i < 4; i++) {
		if (i == 0) {
			col1 = flash_col_pow1a;
			col2 = flash_col_pow1b;
			pvtx = &pendynamic->vtx_p_up_msg[0].v;
		}
		else if (i == 1) {
			pvtx = &pendynamic->vtx_maxpower_msg[0].v;
		}
		else if (i == 2) {
			col1 = flash_col_pow2a;
			col2 = flash_col_pow2b;
			pvtx = &pendynamic->vtx_p_down_msg[0].v;
		}
		else {
			pvtx = &pendynamic->vtx_miss_msg[0].v;
		}
			
		if (i == 0 || i == 2) {
			r1 = col1[iflash_pow][0] * f;
			g1 = col1[iflash_pow][1] * f;
			b1 = col1[iflash_pow][2] * f;
			r1 += col1[iflash_pow + 1][0] * g;
			g1 += col1[iflash_pow + 1][1] * g;
			b1 += col1[iflash_pow + 1][2] * g;
		
			r2 = col2[iflash_pow][0] * f;
			g2 = col2[iflash_pow][1] * f;
			b2 = col2[iflash_pow][2] * f;
			r2 += col2[iflash_pow + 1][0] * g;
			g2 += col2[iflash_pow + 1][1] * g;
			b2 += col2[iflash_pow + 1][2] * g;
		}
		
		pvtx->cn[0] = r1;
		pvtx->cn[1] = g1;
		pvtx->cn[2] = b1;
		pvtx++;
		pvtx->cn[0] = r1;
		pvtx->cn[1] = g1;
		pvtx->cn[2] = b1;
		pvtx++;
		pvtx->cn[0] = r2;
		pvtx->cn[1] = g2;
		pvtx->cn[2] = b2;
		pvtx++;
		pvtx->cn[0] = r2;
		pvtx->cn[1] = g2;
		pvtx->cn[2] = b2;
	}

	if (pause_mode == PAUSE_MODE_OFF && ++cflash_pow >= FLASH_FRAME) {
		cflash_pow = 0;
/*		iflash_pow ^= 1;	*/
		iflash_pow = ++iflash_pow & 3;
	}

/*---------------------------------------------------------------------------*/
/* draw */

	gSPClearGeometryMode(pgfx++, G_GEOM_ALL);
	gSPSetGeometryMode(pgfx++, G_ZBUFFER | G_SHADE | G_SHADING_SMOOTH | G_CULL_BACK);
	gSPTexture(pgfx++, 0x8000, 0x8000, 0, G_TX_RENDERTILE, G_ON);
	gDPPipeSync(pgfx++);
	gDPSetCycleType(pgfx++, G_CYC_1CYCLE);
	gDPSetTexturePersp(pgfx++, G_TP_PERSP);
	gDPSetTextureFilter(pgfx++, G_TF_BILERP);
	gDPSetCombineMode(pgfx++, G_CC_MODULATEIA, G_CC_MODULATEIA);
	gDPSetRenderMode(pgfx++, G_RM_XLU_SURF, G_RM_XLU_SURF2);
	gDPSetAlphaCompare(pgfx++, G_AC_NONE);

	gSPMatrix(pgfx++, &rsp_endynamic.mtx_ortho2, G_MTX_PROJECTION | G_MTX_LOAD | G_MTX_NOPUSH);

	for (n = 0; n < players; n++) {
		if (n == 0)
			pchkcrs = &chkcrs[my_hover];
		else
			pchkcrs = &chkcrs[your_hover];
	
		for (j = 0; j < PASS_MSG_MAX; j++) {
			ppassmsg = &passmsg[n][j];
			if (ppassmsg->fg) {
				egTranslate(&pendynamic->mtx_model[ienmtxmdl], ppassmsg->px + (float)scrofs2, ppassmsg->py, 0.F);
				gSPMatrix(pgfx++, &rsp_endynamic.mtx_model[ienmtxmdl++], G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_NOPUSH);
				egScale(&pendynamic->mtx_model[ienmtxmdl], ppassmsg->sc, ppassmsg->sc, 1.F);
				gSPMatrix(pgfx++, &rsp_endynamic.mtx_model[ienmtxmdl++], G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_NOPUSH);
				switch (ppassmsg->fg) {
					case PASS_MSG_MISS:
						gSPDisplayList(pgfx++, gfx_miss_msg);
						break;
					case PASS_MSG_UP:
						if (pchkcrs->passpnt >= PASSPNT_MAX) {
							gSPDisplayList(pgfx++, gfx_maxpower_msg);
						}
						else {
							gSPDisplayList(pgfx++, gfx_p_up_msg);
						}
						break;
					case PASS_MSG_DOWN:
						gSPDisplayList(pgfx++, gfx_p_down_msg);
						break;
				}
			}
		}
	}

	*ppgfx = pgfx;
}

/******************************************************************************
	do course out message
******************************************************************************/

void DoCrsOutMsg(void)
{
	int	n, k, fvsend, fout, fground;
	float	px, pz;
	Chkcrs	*pchkcrs;
	Boat	*pboat;

	if (game_kind == GAME_KIND_VS &&
	    (chkcrs[my_hover].ffinish || chkcrs[my_hover].fretire ||
	     chkcrs[your_hover].ffinish || chkcrs[your_hover].fretire))
		fvsend = 1;
	else
		fvsend = 0;

	for (n = 0; n < players; n++) {
		if (n == 0) {
			pboat = &hover[my_hover];
			pchkcrs = &chkcrs[my_hover];
		}
		else {
			pboat = &hover[your_hover];
			pchkcrs = &chkcrs[your_hover];
		}
		if (pchkcrs->fretire || pchkcrs->ffinish)
			continue;

		px = pboat->obj.gpx;
		pz = pboat->obj.gpz;

		fground = ncourse != NCOURSE_8 && pboat->ground_count > 4 * FRAME_SEC;
		fout = (ChkCrsOut(px, pz) || fground) && !fvsend && retire_sw;

/*		printf("co: %d\n", pboat->ground_count);	*/

		if (pchkcrs->fcrsout) {
			if (!fout)
				pchkcrs->fcrsout = 0;
			else if (pboat->anim_no == FREE_AN || pboat->anim_no == BOARD_AN) {
			}
			else if (pchkcrs->ccrsout > 0) {
				if (pchkcrs->ccrsout <= crsout_time) {
					if (fground)
						k = 0x80;
					else
						k = 0;
					if (pchkcrs->ccrsout == crsout_time) {
						Na_SystemSound(NA_SYS_COUT, pchkcrs->ccrsout / FRAME_SEC + k);
					}
					else if ((pchkcrs->ccrsout % FRAME_SEC) == 0) {
						Na_SystemSound(NA_SYS_COUT, pchkcrs->ccrsout / FRAME_SEC - 1 + k);
					}
				}
				pchkcrs->ccrsout--;
			}
			else if (pchkcrs->ccrsout == 0)
				SetRetire(pchkcrs);
		}
		else if (fout) {
			pchkcrs->fcrsout = 1;
			pchkcrs->ccrsout = crsout_time + 1 * FRAME_SEC;
/*			Na_SystemSound(NA_SYS_COUT, pchkcrs->ccrsout / FRAME_SEC - 1);	*/
		}
	}
}


/******************************************************************************
	draw course out message
******************************************************************************/
void DrawCrsOutMsg(Gfx **ppgfx)
{
	int	i, n, ix, iy, font_flag, fpark;
	int	r0, g0, b0, r1, g1, b1;
	Gfx	*pgfx = *ppgfx;
	Boat	*pboat;
	Chkcrs	*pchkcrs;

	fpark = game_kind != GAME_KIND_SCORE && ncourse == NCOURSE_PARK;

	for (n = 0; n < players; n++) {
		if (n == 0) {
			pboat = &hover[my_hover];
			pchkcrs = &chkcrs[my_hover];
		}
		else {
			pboat = &hover[your_hover];
			pchkcrs = &chkcrs[your_hover];
		}

		if (pchkcrs->fcrsout && pchkcrs->ccrsout <= crsout_time &&
		    !pchkcrs->fretire && !pchkcrs->ffinish) {
			if (players == 1) {
				ix = DISPLAY_X1 + 152 - 32 - 64 + 4;
				iy = DISPLAY_Y1 + 70;
			}
			else if (n == 0) {
				ix = DISPLAY_X1_1P + 152 - 32 - 64 + 4;
				iy = DISPLAY_Y1_1P + 38;
			}
			else {
				ix = DISPLAY_X1_2P + 152 - 32 - 64 + 4;
				iy = DISPLAY_Y1_2P + 38;
			}
#if LOCALE==CHINA
			// DISPLAY_X1_1P same as DISPLAY_X1_2P
			ix = (( players == 1 ) ? DISPLAY_X1 : DISPLAY_X1_1P );
			{
			   int i = pchkcrs->ccrsout / FRAME_SEC;
			
			   ix += (320 - i - 96 + 8 * ( i < 9 ) )/2;
			}			
#endif			

			if ((pchkcrs->ccrsout % FRAME_SEC) ||
			    pboat->anim_no == FREE_AN || pboat->anim_no == BOARD_AN) {
				font_flag = FONT_FLAG_SHADE;
				r0 = 255; g0 = 255; b0 = 0;
				r1 = 255; g1 =   0; b1 = 0;
			}
			else {
				font_flag = FONT_FLAG_FLASH;
				r0 = 128; g0 = 255; b0 = 128;
				r1 = 255; g1 = 255; b1 = 255;
			}

			// RF: COURSE OUT
#if LOCALE==CHINA
			pgfx = makeStrGlist(pgfx, FONT_TYPE_MAIN, "\x7b\x75",

#else
			pgfx = makeStrGlist(pgfx, FONT_TYPE_MAIN, "COURSE",
#endif
				ix, iy, font_flag,
				r0, g0, b0, r0, g0, b0,
				r1, g1, b1, r1, g1, b1);
#if LOCALE==CHINA
			pgfx = makeStrGlist(pgfx, FONT_TYPE_MAIN, "\x77\x72",
				ix + 48, iy, font_flag,
#else
			pgfx = makeStrGlist(pgfx, FONT_TYPE_MAIN, "OUT",
				ix + 60 + 48 - 24 + 12, iy, font_flag,
#endif
				r0, g0, b0, r0, g0, b0,
				r1, g1, b1, r1, g1, b1);
				
			i = pchkcrs->ccrsout / FRAME_SEC;
			sprintf(strbuf, "%d", i);
			pgfx = makeStrGlist(pgfx, FONT_TYPE_MAIN, strbuf,
#if LOCALE==CHINA
				ix + 96 + 3, iy, font_flag,
#else
				ix + 40 + 3 - 8 - (i > 9) * 5, iy, font_flag,
#endif
				r0, g0, b0, r0, g0, b0,
				r1, g1, b1, r1, g1, b1);
		}
	}

	*ppgfx = pgfx;
}


/******************************************************************************
	do tachometer
******************************************************************************/
void DoTachometer(void)
{
	int	i, j, k;
	float	f, min, scale, screw_al;
	Chkcrs	*pchkcrs;
	Boat	*pboat;

	for (i = 0; i < boat_max; i++) {
		screw_al = hover[i].screw_al;
		pchkcrs = &chkcrs[i];
		pboat = &hover[i];

		f = pboat->screw_accel_max - pboat->screw_accel_min;
		min = pboat->screw_accel_min - f / (float)PASSPNT_MAX;
		scale = f * ((float)PASSPNT_MAX + 1.F) / (float)PASSPNT_MAX;

		if ((f = screw_al) >= min) {
			if (scale > 0.F)
				f = (f - min) / scale;
			if (f < 0.F)
				f = 0.F;
			if (f > 1.F)
				f = 1.F;
			pchkcrs->rpm_dst = f * 180.F;
			
			if ((pchkcrs->rpm_dst += GetRnd(3) * 2 - 2) > 180)
				pchkcrs->rpm_dst = 180;
		}
		else
			pchkcrs->rpm_dst = f / min * (180.F / (float)PASSPNT_MAX);

		j = ABS(pchkcrs->rpm_dst - pchkcrs->rpm_cur);
		if ((k = j / 4) < 2)
			k = 2;
		if (pchkcrs->rpm_dst > pchkcrs->rpm_cur && k > 4)
			k = 4;
		if (j <= k)
			pchkcrs->rpm_cur = pchkcrs->rpm_dst;
		else
			pchkcrs->rpm_cur += SGN(pchkcrs->rpm_dst - pchkcrs->rpm_cur) * k;

/*		printf("%8.2f%8.2f\n", pboat->screw_accel_max, screw_al);	*/
	}

#if 0
	printf("tc: %8d%8d%8d%8.2f, %8d%8d%8d%8.2f\n",
		my_hover, chkcrs[my_hover].passpnt, chkcrs[my_hover].rpm_dst, hover[my_hover].screw_al,
		your_hover, chkcrs[your_hover].passpnt, chkcrs[your_hover].rpm_dst, hover[your_hover].screw_al
	);
#endif

}

/******************************************************************************
	draw lap time sub
		mode:	0 = record
				cnt1: lap,		cnt2: not used
			1 = current
				cnt1: fuse_msec_cnt,	cnt2: msec_cnt
			2 = difference
				cnt1: 1(+) 2(-) 3( ),	cnt2: not used
			3 = difference (select font)
				cnt1: 1(+) 2(-) 3( ),	cnt2: color (0:W, 1:R, 2:G)

******************************************************************************/

static void DrawLapTimeSub(Gfx **ppgfx,
	int sx, int sy, int ctime, int mode, int cnt1, int cnt2)
{
	int	i, k, ix, iy, min, sec, msec, izero;
	int	cr, cg, cb;
/*	float	f;	*/
	Gfx	*pgfx = *ppgfx;
	Chkcrs	*pchkcrs;

/*---------------------------------------------------------------------------*/
/* time */
	if (ctime < 0)
		ctime = 0;
	if (ctime > CTIME_MAX)
		ctime = CTIME_MAX;
	
	min = (ctime / (FRAME_SEC * CTIME_FRAME)) / 60;
	sec = (ctime / (FRAME_SEC * CTIME_FRAME)) % 60;
/*	msec = (float)(ctime % (FRAME_SEC * CTIME_FRAME)) / (FRAME_SEC * CTIME_FRAME) * 1000.F;	*/
	msec = ctime % (FRAME_SEC * CTIME_FRAME);

	laptime_fig[0] = min;
	laptime_fig[1] = sec / 10;
	laptime_fig[2] = sec % 10;
	laptime_fig[3] = msec / 100;
	if (mode != 1 || cnt1 != 1) {
		laptime_fig[4] = (msec % 100) / 10;
		laptime_fig[5] = msec % 10;
	}	
	else if (ctime == 0)
		laptime_fig[4] = laptime_fig[5] = 0;
	else if (ctime == CTIME_MAX)
		laptime_fig[4] = laptime_fig[5] = 9;
	else {
		laptime_fig[4] = (cnt2 + 5) % 10;
		laptime_fig[5] = (cnt2    ) % 10;
	}

	ix = sx;
	iy = sy;

	if (mode == 2 || mode == 3) {
		if (ctime < 10 * FRAME_SEC * CTIME_FRAME)
			izero = 2;
		else if (min == 0)
			izero = 1;
		else
			izero = 0;
	}
	else
		izero = 0;

	if (mode == 1) {
		/*---------------------------------------------------------------------------*/
		/* normal (current) */

		gDPPipeSync(pgfx++);
		gDPSetPrimColor(pgfx++, 0, 0,  255, 255, 255, 255);
		for (i = 0; i < 6; i++) {
			gDPLoadTextureBlock(pgfx++, tx_middle_font + laptime_fig[i] * 12 * 16, G_IM_FMT_RGBA, G_IM_SIZ_32b, 12, 16, 0,
				G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
			gSPTextureRectangle(pgfx++, ix << 2, iy << 2, ix + 12 << 2, iy + 16 << 2, G_TX_RENDERTILE,
				0 << 5, 0 << 5, 1 << 10, 1 << 10);
			ix += 13;
			if (i == 0)
				ix += 6;
			else if (i == 2)
				ix += 7;
		}
	
		gDPLoadTextureBlock(pgfx++, tx_middle_font + 10 * 12 * 16, G_IM_FMT_RGBA, G_IM_SIZ_32b, 12, 16, 0,
			G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
		gSPTextureRectangle(pgfx++, sx + 12 << 2, sy << 2, sx + 12 + 12 << 2, sy + 16 << 2, G_TX_RENDERTILE,
			0 << 5, 0 << 5, 1 << 10, 1 << 10);
		gDPLoadTextureBlock(pgfx++, tx_middle_font + 11 * 12 * 16, G_IM_FMT_RGBA, G_IM_SIZ_32b, 12, 16, 0,
			G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
		gSPTextureRectangle(pgfx++, sx + 44 << 2, sy << 2, sx + 44 + 12 << 2, sy + 16 << 2, G_TX_RENDERTILE,
			0 << 5, 0 << 5, 1 << 10, 1 << 10);
	}
	else if (mode == 0 || mode == 2) {
		/*---------------------------------------------------------------------------*/
		/* small (record & difference) */

		gDPPipeSync(pgfx++);
		gDPSetPrimColor(pgfx++, 0, 0,  255, 255, 255, 255);
		if (mode == 0) {
			pchkcrs = &chkcrs[my_hover];
			k = pchkcrs->ffinish ? pchkcrs->lap : pchkcrs->lap - 1;
			
			gDPPipeSync(pgfx++);
			if (clast_lap_flash && cnt1 == k) {
				gDPSetPrimColor(pgfx++, 0, 0, en_flash_r2, en_flash_g2, en_flash_b2, 255);
			}
			else if (ctime <= best_lap_time) {
				gDPSetPrimColor(pgfx++, 0, 0, en_flash_r1, en_flash_g1, en_flash_b1, 255);
			}
			else {
				gDPSetPrimColor(pgfx++, 0, 0,  255, 255, 255, 255);
			}
		}
		else if (cnt1 != 3) {
			if (cnt1 == 1) {
				/* plus */
				gDPLoadTextureBlock(pgfx++, tx_small_font + 39 * 8 * 8, G_IM_FMT_IA, G_IM_SIZ_8b, 8, 8, 0,
					G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
			}
			else {
				/* minus */
				gDPLoadTextureBlock(pgfx++, tx_small_font + 36 * 8 * 8, G_IM_FMT_IA, G_IM_SIZ_8b, 8, 8, 0,
					G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
			}
			
			if (izero == 0)
				k = sx - 8;
			else if (izero == 1)
				k = sx - 8 + 12;
			else
				k = sx - 8 + 12 + 6;
			gSPScisTextureRectangle(pgfx++, k << 2, sy << 2, k + 8 << 2, sy + 8 << 2, G_TX_RENDERTILE,
				0 << 5, 0 << 5, 1 << 10, 1 << 10);
		}
				
		
		for (i = 0; i < 6; i++) {
			if (!izero || i >= izero) {
				gDPLoadTextureBlock(pgfx++, tx_small_font + laptime_fig[i] * 8 * 8, G_IM_FMT_IA, G_IM_SIZ_8b, 8, 8, 0,
					G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
				gSPScisTextureRectangle(pgfx++, ix << 2, iy << 2, ix + 8 << 2, iy + 8 << 2, G_TX_RENDERTILE,
					0 << 5, 0 << 5, 1 << 10, 1 << 10);
			}
			ix += 7;
			if (i == 0 || i == 2)
				ix += 5;
		}
	
		if (!izero) {
			gDPLoadTextureBlock(pgfx++, tx_small_font + 37 * 8 * 8, G_IM_FMT_IA, G_IM_SIZ_8b, 8, 8, 0,
				G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
			gSPScisTextureRectangle(pgfx++, sx + 6 << 2, sy << 2, sx + 6 + 8 << 2, sy + 8 << 2, G_TX_RENDERTILE,
				0 << 5, 0 << 5, 1 << 10, 1 << 10);
		}
		gDPLoadTextureBlock(pgfx++, tx_small_font + 38 * 8 * 8, G_IM_FMT_IA, G_IM_SIZ_8b, 8, 8, 0,
			G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
		gSPScisTextureRectangle(pgfx++, sx + 25 << 2, sy << 2, sx + 25 + 8 << 2, sy + 8 << 2, G_TX_RENDERTILE,
			0 << 5, 0 << 5, 1 << 10, 1 << 10);

		if (mode == 0) {
			/* "L" lap number */
			gDPLoadTextureBlock(pgfx++, tx_small_font + (10 + 'L' - 'A') * 8 * 8, G_IM_FMT_IA, G_IM_SIZ_8b, 8, 8, 0,
				G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
			gSPScisTextureRectangle(pgfx++, sx + 60 << 2, sy << 2, sx + 60 + 8 << 2, sy + 8 << 2, G_TX_RENDERTILE,
				0 << 5, 0 << 5, 1 << 10, 1 << 10);
			gDPLoadTextureBlock(pgfx++, tx_small_font + cnt1 * 8 * 8, G_IM_FMT_IA, G_IM_SIZ_8b, 8, 8, 0,
				G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
			gSPScisTextureRectangle(pgfx++, sx + 66 << 2, sy << 2, sx + 66 + 8 << 2, sy + 8 << 2, G_TX_RENDERTILE,
				0 << 5, 0 << 5, 1 << 10, 1 << 10);
		}

	}
	else if (mode == 3) {
		/*---------------------------------------------------------------------------*/
		/* difference (select font) */

		gDPPipeSync(pgfx++);
		if (cnt2 == 0) {
			gDPSetPrimColor(pgfx++, 0, 0,  255, 255, 255, 255);
		}
		else if (cnt2 == 1) {
			gDPSetPrimColor(pgfx++, 0, 0,  en_flash_r3, en_flash_g3, en_flash_b3, 255);
		}
		else {
			gDPSetPrimColor(pgfx++, 0, 0,  en_flash_r4, en_flash_g4, en_flash_b4, 255);
		}
		
		if (cnt1 != 3) {
			if (cnt1 == 1) {
				/* plus */
				gDPLoadTextureBlock(pgfx++, tx_select_font + 45 * 16 * 12, G_IM_FMT_IA, G_IM_SIZ_8b, 16, 12, 0,
					G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
			}
			else {
				/* minus */
				gDPLoadTextureBlock(pgfx++, tx_select_font + 37 * 16 * 12, G_IM_FMT_IA, G_IM_SIZ_8b, 16, 12, 0,
					G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
			}
			
			if (izero == 0)
				k = sx - 10;
			else if (izero == 1)
				k = sx - 10 + 15;
			else
				k = sx - 10 + 15 + 11;
			gSPTextureRectangle(pgfx++, k << 2, sy << 2, k + 16 << 2, sy + 12 << 2, G_TX_RENDERTILE,
				0 << 5, 0 << 5, 1 << 10, 1 << 10);
		}
		
		for (i = 0; i < 6; i++) {
			if (!izero || i >= izero) {
				gDPLoadTextureBlock(pgfx++, tx_select_font + laptime_fig[i] * 16 * 12, G_IM_FMT_IA, G_IM_SIZ_8b, 16, 12, 0,
					G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
				gSPTextureRectangle(pgfx++, ix << 2, iy << 2, ix + 16 << 2, iy + 12 << 2, G_TX_RENDERTILE,
					0 << 5, 0 << 5, 1 << 10, 1 << 10);
			}
			ix += 11;
			if (i == 0 || i == 2)
				ix += 4;
		}
	
		if (!izero) {
			gDPLoadTextureBlock(pgfx++, tx_select_font + 38 * 16 * 12, G_IM_FMT_IA, G_IM_SIZ_8b, 16, 12, 0,
				G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
			gSPTextureRectangle(pgfx++, sx + 10 << 2, sy << 2, sx + 10 + 16 << 2, sy + 12 << 2, G_TX_RENDERTILE,
				0 << 5, 0 << 5, 1 << 10, 1 << 10);
		}
		gDPLoadTextureBlock(pgfx++, tx_select_font + 39 * 16 * 12, G_IM_FMT_IA, G_IM_SIZ_8b, 16, 12, 0,
			G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
		gSPTextureRectangle(pgfx++, sx + 36 << 2, sy << 2, sx + 36 + 16 << 2, sy + 12 << 2, G_TX_RENDERTILE,
			0 << 5, 0 << 5, 1 << 10, 1 << 10);
	}
	

/*---------------------------------------------------------------------------*/
/* end */
	*ppgfx = pgfx;
}

/******************************************************************************
	draw lap time
******************************************************************************/

void DrawLapTime(Gfx **ppgfx)
{

	int	i, j, k, m, n, ctime;
	int	nofline, lapbase;
	int	sx, sy, ix, iy, jx, jy;
	Gfx	*pgfx = *ppgfx;
	Chkcrs	*pchkcrs;

/*---------------------------------------------------------------------------*/
/* init RCP */
	gSPDisplayList(pgfx++, gfx_init_lap_time);

/*---------------------------------------------------------------------------*/
/* laptime */
	if ((game_kind == GAME_KIND_TOUR || game_kind == GAME_KIND_ATTACK) &&
	    ncourse != NCOURSE_PARK) {
		/*---------------------------------------------------------------------------*/
		/* record */
		pchkcrs = &chkcrs[my_hover];
		
		if (pchkcrs->lap >= 2 || flapstop) {
			sx = DISPLAY_X1 + 16;
			sy = DISPLAY_Y1 + 32;
#if 1
			if ((nofline = pchkcrs->lap - 1) > LAP_MAX) {
				lapbase = nofline - LAP_MAX;
				nofline = LAP_MAX;
			}
			else
				lapbase = 0;
			
			if (pchkcrs->ffinish || flapstop)
				nofline += 1;
	
/*			for (k = nofline - 1; k >= 0; k--) {	*/
			for (k = 0; k < nofline; k++) {
				DrawLapTimeSub(&pgfx, sx + scrofs2, sy, pchkcrs->rectime[k], 0, (k + 1 + lapbase) % 10, 0);
				sy += 10;
			}
#endif
#if 0
			nofline = pchkcrs->lap - 1;
			if (pchkcrs->ffinish || flapstop)
				nofline += 1;
			if (nofline > LAP_DSP_MAX) {
				lapbase = nofline - LAP_DSP_MAX;
				nofline = LAP_DSP_MAX;
			}
			else
				lapbase = 0;
			for (k = 0; k < nofline; k++) {
				DrawLapTimeSub(&pgfx, sx, sy, pchkcrs->rectime[k + lapbase], 0, (k + 1 + lapbase) % 10, 0);
				sy += 10;
			}
#endif

		}

		/*---------------------------------------------------------------------------*/
		/* current */
			if (pchkcrs->ffinish || pchkcrs->fretire == FRETIRE_TIME)
				i = 0;
			else
				i = 1;
			DrawLapTimeSub(&pgfx,
				DISPLAY_X1 + 16 + scrofs1, DISPLAY_Y1 + 14,
				pchkcrs->ctime_total, 1, i, pchkcrs->ctime_msec);
	}
	else if (game_kind == GAME_KIND_VS) {
		i = chkcrs[my_hover].ffinish ? 0 : 1;
		DrawLapTimeSub(&pgfx, 
			DISPLAY_X1_1P + 16, DISPLAY_Y1_1P + 2,
			chkcrs[my_hover].ctime_total, 1, i, chkcrs[my_hover].ctime_msec);
		i = chkcrs[your_hover].ffinish ? 0 : 1;
		DrawLapTimeSub(&pgfx, 
			DISPLAY_X1_2P + 16, DISPLAY_Y1_2P + 2,
			chkcrs[your_hover].ctime_total, 1, i, chkcrs[your_hover].ctime_msec);
	}

/*---------------------------------------------------------------------------*/
/* goal time display */
	if (game_kind == GAME_KIND_TOUR && ncourse != NCOURSE_PARK &&
	    cafter_goal >= 40) {
		for (n = 0; n < boat_max; n++)
			if (chkcrs[n].ffinish && chkcrs[n].rank == 0)
				break;
		if (n >= boat_max)
			n = 0;
		ctime = chkcrs[n].ctime_total;
		
		sx = DISPLAY_X1 + 254;
		sy = DISPLAY_Y1 + 40;
		for (i = 0; i < boat_max; i++) {
			if (cafter_goal < 40 + chkcrs[i].rank * 10)
				continue;
			ix = sx + rankface[0][i].px - 86;
			iy = sy + rankface[0][i].py + 3;
			m = (i == my_hover) ? 2 : 1;
			if (i == n) {
				DrawLapTimeSub(&pgfx,
					ix + scrofs1, iy,
					chkcrs[i].ctime_total, 3, 3, m);
			}
			else if (chkcrs[i].ffinish) {
				DrawLapTimeSub(&pgfx,
					ix + scrofs1, iy,
					chkcrs[i].ctime_total - ctime, 3, 1, m);
			}
		}
	}

/*---------------------------------------------------------------------------*/
/* time difference */
	/*---------------------------------------------------------------------------*/
	/* VS */
	if (game_kind == GAME_KIND_VS) {
		for (i = 0; i < players; i++) {
			if (i == 0) {
				ix = DISPLAY_X1_1P + 120;
				iy = DISPLAY_Y1_1P + 56;
				pchkcrs = &chkcrs[my_hover];
			}
			else {
				ix = DISPLAY_X1_2P + 120;
				iy = DISPLAY_Y1_2P + 56;
				pchkcrs = &chkcrs[your_hover];
			}
#if 0
			pchkcrs->ctime_dif = stw0 * 1000;
			pchkcrs->ttime_dif = 1;
			pchkcrs->ftime_dif = 1+i;
#endif
			if (pchkcrs->ttime_dif) {
				if (pchkcrs->ctime_dif < 10 * FRAME_SEC * CTIME_FRAME)
					k = -15;
				else if (pchkcrs->ctime_dif < 60 * FRAME_SEC * CTIME_FRAME)
					k = -10;
				else
					k = 0;
				DrawLapTimeSub(&pgfx,
					ix + k, iy,
					pchkcrs->ctime_dif, 3, pchkcrs->ftime_dif, pchkcrs->ftime_dif == 1 ? 1 : 2);
			}
		}
	}

	/*---------------------------------------------------------------------------*/
	/* tour (enemy) */
	if (game_kind == GAME_KIND_TOUR && ncourse != NCOURSE_PARK) {
		sx = DISPLAY_X1 + 254;
		sy = DISPLAY_Y1 + 40;

		for (i = 0; i < boat_max; i++) {
			if (i == my_hover)
				continue;
			pchkcrs = &chkcrs[i];
			ix = sx + rankface[0][i].px - 76;
			iy = sy + rankface[0][i].py + 3;

			
#if 0
			pchkcrs->ctime_dif = 150 * 1000;
			pchkcrs->ttime_dif = 1;
#endif

			if (pchkcrs->ttime_dif) {
				DrawLapTimeSub(&pgfx,
					ix, iy,
					pchkcrs->ctime_dif, 3, pchkcrs->ftime_dif, 1);
			}
		}
	}
	
	
	/*---------------------------------------------------------------------------*/
	/* tour (player) & time attack */
	if (game_kind == GAME_KIND_TOUR || game_kind == GAME_KIND_ATTACK) {
		pchkcrs = &chkcrs[my_hover];
#if 0
		pchkcrs->ctime_dif = stw0 * 1000;
		pchkcrs->ttime_dif = 1;
		pchkcrs->ftime_dif = 1;
		pchkcrs->ntime_dif = 2;
#endif
		if (pchkcrs->ttime_dif) {
			if (pchkcrs->ctime_dif < 10 * FRAME_SEC * CTIME_FRAME)
				k = 2;
			else if (pchkcrs->ctime_dif < 60 * FRAME_SEC * CTIME_FRAME)
				k = 1;
			else
				k = 0;

			sx = DISPLAY_X1 + 132;
			sy = DISPLAY_Y1 +  82 + 24;
			if (k == 1)
				sx -= 7;
			else if (k == 2)
				sx -= 13;

			/*---------------------------------------------------------------------------*/
			/* time */
			if (game_kind == GAME_KIND_ATTACK && pchkcrs->ftime_dif == 1)
				j = 1;
			else
				j = 2;
			DrawLapTimeSub(&pgfx,
				sx, sy,
				pchkcrs->ctime_dif, 3, pchkcrs->ftime_dif, j);

			/*---------------------------------------------------------------------------*/
			gDPPipeSync(pgfx++);
			gDPSetCombineMode(pgfx++, G_CC_DECALRGBA, G_CC_DECALRGBA);
			ix = sx - 40;
			iy = sy - 4;
			if (k == 1)
				ix += 15;
			else if (k == 2)
				ix += 26;

			if (game_kind == GAME_KIND_TOUR) {
				/*---------------------------------------------------------------------------*/
				/* back */
				gDPLoadTextureBlock(pgfx++, tx_face_back2, G_IM_FMT_RGBA, G_IM_SIZ_16b, 32, 20, 0,
					G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
				gSPTextureRectangle(pgfx++, ix << 2, iy << 2, ix + 32 << 2, iy + 20 << 2, G_TX_RENDERTILE,
					0 << 5, 0 << 5, 1 << 10, 1 << 10);

				/*---------------------------------------------------------------------------*/
				/* face */
				gDPLoadTextureBlock(pgfx++, face_tbl[hover[pchkcrs->ntime_dif].boat_number], G_IM_FMT_RGBA, G_IM_SIZ_16b, 20, 20, 0,
					G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
				ix += 9;
				iy += 2;
				gSPTextureRectangle(pgfx++, ix << 2, iy << 2,
					ix + 16 << 2, iy + 16 << 2, G_TX_RENDERTILE,
					0 << 5, 0 << 5, 1280, 1280);
			}
			else {
				ix -= 6;

				gDPLoadTextureBlock(pgfx++, tx_face_back_bt, G_IM_FMT_RGBA, G_IM_SIZ_16b, 32, 20, 0,
					G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
				gSPTextureRectangle(pgfx++, ix << 2, iy << 2, ix + 32 << 2, iy + 20 << 2, G_TX_RENDERTILE,
					0 << 5, 0 << 5, 1 << 10, 1 << 10);
			}
		}
	}

/*---------------------------------------------------------------------------*/
/* laptime name */
	gDPPipeSync(pgfx++);
	gDPSetCombineMode(pgfx++, G_CC_DECALRGBA, G_CC_DECALRGBA);

	if ((game_kind == GAME_KIND_TOUR || game_kind == GAME_KIND_ATTACK) &&
	    ncourse != NCOURSE_PARK) {
		gDPLoadTextureBlock(pgfx++, tx_sc_time_mark, G_IM_FMT_RGBA, G_IM_SIZ_32b, 32, 12, 0,
			G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
		gSPTextureRectangle(pgfx++, 
			DISPLAY_X1 + 48 + scrofs1 << 2, DISPLAY_Y1 + 1 << 2,
			DISPLAY_X1 + 48 + 32 + scrofs1 << 2, DISPLAY_Y1 + 1 + 12 << 2, G_TX_RENDERTILE,
			0 << 5, 0 << 5, 1 << 10, 1 << 10);
	}
	
/*---------------------------------------------------------------------------*/
/* lap number */

	if (game_kind != GAME_KIND_SCORE && ncourse != NCOURSE_PARK) {
		/*---------------------------------------------------------------------------*/
		/* name */
		if (players == 1) {
			if (game_kind == GAME_KIND_TOUR)
				ix = DISPLAY_X1 + 180 + scrofs1;
			else
				ix = DISPLAY_X1 + 124;
			iy = DISPLAY_Y1 + 1;
		}
		else {
			ix = DISPLAY_X1_1P + 234 - 12 - 28;
			iy = DISPLAY_Y1_1P + 1;
			jx = DISPLAY_X1_2P + 234 - 12 - 28;
			jy = DISPLAY_Y1_2P + 1;
		}
		gDPLoadTextureBlock(pgfx++, tx_lap, G_IM_FMT_RGBA, G_IM_SIZ_32b, 24, 12, 0,
			G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
		gSPTextureRectangle(pgfx++, ix << 2, iy << 2, ix + 24 << 2, iy + 12 << 2, G_TX_RENDERTILE,
			0 << 5, 0 << 5, 1 << 10, 1 << 10);
		if (players == 2) {
			gSPTextureRectangle(pgfx++, jx << 2, jy << 2, jx + 24 << 2, jy + 12 << 2, G_TX_RENDERTILE,
				0 << 5, 0 << 5, 1 << 10, 1 << 10);
		}

		/*---------------------------------------------------------------------------*/
		/* number */
		for (i = 0; i < players; i++) {
			if (players == 1) {
				if (game_kind == GAME_KIND_TOUR)
					ix = DISPLAY_X1 + 184 + scrofs1;
				else
					ix = DISPLAY_X1 + 128;
				iy = DISPLAY_Y1 + 14;
				n = chkcrs[my_hover].lap;
			}
			else if (i == 0) {
				ix = DISPLAY_X1_1P + 228 - 28;
				iy = DISPLAY_Y1_1P + 13;
				n = chkcrs[my_hover].lap;
			}
			else {
				ix = DISPLAY_X1_2P + 228 - 28;
				iy = DISPLAY_Y1_2P + 13;
				n = chkcrs[your_hover].lap;
			}
		
			if (n > finishLap)
				n = finishLap;
			if (players == 1) {
				gDPLoadTextureBlock(pgfx++, tx_speed_font + (n % 10) * 16 * 20, G_IM_FMT_RGBA, G_IM_SIZ_32b, 16, 20, 0,
					G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
				gSPTextureRectangle(pgfx++, ix << 2, iy << 2, ix + 16 << 2, iy + 20 << 2, G_TX_RENDERTILE,
					0 << 5, 0 << 5, 1 << 10, 1 << 10);
			}
			else {
				gDPLoadTextureBlock(pgfx++, tx_middle_font + (n % 10) * 12 * 16, G_IM_FMT_RGBA, G_IM_SIZ_32b, 12, 16, 0,
					G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
				gSPTextureRectangle(pgfx++, ix << 2, iy << 2, ix + 12 << 2, iy + 16 << 2, G_TX_RENDERTILE,
					0 << 5, 0 << 5, 1 << 10, 1 << 10);
			}
		}
	}

/*---------------------------------------------------------------------------*/
/* rank */
	if (game_kind == GAME_KIND_TOUR && ncourse != NCOURSE_PARK) {
		/*---------------------------------------------------------------------------*/
		/* name */
		gDPLoadTextureBlock(pgfx++, tx_rank, G_IM_FMT_RGBA, G_IM_SIZ_32b, 36, 12, 0,
			G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
		gSPTextureRectangle(pgfx++, DISPLAY_X1 + 124 + scrofs1 << 2, DISPLAY_Y1 + 1 << 2,
			DISPLAY_X1 + 124 + 36 + scrofs1 << 2, DISPLAY_Y1 + 1 + 12 << 2, G_TX_RENDERTILE,
			0 << 5, 0 << 5, 1 << 10, 1 << 10);

		/*---------------------------------------------------------------------------*/
		/* number */
		gDPLoadTextureBlock(pgfx++, tx_speed_font + (chkcrs[my_hover].rank + 1) * 16 * 20, G_IM_FMT_RGBA, G_IM_SIZ_32b, 16, 20, 0,
			G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
		ix = DISPLAY_X1 + 124 + 4 + scrofs1;
		iy = DISPLAY_Y1 + 14;

		if (!frank_zoom) {
			gSPTextureRectangle(pgfx++,
				ix << 2, iy << 2,
				ix + 16 << 2, iy + 20 << 2, G_TX_RENDERTILE,
				0 << 5, 0 << 5, 1 << 10, 1 << 10);
		}
		else {
			j = srank_zoom * 3;
			jx = 16 + j * 2;
			jy = 20 + j * 2;
		
			gDPPipeSync(pgfx++);
			gDPSetTextureFilter(pgfx++, G_TF_BILERP);
			gSPTextureRectangle(pgfx++,
				ix - j * 2 << 2, iy << 2,
				ix + 16 << 2, iy + 20 + j * 2 << 2, G_TX_RENDERTILE,
				0 << 5, 0 << 5, 1024 * 16 / jx, 1024 * 20 / jy);
			gDPPipeSync(pgfx++);
			gDPSetTextureFilter(pgfx++, G_TF_POINT);
		}


		/*---------------------------------------------------------------------------*/
		/* up arrow */
		gDPPipeSync(pgfx++);
		gDPSetCombineMode(pgfx++, G_CC_ENTEXENV, G_CC_ENTEXENV);
		if (chkcrs[my_hover].rank > withinRank) {
			gDPSetEnvColor(pgfx++, en_flash_r1, en_flash_g1, en_flash_b1, 255);
		}
		else {
			gDPSetEnvColor(pgfx++, 255, 255, 255, 255);
		}
		gDPLoadTextureBlock(pgfx++, tx_arrow_up, G_IM_FMT_IA, G_IM_SIZ_8b, 8, 10, 0,
			G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
		gSPTextureRectangle(pgfx++, DISPLAY_X1 + 124 + 23 + scrofs1 << 2, DISPLAY_Y1 + 12 << 2,
			DISPLAY_X1 + 124 + 23 + 8 + scrofs1 << 2, DISPLAY_Y1 + 12 + 10 << 2, G_TX_RENDERTILE,
			0 << 5, 0 << 5, 1 << 10, 1 << 10);

		/*---------------------------------------------------------------------------*/
		/* within number */
		if (withinRank < 4)
			k = withinRank + 1;
		else 
			k = 37;
		gDPLoadTextureBlock(pgfx++, tx_select_font + k * 16 * 12, G_IM_FMT_IA, G_IM_SIZ_8b, 16, 12, 0,
			G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
		gSPTextureRectangle(pgfx++, DISPLAY_X1 + 124 + 22 + scrofs1 << 2, DISPLAY_Y1 + 22 << 2,
			DISPLAY_X1 + 124 + 22 + 16 + scrofs1 << 2, DISPLAY_Y1 + 22 + 12 << 2, G_TX_RENDERTILE,
			0 << 5, 0 << 5, 1 << 10, 1 << 10);
		gDPPipeSync(pgfx++);
		gDPSetCombineMode(pgfx++, G_CC_DECALRGBA, G_CC_DECALRGBA);
	}

/*---------------------------------------------------------------------------*/
/* speed */
	/* name */
	gDPLoadTextureBlock(pgfx++, tx_speed, G_IM_FMT_RGBA, G_IM_SIZ_32b, 32, 12, 0,
		G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
	if (game_kind == GAME_KIND_SCORE) {
		gSPTextureRectangle(pgfx++, 
			DISPLAY_X1 + 228 << 2, DISPLAY_Y1 + 2 << 2,
			DISPLAY_X1 + 228 + 32 << 2, DISPLAY_Y1 + 2 + 12 << 2, G_TX_RENDERTILE,
			0 << 5, 0 << 5, 1 << 10, 1 << 10);
	}
	else if (players == 1) {
		if (ncourse == NCOURSE_PARK)
			k = 217;
		else if (game_kind == GAME_KIND_ATTACK)
			k = 151;
		else
			k = 217;
		gSPTextureRectangle(pgfx++, 
			DISPLAY_X1 + k + 16 + scrofs1 << 2, DISPLAY_Y1 + 1 << 2,
			DISPLAY_X1 + k + 16 + 32 + scrofs1 << 2, DISPLAY_Y1 + 1 + 12 << 2, G_TX_RENDERTILE,
			0 << 5, 0 << 5, 1 << 10, 1 << 10);
	}
	else {
		gSPTextureRectangle(pgfx++, 
			DISPLAY_X1_1P + 234 << 2, DISPLAY_Y1_1P + 1 << 2,
			DISPLAY_X1_1P + 234 + 32 << 2, DISPLAY_Y1_1P + 1 + 12 << 2, G_TX_RENDERTILE,
			0 << 5, 0 << 5, 1 << 10, 1 << 10);
		gSPTextureRectangle(pgfx++, 
			DISPLAY_X1_2P + 234 << 2, DISPLAY_Y1_2P + 1 << 2,
			DISPLAY_X1_2P + 234 + 32 << 2, DISPLAY_Y1_2P + 1 + 12 << 2, G_TX_RENDERTILE,
			0 << 5, 0 << 5, 1 << 10, 1 << 10);
	}

	/* number */
	for (i = 0; i < players; i++) {

		if (players == 1) {
			ix = DISPLAY_X1 + 217 + scrofs1;
			iy = DISPLAY_Y1 + 14;
			n = hover[my_hover].body_speed;
		}
		else if (i == 0) {
			ix = DISPLAY_X1_1P + 228;
			iy = DISPLAY_Y1_1P + 13;
			n = hover[my_hover].body_speed;
		}
		else {
			ix = DISPLAY_X1_2P + 228;
			iy = DISPLAY_Y1_2P + 13;
			n = hover[your_hover].body_speed;
		}
		
		if (ncourse == NCOURSE_PARK)
			ix = DISPLAY_X1 + 217;
		else if (game_kind == GAME_KIND_ATTACK)
			ix = DISPLAY_X1 + 151;
	
		if ((n *= KM_H) > 999)
			n = 999;

		if (game_kind == GAME_KIND_SCORE) {
			ix = DISPLAY_X1 + 220;
			iy = DISPLAY_Y1 + 18;
		
			if (n >= 100) {
				gDPLoadTextureBlock(pgfx++, tx_speed2 + (n / 100) * 12 * 16, G_IM_FMT_RGBA, G_IM_SIZ_32b, 12, 16, 0,
					G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
				gSPTextureRectangle(pgfx++, ix << 2, iy << 2, ix + 12 << 2, iy + 16 << 2, G_TX_RENDERTILE,
					0 << 5, 0 << 5, 1 << 10, 1 << 10);
			}
			ix += 14;
			if (n >= 10) {
				gDPLoadTextureBlock(pgfx++, tx_speed2 + ((n % 100) / 10) * 12 * 16, G_IM_FMT_RGBA, G_IM_SIZ_32b, 12, 16, 0,
					G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
				gSPTextureRectangle(pgfx++, ix << 2, iy << 2, ix + 12 << 2, iy + 16 << 2, G_TX_RENDERTILE,
					0 << 5, 0 << 5, 1 << 10, 1 << 10);
			}
			ix += 14;
			gDPLoadTextureBlock(pgfx++, tx_speed2 + (n % 10) * 12 * 16, G_IM_FMT_RGBA, G_IM_SIZ_32b, 12, 16, 0,
				G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
			gSPTextureRectangle(pgfx++, ix << 2, iy << 2, ix + 12 << 2, iy + 16 << 2, G_TX_RENDERTILE,
				0 << 5, 0 << 5, 1 << 10, 1 << 10);
		}
		else if (players == 1) {
			if (n >= 100) {
				gDPLoadTextureBlock(pgfx++, tx_speed_font + (n / 100) * 16 * 20, G_IM_FMT_RGBA, G_IM_SIZ_32b, 16, 20, 0,
					G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
				gSPTextureRectangle(pgfx++, ix << 2, iy << 2, ix + 16 << 2, iy + 20 << 2, G_TX_RENDERTILE,
					0 << 5, 0 << 5, 1 << 10, 1 << 10);
			}
			ix += 16;
			if (n >= 10) {
				gDPLoadTextureBlock(pgfx++, tx_speed_font + ((n % 100) / 10) * 16 * 20, G_IM_FMT_RGBA, G_IM_SIZ_32b, 16, 20, 0,
					G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
				gSPTextureRectangle(pgfx++, ix << 2, iy << 2, ix + 16 << 2, iy + 20 << 2, G_TX_RENDERTILE,
					0 << 5, 0 << 5, 1 << 10, 1 << 10);
			}
			ix += 16;
			gDPLoadTextureBlock(pgfx++, tx_speed_font + (n % 10) * 16 * 20, G_IM_FMT_RGBA, G_IM_SIZ_32b, 16, 20, 0,
				G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
			gSPTextureRectangle(pgfx++, ix << 2, iy << 2, ix + 16 << 2, iy + 20 << 2, G_TX_RENDERTILE,
				0 << 5, 0 << 5, 1 << 10, 1 << 10);
		}
		else {
			if (n >= 100) {
				gDPLoadTextureBlock(pgfx++, tx_middle_font + (n / 100) * 12 * 16, G_IM_FMT_RGBA, G_IM_SIZ_32b, 12, 16, 0,
					G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
				gSPTextureRectangle(pgfx++, ix << 2, iy << 2, ix + 12 << 2, iy + 16 << 2, G_TX_RENDERTILE,
					0 << 5, 0 << 5, 1 << 10, 1 << 10);
			}
			ix += 13;
			if (n >= 10) {
				gDPLoadTextureBlock(pgfx++, tx_middle_font + ((n % 100) / 10) * 12 * 16, G_IM_FMT_RGBA, G_IM_SIZ_32b, 12, 16, 0,
					G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
				gSPTextureRectangle(pgfx++, ix << 2, iy << 2, ix + 12 << 2, iy + 16 << 2, G_TX_RENDERTILE,
					0 << 5, 0 << 5, 1 << 10, 1 << 10);
			}
			ix += 13;
			gDPLoadTextureBlock(pgfx++, tx_middle_font + (n % 10) * 12 * 16, G_IM_FMT_RGBA, G_IM_SIZ_32b, 12, 16, 0,
				G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
			gSPTextureRectangle(pgfx++, ix << 2, iy << 2, ix + 12 << 2, iy + 16 << 2, G_TX_RENDERTILE,
				0 << 5, 0 << 5, 1 << 10, 1 << 10);
		}
	}
	
	/* km */
	gDPLoadTextureBlock(pgfx++, tx_speed_km, G_IM_FMT_RGBA, G_IM_SIZ_32b, 24, 12, 0,
		G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
	if (game_kind == GAME_KIND_SCORE) {
		gSPTextureRectangle(pgfx++,
			DISPLAY_X1 + 228 + 34 << 2, DISPLAY_Y1 + 23 << 2,
			DISPLAY_X1 + 228 + 34 + 24 << 2, DISPLAY_Y1 + 23 + 12 << 2, G_TX_RENDERTILE,
			0 << 5, 0 << 5, 1 << 10, 1 << 10);
	}
	else if (players == 1) {	
		if (ncourse == NCOURSE_PARK)
			k = 217;
		else if (game_kind == GAME_KIND_ATTACK)
			k = 151;
		else
			k = 217;
		gSPTextureRectangle(pgfx++,
			DISPLAY_X1 + k + 49 + scrofs1 << 2, DISPLAY_Y1 + 22 << 2,
			DISPLAY_X1 + k + 49 + 24 + scrofs1 << 2, DISPLAY_Y1 + 22 + 12 << 2, G_TX_RENDERTILE,
			0 << 5, 0 << 5, 1 << 10, 1 << 10);
	}
	else {
		gSPTextureRectangle(pgfx++,
			DISPLAY_X1_1P + 268 << 2, DISPLAY_Y1_1P + 18 << 2,
			DISPLAY_X1_1P + 268 + 24 << 2, DISPLAY_Y1_1P + 18 + 12 << 2, G_TX_RENDERTILE,
			0 << 5, 0 << 5, 1 << 10, 1 << 10);
		gSPTextureRectangle(pgfx++,
			DISPLAY_X1_2P + 268 << 2, DISPLAY_Y1_2P + 18 << 2,
			DISPLAY_X1_2P + 268 + 24 << 2, DISPLAY_Y1_2P + 18 + 12 << 2, G_TX_RENDERTILE,
			0 << 5, 0 << 5, 1 << 10, 1 << 10);
	}
	
	
/*---------------------------------------------------------------------------*/
/* miss mark */
	if (game_kind != GAME_KIND_SCORE && ncourse != NCOURSE_PARK) {

		/*---------------------------------------------------------------------------*/
		/* name */
		if (players == 1) {
			ix = DISPLAY_X1 + 16 + scrofs2;
			iy = DISPLAY_Y1 + 185;
			gDPLoadTextureBlock(pgfx++, tx_miss_mark, G_IM_FMT_RGBA, G_IM_SIZ_32b, 24, 12, 0,
				G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
			gSPScisTextureRectangle(pgfx++, ix << 2, iy << 2, ix + 24 << 2, iy + 12 << 2, G_TX_RENDERTILE,
				0 << 5, 0 << 5, 1 << 10, 1 << 10);
		}
	
		/*---------------------------------------------------------------------------*/
		/* mark */
		gDPLoadTextureBlock(pgfx++, tx_buoy_mark1, G_IM_FMT_RGBA, G_IM_SIZ_32b, 12, 12, 0,
			G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
		if ((m = miss_limit) > 28)
			m = 28;
	
		for (i = 0; i < players; i++) {
			if (players == 1) {
				ix = DISPLAY_X1 + 48 + scrofs2;
				iy = DISPLAY_Y1 + 185;
			}
			else if (i == 0) {
				ix = DISPLAY_X1_1P + 16;
				iy = DISPLAY_Y1_1P + 92;
			}
			else {
				ix = DISPLAY_X1_2P + 16;
				iy = DISPLAY_Y1_2P + 92;
			}
			for (k = 0; k < m; k++) {
				gSPScisTextureRectangle(pgfx++, ix << 2, iy << 2, ix + 12 << 2, iy + 12 << 2, G_TX_RENDERTILE,
					0 << 5, 0 << 5, 1 << 10, 1 << 10);
				ix += 14;
			}
		}
	
		gDPLoadTextureBlock(pgfx++, tx_buoy_mark2, G_IM_FMT_RGBA, G_IM_SIZ_32b, 12, 12, 0,
			G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
		for (i = 0; i < players; i++) {
			if (players == 1) {
				ix = DISPLAY_X1 + 48 + scrofs2;
				iy = DISPLAY_Y1 + 185;
				n = chkcrs[my_hover].miss_sum;
			}
			else if (i == 0) {
				ix = DISPLAY_X1_1P + 16;
				iy = DISPLAY_Y1_1P + 92;
				n = chkcrs[my_hover].miss_sum;
			}
			else {
				ix = DISPLAY_X1_2P + 16;
				iy = DISPLAY_Y1_2P + 92;
				n = chkcrs[your_hover].miss_sum;
			}
			if (passmsg[i][0].fg == PASS_MSG_MISS)
				n--;

			if ((j = m - n) < 0)
				j = 0;
			ix += j * 14;
		
			for (k = j; k < m; k++) {
				gSPScisTextureRectangle(pgfx++, ix << 2, iy << 2, ix + 12 << 2, iy + 12 << 2, G_TX_RENDERTILE,
					0 << 5, 0 << 5, 1 << 10, 1 << 10);
				ix += 14;
			}
		}

	}


/*---------------------------------------------------------------------------*/
/* power lamp */
	if (ncourse != NCOURSE_PARK && game_kind != GAME_KIND_SCORE) {

		/*---------------------------------------------------------------------------*/
		/* name */
		if (players == 1) {
			ix = DISPLAY_X1 + 152 - 12 + scrofs2;
			iy = DISPLAY_Y1 + 185;
			gDPLoadTextureBlock(pgfx++, tx_power_mark, G_IM_FMT_RGBA, G_IM_SIZ_32b, 32, 12, 0,
				G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
			gSPScisTextureRectangle(pgfx++, ix << 2, iy << 2, ix + 32 << 2, iy + 12 << 2, G_TX_RENDERTILE,
				0 << 5, 0 << 5, 1 << 10, 1 << 10);
		}

		/*---------------------------------------------------------------------------*/
		/* number */
		for (i = 0; i < players; i++) {
			if (players == 1) {
				ix = DISPLAY_X1 + 152 - 4 + 32 + scrofs2;
				iy = DISPLAY_Y1 + 185 + 2;
				n = chkcrs[my_hover].pow;
			}
			else if (i == 0) {
				ix = DISPLAY_X1_1P + 152 - 4 + 32;
				iy = DISPLAY_Y1_1P + 92 + 2;
				n = chkcrs[my_hover].pow;
			}
			else {
				ix = DISPLAY_X1_2P + 152 - 4 + 32;
				iy = DISPLAY_Y1_2P + 92 + 2;
				n = chkcrs[your_hover].pow;
			}

			for (j = 0; j < PASSPNT_MAX; j++) {
				if (j == n - 1) {
					k = (centest / 1) % 6;
					if (k > 3)
						k = 6 - k;
				}
				else if (j < n)
					k = 3;
				else
					k = 0;
				k += j * 4;
				gDPLoadTextureBlock(pgfx++, tx_power + k * 20 * 8, G_IM_FMT_RGBA, G_IM_SIZ_32b, 20, 8, 0,
					G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
				gSPScisTextureRectangle(pgfx++, ix << 2, iy << 2, ix + 20 << 2, iy + 8 << 2, G_TX_RENDERTILE,
					0 << 5, 0 << 5, 1 << 10, 1 << 10);
				ix += 22;
			}
		}
	}



/*---------------------------------------------------------------------------*/
/* score */
	if (game_kind == GAME_KIND_SCORE) {
		gDPLoadTextureBlock(pgfx++, tx_sc_score_mark, G_IM_FMT_RGBA, G_IM_SIZ_32b, 36, 12, 0,
			G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
		gSPTextureRectangle(pgfx++, DISPLAY_X1 + 37 << 2, DISPLAY_Y1 + 2 << 2,
			DISPLAY_X1 + 37 + 36 << 2, DISPLAY_Y1 + 2 + 12 << 2, G_TX_RENDERTILE,
			0 << 5, 0 << 5, 1 << 10, 1 << 10);

		ix = DISPLAY_X1 + 20;
		iy = DISPLAY_Y1 + 18;
		n = sca_score;
		if (n > SCA_SCORE_MAX)
			n = SCA_SCORE_MAX;

		for (i = 0; i < 5; i++) {
			strbuf[5 - 1 - i] = n % 10;
			n /= 10;
		}

		for (i = 0; i < 5; i++) {
			gDPLoadTextureBlock(pgfx++, tx_score_a + (int)strbuf[i] * 12 * 16, G_IM_FMT_RGBA, G_IM_SIZ_32b, 12, 16, 0,
				G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
			gSPTextureRectangle(pgfx++, ix << 2, iy << 2, ix + 12 << 2, iy + 16 << 2, G_TX_RENDERTILE,
				0 << 5, 0 << 5, 1 << 10, 1 << 10);
			ix += 14;
		}
	}

/*---------------------------------------------------------------------------*/
/* left time */
#define G_CC_LEFTTIME	TEXEL0, 0, ENVIRONMENT, 0,  TEXEL0, 0, ENVIRONMENT, 0

	if (game_kind == GAME_KIND_SCORE) {
		/*---------------------------------------------------------------------------*/
		/* name */
		gDPLoadTextureBlock(pgfx++, tx_sc_time_mark, G_IM_FMT_RGBA, G_IM_SIZ_32b, 32, 12, 0,
			G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
		gSPTextureRectangle(pgfx++, DISPLAY_X1 + 133 << 2, DISPLAY_Y1 + 2 << 2,
			DISPLAY_X1 + 133 + 32 << 2, DISPLAY_Y1 + 2 + 12 << 2, G_TX_RENDERTILE,
			0 << 5, 0 << 5, 1 << 10, 1 << 10);

		/*---------------------------------------------------------------------------*/
		/* number */
		n = chkcrs[my_hover].lefttime;
		ix = DISPLAY_X1 + 124;
		iy = DISPLAY_Y1 + 18;
		
		k = n / (FRAME_SEC * CTIME_FRAME);
		m = (n % (FRAME_SEC * CTIME_FRAME)) / 100;

		gDPLoadTextureBlock(pgfx++, tx_middle_font + m * 12 * 16, G_IM_FMT_RGBA, G_IM_SIZ_32b, 12, 16, 0,
			G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
		gSPTextureRectangle(pgfx++, DISPLAY_X1 + 162 << 2, DISPLAY_Y1 + 18 << 2,
			DISPLAY_X1 + 162 + 12 << 2, DISPLAY_Y1 + 18 + 16 << 2, G_TX_RENDERTILE,
			0 << 5, 0 << 5, 1 << 10, 1 << 10);

		/*---------------------------------------------------------------------------*/
		/* " */
		gDPLoadTextureBlock(pgfx++, tx_middle_font + 11 * 12 * 16, G_IM_FMT_RGBA, G_IM_SIZ_32b, 12, 16, 0,
			G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
		gSPTextureRectangle(pgfx++, DISPLAY_X1 + 154 << 2, DISPLAY_Y1 + 15 << 2,
			DISPLAY_X1 + 154 + 12 << 2, DISPLAY_Y1 + 15 + 16 << 2, G_TX_RENDERTILE,
			0 << 5, 0 << 5, 1 << 10, 1 << 10);

		if (k > 5 || chkcrs[my_hover].ffinish || chkcrs[my_hover].fretire) {
			if (k >= 10) {
				gDPLoadTextureBlock(pgfx++, tx_time_a + (k / 10) * 16 * 20, G_IM_FMT_RGBA, G_IM_SIZ_32b, 16, 20, 0,
					G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
				gSPTextureRectangle(pgfx++, ix << 2, iy << 2, ix + 16 << 2, iy + 20 << 2, G_TX_RENDERTILE,
					0 << 5, 0 << 5, 1 << 10, 1 << 10);
			}
			ix += 16;
			gDPLoadTextureBlock(pgfx++, tx_time_a + (k % 10) * 16 * 20, G_IM_FMT_RGBA, G_IM_SIZ_32b, 16, 20, 0,
				G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
			gSPTextureRectangle(pgfx++, ix << 2, iy << 2, ix + 16 << 2, iy + 20 << 2, G_TX_RENDERTILE,
				0 << 5, 0 << 5, 1 << 10, 1 << 10);
		}
		else {
			j = n % (FRAME_SEC * CTIME_FRAME);
#if 0
			if ((j -= 800) < 0)
				j = 0;
			j = j * 10 / 200;			
#endif
			if ((j -= 700) < 0)
				j = 0;
			j = j * 16 / 300;			

			jx = 32 - j * 2;
			jy = 40 - j * 2;

			if (jx > 0 && jy > 0) {
				gDPPipeSync(pgfx++);
				gDPSetTextureFilter(pgfx++, G_TF_BILERP);
				gDPSetCombineMode(pgfx++, G_CC_LEFTTIME, G_CC_LEFTTIME);
				gDPSetEnvColor(pgfx++, en_flash_r1, en_flash_g1, en_flash_b1, 255);

				gDPLoadTextureBlock(pgfx++, tx_time_b + k * 32 * 40, G_IM_FMT_IA, G_IM_SIZ_8b, 32, 40, 0,
					G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
				gSPTextureRectangle(pgfx++, ix + j << 2, iy + j << 2,
					ix + 32 - j << 2, iy + 40 - j << 2, G_TX_RENDERTILE,
					0 << 5, 0 << 5, 1024 * 32 / jx, 1024 * 40 / jy);
			}
		}

	}

#if 0
/*---------------------------------------------------------------------------*/
/* test */
	sx = 180;
	sy = 120;
	gDPSetTextureFilter(pgfx++, G_TF_POINT);
	gDPLoadTextureBlock(pgfx++, tx_test, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0,
		G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
	gSPTextureRectangle(pgfx++, sx << 2, sy << 2, sx + 64 << 2, sy + 32 << 2, G_TX_RENDERTILE,
		0 << 5, 0 << 5, 1 << 10, 1 << 10);
	sx = 180;
	sy = 120 + 24;
	gDPSetTextureFilter(pgfx++, G_TF_POINT);
	gDPLoadTextureBlock(pgfx++, tx_test2, G_IM_FMT_RGBA, G_IM_SIZ_32b, 64, 16, 0,
		G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
	gSPTextureRectangle(pgfx++, sx << 2, sy << 2, sx + 64 << 2, sy + 16 << 2, G_TX_RENDERTILE,
		0 << 5, 0 << 5, 1 << 10, 1 << 10);
	sy += 16;
	gDPLoadTextureBlock(pgfx++, tx_test2 + 64 * 16, G_IM_FMT_RGBA, G_IM_SIZ_32b, 64, 16, 0,
		G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
	gSPTextureRectangle(pgfx++, sx << 2, sy << 2, sx + 64 << 2, sy + 16 << 2, G_TX_RENDERTILE,
		0 << 5, 0 << 5, 1 << 10, 1 << 10);
#endif

/*---------------------------------------------------------------------------*/
/* attack record time */
	if (game_kind == GAME_KIND_ATTACK && ncourse != NCOURSE_PARK) {
		ix = DISPLAY_X1 + 230;
		iy = DISPLAY_Y1 + 2;

		// RF: BEST TIME
#if LOCALE==CHINA
		pgfx = makeStrGlist(pgfx, FONT_TYPE_SELECT, "\x76\x73\x71\x74",
#else
		pgfx = makeStrGlist(pgfx, FONT_TYPE_SMALL, "BEST TIME",
#endif

			ix, iy, FONT_FLAG_NORMAL,
			0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0);

		iy += 13;
		pgfx = makeTimeGlist(pgfx, FONT_TYPE_SMALL, best_total_time_prev,
			ix, iy, FONT_FLAG_NORMAL,
			0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0);

		if (!reverseRunFlag) {
			iy += 11;
			// RF: BEST LAP
#if LOCALE==CHINA
			pgfx = makeStrGlist(pgfx, FONT_TYPE_SELECT, "\x72\x75\x76\x73\x71\x74",
				ix - 6, iy, FONT_FLAG_NORMAL,
#else
			pgfx = makeStrGlist(pgfx, FONT_TYPE_SMALL, "BEST LAP",
				ix, iy, FONT_FLAG_NORMAL,
#endif
				0, 0, 0, 0, 0, 0,
				0, 0, 0, 0, 0, 0);

			iy += 13;
			pgfx = makeTimeGlist(pgfx, FONT_TYPE_SMALL, best_lap_time_prev,
				ix, iy, FONT_FLAG_NORMAL,
				0, 0, 0, 0, 0, 0,
				0, 0, 0, 0, 0, 0);
		}
	}

/*---------------------------------------------------------------------------*/
/* end */
	*ppgfx = pgfx;
}

/******************************************************************************
	do rank face
******************************************************************************/

void DoRankFace(void)
{
	int	i, j, k, n, d, a, fchase;
	float	f, vx, vz;
	Rankface	*prankface;

/*---------------------------------------------------------------------------*/
/* rank changing animation */
#if 0
	/* no animation */
	for (n = 0; n < players; n++) {
		for (i = 0; i < boat_max; i++) {
			rankface[n][i].px = 0;
			rankface[n][i].py = chkcrs[i].rank * 24;
		}
		for (i = 0; i < boat_max; i++) {
			if (players == 1) {
				if (chkcrs[i].rank > chkcrs[my_hover].rank)
					rankface[n][i].py += 4;
			}
			else if (n == 0) {
				if (chkcrs[i].rank > chkcrs[my_hover].rank)
					rankface[n][i].py += 4;
			}
			else if (chkcrs[i].rank > chkcrs[your_hover].rank)
				rankface[n][i].py += 4;
		}
	}
#else
	for (n = 0; n < players; n++) {
		for (i = 0; i < boat_max; i++) {
			rankface[n][i].dy = chkcrs[i].rank * 24;
		}
		for (i = 0; i < boat_max; i++) {
			if (players == 1) {
				if (chkcrs[i].rank > chkcrs[my_hover].rank)
					rankface[n][i].dy += 4;
			}
			else if (n == 0) {
				if (chkcrs[i].rank > chkcrs[my_hover].rank)
					rankface[n][i].dy += 4;
			}
			else if (chkcrs[i].rank > chkcrs[your_hover].rank)
				rankface[n][i].dy += 4;
		}

		for (i = 0; i < boat_max; i++) {
			prankface = &rankface[n][i];
			if (prankface->py != prankface->dy) {
				d = prankface->dy - prankface->py;
				a = ABS(d);
				if (a <= 4) {
					prankface->py = prankface->dy;
					prankface->dx = 0;
				}
				else {
					prankface->py += SGN(d) * 4;
					if (d < 0)
						prankface->dx = 0;
					else if (a < 16)
						prankface->dx = a / 2;
					else
						prankface->dx = 8;
				}
			}
			else 
				prankface->dx = 0;
			
			if (prankface->px != prankface->dx) {
				d = prankface->dx - prankface->px;
				a = ABS(d);
				if (a <= 2) {
					prankface->px = prankface->dx;
				}
				else {
					prankface->px += SGN(d) * 2;
				}
			}
		}
	}
#endif

/*---------------------------------------------------------------------------*/
/* fall animation */

	for (i = 0; i < boat_max; i++) {
		k = hover[i].face_panel_mode;
		if (k == FPM_DROWN) {
			face_ofs_dst[i] = -15;
		}
		else if (k == FPM_HANG) {
			face_ofs_dst[i] = -5;
		}
		else {
			face_ofs_v[i] = 1;
			face_ofs_dst[i] = 0;
		}

		if (face_ofs[i] != face_ofs_dst[i]) {
			j = face_ofs_dst[i] - face_ofs[i];
			k = ABS(j);
			face_ofs_v[i]++;
			if (j > 0)
				face_ofs[i] += 1;
			else if (k <= face_ofs_v[i])
				face_ofs[i] = face_ofs_dst[i];
			else
				face_ofs[i] -= face_ofs_v[i];
			if (face_ofs[i] == face_ofs_dst[i])
				face_ofs_v[i] = 1;
		}
	}



/*---------------------------------------------------------------------------*/
/* catching up */
	for (n = 0; n < players; n++) {
		for (i = 0; i < boat_max; i++) {
			fchase = 0;
			if (rankface[n][i].px == rankface[n][i].dx &&
			    rankface[n][i].py == rankface[n][i].dy && !fgoal_process && !chkcrs[i].ffinish) {
				if ((n == 0 && chkcrs[i].rlap == chkcrs[my_hover].rlap && chkcrs[i].rank == chkcrs[my_hover].rank + 1) ||
				    (n == 1 && chkcrs[i].rlap == chkcrs[your_hover].rlap && chkcrs[i].rank == chkcrs[your_hover].rank + 1)) {
					if (n == 0)
						k = my_hover;
					else
						k = your_hover;
					if (chkcrs[i].ibrail == chkcrs[k].ibrail && signal_mode == SIGNAL_MODE_RACE) {
						vx = hover[k].obj.gpx - hover[i].obj.gpx;
						vz = hover[k].obj.gpz - hover[i].obj.gpz;
						if ((f = LENGTH2(vx, vz)) < 512.F) {
							fchase = 0;
							k = rankface[n][i].cy;
							if (f < 256.F)
								k += 2;
							else
								k++;
							rankface[n][i].cy = k & (CHASE_PATTERN - 1);
						}
					}
				}
			}
			
			if (!fchase && rankface[n][i].cy) {
				if (++rankface[n][i].cy >= CHASE_PATTERN)
					rankface[n][i].cy = 0;
			}
		}
	}

/*---------------------------------------------------------------------------*/
/* rank zoom */
	if (frank_zoom == 1) {
		frank_zoom = 2;
		srank_zoom_dst = 4;
	}

	if (srank_zoom != srank_zoom_dst) {
		k = srank_zoom_dst - srank_zoom;
		srank_zoom += SGN(k);
	}

	if (srank_zoom == srank_zoom_dst) {
		if (srank_zoom > 0) {
			frank_zoom = 3;
			srank_zoom_dst = 0;
		}
		else {
			frank_zoom = 0;
			srank_zoom_dst = 0;
		}
	}

/*	printf("rz: %8d%8d%8d\n", frank_zoom, srank_zoom, srank_zoom_dst);	*/

}


/******************************************************************************
	draw rank face
******************************************************************************/

void DrawRankFace(Gfx **ppgfx)
{
	int	i, j, k, n, ix, iy, sx, sy, tx, ty, icolor, femph;
	ushort	*ptex;
	float	g;
	Gfx	*pgfx = *ppgfx;
	static float	chase_ofs[CHASE_PATTERN] = { 0.F, 0.9F,  1.F, 0.83F,  0.66F, 0.50F,  0.33F, 0.17F };

/*---------------------------------------------------------------------------*/
/* draw */

#define G_CC_RANKNUM	TEXEL0, 0, ENVIRONMENT, 0,  0, 0, 0, TEXEL0

	if (players == 1) {
		gSPDisplayList(pgfx++, gfx_init_rank_face);
	}
	else {
		gSPDisplayList(pgfx++, gfx_init_rank_face_2p);
	}

	for (n = 0; n < players; n++) {
		if (players == 1) {
			sx = DISPLAY_X1 + 254 + scrofs1;
			sy = DISPLAY_Y1 + 40;
		}
		else if (n == 0) {
			sx = DISPLAY_X1_1P + 256;
			sy = DISPLAY_Y1_1P + 36 - 5;
		}
		else {
			sx = DISPLAY_X1_2P + 256;
			sy = DISPLAY_Y1_2P + 36 - 5;
		}

		for (j = 0; j < boat_max; j++) {
			if (n == 0)
				i = boat_max - 1 - j;
			else
				i = j;
			
			tx = sx + rankface[n][i].px;
			ty = sy + rankface[n][i].py;

			/*---------------------------------------------------------------------------*/
			/* catching up */

			g = chase_ofs[rankface[n][i].cy & (CHASE_PATTERN - 1)] * 4.F;
			ty -= g;
#if 0
			if (rankface[n][i].px == rankface[n][i].dx &&
			    rankface[n][i].py == rankface[n][i].dy && !fgoal_process) {
				if ((n == 0 && chkcrs[i].rank == chkcrs[my_hover].rank + 1) ||
				    (n == 1 && chkcrs[i].rank == chkcrs[your_hover].rank + 1)) {
					if (n == 0)
						k = my_hover;
					else
						k = your_hover;
					if (chkcrs[i].ibrail == chkcrs[k].ibrail && signal_mode == SIGNAL_MODE_RACE) {
						vx = hover[k].obj.gpx - hover[i].obj.gpx;
						vz = hover[k].obj.gpz - hover[i].obj.gpz;
						if ((f = LENGTH2(vx, vz)) < 512.F) {
#if 0
							k = (centest % 3) * 3;
							ty -= (int)((1.F - f / 512.F) * k);
#endif
							if (f < 256.F)
								k = centest * 2;
							else
								k = centest;
							g = chase_ofs[k & 7] * 4.F;
							ty -= g;
						}
					}
				}
			}
#endif

			/*---------------------------------------------------------------------------*/
			/* emphasize flag */
			if ((n == 0 && i == my_hover) ||
			    (n == 1 && i == your_hover))
				femph = 1;
			else
				femph = 0;

			/*---------------------------------------------------------------------------*/
			/* back */

			gDPPipeSync(pgfx++);
			gDPSetCombineMode(pgfx++, G_CC_DECALRGBA, G_CC_DECALRGBA);
			gDPSetRenderMode(pgfx++, G_RM_AA_TEX_EDGE, G_RM_AA_TEX_EDGE2);
			
			if (femph) {
				if (!chkcrs[i].ffinish)
					ptex = tx_face_back1;
				else
					ptex = tx_face_back4;
				gDPLoadTextureBlock(pgfx++, ptex, G_IM_FMT_RGBA, G_IM_SIZ_16b, 36, 24, 0,
					G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
				gSPTextureRectangle(pgfx++, tx - 7 << 2, ty << 2, tx - 7 + 36 << 2, ty + 24 << 2, G_TX_RENDERTILE,
					0 << 5, 0 << 5, 1 << 10, 1 << 10);
			}
			else {
				if (!chkcrs[i].ffinish)
					ptex = tx_face_back2;
				else
					ptex = tx_face_back3;
				gDPLoadTextureBlock(pgfx++, ptex, G_IM_FMT_RGBA, G_IM_SIZ_16b, 32, 20, 0,
					G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
				gSPTextureRectangle(pgfx++, tx << 2, ty << 2, tx + 32 << 2, ty + 20 << 2, G_TX_RENDERTILE,
					0 << 5, 0 << 5, 1 << 10, 1 << 10);
			}

			/*---------------------------------------------------------------------------*/
			/* face */

			if ((i == my_hover && machine_2Pcolor_flag[0]) ||
			    (players == 2 && i == your_hover && machine_2Pcolor_flag[1]))
				icolor = 4;
			else
				icolor = 0;
			gDPLoadTextureBlock(pgfx++, face_tbl[hover[i].boat_number + icolor], G_IM_FMT_RGBA, G_IM_SIZ_16b, 20, 20, 0,
				G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
			
			if (femph) {
				gSPTextureRectangle(pgfx++, tx + 5 << 2, ty + 2 << 2,
					tx + 5 + 20 << 2, ty + 2 + 20 << 2, G_TX_RENDERTILE,
					0 << 5, face_ofs[i] << 5, 1 << 10, 1 << 10);
			}
			else {
				gSPTextureRectangle(pgfx++, tx + 9 << 2, ty + 2 << 2,
					tx + 9 + 16 << 2, ty + 2 + 16 << 2, G_TX_RENDERTILE,
					0 << 5, face_ofs[i] << 5, 1280, 1280);
			}


			/*---------------------------------------------------------------------------*/
			/* number */

			gDPPipeSync(pgfx++);
			gDPSetRenderMode(pgfx++, G_RM_XLU_SURF, G_RM_XLU_SURF2);
			gDPSetCombineMode(pgfx++, G_CC_RANKNUM, G_CC_RANKNUM);

			if (femph) {
				gDPSetEnvColor(pgfx++, en_flash_r2, en_flash_g2, en_flash_b2, 255);
				ix = tx - 7 + 3;
				iy = ty + 4;
			}
			else {
				gDPSetEnvColor(pgfx++, 255, 255, 255, 255);
				ix = tx + 2;
				iy = ty + 2;
			}
			gDPLoadTextureBlock(pgfx++, tx_small_font + (chkcrs[i].rank + 1) * 8 * 8, G_IM_FMT_IA, G_IM_SIZ_8b, 8, 8, 0,
				G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
			gSPTextureRectangle(pgfx++, ix << 2, iy << 2, ix + 8 << 2, iy + 8 << 2, G_TX_RENDERTILE,
				0 << 5, 0 << 5, 1 << 10, 1 << 10);

		}
	}

/*---------------------------------------------------------------------------*/
/* end */
	*ppgfx = pgfx;

}

/******************************************************************************
	do enemy mark
******************************************************************************/
#define EM_ANGLE	(135.F)

void DoEnemyMark(void)
{
	int	i, n, nplayer;
	float	f, ds;
	float	mx, mz, fx, fz, px, pz, vx, vz, sx, sz, ox, oy;
	float	dside, lside, aside, rside, rot, arot, srot, dback;
	float	fcos, fsin, ang;
	float	camera_dst;
	Enemymark	*penemymark;
	Camera		*pcamera;
	int	num;

/*---------------------------------------------------------------------------*/
	fghost = (game_kind == GAME_KIND_ATTACK && ghost_data_sw == 1 && ghost_disp_sw == 1);
	num = boat_max + fghost;		
/*	printf("de: %d %d %d\n", ghost_data_sw, ghost_disp_sw, fghost);	*/

/*---------------------------------------------------------------------------*/
/* enemy mark */
/*	return;	*/

	for (n = 0; n < players; n++) {
		if (n == 0) {
			nplayer = my_hover;
			pcamera = &camera[my_camera];
		}
		else {
			nplayer = your_hover;
			pcamera = &camera[your_camera];
		}

#if 0
		mx = hover[nplayer].obj.gpx;
		mz = hover[nplayer].obj.gpz;
#endif
		mx = pcamera->camera_px;
		mz = pcamera->camera_pz;
		fx = -pcamera->camera_fx_2d;
		fz = -pcamera->camera_fz_2d;
		sx =  fz;
		sz = -fx;

		vx = pcamera->look_px - mx;
		vz = pcamera->look_pz - mz;
		camera_dst = LENGTH2(vx, vz);


		for (i = 0; i < num; i++) {
			penemymark = &enemymark[n][i];
			penemymark->fg = 0;
			if (i == nplayer || (!fghost && chkcrs[i].rank < chkcrs[nplayer].rank))
				continue;
			vx = hover[i].obj.gpx - mx;
			vz = hover[i].obj.gpz - mz;
			dside = vx * sx + vz * sz;
			dback = vx * fx + vz * fz;

			if ((ds = LENGTH2(vx, vz)) > 0.F) {
				vx /= ds;
				vz /= ds;
			}
			fcos = vx * fx + vz * fz;
			fsin = fx * vz - fz * vx;

			ang = acos(fcos);

			if (ds > 1024.F || ang > EM_ANGLE)
				continue;

/*			lside = 60.F;	*/
			if ((f = dback) < 0.F)
				f = 0.F;
			lside = 60.F + f / 1024.F * 1024.F;



			rside = dside / lside;
			aside = ABS(rside);
			
			if (rside > 1.F) {
				rot = atan2(rside - 1.F, dback / lside);
				rside = 1.F;
			}
			else if (rside < -1.F) {
				rot = atan2(rside + 1.F, dback / lside);
				rside = -1.F;
			}
			else {
				rot = 0.F;
			}

			if (rot > 180.F)
				rot = rot - 360.F;
			arot = ABS(rot);
			srot = SGN(rot);
			if (arot > 0.F) {
				if ((arot *= 90.F / EM_ANGLE) > 90.F)
					arot = 90.F;
				ox = srot * sint(arot) * 32.F;
				oy = -(1.F - cost(arot)) * 24.F;
			}
			else
				ox = oy = 0.F;

			penemymark->fg = 1;
			penemymark->ag = srot * arot;
			penemymark->px = rside * 94.F + ox;
			penemymark->py = oy;
#if 0
			penemymark->ag = -ang * SGN(fsin);
			penemymark->px = penemymark->ag / EM_ANGLE * 144.F;
			penemymark->py = -ang / EM_ANGLE * 24.F;
#endif
#if 0
			if (i == 0) {
				printf("em: %8.0f%8.2f%8.0f\n",
					dside, rot, camera_dst);
			}
#endif
#if 0
			if (i == 0)
				printf("em: %8.0f, %8.0f%8.0f, %8.0f%8.0f\n",
					rside, rot, arot, ox, lside);
#endif
#if 0
			printf("em: %8.0f%8.0f, %8.0f%8.0f, %8.0f\n",
				mx, mz, fx, fz, ang);
#endif

	
		}
	}


}

/******************************************************************************
	draw enemy mark
******************************************************************************/

void DrawEnemyMark(Gfx **ppgfx)
{
	int	i, j, k, n, ix, iy, icolor;
	ushort	*ptex;
	Gfx	*pgfx = *ppgfx;
	Enemymark	*penemymark;
	int	num;

/*---------------------------------------------------------------------------*/
	num = boat_max + fghost;		

/*---------------------------------------------------------------------------*/
/* init */
/*	return;	*/

#if 1
	gSPClearGeometryMode(pgfx++, G_GEOM_ALL);
	gSPSetGeometryMode(pgfx++, G_SHADE);
	gDPPipeSync(pgfx++);
	gDPSetCycleType(pgfx++, G_CYC_1CYCLE);
	gDPSetCombineMode(pgfx++, G_CC_SHADE, G_CC_SHADE);
	gDPSetRenderMode(pgfx++, G_RM_ENCLRCVG, G_RM_ENCLRCVG2);
	gDPSetAlphaCompare(pgfx++, G_AC_NONE);
	gDPSetFillColor(pgfx++, 0xffffffff);

	for (n = 0; n < players; n++) {
		for (i = 0; i < num; i++) {
			penemymark = &enemymark[n][i];
			if (!penemymark->fg)
				continue;

			if (players == 1) {
				ix = DISPLAY_X1 + 152 + penemymark->px;
				iy = DISPLAY_Y1 + 170 + penemymark->py;
			}
			else if (n == 0) {
				ix = DISPLAY_X1_1P + 152 + penemymark->px;
				iy = DISPLAY_Y1_1P +  84 + penemymark->py;
			}
			else {
				ix = DISPLAY_X1_2P + 152 + penemymark->px;
				iy = DISPLAY_Y1_2P +  84 + penemymark->py;
			}

			gDPFillRectangle(pgfx++, ix - 10, iy - 10,
				ix + 10, iy + 10);
		}
	}
#endif


/*---------------------------------------------------------------------------*/
	gSPDisplayList(pgfx++, gfx_init_enemy_mark);
#if 0
	gSPClearGeometryMode(pgfx++, G_GEOM_ALL);
	gSPSetGeometryMode(pgfx++, G_SHADE);
	gSPTexture(pgfx++, 0x8000, 0x8000, 0, G_TX_RENDERTILE, G_ON);
	gDPPipeSync(pgfx++);
	gDPSetCycleType(pgfx++, G_CYC_1CYCLE);
	gDPSetTexturePersp(pgfx++, G_TP_PERSP);
	gDPSetTextureFilter(pgfx++, G_TF_BILERP);
	gDPSetCombineMode(pgfx++, G_CC_ENTEXENV, G_CC_ENTEXENV);
	gDPSetRenderMode(pgfx++, G_RM_AA_XLU_SURF, G_RM_AA_XLU_SURF2);
	gDPSetAlphaCompare(pgfx++, G_AC_NONE);
#endif
	
/*---------------------------------------------------------------------------*/
/* frame */
	gDPSetEnvColor(pgfx++, en_flash_r1, en_flash_g1, en_flash_b1, 255);
	gDPLoadTextureBlock(pgfx++, tx_back_enemy, G_IM_FMT_IA, G_IM_SIZ_8b, 16, 24, 0,
		G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
	gSPMatrix(pgfx++, &rsp_endynamic.mtx_ortho2, G_MTX_PROJECTION | G_MTX_LOAD | G_MTX_NOPUSH);

	for (n = 0; n < players; n++) {
		for (i = 0; i < num; i++) {
			penemymark = &enemymark[n][i];
			if (!penemymark->fg)
				continue;

			if (players == 1) {
				ix = DISPLAY_X1 + 152 + penemymark->px;
				iy = DISPLAY_Y1 + 170 + penemymark->py;
			}
			else if (n == 0) {
				ix = DISPLAY_X1_1P + 152 + penemymark->px;
				iy = DISPLAY_Y1_1P +  84 + penemymark->py;
			}
			else {
				ix = DISPLAY_X1_2P + 152 + penemymark->px;
				iy = DISPLAY_Y1_2P +  84 + penemymark->py;
			}

			egTranslate(&pendynamic->mtx_model[ienmtxmdl], (float)ix, (float)iy, 0.F);
			gSPMatrix(pgfx++, &rsp_endynamic.mtx_model[ienmtxmdl++], G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_NOPUSH);
		 	egRotate(&pendynamic->mtx_model[ienmtxmdl], -penemymark->ag, 0.F, 0.F, 1.F);
			gSPMatrix(pgfx++, &rsp_endynamic.mtx_model[ienmtxmdl++], G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_NOPUSH);

#if 0
			gSPTextureRectangle(pgfx++, ix << 2, iy << 2, ix + 16 << 2, iy + 24 << 2, G_TX_RENDERTILE,
				0 << 5, 0 << 5, 1 << 10, 1 << 10);
#endif
			gSPDisplayList(pgfx++, gfx_enemy_mark);

		}
	}

/*---------------------------------------------------------------------------*/
/* face */
	gDPPipeSync(pgfx++);
	gDPSetTexturePersp(pgfx++, G_TP_NONE);
	gDPSetCombineMode(pgfx++, G_CC_DECALRGBA, G_CC_DECALRGBA);
	gDPSetRenderMode(pgfx++, G_RM_AA_OPA_SURF, G_RM_AA_OPA_SURF2);

	for (n = 0; n < players; n++) {
		for (i = 0; i < num; i++) {
			penemymark = &enemymark[n][i];
			if (!penemymark->fg)
				continue;

			if (players == 1) {
				ix = DISPLAY_X1 + 152 + penemymark->px;
				iy = DISPLAY_Y1 + 170 + penemymark->py;
			}
			else if (n == 0) {
				ix = DISPLAY_X1_1P + 152 + penemymark->px;
				iy = DISPLAY_Y1_1P +  84 + penemymark->py;
			}
			else {
				ix = DISPLAY_X1_2P + 152 + penemymark->px;
				iy = DISPLAY_Y1_2P +  84 + penemymark->py;
			}

			icolor = 0;
			if (players == 2) {
				if ((i == my_hover   && machine_2Pcolor_flag[0]) ||
				    (i == your_hover && machine_2Pcolor_flag[1]))
					icolor = 4;
			}
			
			if (!fghost) {
				ix -= 5;
				iy -= 5;
				gDPLoadTextureBlock(pgfx++, face_tbl[hover[i].boat_number + icolor], G_IM_FMT_RGBA, G_IM_SIZ_16b, 20, 20, 0,
					G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
				gSPTextureRectangle(pgfx++, ix << 2, iy << 2,
					ix + 10 << 2, iy + 10 << 2, G_TX_RENDERTILE,
					0 << 5, 0 << 5, 2048, 2048);
			}
			else {
				ix -= 4;
				iy -= 5;
				gDPSetCombineMode(pgfx++, G_CC_ENTEXENV, G_CC_ENTEXENV);
				gDPSetRenderMode(pgfx++, G_RM_AA_XLU_SURF, G_RM_AA_XLU_SURF2);
				gDPSetEnvColor(pgfx++, en_flash_r2, en_flash_g2, en_flash_b2, 255);
				gDPLoadTextureBlock(pgfx++, tx_small_font + ('G' - 'A' + 10) * 8 * 8, G_IM_FMT_IA, G_IM_SIZ_8b, 8, 8, 0,
					G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
				gSPTextureRectangle(pgfx++, ix << 2, iy << 2,
					ix + 10 << 2, iy + 10 << 2, G_TX_RENDERTILE,
					0 << 5, 0 << 5, 8 * 1024 / 10, 8 * 1024 / 10);
			}
		}
	}

/*---------------------------------------------------------------------------*/
/* end */
	*ppgfx = pgfx;
}


/******************************************************************************
	dot line
******************************************************************************/
void DotLine(int bx, int by, int ex, int ey, int *nd, int *px, int *py)
{
	int	x, y, dx, dy, vx, vy, n, w;
	
/*	printf("dl: %d %d %d %d\n", bx, by, ex, ey);	*/

	dx = ex - bx;
	dy = ey - by;
	vx = SGN(dx);
	vy = SGN(dy);
	dx = ABS(dx);
	dy = ABS(dy);
	
	x = bx;
	y = by;
	n = w = 0;
	px[n] = x;
	py[n++] = y;
	
	if (dx >= dy) {
		while (x != ex) {
			x += vx;
			w += dy;
			if (w * 2 >= dx) {
				w -= dx;
				y += vy;
			}
			px[n] = x;
			py[n++] = y;
		}
	}
	else {
		while (y != ey) {
			y += vy;
			w += dx;
			if (w * 2 >= dy) {
				w -= dy;
				x += vx;
			}
			px[n] = x;
			py[n++] = y;
		}
	}
	
	*nd = n;
}

/******************************************************************************
	make mini-map
******************************************************************************/
#define set_minimap0(x, y, c)	tx_minimap[(x) + (y) * MINIMAP_WD] = (c)
#define set_minimap(x, y, c)					\
	if ((x) >= 0 && (x) <= MINIMAP_WD - 1 &&		\
	    (y) >= 0 && (y) <= MINIMAP_HT - 1)			\
	    	tx_minimap[(x) + (y) * MINIMAP_WD] = (c)

void MakeMiniMap(void)
{

#ifndef ROM_FLAG
	int	i, j, k, inext, x, y, sx, sy, ex, ey, c1, c2, nd;

/*---------------------------------------------------------------------------*/
/* clear */
	for (y = 0; y < MINIMAP_HT; y++)
		for (x = 0; x < MINIMAP_WD; x++)
			set_minimap0(x, y, GPACK_RGBA5551(0, 0, 0, 0));

/*---------------------------------------------------------------------------*/
/* buoy line */
	for (i = 0; i < nofbuoy; i++) {
		if (buoy[i].user >= BUOY_USER_EN)
			continue;
		sx = (buoy[i].ox / crsscale + 1.F) / 2.F * (MINIMAP_WD - 3);
		sy = (buoy[i].oz / crsscale + 1.F) / 2.F * (MINIMAP_WD - 3);
		inext = buoy[i].c1;
		ex = (buoy[inext].ox / crsscale + 1.F) / 2.F * (MINIMAP_WD - 3);
		ey = (buoy[inext].oz / crsscale + 1.F) / 2.F * (MINIMAP_WD - 3);

		DotLine(sx + 1, sy + 1, ex + 1, ey + 1, &nd, minimapx, minimapy);
		
		for (j = 0; j < nd; j++) {
			x = minimapx[j];
			y = minimapy[j];
			set_minimap(x, y, GPACK_RGBA5551(0, 0, 255, 1));
		}
	}

/*---------------------------------------------------------------------------*/
/* crsbuoy line */
#if 0
    for (k = 0; k < 2; k++) {
	for (i = 0; i < nofcrsbuoy; i++) {
		sx = (crsuoy[inext].px / crsscale + 1.F) / 2.F * (MINIMAP_WD - 3);
		sz = (crsbuoy[inext].pz / crsscale + 1.F) / 2.F * (MINIMAP_WD - 3);
		inext = (i + 1) % nofcrsbuoy;
		while (crsbuoy[i].type != crsbuoy[inext].type)
			inext = (inext + 1) % nofcrsbuoy;
		
		ex = (crsuoy[inext].px / crsscale + 1.F) / 2.F * (MINIMAP_WD - 3);
		ez = (crsbuoy[inext].pz / crsscale + 1.F) / 2.F * (MINIMAP_WD - 3);

		DotLine(sx + 1, sy + 1, ex + 1, ey + 1, &nd, minimapx, minimapy);
		
		switch (crsbuoy[i].type) {
			default:
			case CRSBUOY_KD_IN:
				c1 = GPACK_RGBA5551(0, 255, 0, 1);
				break;
			case CRSBUOY_KD_OUT:
				c1 = GPACK_RGBA5551(255, 0, 255, 1);
				break;
		}
		
		if (k == 0) {
			for (j = 0; j < nd; j++) {
				x = minimapx[j];
				y = minimapy[j];
				set_minimap(x    , y - 1, 1);
				set_minimap(x - 1, y    , 1);
				set_minimap(x + 1, y    , 1);
				set_minimap(x    , y + 1, 1);
			}
		}
		else {
			for (j = 0; j < nd; j++) {
				x = minimapx[j];
				y = minimapy[j];
				set_minimap(x, y, c1);
			}
		}
	}
    }
#endif

/*---------------------------------------------------------------------------*/
/* buoy */
	for (i = 0; i < nofbuoy; i++) {
		if (buoy[i].user >= BUOY_USER_EN)
			continue;
		x = (buoy[i].ox / crsscale + 1.F) / 2.F * (MINIMAP_WD - 3);
		y = (buoy[i].oz / crsscale + 1.F) / 2.F * (MINIMAP_WD - 3);
	
		switch (buoy[i].type) {
			default:
			case BUOY_KD_RIGHT:
				c1 = GPACK_RGBA5551(255, 0, 0, 1);
				c2 = GPACK_RGBA5551(128, 0, 0, 1);
				break;
			case BUOY_KD_LEFT:
				c1 = GPACK_RGBA5551(255, 255, 0, 1);
				c2 = GPACK_RGBA5551(128, 128, 0, 1);
				break;
			case BUOY_KD_CHECK:
				c1 = GPACK_RGBA5551(255, 0, 255, 1);
				c2 = GPACK_RGBA5551(128, 0, 128, 1);
				break;
			case BUOY_KD_GOAL:
				c1 = GPACK_RGBA5551(0, 255, 255, 1);
				c2 = GPACK_RGBA5551(0, 128, 128, 1);
				break;
		}
		
		set_minimap(x    , y    , c2);
		set_minimap(x + 1, y    , c1);
		set_minimap(x + 2, y    , c2);
		set_minimap(x    , y + 1, c1);
		set_minimap(x + 1, y + 1, c1);
		set_minimap(x + 2, y + 1, c1);
		set_minimap(x    , y + 2, c2);
		set_minimap(x + 1, y + 2, c1);
		set_minimap(x + 2, y + 2, c2);
	}

#if 1
/*---------------------------------------------------------------------------*/
/* crsbuoy */
	for (i = 0; i < nofcrsbuoy; i++) {
		x = (crsbuoy[i].px / crsscale + 1.F) / 2.F * (MINIMAP_WD - 3);
		y = (crsbuoy[i].pz / crsscale + 1.F) / 2.F * (MINIMAP_WD - 3);
	
		switch (crsbuoy[i].type) {
			default:
			case CRSBUOY_KD_IN:
				c1 = GPACK_RGBA5551(255, 255, 0, 1);
				c2 = GPACK_RGBA5551(128, 128, 0, 1);
				break;
			case CRSBUOY_KD_OUT:
				c1 = GPACK_RGBA5551(255, 0, 0, 1);
				c2 = GPACK_RGBA5551(128, 0, 0, 1);
				break;
		}
		
		set_minimap(x    , y    , c1);
		set_minimap(x + 1, y    , c1);
/*		set_minimap(x    , y + 1, c1);	*/
/*		set_minimap(x + 1, y + 1, c1);	*/
	}
#endif

#endif	/* ROM_FLAG */

}


/******************************************************************************
	draw mini-map
******************************************************************************/
void DrawMiniMap(Gfx **ppgfx)
{
#ifndef ROM_FLAG

	int	i, j, n, ix, iy;
	uchar	*list;
	Gfx	*pgfx = *ppgfx;

/*---------------------------------------------------------------------------*/
/* back */
	gSPClearGeometryMode(pgfx++, G_GEOM_ALL);
	gSPSetGeometryMode(pgfx++, G_SHADE);
	gSPTexture(pgfx++, 0x8000, 0x8000, 0, G_TX_RENDERTILE, G_ON);
	gDPPipeSync(pgfx++);
	gDPSetCycleType(pgfx++, G_CYC_1CYCLE);
	gDPSetTexturePersp(pgfx++, G_TP_NONE);
	gDPSetPrimColor(pgfx++, 0, 0,  0, 0, 0, 128);
	gDPSetCombineMode(pgfx++, G_CC_PRIMITIVE, G_CC_PRIMITIVE);
	gDPSetRenderMode(pgfx++, G_RM_XLU_SURF, G_RM_XLU_SURF2);
#if 0
	gDPScisFillRectangle(pgfx++, MINIMAP_X - 4, MINIMAP_Y - 4,
		MINIMAP_X + MINIMAP_WD + 4, MINIMAP_Y + MINIMAP_HT + 4);
#endif


/*---------------------------------------------------------------------------*/
/* map */
	gDPPipeSync(pgfx++);
	gDPSetCombineMode(pgfx++, G_CC_DECALRGBA, G_CC_DECALRGBA);
	gDPSetRenderMode(pgfx++, G_RM_AA_TEX_EDGE, G_RM_AA_TEX_EDGE2);

	ix = MINIMAP_X;
#if 1
	for (i = 0; i < MINIMAP_HT / 16; i++) {
		iy = MINIMAP_Y + i * 16;;
		gDPPipeSync(pgfx++);
		gDPLoadTextureBlock(pgfx++, tx_minimap + i * MINIMAP_WD * 16, G_IM_FMT_RGBA, G_IM_SIZ_16b, MINIMAP_WD, 16, 0,
			G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
		gSPTextureRectangle(pgfx++,
			ix << 2, iy << 2, ix + MINIMAP_WD << 2, iy + 16 << 2, G_TX_RENDERTILE,
			(0 << 5), (0 << 5), (1 << 10), (1 << 10));
	}
#endif

#if 0
	ix = 64;
	for (i = 0; i < MINIMAP_HT / 16; i++) {
		iy = 64 + i * 16 * 2;;
		gDPPipeSync(pgfx++);
		gDPLoadTextureBlock(pgfx++, tx_minimap + i * MINIMAP_WD * 16, G_IM_FMT_RGBA, G_IM_SIZ_16b, MINIMAP_WD, 16, 0,
			G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
		gSPTextureRectangle(pgfx++,
			ix << 2, iy << 2, ix + MINIMAP_WD * 2 << 2, iy + 16 * 2 << 2, G_TX_RENDERTILE,
			(0 << 5), (0 << 5), (1 << 9), (1 << 9));
	}
#endif
	
/*---------------------------------------------------------------------------*/
/* next buoy */
	if (centest & 2) {
/*		i = chkcrs[my_hover].ibnext;	*/
		i = chkcrs[my_hover].ibrail;
		ix = (buoy[i].ox / crsscale + 1.F) / 2.F * (MINIMAP_WD - 3) + MINIMAP_X;
		iy = (buoy[i].oz / crsscale + 1.F) / 2.F * (MINIMAP_WD - 3) + MINIMAP_Y;
	
		gDPPipeSync(pgfx++);
		gDPSetPrimColor(pgfx++, 0, 0,  255, 255, 255, 255);
		gDPSetCombineMode(pgfx++, G_CC_PRIMITIVE, G_CC_PRIMITIVE);
		gDPSetRenderMode(pgfx++, G_RM_OPA_SURF, G_RM_OPA_SURF2);
		gDPScisFillRectangle(pgfx++, ix, iy, ix + 3, iy + 3);
	}
	
/*---------------------------------------------------------------------------*/
/* machine */
#if 0
	ix = (hover[my_hover].obj.gpx - crs_xmin) / crs_xsize * (MINIMAP_WD - 3) + MINIMAP_X;
	iy = (hover[my_hover].obj.gpz - crs_zmin) / crs_zsize * (MINIMAP_HT - 3) + MINIMAP_Y;
	
	gDPPipeSync(pgfx++);
	gDPSetPrimColor(pgfx++, 0, 0,  255, 255, 255, 255);
	gDPSetCombineMode(pgfx++, G_CC_PRIMITIVE, G_CC_PRIMITIVE);
	gDPSetRenderMode(pgfx++, G_RM_OPA_SURF, G_RM_OPA_SURF2);
	gDPScisFillRectangle(pgfx++, ix, iy, ix + 3, iy + 3);
#endif
	gDPPipeSync(pgfx++);
	gDPSetCombineMode(pgfx++, G_CC_PRIMITIVE, G_CC_PRIMITIVE);
	gDPSetRenderMode(pgfx++, G_RM_OPA_SURF, G_RM_OPA_SURF2);
	for (i = boat_max - 1; i >= 0; i--) {
		ix = (hover[i].obj.gpx / crsscale + 1.F) / 2.F * (MINIMAP_WD - 3) + MINIMAP_X;
		iy = (hover[i].obj.gpz / crsscale + 1.F) / 2.F * (MINIMAP_WD - 3) + MINIMAP_Y;
		ix -= 1;
		iy -= 1;
		if (ix < DISPLAY_X1 || ix + 5 > DISPLAY_X2 || 
			iy < DISPLAY_Y1 || iy + 5 > DISPLAY_Y2)
			continue;
		gDPPipeSync(pgfx++);
		gDPSetPrimColor(pgfx++, 0, 0,  
			0, 0, 0, 255);
		gDPScisFillRectangle(pgfx++, ix, iy, ix + 5, iy + 5);
		gDPPipeSync(pgfx++);
		gDPSetPrimColor(pgfx++, 0, 0,  
			machine_color[i][0], machine_color[i][1], machine_color[i][2], 255);
		gDPScisFillRectangle(pgfx++, ix + 1, iy + 1, ix + 4, iy + 4);
	}

#if 0
/*---------------------------------------------------------------------------*/
/* test course list */
	n = GetCrsBuoyList(hover[my_hover].obj.gpx, hover[my_hover].obj.gpz, &list);
	for (i = 0; i < n; i++) {
		j = list[i];
		ix = (crsbuoy[j].px / crsscale + 1.F) / 2.F * (MINIMAP_WD - 3) + MINIMAP_X;
		iy = (crsbuoy[j].pz / crsscale + 1.F) / 2.F * (MINIMAP_WD - 3) + MINIMAP_Y;
	
		gDPPipeSync(pgfx++);
		gDPSetPrimColor(pgfx++, 0, 0,  128, 255, 255, 255);
		gDPSetCombineMode(pgfx++, G_CC_PRIMITIVE, G_CC_PRIMITIVE);
		gDPSetRenderMode(pgfx++, G_RM_OPA_SURF, G_RM_OPA_SURF2);
		gDPScisFillRectangle(pgfx++, ix, iy, ix + 3, iy + 3);
	}
#endif
		
	
/*---------------------------------------------------------------------------*/
/* rank */
#if 0
	print_decimal(160, 32     , chkcrs[my_hover].lap, 6);
	print_decimal(160, 32 +  8, chkcrs[my_hover].rank, 6);
	print_decimal(160, 32 + 16, chkcrs[my_hover].irank, 6);
	print_decimal(160, 32 + 24, chkcrs[my_hover].ctime, 6);
#endif

/*---------------------------------------------------------------------------*/
	*ppgfx = pgfx;

#endif	/* ROM_FLAG */
}

/******************************************************************************
	draw lap message
******************************************************************************/
void DrawLapMsg(Gfx **ppgfx)
{
#define	R0	255	
#define	G0	255	
#define	B0	0	
#define	R1	0	
#define	G1	255	
#define	B1	0

	int	i, j, k, n, ix, iy;
	int	r1, g1, b1;
	int	r2, g2, b2;
	float	f, g, sc;
	Gfx	*pgfx = *ppgfx;
	Chkcrs	*pchkcrs;


#if 0
	if (fbest_lap_msg && chkcrs[my_hover].ttime_dif <= 0) {
		fbest_lap_msg = 0;
		tbest_lap_msg =  BEST_LAP_MSG_FRAME;
		cbest_lap_msg = ibest_lap_msg = 0;
	}
	
	if (tbest_lap_msg > 0) {
		tbest_lap_msg--;

		f = (float)(FLASH_FRAME_LAP - cbest_lap_msg) / (float)FLASH_FRAME_LAP;
		g = 1.F - f;
		i = ibest_lap_msg;
		j = i + 1;
		r1 = flash_col_pow1a[i][0] * f + flash_col_pow1a[j][0] * g;
		g1 = flash_col_pow1a[i][1] * f + flash_col_pow1a[j][1] * g;
		b1 = flash_col_pow1a[i][2] * f + flash_col_pow1a[j][2] * g;
		r2 = flash_col_pow1b[i][0] * f + flash_col_pow1b[j][0] * g;
		g2 = flash_col_pow1b[i][1] * f + flash_col_pow1b[j][1] * g;
		b2 = flash_col_pow1b[i][2] * f + flash_col_pow1b[j][2] * g;
		if (++cbest_lap_msg >= FLASH_FRAME_LAP) {
			cbest_lap_msg = 0;
			ibest_lap_msg = ++ibest_lap_msg & 3;
		}
		// RF: BEST LAP
		pgfx = makeStrGlistS(pgfx, FONT_TYPE_MAIN, "BESTZH",
			DISPLAY_X1 + 88, DISPLAY_Y1 + 59, FONT_FLAG_SHADE,
			r1, g1, b1, r1, g1, b1, 
			r2, g2, b2, r2, g2, b2, 1.2F);
		pgfx = makeStrGlistSub(pgfx, FONT_TYPE_MAIN, "LAPZH",
			DISPLAY_X1 + 88 + 76, DISPLAY_Y1 + 59);
		*ppgfx = pgfx;
		return;
	}
#endif
		
	for (n = 0; n < players; n++) {
		if (n == 0)
			pchkcrs = &chkcrs[my_hover];
		else
			pchkcrs = &chkcrs[your_hover];

		if (pchkcrs->flapmsg) {
			pchkcrs->flapmsg = 0;
			tflash_lap[n] = LAP_MSG_FRAME;
			iflash_lap[n] = cflash_lap[n] = 0;
		}

		if (tflash_lap[n] > 0) {
			tflash_lap[n]--;
#if 0
			if (tflash_lap[n] <= 0)
				clast_lap_flash = 0;
#endif

			f = (float)(FLASH_FRAME_LAP - cflash_lap[n]) / (float)FLASH_FRAME_LAP;
			g = 1.F - f;
			i = iflash_lap[n];
			j = i + 1;
			r1 = flash_col_pow1a[i][0] * f + flash_col_pow1a[j][0] * g;
			g1 = flash_col_pow1a[i][1] * f + flash_col_pow1a[j][1] * g;
			b1 = flash_col_pow1a[i][2] * f + flash_col_pow1a[j][2] * g;
			r2 = flash_col_pow1b[i][0] * f + flash_col_pow1b[j][0] * g;
			g2 = flash_col_pow1b[i][1] * f + flash_col_pow1b[j][1] * g;
			b2 = flash_col_pow1b[i][2] * f + flash_col_pow1b[j][2] * g;
			if (++cflash_lap[n] >= FLASH_FRAME_LAP) {
				cflash_lap[n] = 0;
				iflash_lap[n] = ++iflash_lap[n] & 3;
			}

			if (pchkcrs->lap < finishLap) {
/*				printf("lap: %d\n", ix);	*/
#if LOCALE==CHINA
			   int k2 = 0;
#endif

				if (players == 1) {
#if LOCALE==CHINA
					ix = DISPLAY_X1 + (320 - 24 * 3 )/2 - 3 ;
					k = 24;
					k2 = 24;
#else
					ix = DISPLAY_X1 + 108;
					k = 60;
#endif

					iy = DISPLAY_Y1 + 50;
					sc = 1.3F;
				}
				else if (n == 0) {
#if LOCALE==CHINA
					ix = DISPLAY_X1_1P + (320 - 24 * 3 )/2;
					k = 18;
					k2 = 18;
#else
					ix = DISPLAY_X1_1P + 99 + 18;
					k = 48;
#endif
					iy = DISPLAY_Y1_1P + 28;
					sc = 1.F;
				}
				else {
#if LOCALE==CHINA
					ix = DISPLAY_X1_1P + (320 - 24 * 3 )/2;
					k = 18;
					k2 = 18;
#else
					ix = DISPLAY_X1_2P + 99 + 18;
					k = 48;
#endif
					iy = DISPLAY_Y1_2P + 28;
					sc = 1.F;
				}

				// RF: LAP NUMBER
#if LOCALE==CHINA

				pgfx = makeStrGlistS(pgfx, FONT_TYPE_MAIN, "\x7d",
					ix, iy, FONT_FLAG_SHADE,
					r1, g1, b1, r1, g1, b1, 
						     r2, g2, b2, r2, g2, b2, sc);
#else
				pgfx = makeStrGlistS(pgfx, FONT_TYPE_MAIN, "LAP",
					ix, iy, FONT_FLAG_SHADE,
					r1, g1, b1, r1, g1, b1, 
					r2, g2, b2, r2, g2, b2, sc);
#endif
				sprintf(strbuf, "%d", pchkcrs->lap);

				pgfx = makeStrGlistSub(pgfx, FONT_TYPE_MAIN, strbuf,
					ix + k, iy);

#if LOCALE==CHINA
				pgfx = makeStrGlistSub(pgfx, FONT_TYPE_MAIN, "\x76",
					ix + k + k2, iy);


#endif

			}
			else {
/*				printf("lap: %d\n", ix);	*/
				if (players == 1) {
#if LOCALE==CHINA
				   ix = DISPLAY_X1;
				   ix += ( 320 - 96 - 16 ) / 2;
				   k = 85;
#else
					ix = DISPLAY_X1 + 74;
					k = 98;
#endif
					iy = DISPLAY_Y1 + 50;
					sc = 1.3F;
				}
				else if (n == 0) {
#if LOCALE==CHINA
				   ix = DISPLAY_X1_1P;
				   ix += ( 320 - 96 - 16 ) / 2;
				   k = 70;
#else
					ix = DISPLAY_X1_1P + 92;
					k = 77;
#endif
					iy = DISPLAY_Y1_1P + 28;
					sc = 1.F;
				}
				else {
#if LOCALE==CHINA
				   ix = DISPLAY_X1_2P;
				   ix += ( 320 - 96 - 16 ) / 2;
				   iy = DISPLAY_Y1_2P + 28;
				   k = 70;
#else

					ix = DISPLAY_X1_2P + 92;
					k = 77;
#endif
					iy = DISPLAY_Y1_2P + 28;
					sc = 1.F;
				}



				// RF: FINAL LAP
#if LOCALE==CHINA
				pgfx = makeStrGlistS(pgfx, FONT_TYPE_MAIN, "\x7c\x73\x7a",
						     //				pgfx = makeStrGlistS(pgfx, FONT_TYPE_MAIN, "\x71\x72\x73\x74\x75\x76\x77\x78",

#else
				pgfx = makeStrGlistS(pgfx, FONT_TYPE_MAIN, "FINAL",
#endif
					ix, iy, FONT_FLAG_SHADE,
					r1, g1, b1, r1, g1, b1, 
					r2, g2, b2, r2, g2, b2, sc);
#if LOCALE==CHINA
				pgfx = makeStrGlistSub(pgfx, FONT_TYPE_MAIN, "\x76",
#else
				pgfx = makeStrGlistSub(pgfx, FONT_TYPE_MAIN, "LAP",
#endif

					ix + k, iy);
			}
		}
	}

	*ppgfx = pgfx;

#undef	R0
#undef	G0
#undef	B0
#undef	R1
#undef	G1
#undef	B1

}


/******************************************************************************
	set score message
******************************************************************************/
void SetScoreMsg(int fg, int sc, int op)
{
	int		i;
	Scoremsg	*pscoremsg;
	
	for (i = 0; i < SCORE_MSG_MAX; i++)
		if (!scoremsg[i].fg)
			break;
	if (i >= SCORE_MSG_MAX)
		i = 0;
	pscoremsg = &scoremsg[i];
	pscoremsg->fg = fg;
	pscoremsg->sc = sc;
	pscoremsg->ct = pscoremsg->px = pscoremsg->py = 0;
	pscoremsg->vy = -8;
	if (op == 0)
		pscoremsg->oy = 0;
	else
		pscoremsg->oy = -32;

	iflash_sc = cflash_sc = 0;
}


/******************************************************************************
	draw score message
******************************************************************************/
void DrawScoreMsg(Gfx **ppgfx)
{
#define G_CC_SCRMSG	TEXEL0, 0, ENVIRONMENT, 0,  TEXEL0, 0, ENVIRONMENT, 0

	int	i, j, k, n, a, ix, iy, sx;
	int	cr, cg, cb;
	float	f;
	Gfx	*pgfx = *ppgfx;
	Chkcrs	*pchkcrs;
	uchar	*ptex;
	Scoremsg	*pscoremsg;

/*---------------------------------------------------------------------------*/
/* flash color */
	f = (float)(FLASH_FRAME - cflash_sc) / (float)FLASH_FRAME;
	cr = flash_col_pow1a[iflash_sc][0] * f;
	cg = flash_col_pow1a[iflash_sc][1] * f;
	cb = flash_col_pow1a[iflash_sc][2] * f;
	f = 1.F - f;
	cr += flash_col_pow1a[iflash_sc + 1][0] * f;
	cg += flash_col_pow1a[iflash_sc + 1][1] * f;
	cb += flash_col_pow1a[iflash_sc + 1][2] * f;
	if (++cflash_sc >= FLASH_FRAME) {
		cflash_sc = 0;
		iflash_sc = ++iflash_sc & 3;
	}

/*---------------------------------------------------------------------------*/
	gSPClearGeometryMode(pgfx++, G_GEOM_ALL);
	gSPSetGeometryMode(pgfx++, G_SHADE);
	gSPTexture(pgfx++, 0x8000, 0x8000, 0, G_TX_RENDERTILE, G_ON);
	gDPPipeSync(pgfx++);
	gDPSetCycleType(pgfx++, G_CYC_1CYCLE);
	gDPSetTexturePersp(pgfx++, G_TP_NONE);
	gDPSetTextureFilter(pgfx++, G_TF_BILERP);
	gDPSetCombineMode(pgfx++, G_CC_SCRMSG, G_CC_SCRMSG);
	gDPSetRenderMode(pgfx++, G_RM_XLU_SURF, G_RM_XLU_SURF2);
	gDPSetAlphaCompare(pgfx++, G_AC_NONE);

	for (j = 0; j < SCORE_MSG_MAX; j++) {
		if (scoremsg[j].fg) {
			pscoremsg = &scoremsg[j];
			if (pscoremsg->ct < 4)
				a = pscoremsg->ct * 255 / 4;
			else if (pscoremsg->ct > 23 - 4)
				a = (23 - pscoremsg->ct) * 255 / 4;
			else
				a = 255;
			gDPPipeSync(pgfx++);
/*			gDPSetEnvColor(pgfx++, cr, cg, cb, a);	*/

			/*---------------------------------------------------------------------------*/
			/* name */

			switch (pscoremsg->fg) {
				case SCORE_MSG_TIME:
					ptex = tx_sc_time;
					sx = 32;
					ix = DISPLAY_X1 + 136;
					gDPSetEnvColor(pgfx++, 255, 133, 255, a);
					break;
				case SCORE_MSG_ACTION:
					ptex = tx_sc_action;
					sx = 48;
					ix = DISPLAY_X1 + 128;
					gDPSetEnvColor(pgfx++, 100, 255, 100, a);
					break;
				case SCORE_MSG_RING:
					ptex = tx_sc_ring;
					sx = 32;
					ix = DISPLAY_X1 + 136;
					gDPSetEnvColor(pgfx++, 255, 255, 128, a);
					break;
			}
			ix += pscoremsg->px;
			iy = DISPLAY_Y1 + 88 + 8 + pscoremsg->py + pscoremsg->oy;
	
			gDPLoadTextureBlock(pgfx++, ptex, G_IM_FMT_IA, G_IM_SIZ_8b, sx, 12, 0,
				G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
			gSPTextureRectangle(pgfx++,
				ix << 2, iy << 2, ix + sx << 2, iy + 12 << 2, G_TX_RENDERTILE,
				0 << 5, 0 << 5, 1 << 10, 1 << 10);
	

			/*---------------------------------------------------------------------------*/
			/* number */

			n = pscoremsg->sc;
			for (i = 0; i < 5; i++) {
				strbuf[5 - 1 - i] = n % 10;
				n /= 10;
				if (n == 0)
					break;
			}

			if ((k = i + 1) > 5)
				k = 5;

			ix = DISPLAY_X1 + (304 - k * 14) / 2 + pscoremsg->px;
			iy = DISPLAY_Y1 +  100 + 8 + pscoremsg->py + pscoremsg->oy;

			for (i = 0; i < k; i++) {
				gDPLoadTextureBlock(pgfx++, tx_score_b + (int)strbuf[5 - k + i] * 16 * 16, G_IM_FMT_IA, G_IM_SIZ_8b, 16, 16, 0,
				G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
				gSPTextureRectangle(pgfx++,
					ix << 2, iy << 2, ix + 16 << 2, iy + 16 << 2, G_TX_RENDERTILE,
					0 << 5, 0 << 5, 1 << 10, 1 << 10);
				ix += 14;
			}

			/*---------------------------------------------------------------------------*/
			/* move */

			pscoremsg->py += pscoremsg->vy;
			if (pscoremsg->vy >= -8)
				pscoremsg->vy += 1;
			if (pscoremsg->py >= 0) {
				pscoremsg->vy = -10;
				pscoremsg->py = 0;
			}
			if (pscoremsg->vy == -10)
				pscoremsg->px -= 10;
	
			/*---------------------------------------------------------------------------*/
			/* add score */
			if (++pscoremsg->ct >= 23) {
				if ((sca_score += pscoremsg->sc) > SCA_SCORE_MAX)
					sca_score = SCA_SCORE_MAX;
				switch (pscoremsg->fg) {
					case SCORE_MSG_TIME:
						if ((sca_score_time += pscoremsg->sc) >  SCA_SCORE_MAX)
							sca_score_time = SCA_SCORE_MAX;
						break;
					case SCORE_MSG_ACTION:
						if ((sca_score_act += pscoremsg->sc) > SCA_SCORE_MAX)
							sca_score_act = SCA_SCORE_MAX;
						break;
					case SCORE_MSG_RING:
						if ((sca_score_ring += pscoremsg->sc) > SCA_SCORE_MAX)
							sca_score_ring = SCA_SCORE_MAX;
						break;
				}
				pscoremsg->fg = 0;
			}
		}
	}

/*---------------------------------------------------------------------------*/
	if (cextend_msg) {
	   // RF: TIME EXTEND
		cextend_msg--;
#if LOCALE==CHINA
		pgfx = makeStrGlist(pgfx, FONT_TYPE_MAIN, "\x78\x74",
			DISPLAY_X1 + 72 + 40, DISPLAY_Y1 + 40, FONT_FLAG_FLASH_5,

#else
		pgfx = makeStrGlist(pgfx, FONT_TYPE_MAIN, "TIME",
			DISPLAY_X1 + 72, DISPLAY_Y1 + 40, FONT_FLAG_FLASH_5,
#endif
			0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0);
#if LOCALE==CHINA
			pgfx = makeStrGlist(pgfx, FONT_TYPE_MAIN, "\x79\x71",
			DISPLAY_X1 + 72 + 40 + 48, DISPLAY_Y1 + 40, FONT_FLAG_FLASH_5,

#else
			pgfx = makeStrGlist(pgfx, FONT_TYPE_MAIN, "EXTEND",
			DISPLAY_X1 + 145, DISPLAY_Y1 + 40, FONT_FLAG_FLASH_5,

#endif
			0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0);
	}

/*---------------------------------------------------------------------------*/
	if (fdrawmap && cacrobat_score) {
		sprintf(strbuf, "%04d", cacrobat_score);
		pgfx = makeStrGlist(pgfx, FONT_TYPE_MAIN, strbuf,
			DISPLAY_X1 + 216, DISPLAY_Y1 + 168, FONT_FLAG_FLASH_5,
			0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0);
	}

	*ppgfx = pgfx;
}

#ifdef EN_DSPRESULT_FLAG
/******************************************************************************
	draw vs result
******************************************************************************/
void DrawVsResult(Gfx **ppgfx)
{
	int	i, j, cx, cy, ix, ix2, ss, st, wd;
	float	f;
	float	sx, sy, px, py, dy;
	Gfx	*pgfx = *ppgfx;
	uint	*ptex;


	gSPDisplayList(pgfx++, gfx_init_vs_result);

	for (i = 0; i < SIMPLAY_MAX; i++) {
		if (!fvs_result[i])
			continue;
	
		if (i == 0) {
			cx = DISPLAY_X1_1P + 152;
			cy = DISPLAY_Y1_1P + 52;
		}
		else {
			cx = DISPLAY_X1_2P + 152;
			cy = DISPLAY_Y1_2P + 52;
		}

		if (cvs_result[i] <= 5) {
			f = (float)cvs_result[i] / 5.F * 1.3F;
		}
		else
			f = 1.F;

		switch (fvs_result[i]) {
			case 1:
				ptex = tx_vs_won;
				wd = 96;
				break;
			case 2:
				ptex = tx_vs_lost;
				wd = 96;
				break;
			case 3:
			default:
				ptex = tx_vs_draw;
				wd = 112;
				break;
		}



		sx = (float)wd * f;
		sy = 32.F * f;
		px = cx - sx / 2.F;
		py = cy - sy / 2.F;
		dy = sy / 4.F;
		ix  = px * 4.F;
		ix2 = (px + sx) * 4.F;
		ss = 1024 * wd / sx;
		st = 1024 * 32 / sy;


		for (j = 0; j < 4; j++) {
			gDPLoadTextureTile(pgfx++, ptex + wd * 8 * j, G_IM_FMT_RGBA, G_IM_SIZ_32b,
				wd, 32, 0, 0, wd - 1, 7, 0,
				G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
			gSPTextureRectangle(pgfx++, ix, (int)(py * 4.F), ix2, (int)((py + dy) * 4.F), G_TX_RENDERTILE,
				0 << 5, 0 << 5, ss, st);
			py += dy;
		}
	}

	*ppgfx = pgfx;
}
#endif

/******************************************************************************
	do game status
******************************************************************************/
void DoGameStatus(void)
{
	int	i;



/*---------------------------------------------------------------------------*/
/* status move */
#if 0
	if (pad[pad_no[0]].trig & L_TRIG) {
		fstatus_move = 1;
		scrofs1 = scrofs2 = 0;
	}
#endif

	if (fstatus_move == 1) {
		scrofs1 += 30;
		scrofs2 -= 30;
		if (scrofs1 >= SCREEN_WD)
			fstatus_move = 2;
	}


#ifdef EN_DSPRESULT_FLAG
/*---------------------------------------------------------------------------*/
/* vs result */
#if 0
	if (pad[pad_no[0]].trig & L_TRIG) {
		fvs_result_draw = stw0;
	}
#endif
#if 0
	if (pad[pad_no[0]].trig & L_TRIG) {
		chkcrs[my_hover].ctime_total = (9 * 60 + 55) * 1000;
		chkcrs[your_hover].ctime_total = (9 * 60 + 55) * 1000;
	}
#endif

	if (game_kind == GAME_KIND_VS) {
		if (fvs_result_draw) {
			if (fvs_result_draw == 1) {
				fvs_result[0] = 1;
				fvs_result[1] = 2;
			}
			else if (fvs_result_draw == 2) {
				fvs_result[0] = 2;
				fvs_result[1] = 1;
			}
			else {
				fvs_result[0] = fvs_result[1] = 3;
			}
			fvs_result_draw = 0;
			cvs_result[0] = cvs_result[1] = 0;
		}
	
		for (i = 0; i < players; i++) 
			if (fvs_result[i] && cvs_result[i] < 0x7fffffff)
				cvs_result[i]++;
	}
#endif

}

/******************************************************************************
	draw game status
******************************************************************************/
void DrawGameStatus(Gfx **ppgfx)
{
	int	i, j;
	Gfx	*pgfx = *ppgfx;
	
/*---------------------------------------------------------------------------*/
/* test */
#if 0
	if (pad[pad_no[0]].hold & Z_TRIG)
		return;
#endif

/*---------------------------------------------------------------------------*/
/* game stat */
	if (game_stat != GAME_STAT_RACE && game_stat != GAME_STAT_CTITLE)
		return;

/*---------------------------------------------------------------------------*/
/* toggle mini map */
#ifndef ROM_FLAG
	if (pad[pad_no[0]].trig & R_CBUTTONS)
		fdrawmap ^= 1;
#endif

/*---------------------------------------------------------------------------*/
/* set flash color */
	SetFlashColor();

/*---------------------------------------------------------------------------*/
/* set projection matrix */
	SetProjectionMatrix();
	
/*---------------------------------------------------------------------------*/
/* set viewport & scissor */
	gSPViewport(pgfx++, &vp_normal);
	gDPPipeSync(pgfx++);
	if (players == 1) {
		gDPSetScissor(pgfx++, G_SC_NON_INTERLACE,
			DISPLAY_X1, DISPLAY_Y1, DISPLAY_X2, DISPLAY_Y2);
	}
	else {
		gDPSetScissor(pgfx++, G_SC_NON_INTERLACE,
			DISPLAY_X1_1P, DISPLAY_Y1_1P, DISPLAY_X2_2P, DISPLAY_Y2_2P);
	}

/*---------------------------------------------------------------------------*/
/* demo */
	if (game_stat == GAME_STAT_CTITLE) {
		chkcrs[my_hover].ctime_total += CTIME_FRAME;
#ifndef ROM_FLAG
		gSPDisplayList(pgfx++, gfx_init_lap_time);
		DrawLapTimeSub(&pgfx,
			DISPLAY_X1 + 16, DISPLAY_Y1 + 1,
			chkcrs[my_hover].ctime_total, 1, 0, chkcrs[my_hover].ctime_msec);
		if (players == 1 && fdrawmap)
			DrawMiniMap(&pgfx);
#endif
		*ppgfx = pgfx;
		return;
	}

/*---------------------------------------------------------------------------*/
/* enemy mark */
	if ((game_kind == GAME_KIND_TOUR || game_kind == GAME_KIND_VS || fghost) &&
	    signal_mode == SIGNAL_MODE_RACE && ncourse != NCOURSE_PARK &&
	    !frank_process) {
		DrawEnemyMark(&pgfx);
	}

/*---------------------------------------------------------------------------*/
/* start signal */
	if ((signal_mode != SIGNAL_MODE_RACE || fstart_signal == 2) &&
	    !(chkcrs[my_hover].fretire || (players == 2 && chkcrs[your_hover].fretire)))
		DrawStartSignal(&pgfx);
		
/*---------------------------------------------------------------------------*/
/* indicator */
#if 1
	if (game_stat == GAME_STAT_RACE &&
	    pause_mode == PAUSE_MODE_OFF &&
	    signal_mode == SIGNAL_MODE_RACE &&
	    !(players == 2 && defeatPlayer))
		DrawIndicator(&pgfx);
#endif

/*---------------------------------------------------------------------------*/
/* power message */
	if (game_kind != GAME_KIND_SCORE && ncourse != NCOURSE_PARK)
		DrawPowerMsg(&pgfx);

/*---------------------------------------------------------------------------*/
/* course out message */
/* lap message */
	if (pause_mode == PAUSE_MODE_OFF) {
		DrawCrsOutMsg(&pgfx);	
		DrawLapMsg(&pgfx);
		if (game_kind == GAME_KIND_SCORE)
			DrawScoreMsg(&pgfx);
	}

/*---------------------------------------------------------------------------*/
/* lap time */
	DrawLapTime(&pgfx);
	if ((game_kind == GAME_KIND_TOUR || game_kind == GAME_KIND_VS) &&
	    ncourse != NCOURSE_PARK) {
		DrawRankFace(&pgfx);
	}

#ifdef EN_DSPRESULT_FLAG
/*---------------------------------------------------------------------------*/
/* vs result */
	if (game_kind == GAME_KIND_VS) {
		DrawVsResult(&pgfx);
	}
#endif

/*---------------------------------------------------------------------------*/
/* mini map */
	if (players == 1 && fdrawmap)
		DrawMiniMap(&pgfx);
	
/*---------------------------------------------------------------------------*/
/* end */
	*ppgfx = pgfx;

/*---------------------------------------------------------------------------*/
/* debug */
#ifndef ROM_FLAG
	if (ienmtxmdl > ENMTXMDL_MAX)
		printf("ienmtxmdl over !!\n");
#endif
/*	printf("imtx: %d\n", ienmtxmdl);	*/

#if 0
	if (pad[pad_no[0]].trig & R_TRIG)
		chkcrs[my_hover].ctime_total = (9 * 60 + 50) * 1000;
#endif

}


/******************************************************************************
-------------------------------------------------------------------------------
				end of file
-------------------------------------------------------------------------------
******************************************************************************/

