/*
 ******************************************************************************
 *              
 *      コントローラパックメニューのソースファイル
 *	$Id: m_cpak_menu.c,v 1.1 2004/02/12 23:00:01 tong Exp $	
 ******************************************************************************
 */
/*
 * $Log: m_cpak_menu.c,v $
 * Revision 1.1  2004/02/12 23:00:01  tong
 * sources related to cpak, rtc, flash
 *
 * Revision 1.33  2000-12-25 21:39:42+09  hayakawa
 * *** empty log message ***
 *
 * Revision 1.32  2000-11-16 10:46:39+09  komatu
 * *** empty log message ***
 *
 * Revision 1.31  2000-11-15 20:11:44+09  komatu
 * *** empty log message ***
 *
 * Revision 1.30  2000-11-09 22:24:44+09  sakaguti
 * *** empty log message ***
 *
 * Revision 1.29  2000-11-08 23:12:15+09  nii
 * *** empty log message ***
 *
 * Revision 1.28  2000-11-04 23:25:49+09  gen
 * *** empty log message ***
 *
 * Revision 1.27  2000-11-01 23:46:35+09  nii
 * *** empty log message ***
 *
 * Revision 1.26  2000-10-25 12:06:44+09  sakaguti
 * *** empty log message ***
 *
 * Revision 1.25  2000-10-21 23:01:01+09  nii
 * *** empty log message ***
 *
 * Revision 1.24  2000-10-14 22:23:30+09  nii
 * *** empty log message ***
 *
 * Revision 1.23  2000-10-13 17:25:11+09  umemiya
 * *** empty log message ***
 *
 * Revision 1.22  2000-10-13 15:04:41+09  umemiya
 * *** empty log message ***
 *
 * Revision 1.21  2000-10-11 20:13:54+09  umemiya
 * *** empty log message ***
 *
 * Revision 1.20  2000-10-10 19:59:19+09  umemiya
 * *** empty log message ***
 *
 * Revision 1.19  2000-10-10 19:49:08+09  umemiya
 * *** empty log message ***
 *
 * Revision 1.18  2000-09-29 17:20:22+09  hayakawa
 * padmgr関数名変更
 *
 * Revision 1.17  2000-08-12 21:20:12+09  hayakawa
 * game_set_next_game_name→game_goto_next_game_name
 *
 * Revision 1.16  2000-07-04 21:42:12+09  gen
 * *** empty log message ***
 *
 * Revision 1.15  2000-07-03 15:01:03+09  gen
 * *** empty log message ***
 *
 * Revision 1.14  2000-05-19 16:53:11+09  gen
 * *** empty log message ***
 *
 * Revision 1.13  2000-02-03 21:08:28+09  nii
 * *** empty log message ***
 *
 * Revision 1.12  1999-10-20 17:03:30+09  gen
 * *** empty log message ***
 *
 * Revision 1.11  1999-10-06 15:14:41+09  gen
 * *** empty log message ***
 *
 * Revision 1.10  1999-10-05 19:58:21+09  gen
 * *** empty log message ***
 *
 * Revision 1.9  1999-07-05 20:03:22+09  komatu
 * *** empty log message ***
 *
 * Revision 1.8  1999-05-17 17:42:25+09  gen
 * *** empty log message ***
 *
 * Revision 1.7  1999-05-14 18:20:59+09  gen
 * *** empty log message ***
 *
 * Revision 1.6  1999-05-13 20:27:38+09  gen
 * *** empty log message ***
 *
 * Revision 1.5  1999-05-12 20:15:39+09  gen
 * *** empty log message ***
 *
 * Revision 1.4  1999-05-11 18:04:11+09  gen
 * *** empty log message ***
 *
 * Revision 1.3  1999-05-10 18:26:32+09  gen
 * *** empty log message ***
 *
 * Revision 1.2  1999-04-28 17:48:24+09  gen
 * *** empty log message ***
 *
 * Revision 1.1  1999-04-28 15:00:05+09  komatu
 * Initial revision
 *
 *
 */
#include "gfxprint.h"
#include "m_basic.h"
#include "m_trademark.h"
#include "m_rcp.h"
#include "m_font.h"
#include "m_cpak_menu.h"
#include "alloca.h"		/* alloca */
#include "main.h"
#include "m_cpak.h"
#include "pakmenu.h"
#include "padmgr.h"

#include "m_controller_extern.h"

/*
 *	メイン処理
 */
static void cpak_menu_main( GAME *game_p ){
    
    GAME_CPAK_MENU *game_cpak_menu_p = (GAME_CPAK_MENU *)game_p;

    game_cpak_menu_p->menu_move_func( game_cpak_menu_p );

    {
	GRAPH	*graph = game_p->graph;

	game_debug_draw_last(game_p, graph);
	game_draw_last(graph);
    }
}

