/*
 * $Id: m_msg.c,v 1.1 2003/06/06 00:15:12 tong Exp $
 *              
 *      メッセージ表示のライブラリーファイル
 *
 * $Log: m_msg.c,v $
 * Revision 1.1  2003/06/06 00:15:12  tong
 * source files for localization from Nintendo.
 *
 * Revision 1.127  2001-01-27 20:02:35+09  sakakibara
 * アイテム受け渡し 開始、終了 命令追加。
 *
 * Revision 1.126  2001-01-05 21:23:15+09  sakakibara
 * *** empty log message ***
 *
 * Revision 1.125  2001-01-05 19:20:15+09  sakakibara
 * *** empty log message ***
 *
 * Revision 1.124  2000-12-28 21:20:15+09  sakakibara
 * *** empty log message ***
 *
 * Revision 1.123  2000-12-27 20:39:56+09  sakakibara
 * デバッグ集
 *
 * Revision 1.122  2000-12-15 22:42:21+09  sakakibara
 * Revision 1.121  2000-12-14 15:57:56+09  sakakibara
 * fdebug の 「Message」という文字を消した。
 *
 * Revision 1.120  2000-11-18 15:17:57+09  sakakibara
 * Revision 1.119  2000-11-18 01:21:43+09  sakakibara
 * Revision 1.118  2000-11-14 22:15:38+09  sakakibara
 * Revision 1.117  2000-11-13 18:05:17+09  sakakibara
 * (3, 6)
 *
 * Revision 1.116  2000-11-13 17:43:48+09  sakakibara
 * Revision 1.115  2000-11-10 23:56:19+09  sakakibara
 * Revision 1.114  2000-11-09 19:40:18+09  sakakibara
 * Revision 1.113  2000-11-09 13:44:41+09  sakakibara
 * Revision 1.112  2000-11-08 23:41:47+09  sakakibara
 * Revision 1.111  2000-11-07 21:39:42+09  sakakibara
 * Revision 1.110  2000-11-06 23:00:12+09  sakakibara
 * ランダムお手紙チェック
 *
 * Revision 1.109  2000-11-03 14:46:32+09  sakakibara
 * Revision 1.108  2000-11-02 18:35:05+09  sakakibara
 * Revision 1.107  2000-11-02 16:41:26+09  sakakibara
 * Revision 1.106  2000-11-02 16:39:39+09  sakakibara
 * Revision 1.105  2000-11-02 15:59:22+09  sakakibara
 * メッセージ情報画面出力
 *
 * Revision 1.104  2000-10-23 14:23:23+09  komatu
 * Revision 1.103  2000-10-18 16:29:40+09  sakakibara
 * Revision 1.102  2000-10-12 21:18:52+09  sakakibara
 * スペックチェンジ修正
 *
 * Revision 1.101  2000-10-11 20:49:03+09  sakakibara
 * Revision 1.100  2000-09-28 19:45:28+09  sakakibara
 * Spec Change
 */
