


/*	-------------------------------------------------------------------------------------------------
 *		構築
	-------------------------------------------------------------------------------------------------	*/
#include <stdio.h>
#include <sys/bios.h>

#include "common.h"
#include "sprite.h"
#include "bg.h"
#include "key.h"
#include "game.h"
#include "Ranking.h"

/*	-------------------------------------------------------------------------------------------------
 *		グローバル変数
	-------------------------------------------------------------------------------------------------	*/
extern MAIN_REG	g_Reg;										/*	ゲーム全体で使うグローバルな変数		*/
extern void	(*g_GameProc)(void);							/*	ゲームの進行状況を制御します。			*/
extern char	g_Buf[256];

extern unsigned char ucChrFloor[][16];
extern unsigned char ucChrRanking[][16];
extern unsigned char ucChrEntry[][16];
extern unsigned char ucChrName[][16];


/*	-------------------------------------------------------------------------------------------------
 *		ローカル定数
	-------------------------------------------------------------------------------------------------	*/
#define RANKING_STATUS_WAIT			0
#define RANKING_STATUS_RANKIN		1
#define RANKING_STATUS_KEYWAIT		2

#define RANKING_X		3
#define RANKING_Y		6
#define RANKING_SPACE	2

#define RANKIN_SPEED	3

#define RANK_TITLE_X	64
#define RANK_TITLE_Y	15

#define RANKER_MESSAGE_LENGTH	(9+2+3)
#define RANKER_TOTAL_LENGTH		(1+RANKER_MESSAGE_LENGTH+1)

#define  NAMEENTRY_X		8
#define  NAMEENTRY_Y		12
#define  NAMEENTRY_SPACE	5

#define NAMEENTRY_TITLE_X1	40
#define NAMEENTRY_TITLE_Y1	30
#define NAMEENTRY_TITLE_X2	112
#define NAMEENTRY_TITLE_Y2	30

	
/*	-------------------------------------------------------------------------------------------------
 *		ローカル構造体
	-------------------------------------------------------------------------------------------------	*/
typedef struct{
	int iStatus;
	int	iRankInLine;
	int	iPickUpLine;							/*	ランキングマークをつけたい場合その行を指示する	*/

	int	iX, iXX, iY;
	int	iTimer;

	int iTitleX, iTitleY;
	int iTitleXX, iTitleYY;
	int	iTitleTimer;

	int	iBGX, iBGY;
} RANKING_REG;

typedef struct{
	int iX, iXBack;
	int iRank;

	int iTitleX[2], iTitleY[2];
	int iTitleXX[2], iTitleYY[2];
	int	iTitleTimer;

	int	iBGX, iBGY;
	int iScore;
} NAMEENTRY;

RANKING_REG	l_Rank;
NAMEENTRY	l_Name;
unsigned char l_ucLineBuf[30];

/*	-------------------------------------------------------------------------------------------------
 *		ローカル関数
	-------------------------------------------------------------------------------------------------	*/
void Ranking_Main();
void NameEntry_Main();
void SetRankIn( int iLineNo );
void DrawRankerName();
int	InsertRankIn( int iScore );

/*	-------------------------------------------------------------------------------------------------
 *		[概要]
 *
	-------------------------------------------------------------------------------------------------	*/
void Ranking_Start()
{
	int i, j;	
	/*	
	 *	変数の初期化
	 */
	g_GameProc = Ranking_Main;
	key_WithoutRepeat();
	l_Rank.iStatus = RANKING_STATUS_WAIT;
	l_Rank.iTimer = 0;
	l_Rank.iTitleTimer = 0;
	l_Rank.iTitleX = RANK_TITLE_X;
	l_Rank.iTitleY = RANK_TITLE_Y;
	l_Rank.iTitleXX = -4;
	l_Rank.iTitleYY = 3;
	l_Rank.iBGX = 0;
	l_Rank.iBGY = 0;

	/*	
	 *	グラフィック設定
	 */
	sprite_Off();
	bg_Off( SCREEN1 );
	bg_Off( SCREEN2 );

	bg_SetOffset( SCREEN1, 0, 0 );
	bg_SetOffset( SCREEN2, 0, 0 );

	lcd_set_color(uiLCDColorL, uiLCDColorH);			/* パレット設定 */
	sprite_SetCharacter( FLOOR_CHRTOP, 16, ucChrFloor );
	sprite_SetCharacter( SYMBOL_CHRTOP, 20, ucChrRanking );

	bg_Clear( SCREEN2, 0| BG_PALe );
	/*	床の描画		*/
	for( i = 0; i < 16; i++ ){
		for( j = 0; j < 16; j++ ){
			bg_Set( SCREEN1, i*2, j*2,		FLOOR_CHRTOP	| BG_PAL8 );
			bg_Set( SCREEN1, i*2+1, j*2,	FLOOR_CHRTOP+1	| BG_PAL8 );
			bg_Set( SCREEN1, i*2,   j*2+1,	FLOOR_CHRTOP+8	| BG_PAL8 );
			bg_Set( SCREEN1, i*2+1, j*2+1,	FLOOR_CHRTOP+9	| BG_PAL8 );
		}
	}

	/*	文字表記	*/
	bg_Text( SCREEN2, RANKING_X+5, RANKING_Y-1, "SCORE  NAME", BG_PALd );

	bg_On( SCREEN2 );									/*	表示開始									*/
	bg_On( SCREEN1 );
	sprite_On();
}

