/*
	コントローラーパックメニュー
*/
#include "ot_header.h"
//#include <libnos.h>


#include "kn_def.h"
#include "kn_main.h"
#include "kn_font.h"
#include "kn_cpack.h"
#include "kn_title.h"
#include "kn_backup.h"

/*******************************************************
	FUNCTION
*******************************************************/
static Gfx 	*clearAllFBufferForHi( Gfx *gp );
static Gfx 	*makeGameNoteGlist( Gfx *gp );
static Gfx 	*makeOneGameNoteGlist( Gfx *gp, int sx, int sy );
static Gfx 	*makeCPackMessageGlist( Gfx *gp );
static Gfx 	*makeCPackFreeBlocksGlist( Gfx *gp );
static Gfx 	*makeCPackCurGlist( Gfx *gp, int sx, int sy );
static Gfx 	*makeCPackNoteCurGlist( Gfx *gp );
static Gfx 	*makeNosFontGlist( Gfx *gp, uchar code, uint sx, uint sy );
static Gfx 	*makeNosFontStrGlist( Gfx *gp, char *str, int str_length, uint sx, uint sy );
static Gfx *drawBlackRectangleGlistHi( Gfx *gp, uint ulx, uint uly, uint lrx, uint lry, uint a );
static void	changeGameModeCPack( void );
static void initMainGlistCPack2Next( void );

/*******************************************************
	VARIABLE
*******************************************************/
/* --- 外部参照 --- */
/* Display List */
extern Gfx		dlCPackBG[], dlCPackBG2[], dlClearFBufferHi[];
extern Gfx		dlDispCPackMessage[];
#if (SW_KN_LANGUAGE == KN_EU)
extern Gfx		dlDispCPackMessage_Ge[];
#endif
extern Gfx		dlCPackInitBG[], dlCPackInitLetter[];
/* Texture */
extern ushort	texPack3[];
extern uchar	texJf0[], texJf1[],  texJf2[], texJf3[], texJf4[];
extern uchar	texJf5[], texJf6[],  texJf7[], texJf8[], texJf9[];
extern uchar	texJfWaku[], texJfWaku2[];
extern uchar	texNosFont[];
/* コントローラー */
extern sKnPad	mKnPad[];

/* --- 内部参照 --- */
/* メッセージ表示 */
static int	idxCPackMessage = 0;
#if (SW_KN_LANGUAGE == KN_JP || SW_KN_LANGUAGE == KN_ZH)
extern uchar	texJfMe1[], texJfMe2[], texJfMe3[]; 
extern uchar	texJfMe4[], texJfMe5[], texJfMe6[];
static uchar *pCPackMessage[MAX_NUM_CPACK_MESSAGE] = {
	texJfMe1, texJfMe2, texJfMe3, texJfMe4, texJfMe5, texJfMe6, 
};
#elif (SW_KN_LANGUAGE == KN_US)
extern uchar	texEfMe1[], texEfMe2[], texEfMe3[]; 
extern uchar	texEfMe4[], texEfMe5[], texEfMe6[];
static uchar *pCPackMessage[MAX_NUM_CPACK_MESSAGE] = {
	texEfMe1, texEfMe2, texEfMe3, texEfMe4, texEfMe5, texEfMe6, 
};
#elif (SW_KN_LANGUAGE == KN_EU)
extern uchar	texEfMe1[], texEfMe2[], texEfMe3[]; 
extern uchar	texEfMe4[], texEfMe5[], texEfMe6[];
static uchar *pCPackMessage[MAX_NUM_CPACK_MESSAGE] = {
	texEfMe1, texEfMe2, texEfMe3, texEfMe4, texEfMe5, texEfMe6, 
};
extern uchar	texGeMe1[], texGeMe2[], texGeMe3[]; 
extern uchar	texGeMe4[], texGeMe5[], texGeMe6[];
static uchar *pCPackMessage_Ge[MAX_NUM_CPACK_MESSAGE] = {
	texGeMe1, texGeMe2, texGeMe3, texGeMe4, texGeMe5, texGeMe6, 
};
#endif
/* 空きメモリー表示 */
static uchar *pTexJfNumber[10] = {
	texJf0, texJf1, texJf2, texJf3, texJf4, 
	texJf5, texJf6, texJf7, texJf8, texJf9, 
};
/* メニュー */
static int  cpackMenuSeq = CPACK_MENU_SEQ_SEL_MODE;
static int  cpackMenuSelModeNum = CPACK_MENU_MODE_SELECT;
static int  cpackMenuSelOkNum = 1;
static int  cpackMenuSelNoteCurPos = 0;