/*
 *	描画＆移動処理
 */
static void cpak_menu_move(GAME_CPAK_MENU *game_cpak_menu_p)
{
    Submenu_c *submenu = &(game_cpak_menu_p->submenu);
    GAME *game_p = &(game_cpak_menu_p->g);
    GRAPH *graph = game_p->graph;
    Object_Exchange *object_exchange = &(game_cpak_menu_p->object_exchange);
    MemPtr segment =
	mSc_getP_Data_Bank_Status_Segment(object_exchange, KEEP_BANK_ID);

    /* リミッタ─付コントローラ情報の計算 */
    mCon_main(game_p);

    mSM_submenu_move(submenu);

    if (submenu->proc_status == mSM_End_e) {

	game_goto_next_game_name(game_p, trademark, TRADEMARK);

    }

    SetSegmentK0(GAMEPLAY_KEEP_SEGMENT,  segment);

    OPEN_DISP(graph);
    gSPSegment(NEXT_DISP, 0, 0x0);
    gSPSegment(NEXT_POLY_XLU_DISP, 0, 0x0);	/* Physical address segment */
    gSPSegment(NEXT_OVERLAY_DISP,  0, 0x0);	/* Physical address segment */
    gSPSegment(NEXT_FONT_DISP,     0, 0x0);	/* Physical address segment */
    gSPSegment(NEXT_SHDW_DISP,     0, 0x0);	/* Physical address segment */    
    gSPSegment(NEXT_DISP,          GAMEPLAY_KEEP_SEGMENT, segment);
    gSPSegment(NEXT_POLY_XLU_DISP, GAMEPLAY_KEEP_SEGMENT, segment);
    gSPSegment(NEXT_OVERLAY_DISP,  GAMEPLAY_KEEP_SEGMENT, segment);
    gSPSegment(NEXT_FONT_DISP,     GAMEPLAY_KEEP_SEGMENT, segment);
    gSPSegment(NEXT_SHDW_DISP,     GAMEPLAY_KEEP_SEGMENT, segment);
    DisplayList_initialize(graph, 0, 0, 0, NULL);
    gDPPipeSync(NEXT_DISP);
    view_setup_view(&(game_cpak_menu_p->view));

    CLOSE_DISP(graph);

    mSM_submenu_draw(submenu, game_p);
}

/*
 *	初期化関数
 */
static void cpak_menu_move_init(GAME_CPAK_MENU *this)
{
    Submenu_c *submenu = &(this->submenu);

    this->menu_move_func = cpak_menu_move;

    submenu->proc_status = mSM_PREWait_e;
    submenu->menu_type = mSM_CPEdit_e;

    /* サブメニュー */
    PR_SUBMENU_MODE(submenu) = SUBMENU_MODE_NOT_GAME_PLAY_e;

    /* 2000 11/15 komatu 文字表示コンストラクト */
    mFont_ct(NULL, NULL, NULL);

    SetGameFrame(FOREST_SUBMENU_FRAME);
}

/*
 *	後始末
 */
extern void cpak_menu_cleanup(GAME *game_p)
{
    GAME_CPAK_MENU *game_cpak_menu_p = (GAME_CPAK_MENU *)game_p;

    PR_SUBMENU_MODE(&(game_cpak_menu_p->submenu)) = SUBMENU_MODE_IDLE_e;

    mSM_submenu_dt(&(game_cpak_menu_p->submenu));

    /* サブメニューとプレイヤー後始末より後に実行されなければならない */
    mSM_submenu_ovlptr_cleanup(&(game_cpak_menu_p->submenu));
}

/*
 *	初期化
 */
extern void cpak_menu_init(GAME *game_p)
{    
    GAME_CPAK_MENU *game_cpak_menu_p = (GAME_CPAK_MENU *)game_p;
    
    /* 関数ポインタ初期化 */
    game_p->exec = cpak_menu_main;
    game_p->cleanup = cpak_menu_cleanup;

    view_init(&game_cpak_menu_p->view, game_p->graph);
    game_cpak_menu_p->view.setflag = VIEW_DO_ORTHO;
    game_cpak_menu_p->menu_move_func = cpak_menu_move_init;
    SetGameFrame(1);

    mSM_submenu_ovlptr_init(game_p);
    mSc_data_bank_ct(game_p, &(game_cpak_menu_p->object_exchange));
    mSc_decide_exchange_bank(&(game_cpak_menu_p->object_exchange));
    mSM_submenu_ct(&game_cpak_menu_p->submenu);
    new_Matrix(game_p);
}












#if 0				/* 2000/10/14 by umemiya 残り全部外してある */

#define mCPM_PRINT_COLOR( col )	Gfxprint_color( (col[0]),col[1],col[2],255 )