/*	-------------------------------------------------------------------------------------------------
 *		[概要]
 *
	-------------------------------------------------------------------------------------------------	*/
void Ranking_Main()
{
	switch( l_Rank.iStatus ){
		case RANKING_STATUS_WAIT:
			l_Rank.iTimer++;
			if( l_Rank.iTimer > 70 ){
				l_Rank.iTimer = 0;
				l_Rank.iStatus = RANKING_STATUS_RANKIN;
				l_Rank.iRankInLine = RANKER_NUMBER-1;
				SetRankIn( l_Rank.iRankInLine );
			}
			break;
		case RANKING_STATUS_RANKIN:
			l_Rank.iTimer++;
			if( l_Rank.iTimer >= RANKIN_SPEED ){
				l_Rank.iTimer = 0;
				l_Rank.iX += l_Rank.iXX;
				DrawRankerName();
				if( l_Rank.iX == RANKING_X ){
					l_Rank.iRankInLine--;
					if( l_Rank.iRankInLine >= 0 ){
						SetRankIn( l_Rank.iRankInLine );
					} else {
						l_Rank.iStatus = RANKING_STATUS_KEYWAIT;
					}
				}
			}
			break;
		case RANKING_STATUS_KEYWAIT:
			if( l_Rank.iTimer == 0 ){
				bg_Text( SCREEN2, 8, 16, "-PUSH KEY-", BG_PALd );
			} else if( l_Rank.iTimer == 30 ){
				bg_Text( SCREEN2, 8, 16, "          ", BG_PALd );
			}
			l_Rank.iTimer++;
			if( l_Rank.iTimer >= 60 ){
				l_Rank.iTimer = 0;
			}
			if( key_PushDown() ){
				Title_Start();
				g_Reg.iPickUpLine = -1;
				return;
			}
			break;
	}

	/*	ランク文字	*/
	l_Rank.iTitleTimer++;
	if( l_Rank.iTitleTimer > 3 ){
		l_Rank.iTitleTimer = 0;

		l_Rank.iTitleX += l_Rank.iTitleXX;
		l_Rank.iTitleY += l_Rank.iTitleYY;
		if( l_Rank.iTitleX > RANK_TITLE_X ){
			l_Rank.iTitleXX--;
		} else {
			l_Rank.iTitleXX++;
		}
		if( l_Rank.iTitleY > RANK_TITLE_Y ){
			l_Rank.iTitleYY--;
		} else {
			l_Rank.iTitleYY++;
		}
	}
	sprite_Set( 55, l_Rank.iTitleX, l_Rank.iTitleY, SP_PAL7 );

	/*	BG スクロール	*/
	bg_SetOffset( SCREEN1, l_Rank.iBGX/2, l_Rank.iBGY/2 );
	l_Rank.iBGX += 2;
	l_Rank.iBGY += 1;
	l_Rank.iBGX = l_Rank.iBGX % 32;
	l_Rank.iBGY = l_Rank.iBGY % 32;
}
/*	-------------------------------------------------------------------------------------------------
 *		[概要]
 *
	-------------------------------------------------------------------------------------------------	*/
void SetRankIn( int iLineNo )
{
	if( iLineNo % 2 ){
		l_Rank.iXX = 1;
		l_Rank.iX = -RANKER_TOTAL_LENGTH;
	} else {
		l_Rank.iXX = -1;
		l_Rank.iX = 28;
	}
	l_Rank.iY = RANKING_Y + RANKING_SPACE * iLineNo;
	l_Rank.iTimer = 0;
	sprintf( l_ucLineBuf, "  %8d  %c%c%c ", g_Reg.iHiScore[iLineNo],	g_Reg.ucRankerName[iLineNo][0],
																			g_Reg.ucRankerName[iLineNo][1],
																			g_Reg.ucRankerName[iLineNo][2] );
	if( g_Reg.iPickUpLine == iLineNo ){
		l_ucLineBuf[1] = '#';
	}
}