/*
 * Revision 1.99  2000-09-26 20:22:59+09  sakakibara
 * BGM 処理移行作業。
 *
 * Revision 1.98  2000-09-23 21:15:02+09  sakakibara
 * わ
 *
 * Revision 1.97  2000-09-23 16:33:12+09  sakakibara
 * 手紙チェック
 *
 * Revision 1.96  2000-09-13 20:14:09+09  otsuki
 * Revision 1.95  2000/09/04 07:53:52  sakakibara
 * 処理時間計測
 *
 * Revision 1.94  2000-09-04 15:08:14+09  sakakibara
 * 処理飛ばし
 *
 * Revision 1.93  2000-08-03 17:03:52+09  sakakibara
 * わ
 *
 * Revision 1.92  2000-07-24 16:55:27+09  sakakibara
 * Revision 1.91  2000-07-17 18:06:10+09  sakakibara
 * Revision 1.90  2000-07-11 16:39:05+09  sakakibara
 * ＢＧＭプロセス削除関数の引数変更
 *
 * Revision 1.89  2000-07-10 16:01:13+09  sakakibara
 * レジスタ外し。
 *
 * Revision 1.88  2000-07-10 11:50:43+09  sakakibara
 * ↓ の部分を完全消去
 *
 * Revision 1.87  2000-07-07 17:51:33+09  sakakibara
 * 削除予定関数の抜き出し。
 * (こんなの⇒  ЖЖ  テクスチャ領域確保に関わる関数など  ЖЖ)
 *
 * Revision 1.86  2000-07-07 14:49:19+09  sakakibara
 * Revision 1.85  2000-07-06 17:43:34+09  sakakibara
 * メッセージデータ チェック処理作成
 *
 * Revision 1.84  2000-07-05 17:49:29+09  sakakibara
 * Revision 1.83  2000-07-04 18:12:31+09  sakakibara
 * Revision 1.82  2000-07-03 17:06:28+09  sakakibara
 * char * から unchar * へ
 *
 * Revision 1.81  2000-06-29 21:01:17+09  sakakibara
 * Revision 1.80  2000-06-29 17:11:04+09  sakakibara
 * Revision 1.79  2000-06-27 18:35:12+09  sakakibara
 * Revision 1.78  2000-06-19 14:47:12+09  sakakibara
 * Revision 1.77  2000-06-14 22:51:52+09  komatu
 * Revision 1.76  2000-06-14 13:38:54+09  sakakibara
 * コモンデータヘッダをインクルードした。
 *
 * Revision 1.75  2000-06-13 16:15:23+09  sakakibara
 * Revision 1.74  2000-06-12 20:32:21+09  sakakibara
 * Revision 1.73  2000-06-12 19:51:49+09  sakakibara
 * Revision 1.72  2000-06-09 21:30:35+09  sakakibara
 * Revision 1.71  2000-06-06 21:23:17+09  sakakibara
 * Revision 1.70  2000-06-06 15:26:09+09  sakakibara
 * ★ 変更色々
 *
 * Revision 1.69  2000-05-27 11:58:06+09  gen
 * Revision 1.68  2000-05-27 11:49:51+09  gen
 * Revision 1.67  2000-05-26 21:57:11+09  sakakibara
 * Revision 1.66  2000-05-25 15:19:10+09  sakakibara
 * Revision 1.65  2000-05-19 20:58:02+09  sakakibara
 * Revision 1.64  2000-05-17 18:45:49+09  sakakibara
 * Revision 1.63  2000-05-15 18:24:02+09  sakakibara
 * Revision 1.62  2000-05-10 16:07:09+09  sakakibara
 */
#include "m_basic.h"
#include "assert64.h"
#include "gfxprint.h"		/* gfxprint_t	*/
#include "gfxalloc.h"
#include "m_npc.h"
#include "m_actor.h"		/*  */
#include "loadfragment.h"	/*  */
#include "ac_npc_h1.h"		/*  */
#include "m_demo.h"
#include "m_choice.h"
#include "m_msg.h"
#include "m_msg_data.h"
#include "m_common_data.h"
#include "m_land.h"
#include "m_name_table.h"
#include "m_string.h"
#include "m_handbill.h"
#include "audio.h"
#include "m_bgm.h"
#include "m_field_info.h"
#include "field_Name.h"
#include "ac_handOverItem.h"	/* aHOI_CLIP_P, aHOI_MASTER_ACTOR_P */

/* メッセージデータのセグメント */
#ifdef MSG_TOOL
#define _UC_object_msg_tableSegmentRomStart	0x2a00000
#define _UC_object_msgSegmentRomStart		0x2b00000
#define _UC_object_msgSegmentRomEnd		0x2e00000
#else
EXTERN_DEFSEG_DATA(UC_object_msg_table);
EXTERN_DEFSEG_DATA(UC_object_msg);
#endif

/*
 ******************************************************************************
 *	マクロ宣言
 ******************************************************************************
 */
#define M_MSG_TIME_APPEAR	(0.3F*M_SPD_1SEC_FRAME_F)
#define M_MSG_TIME_DISAPPEAR	(0.3F*M_SPD_1SEC_FRAME_F)
//#define M_MSG_TIME_NEXT_PAGE	(((10.0F + (float)kREG(77))/30.0F)*M_SPD_1SEC_FRAME_F)
#define M_MSG_TIME_NEXT_PAGE	((10.0F/30.0F)*M_SPD_1SEC_FRAME_F)