/* カーソル */
static int sxCPackMenuCur[CPACK_MENU_MAX_MODE] = {
	130-6, 328-6,
};
static int		cpackMenuCurPat = 0;
static int		cpackMenuCurCount = 0;
static uint		cpackMenuCurColor;
/* ゲームノート */
static int		cpackGameNoteNum[9] = {
	0, 0, 1, 2, 3, 4, 5, 6, 0,
};
static int		cpackGameNoteScrReq = 0;	/* 0: NOP 1: UP 2: DOWN */
static int		cpackGameNoteScrSy = SY_GAMENOTE;
static int		cpackGameNoteScrOldSy;
/* ゲーム名の長さ */
static int		gameNameLength;
/* エラーコード */
static int		pfsErrCode;
/* ターゲット番号 */
static int  	pfsTargetNum;
/* フェード */
static uint		maskAlpha = 0;
static int		maskCount = 0;
/* 消去用フラグ */
static int		pfsDeleteFlag;

/*******************************************************
	DEFINE
*******************************************************/
/* メッセージテクスチャの大きさ */
#define WD_TEX_CPACK_MESSAGE	360
#define HT_TEX_CPACK_MESSAGE	8
#define HT_NUM_TEX_CPACK_MESSAGE	8
#define SX_TEX_CPACK_MESSAGE	140
#define SY_TEX_CPACK_MESSAGE	59
/* ゲームノートＢＧテクスチャの大きさ */
#define WD_TEX_PACK3	512
#define HT_TEX_PACK3	4
/* 残りメモリーの表示 */
#define WD_TEX_JF_NUMBER	16
#define HT_TEX_JF_NUMBER	18
#define SX_FREE_BLOCKS	508
#define SY_FREE_BLOCKS	368
#define DX_FREE_BLOCKS	(WD_TEX_JF_NUMBER+2)
/* カーソル */
#define WD_TEX_JF_WAKU	192
#define HT_TEX_JF_WAKU	11
/* カーソル点滅時間 */
#define CPACK_CUR_FLASH_COUNT		12
/* ゲームノートのテクスチャの高さ */
#define HT_TEX_GAMENOTE	20
/* フェードアウトの時間 */
#define CPACK_MENU_FADE_OUT_COUNT	10

/* ====================================================================== */
/*
	ムーブ
*/
void moveMainCPack( void )
{
	register int	i;

	/* マシンカーソルの色決定 */
	if( cpackMenuCurPat == 0 ) {
		cpackMenuCurColor = (uint)( 128.0f + 127.0f * (float)( CPACK_CUR_FLASH_COUNT - cpackMenuCurCount )
								   / (float)CPACK_CUR_FLASH_COUNT );
	}
	else {
		cpackMenuCurColor = (uint)( 128.0f + 127.0 * (float)cpackMenuCurCount / (float)CPACK_CUR_FLASH_COUNT );
	}
	cpackMenuCurCount ++;
	if( cpackMenuCurCount >= CPACK_CUR_FLASH_COUNT ) {
		cpackMenuCurCount  = 0;
		cpackMenuCurPat ^= 1;
	}

	/* スクロール */
	if( cpackGameNoteScrReq == 1 ) {
		cpackGameNoteScrSy -= 4;
		if( cpackGameNoteScrSy <= SY_GAMENOTE - HT_TEX_GAMENOTE ) {
			cpackGameNoteScrSy = SY_GAMENOTE;
			cpackGameNoteScrReq = 0;
			for( i = 0 ; i < 8 ; i ++ ) {
				if( i < 7 ) cpackGameNoteNum[i] = cpackGameNoteNum[i+1];
				else {
					if( cpackGameNoteNum[i-1] == 16 || cpackGameNoteNum[i-1] == 0 ) cpackGameNoteNum[i] = 0;
					else cpackGameNoteNum[i] = cpackGameNoteNum[i-1] + 1;
				}
			}
			cpackGameNoteNum[0] = cpackGameNoteNum[8] = 0;
		}
	}
	else if( cpackGameNoteScrReq == 2 ) {
		cpackGameNoteScrSy += 4;
		if( cpackGameNoteScrSy >= SY_GAMENOTE + HT_TEX_GAMENOTE ) {
			cpackGameNoteScrSy = SY_GAMENOTE;
			cpackGameNoteScrReq = 0;
			for( i = 8 ; i > 0 ; i -- ) {
				if( i > 1 ) cpackGameNoteNum[i] = cpackGameNoteNum[i-1];
				else {
					if( cpackGameNoteNum[i+1] == 1 || cpackGameNoteNum[i+1] == 0 ) cpackGameNoteNum[i] = 0;
					else cpackGameNoteNum[i] = cpackGameNoteNum[i+1] - 1;
				}
			}
			cpackGameNoteNum[0] = cpackGameNoteNum[8] = 0;
		}
	}
}