#define mCPM_QUIT_MODE		3

/** カーソルカラー数 */
#define	PAK_CURSOR_COLOR_NUM	(10)
/** カーソル点滅速度 */
#define	PAK_CURSOR_BLINK_PACE	(3)
/** カーソルカラー点滅フレーム数 */
#define	PAK_CURSOR_BLINK	(PAK_CURSOR_COLOR_NUM * PAK_CURSOR_BLINK_PACE)



unsigned int l_fg1[RGB] = {255,250,200};
unsigned int l_shadow_col[RGB] = {0,0,0};
unsigned int l_mid_col[RGB] = {50,25,25};
unsigned int l_iderr_col[RGB] = {255,0,0};

/** JISから n64コードへの変換表 */
static u8 jis2n64[][2] = {
    {' ',  0x0f},
    {'!',  0x34},
    {'\"', 0x35},
    {'#',  0x36},
    {'\'', 0x37},
    {'*',  0x38},
    {'+',  0x39},
    {',',  0x3a},
    {'-',  0x3b},
    {'.',  0x3c},
    {'/',  0x3d},
    {':',  0x3e},
    {'=',  0x3f},
    {'?',  0x40},
    {'@',  0x41},
    {0xa1, 0x42},	/* 。 */
    {0xde, 0x43},	/* 濁点 */
    {0xdf, 0x44},	/* 半濁点 */
    {0xa7, 0x45},	/* ァ */
    {0xa8, 0x46},	/* ィ */
    {0xa9, 0x47},	/* ゥ */
    {0xaa, 0x48},	/* ェ */
    {0xab, 0x49},	/* ォ */
    {0xaf, 0x4a}, 	/* ッ */    
    {0xac, 0x4b},	/* ャ */
    {0xad, 0x4c},	/* ュ */
    {0xae, 0x4d},	/* ョ */
    {0xa6, 0x4e},	/* ヲ */    
    {0xdd, 0x4f},	/* ン */
    {0x00, 0x00},	/* end code */
};



/*----------------------------------------------------------------------*/
/*	nuContPakJisToN64 - 文字コード変換(JIS->N64)			*/
/*	JISコードからN64コードに変換					*/
/*	IN:	*src	変換元の文字列のポインタ			*/
/* 		*dest	変換先の文字列ポインタ				*/
/*		len	変換元の文字列長				*/
/*	RET:	無し							*/
/*----------------------------------------------------------------------*/
void nuContPakJisToN64(u8* src, u8* dest, u32 len){
    
    u32 	cnt;
    u32		cnt_len;
    for(cnt_len = 0; cnt_len < len; cnt_len++){
	if(*src == '\0') {
	    /* NULL文字で終了 */
	    return;
	} else if((0x41 <= *src) && (*src <= 0x5a)){/* アルファベット大文字 */
	    *dest = ( u8 )(*src - 0x27);
	} else if((0x61 <= *src) &&  (*src <= 0x7a)){/* アルファベット小文字 */
	    *dest = ( u8 )(*src - 0x47);
	} else if((0x30 <= *src) && (*src <= 0x39)){  /* 数字  */
	    *dest = ( u8 )(*src -0x20);
	} else if((0xb1 <= *src) && (*src <= 0xdc)){ /* カタカナ */
	    if(*(src+1) == 0xde){		/* 濁点 */
		if( *src < 0xca){
		    *dest = ( u8 )(*src - 0x3a);
		} else {	
		    *dest = ( u8 )(*src - 0x3f );	/* ハ行 */
		}
		src++;
	    } else if(*(src+1) == 0xdf){	/* 半濁点 */
		*dest = ( u8 )(*src - 0x3a);
		src++;		
	    } else {
		*dest = ( u8 )(*src - 0x61);		/* 普通 */
	    }
	} else {		/* その他はテーブル変換 */
	    cnt = 0;
	    /* テーブルサーチ */
	    while(jis2n64[cnt][1]){
		if(jis2n64[cnt][0] == *src){
		    *dest = jis2n64[cnt][1];
		    break;
		}
		cnt++;
	    }
	    /* 見つからなかった場合はスペースにする */
	    if(jis2n64[cnt][1] == 0x00){
		*dest = 0x0f;
	    }
	}
	dest++;
	src++;
    }
}

