//[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
/**
 *	@file		char_manager.h
 *	@brief		キャラクタデータマネージャーヘッダ
 *	@author		tomoya takahashi
 *	@data		2004.11.22
 */
//]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]



#ifndef CHAR_MANAGER_H__
#define	CHAR_MANAGER_H__

#include "nnsys.h"

#undef	GLOBAL
#ifdef	CHAR_MANAGER_H_GLOBAL
#define	GLOBAL	/* */
#else
#define	GLOBAL	extern
#endif

//-----------------------------------------------------------------------------
/**
*		OBJマッピングモードの説明
*
■ＯＢＪマッピングモードについての説明
	ＯＡＭアトリビュートの先頭キャラクタネームのレジスタは10bitで、0~1023の値を入れることが出来ます。
	これで、先頭から32KByteまでに入ったキャラクタデータは参照出来ます。

	しかしＤＳでは、スプライトのキャラクタデータに16KByte~256KByte指定できます。
	16Kbyte 32Kbyteは大丈夫ですが、64KByte~256KByteは先頭から終端までの全てのキャラクタデータを
	０〜１０２３では参照することが出来なくなってしまいます。

	それを回避するために、ＯＢＪマッピングモードで、キャラクタ境界を指定します。
	例）OBJマッピングモード　１２８Ｋb yte　の時
	キャラクタ境界　＝ 　128Byte　＝　４キャラクタ
	４キャラクタずつ先頭キャラクタネームを設定出来ます。
	０		−＞０キャラクタから参照	（レジスタの値　ー＞　実際の参照先のキャラクタナンバー）
	１		−＞４キャラクタから参照
	２		ー＞８キャラクタから参照
	・・・・・・・・・・・・・・・・
	１０２３	ー＞８１８４キャラクタから参照

	これで、０〜１０２３の値で、１２８ＫＢｙｔｅの領域を指定することが出来るようになります。
	その代わりに、１キャラクタサイズのキャラクタデータを使用した時でも、４キャラクタずつ
	Ｖｒａｍに配置していく必要があります。

	上の事から、Vramサイズに合わせて、適切なＯＢＪマッピングモードを設定する必要があります。

*
*	・NitroCharacterでは、上のことを考慮したキャラクタデータを書き出してくれています
*	　ので、セルデータ作成時のOBJマッピングモード設定をしてください。
*	・以下NitroSDKヘルプ
*	GX_OBJVRAMMODE_CHAR_2D	
*		2次元マッピングモードを選択します。 
*		
*	GX_OBJVRAMMODE_CHAR_1D_32K
*		１次元マッピングモードで、先頭キャラクタ境界を32バイトとします。
*		利用可能なOBJ-VRAMの最大容量は32KBになります。 
*		
*	 GX_OBJVRAMMODE_CHAR_1D_64K
*		１次元マッピングモードで、先頭キャラクタ境界を64バイトとします。
*		利用可能なOBJ-VRAMの最大容量は64KBになります。 
*		
*	 GX_OBJVRAMMODE_CHAR_1D_128K
*		１次元マッピングモードで、先頭キャラクタ境界を128バイトとします。
*		利用可能なOBJ-VRAMの最大容量は128KBになります。 
*		
*	 GX_OBJVRAMMODE_CHAR_1D_256K
*		１次元マッピングモードで、先頭キャラクタ境界を256バイトとします。
*		利用可能なOBJ-VRAMの最大容量は256KBになります。 
*
*
*	２つのVram管理方法について
*	
*	■CharSet-CharSetsの動作
*		Vramの先頭からキャラクタデータづつOffsetをずらして
*		転送していきます。DelChar関数を使用しても
*		Offsetを戻すなどの処理が出来ないため、
*		再度使用した領域を使うということが出来ません。
*
*	■CharSetAreaCont-CharSetsAreaContの動作
*		Vramの管理領域を作成して、使用状況を管理します。
*		サイズ分のキャラクタデータを転送する領域が空いているかを
*		チェックしてからキャラクタデータを転送します。
*		DelCharをすると使用領域を空にしますので、
*		領域を再利用することが出来ます。
*/
//-----------------------------------------------------------------------------