/* ====================================================================== */
/*
	メイン
*/
extern ushort texPack4[];
Gfx *makeMainGlistCPack( Gfx *gp )
{
	if( gameModeChangeFlag ) {
		gameModeChangeFlag = 0;
		if( game_mode == GM_CPACK ) {
			gp = clearAllFBufferForHi( gp );
			return( gp );
		}
	}

	/* ディスプレイリストの作成 */
	player_index = 0;
	gSPDisplayList( gp++, dlClearFBufferHi );
	gDPPipeSync( gp++ );
	gDPSetScissor( gp++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WD_HI-1, SCREEN_HT_HI-1 );
	gSPDisplayList( gp++, dlCPackBG );
	/* ゲームノート */
	gp = makeGameNoteGlist( gp );
	gSPDisplayList( gp++, dlCPackBG2 );
#if (SW_KN_LANGUAGE == KN_EU)
	if( euLanguage == EL_ENGLISH ) {
		gSPDisplayList( gp++, dlDispCPackMessage );
	}
	else {
		gSPDisplayList( gp++, dlDispCPackMessage_Ge );
	}
#else
	gSPDisplayList( gp++, dlDispCPackMessage );
#endif
	/* メッセージ */
	gp = makeCPackMessageGlist( gp );
	/* 残り */
	gp = makeCPackFreeBlocksGlist( gp );
	/* カーソル */
	gDPSetPrimColor( gp++, 0, 0, 255, cpackMenuCurColor, 0, 255 );
	gp = makeCPackCurGlist( gp, sxCPackMenuCur[cpackMenuSelModeNum], 134 );
	if( cpackMenuSeq == CPACK_MENU_SEQ_SEL_OK ) {
		gp = makeCPackCurGlist( gp, sxCPackMenuCur[cpackMenuSelOkNum], 394 );
	}
	/* マスク */
	if( game_mode == GM_CPACK2NEXT ) {
		gp = drawBlackRectangleGlistHi( gp, 64, 50, 64+512, 432, maskAlpha );
	}

	/* ゲームモードの変更 */
	if( game_mode == GM_CPACK ) changeGameModeCPack();
	else {
		maskAlpha = (uint)( 255 * maskCount / CPACK_MENU_FADE_OUT_COUNT );
		if( maskAlpha > 255 ) maskAlpha = 255;
		maskCount ++;
		if( maskAlpha == 255 ) knViBlack( 1 );
		if( maskCount > (CPACK_MENU_FADE_OUT_COUNT + 3 ) ) {
			initMainGlistOpen();
		}
	}

	return( gp );
}