/*----------------------------------------------------------------------*/
/*	nuContPakN64ToJis - 文字コード変換(N64->jis)			*/
/*	N64コードからJISコードに変換					*/
/* 	濁点・半濁点は2文字に変換されるので注意してください		*/
/*	IN:	*src	変換元の文字列のポインタ			*/
/* 		*dest	変換先の文字列ポインタ				*/
/*		len	変換元の文字列長				*/
/*	RET:	無し							*/
/*----------------------------------------------------------------------*/
void nuContPakN64ToJis(u8* src, u8* dest, u32 len){

    u32	cnt_len;
    u32	cnt;
    
    for(cnt_len = 0; cnt_len < len; cnt_len++){
	if(*src == '\0') {
	    /* NULL文字はそのまま */
	    *dest = *src;
	} else if((0x1a <= *src) && (*src <= 0x33)){/* アルファベット */
	    *dest = (u8)( *src + 0x27 );
	} else if((0x10 <= *src) && (*src <= 0x19)){  /* 数字  */
	    *dest = (u8)( *src + 0x20 );
	} else if((0x50 <= *src) && (*src <= 0x7b)){ /* カタカナ */
	    *dest = (u8)( *src + 0x61 );
	} else if((0x7c <= *src) && (*src <= 0x8a)){ /* 濁点（ガ-ド） */
	    *dest = (u8)( *src + 0x3a );
	    *(dest + 1) = 0xde;
	    dest++;
	} else if((0x8b <= *src) && (*src <= 0x8f)){ /*濁点（バ行） */
	    *dest = (u8)( *src + 0x3f );
	    *(dest + 1) = 0xde;
	} else if((0x90 <= *src) && (*src <= 0x94)){
	    *dest = (u8)( *src + 0x3a );
	    *(dest + 1) = 0xdf;
	} else {		/* その他はテーブル変換 */
	    cnt = 0;
	    /* テーブルサーチ */
	    while(jis2n64[cnt][1]){
		if(jis2n64[cnt][1] == *src){
		    *dest = jis2n64[cnt][0];
		    break;
		}
		cnt++;
	    }
	    /* 見つからなかった場合はスペースにする */
	    if(jis2n64[cnt][1] == 0x00){
		*dest = 0x0f;
	    }
	}
	dest++;
	src++;
    }
}


/*
  △▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽
  
  ■ 数字を n64コードに変換
 */
void mCPM_u8toStr( u16 n, u8 *str ){

    if (n > 999) {
	n = 999;
    }

#if 1
    str[0] = (u8)(n / 100 + 0x0f + (n >= 100));
    str[1] = (u8)((n % 100) / 10  + 0x0f + (n >= 10));
    str[2] = (u8)(n % 10  + 0x10);
#else
    static  u8  ofs[] = { 0x0f, 0x0f, 0x10, 0x10, 0x10 };
    s32	i;
    
    if      (n >= 100) i = 2;
    else if (n >= 10)  i = 1;
    else               i = 0;
    
    str[0] = n / 100 + ofs[i+0];
    
    n %= 100;  
    str[1] = n / 10  + ofs[i+1];
    str[2] = n % 10  + ofs[i+2];
#endif
}  


/*
  ▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△
  
  ■ 画面へメニューを表示する関数
 */