//-----------------------------------------------------------------------------
/**
*		定数定義
*/
//-----------------------------------------------------------------------------
// 定数
// キャラクタデータコントロールタイプ
// コントロールタイプ
//		オフセットーーーーー先頭からオフセットをずらして、
//							転送オフセットを求める
//		エリアコントロールーVram領域管理配列から空いている領域をチェックして
//							転送オフセットを求める
enum{
	CHARM_CONT_OFFSET,		// オフセットタイプ
	CHARM_CONT_AREACONT,	// エリアコントロールタイプ
};

//----------------------------------------------------------------------------
/**
 *					構造体宣言
 */
//-----------------------------------------------------------------------------
//-------------------------------------
//	
//	キャラクタマネージャー作成
//	構造体
//	
//=====================================
typedef struct {
	int CharDataNum;		// キャラクタ制御数
	int VramTransAreaMain;	// メイン画面のAreaCont用に用意するVramサイズ
	int VramTransAreaSub;	// サブ画面のAreaCont用に用意するVramサイズ
	int heap;				// 使用するヒープ
} CHAR_MANAGER_MAKE;


//-------------------------------------
//	
//	キャラクタデータヘッダー
//	
//=====================================
typedef struct {
	NNSG2dCharacterData*	res_file;		// キャラクタリソース
	u32		type;			// 登録タイプ
							// mainに登録：NNS_G2D_VRAM_TYPE_2DMAIN
							// subに登録 ：NNS_G2D_VRAM_TYPE_2DSUB
							// 両方に登録：NNS_G2D_VRAM_TYPE_2DMAX
	u32		id;				// このキャラクタデータのID

	u32		cont_type;		// Vramコントロールタイプ
							// CHARM_CONT_OFFSET	オフセットタイプ
							// CHARM_CONT_AREACONT	エリアコントロールタイプ
} CHAR_MANAGER_HEADER;

//-------------------------------------
//	
//	キャラクタ転送をこのシステムを
//	使用しないときにVRAMの領域のみ確保する
//	システムの確保領域データ
//	
//=====================================
typedef struct {
	u32 alloc_size;
	u32 alloc_ofs;
	u32	type;		// Vram確保した表示面
	// mainに登録：NNS_G2D_VRAM_TYPE_2DMAIN = 1
	// subに登録 ：NNS_G2D_VRAM_TYPE_2DSUB = 2
} CHAR_MANAGER_ALLOCDATA;


//----------------------------------------------------------------------------
/**
 *					プロトタイプ宣言
 */
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
/**
 *	【キャラクタマネージャ初期化の動作】		
 *	typedef struct {
 *		int CharDataNum;		// キャラクタ制御数
 *		int VramTransAreaMain;	// メイン画面のAreaCont用に用意するVramサイズ
 *		int VramTransAreaSub;	// サブ画面のAreaCont用に用意するVramサイズ
 *		int heap;				// 使用するヒープ
 *	} CHAR_MANAGER_MAKE;
 *	
 *	上のデータで初期化します。
 *	CharDataNum			登録するキャラクタの数を渡してください。
 *						CharDataNum分のワークを作成します。
 *
 *	VramTransAreaMain	AreaCont関数で使用するVram管理領域サイズです。
 *	VramTransAreaSub	このサイズ分を管理します。
 *	
 *	heap				使用するヒープID
 *
 *
 *	このデータで初期化されるVram管理状態
 *		もし、Vramの最大が0x20000でVramTransAreaMainに0x10000
 *		を設定したときは、以下のような管理状態になります。
 *		Vram領域
 *		offset
 *		0x00000000
 *					オフセットづらし用領域		CharSet CharSets
 *		0x00010000
 *					AreaCont用領域		CharSetAreaCont CharSetsAreaCont
 *		0x00020000
 */
//-----------------------------------------------------------------------------

//----------------------------------------------------------------------------
/**
 *
 *@brief	  キャラクタマネージャーを初期化
 
 *@param	CharMakeData	キャラクタマネージャー作成データ
 *
 *@return	none
 *
 * 今設定されているキャラクタモードを見て、Vramの管理領域などの作成を
 * 行います。
 * キャラクタモードを一緒に設定する初期化関数も作成しましたので、
 * 一緒に設定したいときは、そちらをお使いください。
 *	InitCharManagerReg関数
 * 
 */