/* ====================================================================== */
/*
	ゲームモードの変更
*/
static void changeGameModeCPack( void )
{
	register int		f;
	register OSPfsState	*pfs_state_p;

	/* ファイル消去 */
	if( cpackMenuSeq == CPACK_MENU_SEQ_DEL_FILE ) {
		if( pfsDeleteFlag == 0 ) pfsDeleteFlag = 1;
		else {
			pfsErrCode = 0;
			pfs_state_p = &pfsState[pfsTargetNum];
			pfsErrCode = osPfsDeleteFile( &pfs,
										  pfs_state_p->company_code,
										  pfs_state_p->game_code,
										  (uchar *)pfs_state_p->game_name,
										  (uchar *)pfs_state_p->ext_name );
			#ifndef ROM_FLAG
			osSyncPrintf( "target[%d] : pfsErrCode = %d\n", pfsTargetNum, pfsErrCode );
			#endif
			switch( pfsErrCode ) {
				case 0:		/* 消去成功 */
					pfsStateRet[pfsTargetNum] = -1;
					pfsFreeBlocks += (uchar)( ( pfs_state_p->file_size + 255 ) >> 8 );
					cpackMenuSeq = CPACK_MENU_SEQ_SEL_MODE;
					idxCPackMessage = 0;
					break;
				case PFS_ERR_NOPACK:
					cpackMenuSeq = CPACK_MENU_SEQ_ERR;
					idxCPackMessage = 3;
					break;
				case PFS_ERR_NEW_PACK:
					cpackMenuSeq = CPACK_MENU_SEQ_ERR;
					idxCPackMessage = 4;
					break;
				default:
					cpackMenuSeq = CPACK_MENU_SEQ_ERR;
					idxCPackMessage = 2;
					break;
			}
		}
	}
	
	if( mKnPad[KN_PAD_1P].pad.trig & BUTTON_ARG_ANY ) {
		switch( cpackMenuSeq ) {
			case CPACK_MENU_SEQ_SEL_MODE:
				if( cpackMenuSelModeNum == CPACK_MENU_MODE_SELECT ) {
					/* 記録を選ぶ */
					cpackMenuSeq = CPACK_MENU_SEQ_SEL_NOTE;
					cpackMenuSelNoteCurPos = 0;
				}
				else {
					/* 終る */
					initMainGlistCPack2Next();
				}
				break;
			case CPACK_MENU_SEQ_SEL_NOTE:
				pfsTargetNum = cpackGameNoteNum[cpackMenuSelNoteCurPos + 2] - 1;
				if( pfsStateRet[pfsTargetNum] == 0 ) {
					cpackMenuSeq = CPACK_MENU_SEQ_SEL_OK;
					cpackMenuSelOkNum = 1;
					idxCPackMessage = 1;
				}
				break;
			case CPACK_MENU_SEQ_SEL_OK:
				cpackMenuSeq = CPACK_MENU_SEQ_SEL_NOTE;
				idxCPackMessage = 0;
				if( cpackMenuSelOkNum == 0 ) {
					/* 消す */
					cpackMenuSeq = CPACK_MENU_SEQ_DEL_FILE;
					idxCPackMessage = 5;
					pfsDeleteFlag = 0;
				}
				break;
			case CPACK_MENU_SEQ_ERR:
				cpackMenuSeq = CPACK_MENU_SEQ_SEL_MODE;
				idxCPackMessage = 0;
				break;
		}
		#if SOUND_SW
		Na_SystemSound( NA_SYS_DECIDE, 0 );
		#endif
	}
	else if( mKnPad[KN_PAD_1P].pad.trig & BUTTON_ARG_CANCEL ) {
		switch( cpackMenuSeq ) {
			case CPACK_MENU_SEQ_SEL_NOTE:
				if( !cpackGameNoteScrReq ) {
					cpackMenuSeq = CPACK_MENU_SEQ_SEL_MODE;
					idxCPackMessage = 0;
				}
				break;
			case CPACK_MENU_SEQ_SEL_OK:
				cpackMenuSeq = CPACK_MENU_SEQ_SEL_NOTE;
				idxCPackMessage = 0;
				break;
		}
		#if SOUND_SW
		Na_SystemSound( NA_SYS_CANCEL, 0 );
		#endif
	}
	else if( mKnPad[KN_PAD_1P].pad.trig & BUTTON_ARG_LEFT ) {
		switch( cpackMenuSeq ) {
			case CPACK_MENU_SEQ_SEL_MODE:
				cpackMenuSelModeNum ++;
				if( cpackMenuSelModeNum == CPACK_MENU_MAX_MODE ) cpackMenuSelModeNum = 0;
				/* SE */
				#if SOUND_SW
				Na_SystemSound( NA_SYS_CURMOVE, 0 );
				#endif
				break;
			case CPACK_MENU_SEQ_SEL_OK:
				cpackMenuSelOkNum ^= 1;
				#if SOUND_SW
				Na_SystemSound( NA_SYS_CURMOVE, 0 );
				#endif
				break;
		}
	}
	else if( mKnPad[KN_PAD_1P].pad.trig & BUTTON_ARG_RIGHT ) {
		switch( cpackMenuSeq ) {
			case CPACK_MENU_SEQ_SEL_MODE:
				cpackMenuSelModeNum --;
				if( cpackMenuSelModeNum < 0 ) cpackMenuSelModeNum = CPACK_MENU_MAX_MODE - 1;
				#if SOUND_SW
				Na_SystemSound( NA_SYS_CURMOVE, 0 );
				#endif
				break;
			case CPACK_MENU_SEQ_SEL_OK:
				cpackMenuSelOkNum ^= 1;
				#if SOUND_SW
				Na_SystemSound( NA_SYS_CURMOVE, 0 );
				#endif
				break;
		}
	}
	else if( mKnPad[KN_PAD_1P].pad.trig & BUTTON_ARG_UP ) {
		switch( cpackMenuSeq ) {
			case CPACK_MENU_SEQ_SEL_NOTE:
				if( !cpackGameNoteScrReq ) {
					cpackMenuSelNoteCurPos --;
					#if SOUND_SW
					Na_SystemSound( NA_SYS_CURMOVE, 0 );
					#endif
					if( cpackMenuSelNoteCurPos < 0 ) {
						cpackMenuSelNoteCurPos = 0;
						if( cpackGameNoteNum[cpackMenuSelNoteCurPos+2] != 1 ) {
							cpackGameNoteScrReq = 2;	/* 2: DOWN */
							#if SOUND_SW
							Na_SystemSound( NA_SYS_SCROLL, 0 );
							#endif
						}
					}
				}
				break;
		}
	}
	else if( mKnPad[KN_PAD_1P].pad.trig & BUTTON_ARG_DOWN ) {
		switch( cpackMenuSeq ) {
			case CPACK_MENU_SEQ_SEL_NOTE:
				if( !cpackGameNoteScrReq ) {
					cpackMenuSelNoteCurPos ++;
					#if SOUND_SW
					Na_SystemSound( NA_SYS_CURMOVE, 0 );
					#endif
					if( cpackMenuSelNoteCurPos > 4 ) {
						cpackMenuSelNoteCurPos = 4;
						if( cpackGameNoteNum[cpackMenuSelNoteCurPos+2] != 16 ) {
							cpackGameNoteScrReq = 1;	/* 1: UP */
							#if SOUND_SW
							Na_SystemSound( NA_SYS_SCROLL, 0 );
							#endif
						}
					}
				}
				break;
		}
	}
}