static void mCPM_DisplayTerm(
    mCPk_pkinfo_c	*pak,
    int 		sel,
    int			n,
    unsigned int	*fg1,
    unsigned int	*fg2,
    gfxprint_t		*gfxprint ){
    
    OSPfsState	*fileState = &(pak->fileState[n]);
    s32		*fileState_ret = &(pak->fileState_ret[n]);
    u8		name_buf[17];	/** JISに変換後の game_name */
    u8		ext_buf[2];	/** JISに変換後の ext_name */
    u8		ibuf[4];	/** n64コードに変換後の file_size */
    u8		num_buf[4];	/** JISに変換後の file_size */
    int		cy;		/** カーソルの Y座標 */
    char	*cmd_str[PAK_COMMAND_END] = {
	STR_CMD_ERASE, STR_CMD_OK, STR_CMD_QUIT
    };
    int		i;
    
    /* Check if pointer on the filename */
    cy = n * FONT_HSKIP + MENU_FILE_Y + 1;
    if ( n < 16 ){
	/* Check if file exists */
	if( *fileState_ret == 0 ){
	    /* Draw filename and # of blocks */
	    mCPM_PRINT_COLOR( fg1 );
	    Gfxprint_locate8x8( MENU_FILE_X, cy );
	    /* game_nameの表示 */
	    for( i = 0; i < 17; i++ ){
		name_buf[i] = '\0';
	    }
	    nuContPakN64ToJis((unchar *)(&(fileState->game_name[0])),
			      name_buf, 16 );
	    Gfxprint_printf1("%s", name_buf );
	    /* ext_nameがあれば表示 */
	    if( fileState->ext_name[0]){
		mCPM_PRINT_COLOR( fg1 );
		Gfxprint_printf0(".");
		mCPM_PRINT_COLOR( fg1 );
		ext_buf[0] = '\0';
		ext_buf[1] = '\0';
		nuContPakN64ToJis((unchar *)(&(fileState->ext_name)),
				  ext_buf, 1);
		Gfxprint_printf1("%s", ext_buf );
	    }
	    /** ページ数の表示 */
	    mCPM_PRINT_COLOR( fg1 );
	    Gfxprint_locate8x8( MENU_BLOCK_X, cy );
	    for( i = 0; i < 5; i++ ){
		ibuf[i] = '\0';
	    }
	    mCPM_u8toStr((u16)(( fileState->file_size+255) >> 8),
			 ibuf );
	    for( i = 0; i < 4; i++ ){
		num_buf[i] = '\0';
	    }
	    nuContPakN64ToJis( ibuf, num_buf, 3);
	    Gfxprint_printf1("%s", num_buf );
	    /* "ERASE"の表示 */
	    if( sel == PAK_CMD_OK ){
		Gfxprint_locate8x8( MENU_BLOCK_X + 3, cy );
	    } else if( sel == PAK_CMD_QUIT ){
		Gfxprint_locate8x8( MENU_BLOCK_X + 3, cy + 1 );
	    }
	    mCPM_PRINT_COLOR( fg2 );
	    Gfxprint_printf1("%s", cmd_str[sel] );
	}
	/* "(1-16):"の表示 */
	if( n < 9 ){
	    Gfxprint_locate8x8( MENU_NUM_X - 2, cy );
	    mCPM_PRINT_COLOR( fg1 );
	    Gfxprint_printf1("%d", n + 1 );
	} else {
	    mCPM_PRINT_COLOR( fg1 );
	    Gfxprint_locate8x8( MENU_NUM_X - 3, cy );
	    Gfxprint_printf1("%d", n + 1 );
	}
	mCPM_PRINT_COLOR( fg1 );
	Gfxprint_locate8x8( MENU_NUM_X - 1, cy );
	Gfxprint_printf0(":");
    } else {
	/* Draw "QUIT" */
	mCPM_PRINT_COLOR( fg1 );
	Gfxprint_locate8x8( MENU_NUM_X, cy + 3 );
	Gfxprint_printf0( STR_CMD_END );
    }
}


/*
  ▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△
  
  ■ パックの空きブロック数を追加し表示する関数
 */
void mCPM_DisplayFreeBlock( gfxprint_t *gfxprint, u16 free_blocks ){
    
    u8	numbuf[5];	/** n64コードに変換後の free_blocks */
    u8	ibuf[4];	/** JISに変換後の free_blocks */
    int	i;
    
    for( i = 0; i < 5; i++ ){
	numbuf[i] = '\0';
    }
    mCPM_u8toStr((u16)(( free_blocks + 255 ) >> 8), numbuf );
    for( i = 0; i < 4; i++ ){
	ibuf[i] = '\0';
    }
    nuContPakN64ToJis( numbuf, ibuf, 3);

    Gfxprint_locate8x8( MENU_FREE_BLK_X2, MENU_FREE_BLK_Y2 );
    mCPM_PRINT_COLOR( l_fg1 );
    Gfxprint_printf1("%s", ibuf );
    
}


/*
  ▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△
  
  ■ 画面全体の表示関数
 */
void mCPk_SetDisplay( GAME_CPAK_MENU *this, gfxprint_t *gfxprint,
		      mCPk_pkinfo_c *pak ){
    
    int		i;

    if( this->screen_type == STYPE_MENU ){

	/* "CONTROLLER PAK MENU"の表示 */
	mCPM_PRINT_COLOR( l_fg1 );
	Gfxprint_locate8x8( MENU_TITLE_X, MENU_TITLE_Y );
	Gfxprint_printf0( STR_MENU_TITLE );
	
	/* "GAME NOTES"の表示 */
	mCPM_PRINT_COLOR( l_fg1 );
	Gfxprint_locate8x8( MENU_NUM_X, MENU_FILE_Y - FONT_HSKIP*1 );
	Gfxprint_printf0( STR_MENU_ITEMS );
	/* "NOT USED"の表示 */
	mCPM_PRINT_COLOR( l_fg1 );
	Gfxprint_locate8x8( MENU_FREE_BLK_X1, MENU_FREE_BLK_Y1 );
	Gfxprint_printf0( STR_BLK_LEFT );
	mCPM_DisplayFreeBlock( gfxprint,
			       (u16)(pak->free_blocks) );
	/** FILE NAMEの表示 */
	for (i = 0; i < 17; i ++){
	    mCPM_DisplayTerm( pak, 0, i,
			      &(this->fg_col[0]), l_shadow_col, gfxprint );
	}
    }else if( this->screen_type == STYPE_NODEL ){
	/* Display message "Cannot delete file" */
	mCPM_PRINT_COLOR( l_fg1 );
	Gfxprint_locate8x8( MENU_WARN_X, MENU_WARN_Y );
	Gfxprint_printf0( STR_PAK_NODEL );
	
 	pak->use_file = 0;
    }
    
}


