/*
 ******************************************************************************
 *
 *	シーン設定
 *	$Id: m_scene.h,v 1.1 2003/06/06 00:15:12 tong Exp $
 ******************************************************************************
 */
#ifndef INCLUDE_M_SCENE_H
#define INCLUDE_M_SCENE_H

#ifdef _LANGUAGE_C_PLUS_PLUS
extern "C" {
#endif	/* _LANGUAGE_C_PLUS_PLUS */









#define	GEN_DEBUG	1	/** Flag を変えるときは m_play.cもね */

#include "m_kankyo.h"
#include "m_actor.h"
#include "loadfragment.h"
    

/*-----------------------------------------------------------------------
 *
 *	バンク関連
 *
 *----------------------------------------------------------------------*/

/* 転送バッファサイズ（５８６Ｋ） */
#define	DATA_BANK_BUFFER_SIZE	(589*1024)

/*
 *	ＮＰＣ関係
 */
/* ＮＰＣ登録数 */
#define	NPC_REGIST_MAX		(10)
/* ＮＰＣシェイプバンク登録数 */
#define	NPC_SHAPE_BANK_MAX	(NPC_REGIST_MAX)
/* ＮＰＣシェイプバンクのサイズ（１０ｋ） */
#define	NPC_SHAPE_BANK_SIZE	(10 * 1024)
/* ＮＰＣテクスチャバンク登録数 */
#define	NPC_TEXTURE_BANK_MAX	(NPC_REGIST_MAX)
/* ＮＰＣテクスチャバンクのサイズ（約５.５ｋ） */
#define	NPC_TEXTURE_BANK_SIZE	((5664 + 0x0f) & ~0x0f)
/* ＮＰＣ服のバンク登録数 */
#define	NPC_CLOTH_DATA_MAX	(NPC_REGIST_MAX)
/* ＮＰＣ服テクスチャデータサイズ */
#define	NPC_CLOTH_TEX_DATA_SIZE	((32 * 16 * 1 + 0x0f) & ~0x0f)
/* ＮＰＣ服パレットデータサイズ */
#define	NPC_CLOTH_PAL_DATA_SIZE	((16 * 2 + 0x0f) & ~0x0f)
/* ＮＰＣ服データサイズ */
#define	NPC_CLOTH_DATA_SIZE	(NPC_CLOTH_TEX_DATA_SIZE + NPC_CLOTH_PAL_DATA_SIZE)
/* ＮＰＣアニメデータ登録数 */
#define	NPC_ANIME_DATA_MAX	(NPC_REGIST_MAX * 2)
/* ＮＰＣアニメデータ領域確保数 */
#define	NPC_ANIME_DATA_KEEP	(1)
/* ＮＰＣアニメデータサイズ */
#define	NPC_ANIME_DATA_SIZE	((1024 * 3 + 0x0f) & ~0x0f)
/* 虫バンク数 */
#define	mSn_INSECT_BANK		(1)
/* 手渡しアイテムバンク数 */
#define	mSn_HANDOVERITEM_BANK	(1)
/* エフェクトバンク数 */
#define	mSn_EFFECT_BANK		(6)
/* お天気バンク数 */
#define mSn_WEATHER_BANK	(1)
/* 家具バンク数 */
#define mSn_FTR_BANK		(1)
/* 建築物バンク */
#define	aSTR_DATA_KEEP		(1)

/*
 *	バンクナンバーなど
 */
enum {
    /* 常駐バンク */
    KEEP_BANK_ID,			/* 常駐バンク */
    PLAYER_BANK_ID,			/* プレイヤーバンク */
    /* 常駐バンク(サブメニュー面でもプレーヤー表示) */
    PLAYER_ANIME0_BANK_ID,		/* プレイヤーアニメバンク */
    PLAYER_ANIME1_BANK_ID,		/* プレイヤーアニメバンク */
    PLAYER_TEX0_BANK_ID,		/* プレイヤーテクスチャバンク０ */
    PLAYER_PALLET0_BANK_ID,		/* プレイヤーパレットバンク０ */
    PLAYER_TEX1_BANK_ID,		/* プレイヤーテクスチャバンク１ */
    PLAYER_PALLET1_BANK_ID,		/* プレイヤーパレットバンク１ */
    PLAYER_ITEM0_BANK_ID,		/* プレイヤーパレットバンク０ */
    PLAYER_ITEM1_BANK_ID,		/* プレイヤーパレットバンク１ */
    PLAYER_FACE_BANK_ID,		/* プレイヤー顔データバンク */
    /* 常駐バンク(ゲーム中は番地表示に サブメニューではウインドウに使用) */
    MENU_TEX0_BANK_ID,			/* サブメニューテクスチャバンク０ */
    MENU_PALLET0_BANK_ID,		/* サブメニューパレットバンク０ */
    MENU_TEX1_BANK_ID,			/* サブメニューテクスチャバンク１ */
    MENU_PALLET1_BANK_ID,		/* サブメニューパレットバンク１ */
    /* 常駐バンク（ＢＧアイテム用） */
    ITEM_BANK_ID,			/* アイテムバンク */

    /* 常駐最大バンク数 */
    KEEP_DATA_BANK_MAX,

    /* データバンク数 */
    DATA_BANK_MAX = KEEP_DATA_BANK_MAX + NPC_SHAPE_BANK_MAX + NPC_TEXTURE_BANK_MAX + NPC_CLOTH_DATA_MAX + NPC_ANIME_DATA_KEEP + aSTR_DATA_KEEP + mSn_INSECT_BANK + mSn_HANDOVERITEM_BANK + mSn_EFFECT_BANK + mSn_WEATHER_BANK + 16

};

enum {
    mSc_DMA_TRANS_STOP_e,	/* ＤＭＡ転送していない	*/
    mSc_DMA_TRANS_READY_e,	/* ＤＭＡ転送準備中	*/
    mSc_DMA_TRANS_NOW_e,	/* ＤＭＡ転送中		*/
    mSc_DMA_TRANS_LOCK_e	/* ＤＭＡ転送させない	*/
};

/* データバンクバッファのブロック数 */
#define DATA_BANK_BUFFER_BLOCK_SUM	2

typedef struct {
    Object_Bank	bank;		/* 負数は読み込み中 */
    MemPtr	ram_start;	/* セグメントアドレス */
    MemPtr	trans_start;	/* 転送先アドレス */
    u32		rom_start;	/* ＲＯＭ開始アドレス */
    size_t	size;		/* データサイズ */
    dma_t	dma;
    OSMesgQueue	mq;
    OSMesg	m;
    short	use;		/* 使用アクター数 */
    unchar	trans_blk;	/* 転送ブロック */
    unchar	trans;		/* 転送フラグ */

} Data_Bank_Status_c;


struct Object_Exchange_s {
    /*
     *	状態テーブル
     */
    /* データバンク状態テーブル */
    Data_Bank_Status_c	status[DATA_BANK_MAX];
    /* 次のＩＤ */
    int			next_ID;
    /* 入れ替え常駐先頭ＩＤ */
    int			exchange_keep_ID;
    /* 入れ替え先頭ＩＤ */
    int			exchange_ID;

    /*
     *	転送先ＲＡＭ
     */
    /* 次のアドレス */
    MemPtr		nextAdrs;
    /* 最終アドレス */
    MemPtr		endAdrs;
    /* 先頭アドレステーブル */
    MemPtr		startAdrsTbl[DATA_BANK_BUFFER_BLOCK_SUM];
    /* 最終アドレステーブル */
    MemPtr		endAdrsTbl[DATA_BANK_BUFFER_BLOCK_SUM];
    /* サブメニューアドレス */
    MemPtr		submenuStartAdrs;
    /* スイッチ */
    int			active_sw;
    /* スイッチ要求 */
    int			switch_request;

};


/*
 ******************************************************************************
 *	ＤＭＡ転送（ＦＧ）
 ******************************************************************************
 */
#if DEBUG
extern void	mSc_dmacopy_fg(
    u32		ram_start,
    u32		ram_end,
    u32		rom_start,
    size_t	dma_size,
    size_t	keep_size,
    Object_Bank	bank
    );
#endif	/* DEBUG */

/*
 ******************************************************************************
 *	常駐バンクＤＭＡ転送（ＦＧ）
 ******************************************************************************
 */
extern int	mSc_dmacopy_keep_bank_fg(
    Object_Exchange *ex_p,
    Object_Bank	    bank		/* バンクのＩＤ（実はshort型） */
    );

/*
 ******************************************************************************
 *	ＤＭＡ転送なし（領域確保のみ）
 *		入れ替え領域取得前のみ有効
 *		常駐領域の次に行う
 ******************************************************************************
 */
extern MemPtr	mSc_secure_exchange_keep_bank(
    Object_Exchange		*ex_p,
    Object_Bank	    		bank,
    size_t			size
    );

/*
 ******************************************************************************
 *	データバンク転送チェック
 *		ここで シーン中のオブジェクトを転送している
 *		常駐以外は転送できる
 ******************************************************************************
 */
extern void	mSc_dmacopy_data_bank(
    Object_Exchange	*ex_p
    );

/*
 ******************************************************************************
 *	データバンク状態テーブル登録インデックス取得
 ******************************************************************************
 */
/* 転送中 もしくは 転送完了 なら 転送バンク配列のインデックスを返す */
extern int	mSc_bank_regist_check(
    Object_Exchange	*ex_p,
    Object_Bank		bank
    );

/*
 ******************************************************************************
 *	データバンク転送中チェック
 ******************************************************************************
 */
/* 転送が既に終了していれば "TRUE" を返す */
#define	mSc_dma_end_check(e,id)		((int)((e)->status[id].bank > 0))

/*
 ******************************************************************************
 *	データバンク（入れ替え）の状態テーブル設定
 *		必ず常駐と入れ替え常駐の後
 ******************************************************************************
 */
extern int	mSc_regist_exchange_bank(
    Object_Exchange	*ex_p,
    Object_Bank	    	bank
    );

/*
 ******************************************************************************
 *	シーン登録データバンクの転送設定
 ******************************************************************************
 */
extern void	mSc_regist_initial_exchange_bank(
    GAME_PLAY	*game_play
    );

/*
 ******************************************************************************
 *	セグメント設定
 ******************************************************************************
 */
#define	mSc_set_exchange_segment(g,id)	SetSegmentK0(GAMEPLAY_OBJECT_EXCHANGE_SEGMENT, (g)->object_exchange.status[id].ram_start)

/*
 ******************************************************************************
 *	ステータスのポインター取得
 ******************************************************************************
 */
#define	mSc_getP_Data_Bank_Status(e,id)		((e)->status + id)

/*
 ******************************************************************************
 *	セグメントのポインター取得
 ******************************************************************************
 */
#define	mSc_getP_Data_Bank_Status_Segment(e,id)		(mSc_getP_Data_Bank_Status(e,id)->ram_start)

/*
 ******************************************************************************
 *	入れ替え及び入れ替え常駐データバンク全読み込み＆詰め込み
 ******************************************************************************
 */
/*
 *
 *
 *	この関数はm_submenu.cからしか呼ばれていません
 *	そのため本来の機能とは違うカスタマイズが施されています
 *
 *	本来なら全てのキープエリアも含めたバンクバッファ全てを再設定しますが
 *	カスタマイズによりキープバンクおよびプレイヤーバンクを除く
 *	入れ替えバンクのみを再設定するようになってます
 *
 *
 */
extern void	mSc_dmacopy_all_exchange_bank(
    Object_Exchange	*ex_p
    );

/*
 ******************************************************************************
 *	データバンクコンストラクト
 ******************************************************************************
 */
extern void	mSc_data_bank_ct(
    GAME		*game,
    Object_Exchange	*ex_p
    );

/*
 ******************************************************************************
 *	入れ替えデータバンクの大きさ決定
 ******************************************************************************
 */
extern void	mSc_decide_exchange_bank(
    Object_Exchange	*ex_p
    );

/*-----------------------------------------------------------------------
 *
 *	シーンＮｏ
 *
 *----------------------------------------------------------------------*/
typedef	int	Scene_No;

/*-----------------------------------------------------------------------
 *
 *	ドアデータ
 *
 *----------------------------------------------------------------------*/
enum {
    DOOR_DRT_0_e,	/* 手前		*/
    DOOR_DRT_1_e,	/* 手前右	*/
    DOOR_DRT_2_e,	/* 右		*/
    DOOR_DRT_3_e,	/* 奥右		*/
    DOOR_DRT_4_e,	/* 奥		*/
    DOOR_DRT_5_e,	/* 奥左		*/
    DOOR_DRT_6_e,	/* 左		*/
    DOOR_DRT_7_e,	/* 手前左	*/

    DOOR_ALL_DRT
};

typedef struct {
    Scene_No	next_scene_no;	/* 移動先のシーンNo. */
    unchar	drt;		/* 移動先でのプレイヤーの向き */
    unchar	restart;	/* リスタートフラグ */
    unshort	arg_data;	/* 移動先でのプレイヤーのarg_data */
    s_xyz	startPos;	/* 移動先のプレイヤー出現座標 */
    mAc_nfs_t	door_name;	/* ドアのＦＧ名 */
    u8		wipe_type;	/* ワイプタイプ */
    unchar	pad_c;
    unshort	pad_s;

} Door_data;

typedef struct {
    unchar	num;
    Door_data	*data;

} Door_Info;

/*
 *	ドアデータクラスコンストラクト
 */
extern void Door_info_ct(Door_Info *this);


/*-----------------------------------------------------------------------
 *
 *	シーン設定コード（シーンデータの中で使う）
 *
 *----------------------------------------------------------------------*/
/* "関数 Scene_ct()"の"Scene_Proc[]"の順番と一致しないといけない */
enum {
    SCENE_ID_PLAYER_PTR,		/* プレイヤー発生データ初期化	*/
    SCENE_ID_CTRL_ACTOR_PTR,		/* 制御アクターデータ初期化	*/
    SCENE_ID_ACTOR_PTR,			/* アクターデータ初期化		*/
    SCENE_ID_OBJECT_EXCHANGE_BANK_PTR,	/* 先読みデータバンク初期化	*/
    SCENE_ID_DOOR_DATA_PTR,		/* ＮｅｘｔＧｏｔｏデータ初期化	*/
    SCENE_ID_FIELD_CT,			/* フィールドデータの初期化	*/
    SCENE_ID_MY_ROOM_CT,		/* プレイヤの部屋の初期化 	*/
    SCENE_ID_ARRANGE_ROOM_CT,		/* アレンジルームの初期化	*/
    SCENE_ID_ARRANGE_FURNITURE_CT,	/* アレンジ家具の初期化		*/
    SCENE_ID_SOUND,

    SCENE_ID_END
};

/* プレイヤーデータポインタ */
#define	Scene_ID_Player_Ptr(num, ptr)\
		{SCENE_ID_PLAYER_PTR, num, 0, 0, (unint)ptr}
/* 制御アクターデータポインタ */
#define	Scene_ID_Ctrl_Actor_Ptr(num, ptr)\
		{SCENE_ID_CTRL_ACTOR_PTR, num, 0, 0, (unint)ptr}
/* アクターデータポインタ */
#define	Scene_ID_Actor_Ptr(num, ptr)\
		{SCENE_ID_ACTOR_PTR, num, 0, 0, (unint)ptr}
/* オブジェクトシェイプバンクデータポインタ */
#define	Scene_ID_Object_Exchange_Bank_Ptr(num, ptr)\
		{SCENE_ID_OBJECT_EXCHANGE_BANK_PTR, num, 0, 0, (unint)ptr}
/* ドアデータポインタ */	
#define	Scene_ID_Door_Data_Ptr(num, ptr)\
		{SCENE_ID_DOOR_DATA_PTR, num, 0, 0, (unint)ptr}
/*
 *	サウンドメモリーモード，ＢＧＭ
 *	field_type	0 → プレーヤーの部屋以外
 *			1 → プレーヤーの部屋
 */
#define	Scene_ID_Sound(mode, field_type, BGM, env)\
		{SCENE_ID_SOUND, mode, field_type, 0, (unint)((env<<8)|BGM)}
/* フィールドデータ初期化 */
#define	Scene_ID_Field_Ct(data1, bg_num, data3)\
		{SCENE_ID_FIELD_CT, data1, bg_num, 0, (unint)data3}

/* 部屋の壁紙,じゅうたんバンク確保（ダブル）--- プレイヤの部屋用  */
#define Scene_ID_MyRoom_Ct() \
		{SCENE_ID_MY_ROOM_CT, 0, 0, 0, 0}
/* アレンジルーム 壁紙,じゅうたんの確保 */
#define Scene_ID_ArrangeRoom_Ct() \
		{SCENE_ID_ARRANGE_ROOM_CT, 0, 0, 0, 0}
/* 指定した数だけ家具専用のバンクを確保 */
#define Scene_ID_Furniture_Ct(ftr) \
		{SCENE_ID_ARRANGE_FURNITURE_CT, ftr, 0, 0, 0}
/* データＥＮＤ */
#define	Scene_ID_End()\
		{SCENE_ID_END, 0, 0, 0, 0}



/*-----------------------------------------------------------------------
 *
 *	シーン設定データ
 *
 *----------------------------------------------------------------------*/
typedef struct {
    unchar	code;	/* 制御コード */
    unchar	data1;	/* データ */
    unchar	pad0;
    unchar	pad1;
    unint	data2;	/* データ */
} Scene_Word_Base;
typedef struct {
    unchar	code;	/* 制御コード */
    unchar	num;	/* セット数 */
    unchar	pad0;
    unchar	pad1;
    short	*data;	/* ポインタ */
} Scene_Word_Ctrl_Actor;
typedef struct {
    unchar	code;	/* 制御コード */
    unchar	num;	/* セット数 */
    unchar	pad0;
    unchar	pad1;
    Actor_data	*data;	/* ポインタ */
} Scene_Word_Actor;
typedef struct {
    unchar	code;	/* 制御コード */
    unchar	num;	/* セット数 */
    unchar	pad0;
    unchar	pad1;
    Object_Bank	*data;	/* ポインタ */
} Scene_Word_Object_Bank;
typedef struct {
    unchar	code;	/* 制御コード */
    unchar	num;	/* セット数 */
    unchar	pad0;
    unchar	pad1;
    Door_data	*data;	/* ポインタ */
} Scene_Word_Door;
typedef struct {
    unchar	code;		/* 制御コード */
    unchar	mode;		/* メモリーモード */
    unchar	field_type;	/* フィールドタイプ 0 : 外 / !0 : 内 */
    unchar	pad1;
    unchar	pad2;
    unchar	pad3;
    unchar	pad4;
    unchar	pad5;
} Scene_Word_Sound;
typedef struct {
    unchar	code;		/* 制御コード */
    unchar	item;		/* アイテム情報タイプ */
    unchar	bg_num;		/* BG領域数 */
    unchar	pad1;
    unshort	bg_size;	/* BGサイズ */
    unchar	type;		/* フィールドタイプ */
    unchar	draw;		/* フィールド描画タイプ */
} Scene_Word_Field;

union SCENE_WORD {
    Scene_Word_Base		base;
    Scene_Word_Ctrl_Actor	ctrl_actor;
    Scene_Word_Actor		actor;
    Scene_Word_Object_Bank	object_bank;
    Scene_Word_Door		door;
    Scene_Word_Sound		sound;
    Scene_Word_Field		field;
};

/*-----------------------------------------------------------------------
 *
 *	シーンコンストラクト
 *
 *----------------------------------------------------------------------*/
extern void Scene_ct(GAME_PLAY *game_play, Scene_Word *scene_info);

/*-----------------------------------------------------------------------
 *
 *	シーン移行準備処理
 *
 *----------------------------------------------------------------------*/
extern int	goto_other_scene(GAME_PLAY *game_play, Door_data *data, int player_change_mode);
extern int	goto_next_scene(GAME_PLAY *game_play, int door_no, int player_change_mode);
extern int	goto_emu_game(GAME *game, short cassette_no);
extern void	return_emu_game(GAME *game);

/*
*******************************************************
*  家具のバンク設定ヘッダ miyake
*******************************************************
*/
#include "m_scene_ftr.h"

#if DEBUG
extern void	mSc_debug_print(Object_Exchange *);
#endif	/* DEBUG */



#ifdef _LANGUAGE_C_PLUS_PLUS
} /* extern "C" */
#endif	/* _LANGUAGE_C_PLUS_PLUS */

#endif	/* INCLUDE_M_SCENE_H*/

/*** m_scene.h end ***/