/* ====================================================================== */
/*
	ゲームノートの表示
*/
static Gfx *makeGameNoteGlist( Gfx *gp )
{
	register int		i, j, work, page_num;
	register int		*note_num_p;
	register OSPfsState	*pfs_state_p;

	/* ノート表示 */
	gDPPipeSync( gp++ );
	gDPSetScissor( gp++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WD_HI-1, SY_GAMENOTE + HT_TEX_GAMENOTE * 9 - 1 );
	for( i = 0 ; i < 9 ; i ++ ) {
		if( !cpackGameNoteScrReq && (i == 0 || i == 8) ) continue;
		gp = makeOneGameNoteGlist( gp, 64, cpackGameNoteScrSy + HT_TEX_GAMENOTE * i );
	}

	/* カーソル表示 */
	gSPDisplayList( gp++, dlCPackInitLetter );
	gDPSetPrimColor( gp++, 0, 0, 255, cpackMenuCurColor, 0, 255 );
	if( cpackMenuSeq != CPACK_MENU_SEQ_SEL_MODE ) gp = makeCPackNoteCurGlist( gp );
	/* 文字表示 */
	gDPPipeSync( gp++ );
	gDPSetPrimColor( gp++, 0, 0, 0, 0, 50, 255 );
	for( i = 0, note_num_p = cpackGameNoteNum ; i < 9 ; i ++, note_num_p ++ ) {
		if( *note_num_p == 0 ) continue;
		/* 番号 */
		if( *note_num_p < 10 ) {
			gp = makeNosFontGlist( gp, (uchar)*note_num_p + 0x10,
								   64 + 37, cpackGameNoteScrSy + HT_TEX_GAMENOTE * i + 2);
		}
		else {
			work = *note_num_p % 10;
			gp = makeNosFontGlist( gp, (uchar)work + 0x10,
								   64 + 37 + 5, cpackGameNoteScrSy + HT_TEX_GAMENOTE * i + 2);
			gp = makeNosFontGlist( gp, (uchar)0x11,
								   64 + 37 - 5, cpackGameNoteScrSy + HT_TEX_GAMENOTE * i + 2);
		}
		if( !pfsStateRet[(*note_num_p)-1] ) {
			/* ファイル名 */
			pfs_state_p = &pfsState[(*note_num_p)-1];
			gp = makeNosFontStrGlist( gp, pfs_state_p->game_name, 16,
									  64 + 95, cpackGameNoteScrSy + HT_TEX_GAMENOTE * i + 2);
			if( pfs_state_p->ext_name[0] ) {
				gp = makeNosFontGlist( gp, (uchar)(0x3c),
									  64 + 95 + 16 * (gameNameLength) , cpackGameNoteScrSy + HT_TEX_GAMENOTE * i + 2);
				gp = makeNosFontGlist( gp, (uchar)(pfs_state_p->ext_name[0]),
									  64 + 95 + 16 * (gameNameLength+1) , cpackGameNoteScrSy + HT_TEX_GAMENOTE * i + 2);
			}
			/* ページ数 */
			page_num = (int)( (pfs_state_p->file_size + 255) >> 8 );
			gp = makeNosFontGlist( gp, (uchar)(page_num % 10) + 0x10,
								   64 + 442 + 32, cpackGameNoteScrSy + HT_TEX_GAMENOTE * i + 2);
			if( page_num > 9 ) {
				work = page_num / 10;
				gp = makeNosFontGlist( gp, (uchar)(work % 10) + 0x10,
								   64 + 442 + 16, cpackGameNoteScrSy + HT_TEX_GAMENOTE * i + 2);
			}
			if( page_num > 99 ) {
				work /= 10;
				gp = makeNosFontGlist( gp, (uchar)(work % 10) + 0x10,
								   64 + 442, cpackGameNoteScrSy + HT_TEX_GAMENOTE * i + 2);
			}
		}
	}
	
	gSPDisplayList( gp++, dlCPackInitBG );
	gDPSetScissor( gp++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WD_HI-1, SCREEN_HT_HI-1 );
	
	return( gp );
}