//-----------------------------------------------------------------------------
GLOBAL void InitCharManager( const CHAR_MANAGER_MAKE* CharMakeData );

//----------------------------------------------------------------------------
/**
 *
 *	@brief	キャラクタマネージャを初期化
 *
 *	@param	CharMakeData	キャラクタマネージャ作成データ
 *	@param	modeMain		キャラクタマッピングモード　メイン画面
 *	@param	modeSub			キャラクタマッピングモード　サブ画面
 *
 *	@return	none
 *
 *	GX_OBJVRAMMODE_CHAR_2D			2次元マッピングモードを選択します。 
 *	GX_OBJVRAMMODE_CHAR_1D_32K		１次元マッピングモードで、先頭キャラクタ境界を32バイトとします。
 *									利用可能なOBJ-VRAMの最大容量は32KBになります。 
 *	GX_OBJVRAMMODE_CHAR_1D_64K		１次元マッピングモードで、先頭キャラクタ境界を64バイトとします。
 *									利用可能なOBJ-VRAMの最大容量は64KBになります。 
 *	GX_OBJVRAMMODE_CHAR_1D_128K		１次元マッピングモードで、先頭キャラクタ境界を128バイトとします。
 *									利用可能なOBJ-VRAMの最大容量は128KBになります。 
 *	GX_OBJVRAMMODE_CHAR_1D_256K		１次元マッピングモードで、先頭キャラクタ境界を256バイトとします。
 *									利用可能なOBJ-VRAMの最大容量は256KBになります。 
 *
 * 
 *
 */
//-----------------------------------------------------------------------------
GLOBAL void InitCharManagerReg( const CHAR_MANAGER_MAKE* CharMakeData, GXOBJVRamModeChar modeMain, GXOBJVRamModeChar modeSub );

//----------------------------------------------------------------------------
/**
 *
 *@brief	キャラクタマネージャーを完全に破棄します。
 *
 *@param	none
 *
 *@return	none
 *
 *
 */
//-----------------------------------------------------------------------------
GLOBAL void DeleteCharManager(void);

//----------------------------------------------------------------------------
/**
 *
 *@brief	  ロードを開始する関数	(内部管理のオフセットを初期化)
 *
 *@param	  start_offset：読み込み開始offset
 *
 *@return	  none
 */
//-----------------------------------------------------------------------------
GLOBAL void CharLoadStart( u32 start_offset );	
GLOBAL void CharLoadStartSub( u32 start_offset );

//----------------------------------------------------------------------------
/**
 *
 *@brief	AreaCont用のメイン、サブの両管理領域を初期化
 *
 *@param	none
 *
 *@return	none
 */
//-----------------------------------------------------------------------------
GLOBAL void TransAreaInitAll( void );

//----------------------------------------------------------------------------
/**
 *
 *@brief	  ロードを開始する関数	０でメイン、サブ面のオフセットを初期化する
 *				AreaCont用Vramエリアの初期化も行っています。
 *
 *@param	  none
 *
 *@return	  none
 */
//-----------------------------------------------------------------------------
GLOBAL void CharLoadStartAll( void );

//----------------------------------------------------------------------------
/**
 *	@brief	AreaCont関数用	使用禁止領域設定
 *
 *	@param	offset		使用禁止オフセット位置
 *	@param	size		使用禁止サイズ
 *	@param	disp		画面
 *
 *	disp
 *		mainに登録：NNS_G2D_VRAM_TYPE_2DMAIN = 1
 *		subに登録 ：NNS_G2D_VRAM_TYPE_2DSUB = 2
 *
 *	@return	none
 *	
 *	＊使用上の注意
 *	GLOBAL void TransAreaInitAll( void );
 *	GLOBAL void CharLoadStartAll( void );
 *	を使用した後にこの設定をしてください。
 *	上の２つの関数の中で、禁止領域の初期化も行ってしまいます	
 */
//-----------------------------------------------------------------------------
GLOBAL void SetReserveAreaContCharManager( u32 offset, u32 size, u32 disp );

//----------------------------------------------------------------------------
/**
 *
 *@brief		キャラクタデータ単体をセットしてロード
 *
 *@param		pChatData：キャラクタENTRYデータ
 *
 *@retval		TRUE ：セットできた  
 *@retval		FALSE：セットできなかった
 *
 */