/*
  ▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△
  
  ■ パックの IDエラー表示関数
 */
static void mCPM_MenuDrawIDErr( gfxprint_t *gfxprint ){

    /* エラーメッセージの表示 */

    mCPM_PRINT_COLOR( l_iderr_col );
    Gfxprint_locate8x8( MENU_IDERR_X, MENU_IDERR_Y );
    Gfxprint_printf0( STR_PAK_IDERR );

    mCPM_PRINT_COLOR( l_fg1 );
    Gfxprint_locate8x8( MENU_IDERR_X1, MENU_IDERR_Y1 );
    Gfxprint_printf0( STR_PAK_IDERR1 );
    
    mCPM_PRINT_COLOR( l_fg1 );
    Gfxprint_locate8x8( MENU_IDERR_X2, MENU_IDERR_Y2 );
    Gfxprint_printf0( STR_PAK_IDERR2 );
    
}

/*
  ▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△
  
  ■ メニュー画面で指定したファイルを削除して表示を消す関数
 */
static int mCPk_MenuFileDel( GAME_CPAK_MENU *this, gfxprint_t *gfxprint,
			     mCPk_pkinfo_c *pak ){

    OSMesgQueue		*Q;
    int			*target = &(this->target);

    /** シリアルメッセージキューの取得 */
    Q = padmgr_LockSerialMesgQ( );
    /* 指定されたファイルを削除しエラーであればメッセージを表示 */
    if( sCPk_DeleteFile( &(pak->pakFile),
			 &(pak->fileState[*target])) == 0 ){
	
	this->screen_type = STYPE_NODEL;
	mCPk_SetDisplay( this, gfxprint, pak );
	*target = 16;
	/** シリアルメッセージキューの解放 */
	padmgr_UnlockSerialMesgQ( Q );
	return 0;
    }
    /** シリアルメッセージキューの解放 */
    padmgr_UnlockSerialMesgQ( Q );
    mCPM_DisplayTerm( pak, PAK_CMD_OK, *target,
		      l_shadow_col, l_shadow_col, gfxprint );
    mCPM_DisplayTerm( pak, PAK_CMD_QUIT, *target,
		      l_shadow_col, l_shadow_col, gfxprint );
    pak->fileState_ret[*target] = -1;
    /** 未使用ブロック数の追加 */
    pak->free_blocks += (s32)pak->fileState[*target].file_size;
    /** ブロック数の表示 */
    mCPM_DisplayFreeBlock( gfxprint, (u16)(pak->free_blocks) );
    /* 次のファイルに進む */
    if( *target == 16 ){
	*target = -1;
    }
    while( pak->fileState_ret[++(*target)] && *target <= 15 );
    
    return 1;
    
}

/*
  ▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△
  
  ■ Erase_CMDの表示・非表示を行う関数
  	それにともないファイル名の表示・影表示を行う
 */
static void mCPk_MenuDrawErase( gfxprint_t *gfxprint, mCPk_pkinfo_c *pak,
				int mode, int save_target ){

    unsigned int	*fg;
    int			i;
    
    fg = l_fg1;
    if( mode == 0 ){	/* ERASE_CMD表示を消し, filenameを表示 */
	for( i = 0; i < 17; i++ ){
	    mCPM_DisplayTerm( pak, PAK_CMD_ERASE,
			      i, fg, l_shadow_col, gfxprint );
	}
	fg = l_shadow_col;
    }
    /* ERASE OKの表示 */
    mCPM_DisplayTerm( pak, PAK_CMD_OK, save_target, l_fg1, fg, gfxprint );
    /* CANCELの表示 */
    mCPM_DisplayTerm( pak, PAK_CMD_QUIT, save_target, l_fg1, fg, gfxprint );
    
}

/*
  ▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△
  
  ■ 指定しているカーソルを点滅表示する関数
 */
static void mCPk_MenuFlashCursor( gfxprint_t *gfxprint, mCPk_pkinfo_c *pak,
				  int *flash_cnt, int mode, int target ){

    unsigned int cursor_color[PAK_CURSOR_COLOR_NUM][3] = {
	MENU_COLOR_TARGET_7, MENU_COLOR_TARGET_8, MENU_COLOR_TARGET_9,
	MENU_COLOR_TARGET_0, MENU_COLOR_TARGET_1, MENU_COLOR_TARGET_2,
	MENU_COLOR_TARGET_3, MENU_COLOR_TARGET_4, MENU_COLOR_TARGET_5,
	MENU_COLOR_TARGET_6,
    };

    mCPM_DisplayTerm( pak, mode, target,
		      cursor_color[(int)((*flash_cnt)/PAK_CURSOR_BLINK_PACE)],
		      cursor_color[(int)((*flash_cnt)/PAK_CURSOR_BLINK_PACE)],
		      gfxprint );
    
    if ((++(*flash_cnt)) == PAK_CURSOR_BLINK) *flash_cnt = 0;
	
}