static Gfx *makeOneGameNoteGlist( Gfx *gp, int sx, int sy )
{
	register int		i;
	register ushort		*tex_p;

	for( i = 0, tex_p = texPack3 ; i < 5 ; i ++, tex_p += ( WD_TEX_PACK3 * HT_TEX_PACK3 ) ) {
		gDPLoadTextureBlock( gp++, tex_p,
			G_IM_FMT_RGBA, G_IM_SIZ_16b,
			WD_TEX_PACK3, HT_TEX_PACK3,	0,
			G_TX_CLAMP, G_TX_CLAMP,
			G_TX_NOMASK, G_TX_NOMASK,
			G_TX_NOLOD, G_TX_NOLOD );
		gSPTextureRectangle( gp++,
			(sx) << 2 ,
			(sy + HT_TEX_PACK3 * i) << 2,
			(sx + WD_TEX_PACK3-1) << 2,
			(sy + HT_TEX_PACK3 * i + HT_TEX_PACK3-1) << 2,
			G_TX_RENDERTILE, 0, 0, 4 << 10, 1 << 10 );
	}

	return( gp );
}

/* ====================================================================== */
/*
	メッセージの表示
*/
static Gfx *makeCPackMessageGlist( Gfx *gp )
{
	register int	i;
	register uchar	*tex_p;

#ifndef ROM_FLAG
	if( mKnPad[KN_PAD_1P].pad.trig & U_CBUTTONS ) idxCPackMessage --;
	else if( mKnPad[KN_PAD_1P].pad.trig & D_CBUTTONS ) idxCPackMessage ++;
#endif

#if (SW_KN_LANGUAGE == KN_EU)
	if( euLanguage == EL_ENGLISH ) tex_p = pCPackMessage[idxCPackMessage];
	else tex_p = pCPackMessage_Ge[idxCPackMessage];
#else
	tex_p = pCPackMessage[idxCPackMessage];
#endif
	for( i = 0 ; i < HT_NUM_TEX_CPACK_MESSAGE ; i ++ ) {
		gDPLoadTextureTile( gp++, tex_p, G_IM_FMT_IA, G_IM_SIZ_8b,
			WD_TEX_CPACK_MESSAGE, HT_TEX_CPACK_MESSAGE,
			0, 0,
			WD_TEX_CPACK_MESSAGE - 1, HT_TEX_CPACK_MESSAGE - 1,
			0,
			G_TX_CLAMP, G_TX_CLAMP,
			G_TX_NOMASK, G_TX_NOMASK,
			G_TX_NOLOD, G_TX_NOLOD );
		gSPTextureRectangle( gp++,
			(SX_TEX_CPACK_MESSAGE) << 2,
			(SY_TEX_CPACK_MESSAGE + HT_TEX_CPACK_MESSAGE * i) << 2,
			(SX_TEX_CPACK_MESSAGE + WD_TEX_CPACK_MESSAGE) << 2,
			(SY_TEX_CPACK_MESSAGE + HT_TEX_CPACK_MESSAGE * (i+1)) << 2,
			G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10 );
		tex_p += ( WD_TEX_CPACK_MESSAGE * HT_TEX_CPACK_MESSAGE );
	}

	return( gp );
}