//-----------------------------------------------------------------------------
GLOBAL BOOL CharSet( const CHAR_MANAGER_HEADER* pCharData );

//----------------------------------------------------------------------------
/**
 *
 *@brief		キャラクタデータを複数セット
 *
 *@param		pChatData	キャラクタデータ配列
 *@param		num			配列要素数
 *
 *@return		いくつ登録成功したか
 */
//-----------------------------------------------------------------------------
GLOBAL u16 CharSets( const CHAR_MANAGER_HEADER* pCharData, int num );

//----------------------------------------------------------------------------
/**
 *
 *@brief		キャラクタデータ単体をセットしてロード
 *				マッピングモードを今のレジスタ状態に変更するモード
 *
 *@param		pChatData：キャラクタENTRYデータ
 *
 *@retval		TRUE ：セットできた  
 *@retval		FALSE：セットできなかった
 *
 * この関数の意味
 *	　CharSet関数内で、オブジェキャラクタのマッピングモードの変更をしてしまっているため、
 *	2Dマッピングモードでコンバートしたキャラクタデータを1Dで転送するなど出来ません。
 *	　それを回避するために今設定されているマッピングモードをキャラクタデータに設定して、
 *	転送する関数を作成しました。
 *
 */
//-----------------------------------------------------------------------------
GLOBAL BOOL CharSetCharModeAdjust( const CHAR_MANAGER_HEADER* pCharData );

//----------------------------------------------------------------------------
/**
 *
 *@brief		キャラクタデータを複数セット
 *				マッピングモードを今のレジスタ状態に変更するモード
 *
 *@param		pChatData	キャラクタデータ配列
 *@param		num			配列要素数
 *
 *@return		いくつ登録成功したか
 */
//-----------------------------------------------------------------------------
GLOBAL u16 CharSetsCharModeAdjust( const CHAR_MANAGER_HEADER* pCharData, int num );

//----------------------------------------------------------------------------
/**
 *
 *	@brief	管理IDのVramにキャラクタデータを転送する
 *
 *	@param	id				転送先のデータ管理ID
 *	@param	pCharData		転送するキャラクタデータ
 *
 *	@return	none
 *
 * キャラクタデータのサイズが一緒である必要があります
 *
 */
//-----------------------------------------------------------------------------
GLOBAL void CharDataChg( int id, NNSG2dCharacterData* pCharData );

//----------------------------------------------------------------------------
/**
 *
 *@brief	idのキャラクタデータがもう登録されているかチェック
 *
 *@param	id		チェックするid
 *
 *@retval	TRUE	登録されている
 *@retval	FALSE	登録されていない
 *
 *
 */
//-----------------------------------------------------------------------------
GLOBAL BOOL CheckCharID(int id);

//----------------------------------------------------------------------------
/**
 *
 *@brief	あといくつ登録できるのかを返す
 *
 *@param	none
 *
 *@return	int		残り登録可能数
 *
 *
 */
//-----------------------------------------------------------------------------
GLOBAL int CheckCharRest(void);

//----------------------------------------------------------------------------
/**
 *
 *@brief	キャラクタデータを破棄
 *
 *@param	キャラクタデータID
 *
 *@return	none
 */
//-----------------------------------------------------------------------------
GLOBAL void DelChar( int id );

//----------------------------------------------------------------------------
/**
 *
 *@brief	全キャラクタデータを破棄
 *
 *@param	none
 *
 *@return	none
 */
//-----------------------------------------------------------------------------
GLOBAL void DelCharAll( void );

//----------------------------------------------------------------------------
/**
 *
 *@brief	IDのイメージプロクシを取得
 *
 *@param	キャラクタデータID
 *
 *@return	IDのプロクシ
 */
//-----------------------------------------------------------------------------
GLOBAL NNSG2dImageProxy* GetCharIDProxy( int id );

//----------------------------------------------------------------------------
/**
 *
 *@brief	プロクシのキャラクタデータを取得
 *
 *@param	pImage：イメージプロクシポインタ
 *
 *@return	キャラクタデータ
 */
//-----------------------------------------------------------------------------
GLOBAL NNSG2dCharacterData* GetCharIDData( const NNSG2dImageProxy* pImage );