/*
 ******************************************************************************
 *	典型的な関数の型
 ******************************************************************************
 */
typedef void (*M_MSG_PROC1)(M_MSG_WIN *, GAME *);
typedef int (*M_MSG_PROC2)(M_MSG_WIN *, int *);
typedef int (*M_MSG_PROC3)(unchar *, int *);
typedef void (*M_MSG_PROC4)(M_MSG_WIN *, int);

/*
 ******************************************************************************
 *	プロトタイプ宣言
 ******************************************************************************
 */
static void mMsg_MainSetup_Window(M_MSG_WIN *win_p, GAME *game_p);

/*
 ******************************************************************************
 *	領域確保
 ******************************************************************************
 */
static M_MSG_DATA	mMsg_data[1];
static M_MSG_WIN	mMsg_window[1];

/*
 ***************************************************************
 *	ソースファイルのインクルード
 ***************************************************************
 */
/* ロムのアドレスを調べるためのダミー変数配列 */
//#include "m_msg_array_dummy_start.c"
//#include "m_msg_array_dummy_end.c"

/*************ウインドウの制御の処理*************/
#include "m_msg_control.c"

/*************ウインドウのサウンド処理プロトタイプ宣言*************/
static void mMsg_sound_MessageSpeedForce(float timer);
static void mMsg_sound_MessageStatus(u8 status);

/*************ウインドウのメインの処理*************/
#include "m_msg_main.c"
#include "m_msg_sound.c"
#include "m_msg_main_hide.c"
#include "m_msg_main_appear.c"
#include "m_msg_main_normal.c"
#include "m_msg_main_cursol.c"
#include "m_msg_main_disappear.c"
#include "m_msg_main_appear_wait.c"
#include "m_msg_main_wait.c"
#include "m_msg_main_disappear_wait.c"

/*************ウインドウの描画データ******************/
#include "m_msg_draw_data.c"

/*************ウインドウ枠の描画******************/
#include "m_msg_draw_window.c"

/*************ウインドウ文字の描画******************/
#include "m_msg_draw_font.c"

/**** メッセージデバッグ集 ****/
#if DEBUG
#include "m_msg_debug.c_inc"
#endif

/*
 ******************************************************************************
 *	個々のメッセージウインドウのメインのセットアップ
 ******************************************************************************
 */
static void mMsg_MainSetup_Window(M_MSG_WIN *win_p, GAME *game_p)
{
    static M_MSG_PROC1 proc[TOTAL_M_MSG_MAIN_INDEX] = {
	mMsg_MainSetup_Hide,		/* (0)隠れ */
	mMsg_MainSetup_Appear,		/* (1)出現 */
	mMsg_MainSetup_Normal,		/* (2)通常 */
	mMsg_MainSetup_Cursol,		/* (3)カーソル表示 */
	mMsg_MainSetup_Disappear,	/* (4)消滅 */
	mMsg_MainSetup_Appear_wait,	/* (5)出現(待機から) */
	mMsg_MainSetup_Wait,		/* (6)待機 */
	mMsg_MainSetup_Disappear_wait,	/* (7)消滅(待機へ) */
    };

    int index = win_p->request_main_index;
    
    if(0 <= index) {
	if(!((index < TOTAL_M_MSG_MAIN_INDEX) && (proc[index] != NULL))) {
#if DEBUG
	    PRINTF(ESC_ERROR
		   "mMsg_MainSetup_Window:変更要求メイン処理のインデックスがおかしい!!!!!!!!\n"
		   ESC_NORMAL);
#endif	
	    return;
	}
	(proc[index])(win_p, game_p);
    }
}

/*
 ******************************************************************************
 *	個々のメッセージウインドウのメインの処理
 ******************************************************************************
 */
