/* *****************************************************************************

	Title		: 
	Filename	: vblk.c
	Contents	: VBLANK 関連

	History		: Ver 1.00		2000/12/19		K.Kimura		初版

***************************************************************************** */

#include	"main.h"


#define 	VBLK_DEBUG			FALSE
#define 	VBLK_PAUSE_DEBUG	TRUE

#define 	VBLK_CHG_PALETTE	FALSE
#define 	VBLK_ANM_DEBUG		FALSE


/* ///  ★グローバル変数宣言  /// */
void	( *VblkMoveFunc[ VBLK_MV_FUNC_MAX])( void near *);		/* 動作関連 関数	*/
void	( *VblkDrawFunc[ VBLK_DR_FUNC_MAX])( void near *);		/* 描画関連 関数	*/

extern	PAD	*PadInfo;										/* ﾊﾟｯﾄﾞ情報		*/
VBLKMNG		VblkMng;										/* VBLANK管理構造体	*/
char		vbuf[ 32];


/* ******************************************************************************
　関　　数：VblkLoopInit
　内　　容：
　表　　記：
　引　　数：−
　返　　値：−
　コメント：VBLANKの初期化
		  ：
　履　　歴：Ver 1.00	2000/12/19		K.Kimura		初版（移植）
****************************************************************************** */
void	VblkLoopInit( void)
{
	static	char	i;


	/* ///  ★各登録関数の初期化  /// */
	for (i = 0; i < VBLK_MV_FUNC_MAX; i++)
		VblkMoveFunc[ i] = NULL;						/* 動作関数		*/

	for (i = 0; i < VBLK_DR_FUNC_MAX; i++)
		VblkDrawFunc[ i] = NULL;						/* 描画関数		*/

	/* ///  ★ VBLK 管理構造体の初期化  /// */
	memset( &VblkMng, 0, sizeof( VBLKMNG));
	VblkSetFps( 0);

}


/* ******************************************************************************
　関　　数：VblkRegEvent
　内　　容：関数の登録
　表　　記：void	*VblkRegEvent( u_long mode, void ( *func)( u_long *))
　引　　数：u_long	mode  : MOVE or DRAW ﾓｰﾄﾞ
		  ：void 	*func : 登録関数へのﾎﾟｲﾝﾀ
　返　　値：登録成功 .. ?
		  ：    失敗 .. NULL
　コメント：
		  ：
　履　　歴：Ver 1.00	2000/12/19		K.Kimura		初版（移植）
****************************************************************************** */
void	*VblkRegEvent( u_long mode, void near ( *func)( void near *))
{
	static	char	i;
	static	short	max;
	static	void	( **tbl)(u_long *);



	/* ///  ★モードによる判別  /// */
	if ( mode)
	{
		tbl = &VblkMoveFunc[ 0];
		max = VBLK_MV_FUNC_MAX;
	}
	else
	{
		tbl = &VblkDrawFunc[ 0];
		max = VBLK_DR_FUNC_MAX;
	}

	/* ///  ★関数登録  /// */
	for (i = 0; i < max; i++, tbl++)
	{
		if (*tbl == NULL)
		{
			*tbl = func;

			return ( tbl);
		}
	}

	return ( NULL);
}


/* ******************************************************************************
　関　　数：VblkCheckPause
　内　　容：ポーズ・チェック
　表　　記：char	VblkCheckPause( void)
　引　　数：−
　返　　値：不明
　コメント：
		  ：
　履　　歴：Ver 1.00	1999/07/13		K.Kimura		初版
****************************************************************************** */
char	VblkCheckPause( void)
{
	static	char		ret;
	static	VBLKMNG		*vp;


	vp = &VblkMng;

	ret = 0;

	if ((vp->flag & VBLK_FLAG_PAUSE_ON) == 0)
		return ( ret);

	if (PadInfo->padt & KEY_START)
	{
		vp->pause ^= VBLK_PAUSE;

		/* ＳＥ発音 */
		se_play_n( GMSE_DECIDE);

		if (vp->pause & VBLK_PAUSE)
		{
#if VBLK_CHG_PALETTE
			DbgInitChgPalette();
#endif
			FntPrint( 1, 1, 0, "     *pause*      ", FNT_MODE_ADDY, FNT_PALETTE_NUM);
			FntPrint( 1, 0, 0, " TESTAROSSA 2001  ", FNT_MODE_ADDY, FNT_PALETTE_NUM);
			FntFlush();

		}
		else
		{
			GmSetItemWindowBase( 1, 0, 0, 0, 4);
			GmDispStatus();
		}
	}

	if (vp->pause)
	{
		ret = 1;

		/* パレット変更 */
#if VBLK_CHG_PALETTE
		DbgChangePalette( PadInfo->padt);
#endif

#if	VBLK_ANM_DEBUG
		if (PadInfo->padt & KEY_A)
		{
			/* ＳＥ発音 */
			se_play_n( GMSE_CURSOR);
			ret = 0;
		}
#endif
	}

	return ( ret);
}