/* ====================================================================== */
/*
	空きメモリー
*/
static Gfx *makeCPackFreeBlocksGlist( Gfx *gp )
{
	register int	i, number, answer, rest;

	answer = pfsFreeBlocks;

	if( answer < 10 ) number = 1;
	else if( answer < 100 ) number = 2;
	else number = 3;

	for( i = 0 ; i < number ; i ++ ) {
		rest = answer % 10;
		answer /= 10;
		gDPLoadTextureBlock( gp++, pTexJfNumber[rest],
			G_IM_FMT_IA, G_IM_SIZ_8b,
			WD_TEX_JF_NUMBER, HT_TEX_JF_NUMBER, 0,
			G_TX_CLAMP, G_TX_CLAMP,
			G_TX_NOMASK, G_TX_NOMASK,
			G_TX_NOLOD, G_TX_NOLOD );
		gSPTextureRectangle( gp++,
			(SX_FREE_BLOCKS + ( 2 - i ) * DX_FREE_BLOCKS ) << 2,
			(SY_FREE_BLOCKS) << 2,
			(SX_FREE_BLOCKS + ( 2 - i ) * DX_FREE_BLOCKS + WD_TEX_JF_NUMBER) << 2,
			(SY_FREE_BLOCKS + HT_TEX_JF_NUMBER) << 2,
			G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10 );
	}

	return( gp );
}
/* ====================================================================== */
/*
	カーソル
*/
static Gfx *makeCPackCurGlist( Gfx *gp, int sx, int sy )
{
	register int	i;

	for( i = 0 ; i < 4 ; i ++ ) {
		gDPLoadTextureTile( gp++, texJfWaku + WD_TEX_JF_WAKU * HT_TEX_JF_WAKU * i ,
			G_IM_FMT_IA, G_IM_SIZ_8b,
			WD_TEX_JF_WAKU, HT_TEX_JF_WAKU,
			0, 0,
			WD_TEX_JF_WAKU-1, HT_TEX_JF_WAKU-1,
			0,
			G_TX_CLAMP, G_TX_CLAMP,
			G_TX_NOMASK, G_TX_NOMASK,
			G_TX_NOLOD, G_TX_NOLOD );
		gSPTextureRectangle( gp++,
			(sx) << 2, (sy + HT_TEX_JF_WAKU * i) << 2,
			(sx + WD_TEX_JF_WAKU) << 2,
			(sy + HT_TEX_JF_WAKU * i + HT_TEX_JF_WAKU) << 2,
			G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10 );
	}

	return( gp );
}
/* ====================================================================== */
/*
	ノートカーソル
*/
static Gfx *makeCPackNoteCurGlist( Gfx *gp )
{
	register int	i;

	for( i = 0 ; i < 4 ; i ++ ) {
		gDPLoadTextureTile( gp++, texJfWaku2 + 496 * 5 * i ,
			G_IM_FMT_IA, G_IM_SIZ_8b,
			496, 5,
			0, 0,
			495, 4,
			0,
			G_TX_CLAMP, G_TX_CLAMP,
			G_TX_NOMASK, G_TX_NOMASK,
			G_TX_NOLOD, G_TX_NOLOD );
		gSPTextureRectangle( gp++,
			(72) << 2,
			(248 + HT_TEX_GAMENOTE * cpackMenuSelNoteCurPos + 5 * i) << 2,
			(72 + 496) << 2,
			(248 + HT_TEX_GAMENOTE * cpackMenuSelNoteCurPos + 5 * i + 5) << 2,
			G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10 );
	}

	return( gp );
}
/* ====================================================================== */
/*
	任天堂フォント
*/
Gfx *makeNosFontGlist( Gfx *gp, uchar code, uint sx, uint sy )
{
	register uint	x, y;

	if( code < 0x10 ) return( gp );
	
	/* 英語版はカタカナをマイナスに変更して表示 */
#if (SW_KN_LANGUAGE == KN_US || SW_KN_LANGUAGE == KN_EU)
	if( code >= 0x42 ) code = 0x3b;
#endif

	code -= 0x10;

	x = code % 16;
	y = code / 16;


	gDPLoadTextureBlock( gp++, texNosFont + 16 * 16 * (uint)code,
		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( gp++,
		(sx) << 2, (sy) << 2,
		(sx + 16) << 2, (sy + 16) << 2,
		G_TX_RENDERTILE, 0 << 5, 0 << 5, 1 << 10, 1 << 10 );
	
	return( gp );
}

Gfx *makeNosFontStrGlist( Gfx *gp, char *str, int str_length, uint sx, uint sy )
{
	register uint disp_x;

	disp_x = sx;
	gameNameLength = 0;
	while( str_length ) {
		if( *str ) gameNameLength ++;
		gp = makeNosFontGlist( gp, (uchar)*str++, disp_x, sy );
		disp_x += 16;
		str_length --;
	}
	
	return( gp );
}

/* ====================================================================== */
/*
	ハイレゾ用フレームバッファのクリア
*/
Gfx *clearAllFBufferForHi( Gfx *gp )
{
	register int i;
	
	gSPClearGeometryMode( gp++, 0xffffffff );
    gSPTexture( gp++, 0, 0, 0, 0, G_OFF );
    gDPPipeSync( gp++ );
	gDPSetCycleType( gp++, G_CYC_FILL );
	gDPSetCombineMode( gp++, G_CC_DECALRGBA, G_CC_DECALRGBA );
	gDPSetRenderMode( gp++, G_RM_NOOP, G_RM_NOOP2 );
	gDPSetAlphaCompare( gp++, G_AC_NONE );
	gDPSetScissor( gp++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WD_HI-1, SCREEN_HT_HI-1 );
	for( i = 0 ; i < 2 ; i ++ ) {
 		gDPPipeSync( gp++ );
		gDPSetColorImage( gp++, G_IM_FMT_RGBA, G_IM_SIZ_16b, SCREEN_WD_HI, OS_K0_TO_PHYSICAL( pFBufferHi[i] ) );
	   	gDPSetFillColor( gp++, (GPACK_RGBA5551(0, 0, 0, 1) << 16 | GPACK_RGBA5551(0, 0, 0, 1)) );
	    gDPFillRectangle( gp++, 0, 0, SCREEN_WD_HI-1, SCREEN_HT_HI-1 );
	}

	return( gp );
}

/* ====================================================================== */
/*
	こんとろーらーぱっくめにゅー
*/
static void initMainGlistCPack2Next( void )
{
	/* ゲームモード */
	gameModeOld = game_mode;
	gameModeNext = 0;
	game_mode = GM_CPACK2NEXT;
	game_stat = GAME_STAT_CPACK;
	gameModeChangeFlag = 1;
	gameModeSeq = 0;
	gameModeCount = 0;
	vram_mode = VM_HI;
	Graph_timing_req = GRAPH_TIMING_CPACK;
}

/* ====================================================================== */
/*
	マスク
*/
static Gfx *drawBlackRectangleGlistHi( Gfx *gp, uint ulx, uint uly, uint lrx, uint lry, uint a )
{
    gSPTexture( gp++, 0, 0, 0, 0, G_OFF );
    gDPPipeSync( gp++ );
	gDPSetCycleType( gp++, G_CYC_1CYCLE );
	gDPSetPrimColor( gp++, 0, 0, 0, 0, 0, a );
	gDPSetCombineMode( gp++, G_CC_PRIMITIVE, G_CC_PRIMITIVE );
	gDPSetRenderMode( gp++, G_RM_XLU_SURF, G_RM_XLU_SURF2 );
	gDPSetAlphaCompare( gp++, G_AC_NONE );
    gDPFillRectangle( gp++, ulx, uly, lrx, lry );

	return( gp );
}