static void mMsg_Main_Window(M_MSG_WIN *win_p, GAME *game_p)
{
    static M_MSG_PROC1 proc[TOTAL_M_MSG_MAIN_INDEX] = {
	mMsg_Main_Hide,			/* 隠れ */
//	mMsg_Main_Prepare,		/* 準備 */
	mMsg_Main_Appear,		/* 出現 */
	mMsg_Main_Normal,		/* 通常 */
	mMsg_Main_Cursol,		/* カーソル表示 */
	mMsg_Main_Disappear,		/* 消滅 */
	mMsg_Main_Appear_wait,		/* 出現(待機から) */
	mMsg_Main_Wait,			/* 待機 */
	mMsg_Main_Disappear_wait,	/* 消滅(待機へ) */
    };
    int index = win_p->main_index;
    
    if(!((0 <= index) && (index < TOTAL_M_MSG_MAIN_INDEX) && (proc[index] != NULL))) {
#if DEBUG
	PRINTF(ESC_ERROR
	       "mMsg_Main_Window:メイン処理のインデックスがおかしい!!!!!!!!\n"
	       ESC_NORMAL);
#endif	
	return;
    }
    (proc[index])(win_p, game_p);
}

/*
 ******************************************************************************
 *	個々のメッセージウインドウの描画
 ******************************************************************************
 */
static  void mMsg_Draw_Window(M_MSG_WIN *win_p, GAME *game_p)
{
    if((win_p->flag_draw) && (win_p->able)) {

	/* 文字表示用 マトリックスのセット */
	mFont_SetMatrix(game_p->graph, M_FONT_ENTRY_FONT_DISP);
	/* ウインドウ用 拡大・縮小マトリックスのセット */
	mMsg_SetMatrix(win_p, game_p, M_FONT_ENTRY_FONT_DISP);


	/* ウインドウ枠描画 */
	mMsg_DrawWindowBody(win_p,
			    game_p,
			    M_FONT_ENTRY_FONT_DISP);
	
	/* ウインドウ用 拡大・縮小マトリックスのアンセット */
	mMsg_UnSetMatrix();
	/* 文字表示用 マトリックスのアンセット */
	mFont_UnSetMatrix(game_p->graph, M_FONT_ENTRY_FONT_DISP);
	
	if(win_p->msg_p->able) {
	    /* 文字描画 */
	    mMsg_draw_font(win_p, game_p);
	}
	
        /* 選択ウインドウの描画 */
	mChoice_Draw(&(win_p->choice_win), game_p, M_FONT_ENTRY_FONT_DISP);
	
#if 0
	if(kREG(13)) {
	    GRAPH *graph_p = game_p->graph;
	    OPEN_DISP(graph_p);
	    gDPPipeSync(NEXT_DISP);
	    gDPSetFillColor(NEXT_DISP, 0x00000000);
	    gDPSetCycleType(NEXT_DISP, G_CYC_FILL);
	    gDPSetRenderMode(NEXT_DISP, G_RM_NOOP, G_RM_NOOP2);
	    gDPFillRectangle(NEXT_DISP, kREG(14), kREG(15), 12*16+kREG(14), 16*4+kREG(15));
	    CLOSE_DISP(graph_p);
	}
#endif
    }
}

/*
 ******************************************************************************
 *	メッセージウインドウのコンストラクト(領域確保時の初期化)
 ******************************************************************************
 */
extern void mMsg_ct(GAME *game_p)
{
    mMsg_init(game_p);
    mChoice_ct(&(mMsg_window[0].choice_win), game_p);
    
#if DEBUG && 0
    COLOR_CYAN();
    PRINTF("\n************  Message Area SIZE    ************\n\n");

    PRINTF("M_MSG_WIN               : %d (%x)\n",
	   sizeof(M_MSG_WIN), sizeof(M_MSG_WIN));
    PRINTF("M_MSG_DATA              : %d (%x)\n",
		     sizeof(M_MSG_DATA), sizeof(M_MSG_DATA));
    PRINTF("M_CHOICE_WIN            : %d (%x)\n",
	   sizeof(M_CHOICE_WIN), sizeof(M_CHOICE_WIN));
    PRINTF("M_MSG_MAIN_DATA         : %d (%x)\n",
	   sizeof(M_MSG_MAIN_DATA), sizeof(M_MSG_MAIN_DATA));
    PRINTF("M_MSG_REQUEST_MAIN_DATA : %d (%x)\n",
	   sizeof(M_MSG_REQUEST_MAIN_DATA), sizeof(M_MSG_REQUEST_MAIN_DATA));
    PRINTF("(ACTOR)                 : %d (%x)\n",
	   sizeof(ACTOR), sizeof(ACTOR));
    
    PRINTF("\n************************************************\n\n");
    COLOR_NORMAL();

#if defined(_LANGUAGE_C_PLUS_PLUS)      /* SGI(MIPS) C++ , not GNU C++ */
    PRINTF("_LANGUAGE_C_PLUS_PLUS\n");
#endif
#if defined(__cplusplus)                /* ANSI C++ */
    PRINTF("__cplusplus\n");
#endif
    PRINTF("(%x %x %x %x)\n",
	   _UC_object_msgSegmentStart,
	   _UC_object_msgSegmentEnd,
	   _UC_object_msgSegmentRomStart,
	   _UC_object_msgSegmentRomEnd
	   );
#endif
}