/*
  ▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△
  
  ■ コントローラの入力によりモード切り替えを行う関数
 */
static int mCPk_MenuChangeMode( GAME_CPAK_MENU *this, gfxprint_t *gfxprint,
				mCPk_pkinfo_c *pak ){
    
    u16			trig = getTrigger( );	/** ボタン情報 */

    this->save_target = this->target;
    this->save_mode  = this->mode;
    switch( this->mode ){
      case 0:	/* ファイル選択モード */
	  if( trig & A_BTN ){
	      /* Return if "QUIT" selected */
	      if ( this->target == mCPk_MAX_FILE_NUM ){
		  if( this->screen_type == STYPE_NODEL ){	/* 異常終了 */
		      return mCPM_QUIT_MODE;
		  }else{					/* 正常終了 */
		      return mCPM_QUIT_MODE;
		  }
	      }
	      this->fg_col = l_mid_col;
	      this->mode = 2;
          }else if( trig &  UP_TRG ){		/* go onto front_file */
	      while(( pak->fileState_ret[--(this->target)] ) &&
		    ( this->target >= 0 ));
	      if( this->target == -1 ) this->target = mCPk_MAX_FILE_NUM;
	  }else if( trig & DOWN_TRG ){		/* go onto next_file */
	      if( this->target == mCPk_MAX_FILE_NUM ) this->target = -1;
	      while(( pak->fileState_ret[++(this->target)] ) &&
		    ( this->target <= mCPk_MAX_FILE_NUM - 1 ));
	  }else if( trig & B_BTN ){		/* Go onto "QUIT" */
	      this->target = mCPk_MAX_FILE_NUM;
	  }
	  break;
      case 1:	/* ERASE OK mode */
	  if( trig & DOWN_TRG ){
	      this->mode = 2;
	  }
	  if( trig & B_BTN ){
	      this->mode = 0;
	  }
	  if( trig & A_BTN ){
	      this->mode = 0;
	      if( mCPk_MenuFileDel( this, gfxprint, pak ) == 0 ){
		  this->flash_cnt = 0;
	      }
	  }
	  break;
      case 2:	/* CANCEL mode */
	  if( trig & UP_TRG ){
	      this->mode = 1;
	  }
	  if( trig & ( A_BTN | B_BTN )){
	      this->mode = 0;
	  }
	  break;
    default :
	return 1;
    }
    if( !( pak->use_file )){
	this->target = mCPk_MAX_FILE_NUM;
    }
    if( this->screen_type == STYPE_MENU ){
	if( this->mode != 0 ){
	    /* ERASE_CMDの表示・非表示 */
	    mCPk_MenuDrawErase( gfxprint, pak, this->mode,
				this->save_target );
	}else if( this->target != this->save_target ){
	    mCPM_DisplayTerm( pak, PAK_CMD_ERASE, this->save_target,
			      l_fg1, l_shadow_col,
			      gfxprint );
	    this->flash_cnt = 0;
	}
    }
    /* 指定しているカーソルを点滅させる */
    mCPk_MenuFlashCursor( gfxprint, pak,
			  &this->flash_cnt, this->mode, this->target );
    
    return 0;
    
}


/*
  △▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽

  ■ 描画とその他の処理関数
 */
static void mCPM_SelectMode( GAME_CPAK_MENU *this, gfxprint_t *gfxprint,
			     mCPk_pkinfo_c *pak ){

    OSMesgQueue	*Q;
    s32		file_err = pak->pakFile.error;
    
    if( file_err != PFS_ERR_ID_FATAL ){
	mCPk_SetDisplay( this, gfxprint, pak );
	this->mode_chg_ret = mCPk_MenuChangeMode( this, gfxprint, pak );
    } else if( file_err == PFS_ERR_ID_FATAL ){
	mCPM_MenuDrawIDErr( gfxprint );
	if( chkButton( L_BTN ) && chkButton( R_BTN )){
	    Q = padmgr_LockSerialMesgQ( );
	    sCPk_RepairID( &(pak->pakFile));
	    padmgr_UnlockSerialMesgQ( Q );
	}
    }
	
}

/*
  △▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽

  ■ 描画とその他の処理関数
 */