//----------------------------------------------------------------------------
/**
 *
 *@brief	セルVram転送アニメーション用のキャラクタプロクシを取得
 *
 *@param	id		キャラクタデータID
 *@param	szByte	使用サイズ
 *
 *@return	イメージプロクシ
 *@return	NULL		失敗
 *	
 *	NULLが帰ったときはオリジナルデータが使用中ということなので、コピーを作成してください。（下の関数）
 *	
 */
//-----------------------------------------------------------------------------
GLOBAL NNSG2dImageProxy* GetCharVramTransData( int id, u32 szByte );

//----------------------------------------------------------------------------
/**
 *
 *@brief	セルVram転送アニメーション用のキャラクタプロクシをコピーして取得
 *
 *@param	Orig	オリジナルイメージプロクシ
 *
 *@return	コピーしてVram転送オフセットを取得したイメージプロクシ
 *@return	NULL	オリジナルが使用中でない可能性があります。
 */
//-----------------------------------------------------------------------------
GLOBAL NNSG2dImageProxy* GetCharVramTransProxyCopy( const NNSG2dImageProxy* Orig );

//----------------------------------------------------------------------------
/**
 *
 *@brief	セルVram転送アニメのVram領域を開放
 *
 *@param	pImage：破棄するキャラクタ領域の
 *			イメージプロクシ
 *
 *@return	none
 */
//-----------------------------------------------------------------------------
GLOBAL void DelVramTransData( const NNSG2dImageProxy* pImage );

//----------------------------------------------------------------------------
/**
 *
 *	@brief	OBJキャラクタマッピングモードからキャラクタ境界を取得
 *
 *	@param	mode	OBJキャラクタマッピングモード
 *
 *	@return	キャラクタ境界
 *
 *
 */
//-----------------------------------------------------------------------------
GLOBAL int CharModeMinNum( int mode );

//----------------------------------------------------------------------------
/**
 *
 *	@brief	NNSG2dCharacterDataを使用しないときのVramエリア確保用
 *
 *	@param	szByte		キャラクタデータサイズ
 *	@param	cont_type	Vramコントロールタイプ
 *	@param	type		登録画面
 *	@param	allocData	確保データ格納先
 *
 *	@retval	TRUE	領域確保できた
 *	@retval	FALSE	領域確保できなかった
 *
 *	cont_type
 *		CHARM_CONT_OFFSET	オフセットタイプ
 *		CHARM_CONT_AREACONT	エリアコントロールタイプ
 *
 *	type
 *		NNS_G2D_VRAM_TYPE_2DMAIN	メイン画面VRAM
 *		NNS_G2D_VRAM_TYPE_2DSUB		サブ画面VRAM
 *
 *		**両画面は指定しないでください
 *
 */
//-----------------------------------------------------------------------------
GLOBAL BOOL CharVramAreaAlloc( int szByte, int cont_type, int type, CHAR_MANAGER_ALLOCDATA* allocData );

//----------------------------------------------------------------------------
/**
 *
 *	@brief	NNSG2dCharacterDataを使用しないときのVramエリア破棄用
 *			cont_type = CHARM_CONT_AREACONTのときよう
 *
 *	@param	allocData	登録データ
 * 
 *	@return	none
 *
 * オフセットずらしモードで確保したものは解放できません
 *
 */
//-----------------------------------------------------------------------------
GLOBAL void CharVramAreaFree( CHAR_MANAGER_ALLOCDATA* allocData );


//----------------------------------------------------------------------------
/**
 *	@brief	キャラクタマネージャポインタの取得
 *
 *	@param	none
 *
 *	@return	キャラクタマネージャポインタ
 */
//-----------------------------------------------------------------------------
GLOBAL void* CharManagerPtrGet( void );
//----------------------------------------------------------------------------
/**
 *	@brief	キャラクタマネージャポインタを設定
 *
 *	@param	pdata	キャラクタマネージャポインタ
 *
 *	@return	none
 */
//-----------------------------------------------------------------------------
GLOBAL void CharManagerPtrSet( void* pdata );

//----------------------------------------------------------------------------
/**
 *					グローバル変数宣言
 */
//-----------------------------------------------------------------------------
#undef	GLOBAL
#endif		// __CHAR_MANAGER_H__