#if 0
/*
 ******************************************************************************
 *	メッセージウインドウの後始末
 ******************************************************************************
 */
extern void mMsg_clean(GAME *game_p)
{
    (void)game_p;
}
#endif

/*
 ******************************************************************************
 *	メッセージウインドウのデストラクト(領域解放時の初期化)
 ******************************************************************************
 */
extern void mMsg_dt(GAME *game_p)
{
    mChoice_dt(&(mMsg_window[0].choice_win), game_p);
}




#if 0
/*
 ******************************************************************************
 *	メッセージウインドウの制御処理おおもと
 ******************************************************************************
 */
extern void mMsg_Control(GAME *game_p)
{
    (void)game_p;
}
#endif

#ifdef FDEBUG
/*
 *
 *	メッセージ情報画面出力
 *
 */
extern void mMsg_debug_draw(gfxprint_t *gfxprint)
{
    if (mMsg_window[0].msg_p != NULL) {
	Gfxprint_color(245, 255, 250, 255);		/* (MintCream) */
	Gfxprint_locate8x8(3, 6);
	Gfxprint_printf1("%5d", mMsg_window[0].msg_p->num);
    }
}
#endif

#if DEBUG && 0
static void mMsg_debug_draw_test(void)
{
    GRAPH *graph = getP_game()->graph;
    gfxprint_t gfxprintx, *gfxprint = &gfxprintx;
    Gfx	*gp_opa;
    Gfx	*gp_ovl;
    
    Gfxprint_init();
    OPEN_DISP(graph);
    
    gp_opa = NOW_DISP;
    gp_ovl = gfxopen(gp_opa);
    
    gSPDisplayList(NEXT_OVERLAY_DISP, gp_ovl);
    
    Gfxprint_open(gp_ovl);
    
    mMsg_debug_draw(gfxprint);
    
    gp_ovl = Gfxprint_close();
    
    gSPEndDisplayList(gp_ovl++);
    gfxclose(gp_opa, gp_ovl);
    
    SET_NOW_DISP(gp_ovl);
    CLOSE_DISP(graph);
    Gfxprint_cleanup();
}
#endif


/*
 ******************************************************************************
 *	メッセージウインドウのメインの処理おおもと
 ******************************************************************************
 */
extern void mMsg_Main(GAME *game_p)
{
#if DEBUG
    mMsg_DEBUG_Main_before(game_p);
#endif
    
    mMsg_Main_Window(&(mMsg_window[0]), game_p);
    mChoice_Main(&(mMsg_window[0].choice_win), game_p);
    
#if DEBUG
    mMsg_DEBUG_Main_after(game_p);
#endif
}

/*
 ******************************************************************************
 *	メッセージウインドウの描画おおもと
 ******************************************************************************
 */
extern void mMsg_Draw(GAME *game_p)
{
#if DEBUG
    if ((mREG(7) == 10) || (mREG(7) == 100)) {
	return;	/**** Ｄｒａｗ 処理飛ばし ！！ ****/
    }
    mMsg_DEBUG_Draw_before(game_p);
#endif
    
    mMsg_Draw_Window(&(mMsg_window[0]), game_p);
    
#if DEBUG
    mMsg_DEBUG_Draw_after(game_p);
    
    /* mMsg_debug_draw_test(); */
#endif
}