/*	-------------------------------------------------------------------------------------------------
 *		[概要]
 *			クリッピング込みの文字表示
	-------------------------------------------------------------------------------------------------	*/
void DrawRankerName()
{
	int i, iLength, iStart, iX;

	iStart = 0;
	iX = l_Rank.iX;
	iLength = RANKER_TOTAL_LENGTH;

	/*	左のクリッピング	*/
	if( l_Rank.iX < 0 ){
		iX = 0;
		iStart = -l_Rank.iX;
		iLength = iLength - iStart;
		if( iLength <= 0 ){
			return;
		}
	}

	/*	右側のクリッピング	*/
	if( l_Rank.iX + RANKER_TOTAL_LENGTH >= 28 ){
		iLength = 28 - l_Rank.iX;
	}

	g_Buf[1] = 0;
	for( i = 0; i < iLength; i++ ){
		g_Buf[0] = l_ucLineBuf[iStart+i];
		bg_Text( SCREEN2, iX+i, l_Rank.iY, g_Buf, BG_PALd );
	}
}

/*	-------------------------------------------------------------------------------------------------
 *		[概要]
 *
	-------------------------------------------------------------------------------------------------	*/
void NameEntry_Start(int iScore)
{
	int i, j;	
	/*	
	 *	変数の初期化
	 */
	g_GameProc = NameEntry_Main;
	key_WithoutRepeat();

	l_Name.iScore = iScore;
	l_Name.iBGX = 0;
	l_Name.iBGY = 0;
	l_Name.iX = 0;
	l_Name.iXBack = 2;
	l_Name.iTitleTimer = 0;
	l_Name.iTitleX[0] = NAMEENTRY_TITLE_X1;
	l_Name.iTitleY[0] = NAMEENTRY_TITLE_Y1;
	l_Name.iTitleX[1] = NAMEENTRY_TITLE_X2;
	l_Name.iTitleY[1] = NAMEENTRY_TITLE_Y2;
	l_Name.iTitleXX[0] = 4;
	l_Name.iTitleYY[0] = 2;
	l_Name.iTitleXX[1] = -3;
	l_Name.iTitleYY[1] = 3;
	l_Name.iRank = InsertRankIn( iScore );

	/*	
	 *	グラフィック設定
	 */
	sprite_Off();
	bg_Off( SCREEN1 );
	bg_Off( SCREEN2 );

	bg_SetOffset( SCREEN1, 0, 0 );
	bg_SetOffset( SCREEN2, 0, 0 );

	lcd_set_color(uiLCDColorL, uiLCDColorH);			/* パレット設定 */
	sprite_SetCharacter( FLOOR_CHRTOP, 16, ucChrFloor );
	sprite_SetCharacter( SYMBOL_CHRTOP, 16, ucChrName );
	sprite_SetCharacter( SYMBOL_CHRTOP+16, 16, ucChrEntry );

	bg_Clear( SCREEN2, 0| BG_PALe );
	/*	床の描画		*/
	for( i = 0; i < 16; i++ ){
		for( j = 0; j < 16; j++ ){
			bg_Set( SCREEN1, i*2, j*2,		FLOOR_CHRTOP	| BG_PAL8 );
			bg_Set( SCREEN1, i*2+1, j*2,	FLOOR_CHRTOP+1	| BG_PAL8 );
			bg_Set( SCREEN1, i*2,   j*2+1,	FLOOR_CHRTOP+8	| BG_PAL8 );
			bg_Set( SCREEN1, i*2+1, j*2+1,	FLOOR_CHRTOP+9	| BG_PAL8 );
		}
	}

	/*	文字表記	*/
	sprintf( g_Buf, "Rank in %dTh.", l_Name.iRank + 1 );
	bg_Text( SCREEN2, 8, 9, g_Buf, BG_PALd );

	bg_On( SCREEN2 );									/*	表示開始									*/
	bg_On( SCREEN1 );
	sprite_On();
}

/*	-------------------------------------------------------------------------------------------------
 *		[概要]
 *
	-------------------------------------------------------------------------------------------------	*/