static void cpak_menu_move( GAME_CPAK_MENU *game_cpak_menu_p ){

    GAME *game_p = &(game_cpak_menu_p->g);
    GRAPH *graph = game_p->graph;
    gfxprint_t	*gfxprint;
    mCPk_pkinfo_c	*pak_info_p = mCPk_get_pkinfo( );

    if( game_cpak_menu_p->mode == 0 ){
	game_cpak_menu_p->fg_col = l_fg1;
    }

    OPEN_DISP(graph);
    
    /*
     * セグメントアドレス設定
     */
    gSPSegment(NEXT_DISP, 0, 0x0);	/* Physical address segment */

    /*
     * ディスプレイリスト初期設定
     */
    DisplayList_initialize(graph, 0, 0, 0, NULL);

    /*
     * ビュワー設定
     */ 
    gDPPipeSync(NEXT_DISP);
//    view_set_ScissorBox(&(game_cpak_menu_p->view), 0, 0, SCREEN_WD, SCREEN_HT);

    view_setup_view(&(game_cpak_menu_p->view));

    rect_moji(graph);
    gfxprint = (gfxprint_t *)alloca(sizeof(gfxprint_t));
    Gfxprint_init();
    Gfxprint_open(NOW_DISP);
    {
	mCPM_SelectMode( game_cpak_menu_p, gfxprint, pak_info_p );
    }    
    SET_NOW_DISP(Gfxprint_close());
    Gfxprint_cleanup();
    CLOSE_DISP(graph);
}

/*
  ▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△
  
  ■ コントローラパック初期化関数
 */
static int mCPM_MenuWorkInit( mCPk_pkinfo_c *pak, int idx ){
    
    OSMesgQueue	*Q;
    sCPk_pkf_c		*pakFile = &(pak->pakFile);
    int		rtn_err = 0;
    int		err;

    
    /** パックファイルハンドルの初期化   */
    err = mCPk_PakOpen( pak, idx );
    if( !err ){
	return 0;
    }
    /** シリアルメッセージキューの権利取得 */
    Q = padmgr_LockSerialMesgQ( );
    /* Get number of files */
    if( !mCPk_NoteNum( pak )){
	return 0;
    }
    /* Get file status */
    mCPk_AllFileState( pak );
    /* Get free memory */
    mCPk_FreeBlockNum( pak );
    /** シリアルメッセージキューの権利解放 */
    padmgr_UnlockSerialMesgQ( Q );
    if( pakFile->error = 0 ){
	return 0;
    }

    return rtn_err;
	
}

/*
  △▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽

  ■ メニュー初期化処理関数
 */
static void cpak_menu_move_init( GAME_CPAK_MENU *this ){

    mCPk_pkinfo_c	*pak_info_p = mCPk_get_pkinfo( );

    mCPM_MenuWorkInit( pak_info_p, 0 );
    this->menu_move_func = cpak_menu_move;
}


/*
  △▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽

  ■ GAME_CPAKのメイン処理関数
 */
static void cpak_menu_main( GAME *game_p ){
    
    GAME_CPAK_MENU *game_cpak_menu_p = (GAME_CPAK_MENU *)game_p;

    game_cpak_menu_p->menu_move_func( game_cpak_menu_p );

    if( game_cpak_menu_p->mode_chg_ret == mCPM_QUIT_MODE ){
//	game_goto_next_game_name(game_p, title, TITLE);
	game_goto_next_game_name(game_p, trademark, TITLE);
    }

    {
	GRAPH	*graph = game_p->graph;

	game_debug_draw_last(game_p, graph);
	game_draw_last(graph);
    }
}


/*
  △▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽

  ■ GAME_CPAKの後始末処理関数
 */
extern void cpak_menu_cleanup( GAME *game_p ){    
    (void)game_p;
}


/*
  △▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽△▽

  ■ GAME_CPAKの初期化処理関数
 */
extern void cpak_menu_init( GAME *game_p ){
    
    GAME_CPAK_MENU 	*game_cpak_menu_p = (GAME_CPAK_MENU *)game_p;
    
    /*
     * 関数ポインタ初期化
     */
    game_p->exec = cpak_menu_main;
    game_p->cleanup = cpak_menu_cleanup;

    game_cpak_menu_p->mode = 0;
    game_cpak_menu_p->save_mode = 0;
    game_cpak_menu_p->mode_chg_ret = 0;
    game_cpak_menu_p->target = mCPk_MAX_FILE_NUM;
    game_cpak_menu_p->save_target = mCPk_MAX_FILE_NUM;
    game_cpak_menu_p->screen_type = STYPE_MENU;
    game_cpak_menu_p->flash_cnt = 0;
    game_cpak_menu_p->menu_move_func = cpak_menu_move_init;
    game_cpak_menu_p->fg_col = l_fg1;

    view_init(&game_cpak_menu_p->view, game_p->graph);
//    game_cpak_menu_p->view.setflag = VIEW_DO_ORTHO | VIEW_DO_SCISSOR;
    game_cpak_menu_p->view.setflag = VIEW_DO_ORTHO;
    SetGameFrame(1);
}
#endif