/* ******************************************************************************
　関　　数：VblkCOutFunc
　内　　容：登録関数の実行
　表　　記：char	VblkCOutFunc( void)
　引　　数：−
　返　　値：不明
　コメント：
		  ：
　履　　歴：Ver 1.00	1999/07/13		K.Kimura		初版
****************************************************************************** */
char	VblkCOutFunc( void)
{
	static	char	i;
	static	char	ret;
	static	VBLKMNG	*vp;



	ret = 0;
	vp = &VblkMng;

	/* ///  ★ポーズ判定  /// */
	if ((vp->pause & VBLK_PAUSE_T) == 0)
	{
		/* ///  ★動作関数処理  /// */
		for (i = 0; i < VBLK_MV_FUNC_MAX; i++)
		{
			if (VblkMoveFunc[ i] != NULL)
			{
				( *VblkMoveFunc[ i])(( void *)&VblkMoveFunc[ i]);
			}
		}
	}

	/* ///  ★描画関数処理  /// */
	for (i = 0; i < VBLK_DR_FUNC_MAX; i++)
	{
		if (VblkDrawFunc[ i] != NULL)
		{
			( *VblkDrawFunc[ i])(( void *)&VblkDrawFunc[ i]);
		}
	}

	return ( ret);
}



/* ******************************************************************************
　関　　数：VblkLoop
　内　　容：VBLANK 処理
　表　　記：u_char	VblkLoop( void)
　引　　数：−
　返　　値：VblkMng.loopExit 値
　コメント：すべての処理系は、このループで行われます。
　		  ：必要な関数関数を登録した後、この関数をコールしてください。
		  ：
　履　　歴：Ver 1.00	1999/07/13		K.Kimura		初版
****************************************************************************** */
u_char	VblkLoop( void)
{
	static	VBLKMNG		*vp;
	static	u_short		hline = 0;


	vp = &VblkMng;

	/* ///  ★ループ処理  /// */
	while (vp->loopExit == 0)
	{
		PadRead();										/* ﾊﾟｯﾄﾞﾘｰﾄﾞ&処理			*/
		PadInfo = PadGetInfo( 0);						/* ﾊﾟｯﾄﾞ0取得				*/

#if	VBLK_PAUSE_DEBUG
		if (VblkCheckPause())							/* ﾎﾟｰｽﾞ･ﾁｪｯｸ				*/
			continue;
#endif
		VblkCOutFunc();									/* 登録関数処理				*/

#if VBLK_DEBUG
		DbgDispVRAM( PadInfo->padt);					/* VRAM表示（ﾃﾞﾊﾞｯｸﾞ）		*/
#endif
		vp->fpsCount ++;
		vp->count ++;									/* 汎用ﾀｲﾏｰ･ｶｳﾝﾄ			*/
		AnmExec();										/* ｱﾆﾒｰｼｮﾝ処理				*/

		sys_wait( 1);									/* VSyncWait				*/

		AnmTransfer();									/* ﾃﾞｰﾀ転送処理				*/
		AnmLocateAll();									/* ｽﾌﾟﾗｲﾄ表示処理			*/
		FntFlush();										/* ﾌｫﾝﾄ処理					*/
	}


	return	( vp->loopExit);
}



/* ******************************************************************************
　関　　数：
　内　　容：
　表　　記：
　引　　数：
　返　　値：
　コメント：
　		  ：
		  ：
　履　　歴：Ver 1.00	1999/11/16		K.Kimura		初版
****************************************************************************** */
void	VblkSetFps( u_short time)
{
	VblkMng.fps = VblkMng.fpsCount;
	VblkMng.fpsCount = time;
}



/* ******************************************************************************
　関　　数：
　内　　容：
　表　　記：
　引　　数：
　返　　値：
　コメント：
　		  ：
		  ：
　履　　歴：Ver 1.00	1999/11/16		K.Kimura		初版
****************************************************************************** */
void	VblkDispFps( void)
{
	sprintf( vbuf, "FPS : %3d", VblkMng.fps);
	DbgPrintPort( vbuf);
}



/* ******************************************************************************
　関　　数：VblkGetCount
　内　　容：汎用カウンタの取得
　表　　記：u_long	VblkGetCount( void)
　引　　数：汎用ｶｳﾝﾀ
　返　　値：
　コメント：
		  ：
　履　　歴：Ver 1.00	1999/11/18		K.Kimura		初版
****************************************************************************** */
u_short	VblkGetCount( void)
{
	return ( VblkMng.count);
}


/* ******************************************************************************
　関　　数：
　内　　容：
　表　　記：
　引　　数：
　返　　値：
　コメント：
		  ：
　履　　歴：Ver 1.00	1999/11/18		K.Kimura		初版
****************************************************************************** */
void	VblkSetPause( u_char mode)
{
	if (mode) {
		VblkMng.flag |= VBLK_FLAG_PAUSE_ON;
	} else {
		VblkMng.flag &= ~VBLK_FLAG_PAUSE_ON;
	}

}