void NameEntry_Main()
{
	int iKey, i, iVal;

	/*	入力処理	*/
	iKey = key_PushDown();
	if( iKey & KEY_UP1 ){
		g_Reg.ucRankerName[l_Name.iRank][l_Name.iX]--;
		if( g_Reg.ucRankerName[l_Name.iRank][l_Name.iX] < 48 ){
			g_Reg.ucRankerName[l_Name.iRank][l_Name.iX] = 95;
		}
	}
	if( iKey & KEY_DOWN1 ){
		g_Reg.ucRankerName[l_Name.iRank][l_Name.iX]++;
		if( g_Reg.ucRankerName[l_Name.iRank][l_Name.iX] > 95 ){
			g_Reg.ucRankerName[l_Name.iRank][l_Name.iX] = 48;
		}
	}
	if( iKey & KEY_LEFT1 ){
		l_Name.iX--;
		if( l_Name.iX < 0 ){
			l_Name.iX = 2;
		}
	}
	if( iKey & KEY_RIGHT1 ){
		l_Name.iX++;
		if( l_Name.iX > 2 ){
			l_Name.iX = 0;
		}
	}
	if( iKey & KEY_A ){
		Ranking_Start();
		return;
	}

	g_Buf[1] = 0;
	g_Buf[0] = '<';
	bg_Text( SCREEN2, NAMEENTRY_X + NAMEENTRY_SPACE * l_Name.iX-1, NAMEENTRY_Y, g_Buf, BG_PALd );
	g_Buf[0] = '>';
	bg_Text( SCREEN2, NAMEENTRY_X + NAMEENTRY_SPACE * l_Name.iX+1, NAMEENTRY_Y, g_Buf, BG_PALd );
	if( l_Name.iX != l_Name.iXBack ){
		g_Buf[0] = ' ';
		bg_Text( SCREEN2, NAMEENTRY_X + NAMEENTRY_SPACE * l_Name.iXBack-1, NAMEENTRY_Y, g_Buf, BG_PALd );
		bg_Text( SCREEN2, NAMEENTRY_X + NAMEENTRY_SPACE * l_Name.iXBack+1, NAMEENTRY_Y, g_Buf, BG_PALd );
		l_Name.iXBack = l_Name.iX;
	}

	for( i = 0; i < 3; i++ ){
		g_Buf[0] = g_Reg.ucRankerName[l_Name.iRank][i];
		bg_Text( SCREEN2, NAMEENTRY_X + i * NAMEENTRY_SPACE, NAMEENTRY_Y, g_Buf, BG_PALd );
	}

	/*	Name Entry 文字	*/
	l_Name.iTitleTimer++;
	if( l_Name.iTitleTimer > 3 ){
		l_Name.iTitleTimer = 0;

		for( i = 0; i < 2; i++ ){
			l_Name.iTitleX[i] += l_Name.iTitleXX[i];
			l_Name.iTitleY[i] += l_Name.iTitleYY[i];
			if( i == 0 ){
				iVal = NAMEENTRY_TITLE_X1;
			} else {
				iVal = NAMEENTRY_TITLE_X2;
			}

			if( l_Name.iTitleX[i] > iVal ){
				l_Name.iTitleXX[i]--;
			} else {
				l_Name.iTitleXX[i]++;
			}

			if( i == 0 ){
				iVal = NAMEENTRY_TITLE_Y1;
			} else {
				iVal = NAMEENTRY_TITLE_Y2;
			}

			if( l_Name.iTitleY[i] > iVal ){
				l_Name.iTitleYY[i]--;
			} else {
				l_Name.iTitleYY[i]++;
			}
		}
	}
	for( i = 0; i < 2; i++ ){
		sprite_Set( 56+i, l_Name.iTitleX[i], l_Name.iTitleY[i], SP_PAL7 );
	}

	/*	BG スクロール	*/
	bg_SetOffset( SCREEN1, l_Name.iBGX/2, l_Name.iBGY/2 );
	l_Name.iBGX += 31;
	l_Name.iBGY += 30;
	l_Name.iBGX = l_Name.iBGX % 32;
	l_Name.iBGY = l_Name.iBGY % 32;
}

/*	-------------------------------------------------------------------------------------------------
 *		[概要]
 *			スコアーを挿入し、ランキング順位を返します( Top = 0 )
	-------------------------------------------------------------------------------------------------	*/
int	InsertRankIn( int iScore )
{
	int i, j;
	for( i = 0; i < RANKER_NUMBER-1; i++ ){
		if( g_Reg.iHiScore[i] < iScore ){
			break;
		}
	}

	/*	以下の順位を一つ繰り下げる	*/
	for( j = RANKER_NUMBER-1; j > i; j-- ){
		g_Reg.iHiScore[j] = g_Reg.iHiScore[j-1];
		g_Reg.ucRankerName[j][0] = g_Reg.ucRankerName[j-1][0];
		g_Reg.ucRankerName[j][1] = g_Reg.ucRankerName[j-1][1];
		g_Reg.ucRankerName[j][2] = g_Reg.ucRankerName[j-1][2];
	}

	g_Reg.iHiScore[i] = l_Name.iScore;
	g_Reg.ucRankerName[i][0] = 'A';
	g_Reg.ucRankerName[i][1] = 'A';
	g_Reg.ucRankerName[i][2] = 'A';
	g_Reg.iPickUpLine = i;

	return i;
}