/* *****************************************************************************
	Title : pad.c
***************************************************************************** */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/bios.h>

#include "pad.h"


/* ★グローバル変数		*/
PAD		Pad[ PAD_CONTROLLER_MAX];					/* ﾊﾟｯﾄﾞ情報構造体			*/


/* ******************************************************************************
　関　　数	：ApadInit
　内　　容	：パッド関連の初期化
　表　　記	：void	ApadInit( void)
　引　　数	：−
　返　　値	：−
　コメント	：−
　履　　歴	：Ver 1.00	2000/11/16		K.Kimura		初版（移植）
****************************************************************************** */
void	PadInit( void)
{
	static	short		i, j;


	/* ///  ●パッド構造体の初期化●  /// */
	for (i = 0; i < PAD_CONTROLLER_MAX; i++)
	{
		Pad[ i].repCntSt	= PAD_REPEAT_START;		/* ﾘﾋﾟｰﾄｶｳﾝﾀ（初回設定：V）	*/
		Pad[ i].repCntAf	= PAD_REPEAT_AFTER;		/* ﾘﾋﾟｰﾄｶｳﾝﾀ（２回以降：V）	*/
		Pad[ i].pad			= 0;					/* ﾊﾟｯﾄﾞ処理状態：ﾉｰﾏﾙ		*/
		Pad[ i].padr		= 0;					/*              ：ﾘﾋﾟｰﾄ		*/
		Pad[ i].padt		= 0;					/*              ：ﾄﾘｶﾞ		*/
		Pad[ i].bfPad		= 0;					/* 一回前の pad				*/

		/* ///  リピートカウンタの初期化  /// */
		for (j = 0; j < ( PAD_COUNT_TYPEMAX * 2); j++)
		{
			Pad[ i].wait[ j] = 0;
		}
	}

}



/* ******************************************************************************
　関　　数	：PadRead
　内　　容	：パッド情報の設定
　表　　記	：void	PadRead( void)
　引　　数	：−
　返　　値	：−
　コメント	：PAD_CONTROLLER_MAX 人分のパッド情報を取得＆設定します。
		　	：取得された情報は、Pad[] 内に格納されます。
		　	：
　履　　歴	：Ver 1.00	2000/11/16		K.Kimura		初版（移植）
****************************************************************************** */
void	PadRead( void)
{
	static	short		i;
	static	u_short		key_st;



	/* ///  VBLANK で一度以上の読み込み禁止  /// */
	key_st = key_press_check();

	/* ///  ●パッド情報の設定（最大 APAD_CONTROLLER_MAX 分）●  /// */
	for (i = 0; i < PAD_CONTROLLER_MAX; i++)
	{
		PadSet( i, key_st);
	}

}



/* ******************************************************************************
　関　　数	：PadSet
　内　　容	：パッド情報の詳細設定
　表　　記	：short		PadSet( short num, u_short key)
　引　　数	：short		num  : APad[] 配列ｲﾝﾃﾞｯｸｽ
		　	：u_short	key  : ｷｰ入力状態
　返　　値	：−
　コメント	：パッド情報を取得します。
		　	：リピート処理などの検証をし、Pad 構造体に値を設定します。
		　	：
　履　　歴	：Ver 1.00	2000/11/16		K.Kimura		初版（移植）
****************************************************************************** */
short	PadSet( short num, u_short key)
{
	static	short		ret;
	static	u_short		target;


	ret = 0;

	/* ///  ●通常情報の設定●  /// */
	Pad[ num].pad   = key;								/* 押しっぱなし			*/
	Pad[ num].padr  = 0;								/* ﾘﾋﾟｰﾄ（初期化）		*/

	target  = key ^ Pad[ num].bfPad;
	target &= key;
	Pad[ num].padt  = target;							/* ﾄﾘｶﾞ					*/

	/* ///  キー・リピート判定１（デジタル入力） /// */
	PadCheckRepeat( key, num, &Pad[ num].wait[ 0], PAD_BTN_AB);
	PadCheckRepeat( key, num, &Pad[ num].wait[ 2], PAD_TRG_DURL_X);
	PadCheckRepeat( key, num, &Pad[ num].wait[ 4], PAD_TRG_DURL_Y);

	/* ///  現在のパッド情報保持  /// */
	Pad[ num].bfPad = key;


	return ( ret);

}



/* ******************************************************************************
　関　　数	：PadCheckRepeat
　内　　容	：リピート処理
　表　　記	：short	PadCheckRepeat( u_short key, short num, u_short *wait, u_short target)
　引　　数	：u_short	key		: ﾍﾟﾘﾌｪﾗﾙ情報構造体へのﾎﾟｲﾝﾀ
		　	：short 	num		: Pad[] 配列ｲﾝﾃﾞｯｸｽ
		　	：u_short  *wait	: ｳｪｲﾄ配列へのﾎﾟｲﾝﾀ
		　	：u_short	target 	: ﾘﾋﾟｰﾄ･ﾀｰｹﾞｯﾄ	：	PAD_BTN_ABXY
		　	：										PAD_TRG_DURL_X
		　	：										PAD_TRG_DURL_Y
　返　　値	：不明
　コメント	：キー・リピート判定を行います。
		　	：
　履　　歴	：Ver 1.00	2000/11/16		K.Kimura		初版（移植）
****************************************************************************** */
short	PadCheckRepeat( u_short key, short num, u_short *wait, u_short target)
{
	static	short		ret;


	ret = 0;

	Pad[ num].padr |= ( Pad[ num].padt & target);	/* 最初のﾄﾘｶﾞ&初期化用		*/

	/* ///  ●トリガー発生 or 全リリースで初期化●  /// */
	if ((Pad[ num].padt & target) || ((key & target) == 0))
	{
		wait[ 0] = 0;								/* 第一ｶｳﾝﾀ初期化			*/
	}

	/* ///  ●キー押しっぱなし状態●  /// */
	if (key & target)
	{
		if (wait[ 0] < Pad[ num].repCntSt)
		{
			wait[ 0] += ( u_short)PAD_GAME_VSPEED;	/* ｹﾞｰﾑの基本 VSync			*/

			if (wait[ 0] >= Pad[ num].repCntSt)
			{
				/* ※ここで、wait[ 1] を最大値にするのは、						*/
				/*   この段階で、キーＯＮを発生させる必要があるため。			*/
				wait[ 1] = Pad[ num].repCntAf;
			}
		}
		else if (wait[ 1] < Pad[ num].repCntAf)
		{
			wait[ 1] += ( u_short)PAD_GAME_VSPEED;	/* ｹﾞｰﾑの基本 VSync			*/
		}

		/* ///  ●時間がきたらリピート設定●  /// */
		if ((wait[ 0] >= Pad[ num].repCntSt) && (wait[ 1] >= Pad[ num].repCntAf))
		{
			Pad[ num].padr |= (key & target);		/* ﾊﾟｯﾄﾞ情報の設定			*/
			wait[ 1] = 0;							/* 第二ﾘﾋﾟｰﾄ･ｶｳﾝﾀの初期化	*/
		}
	}


	return ( ret);
}



/* ******************************************************************************
　関　　数	：PadGetInfo
　内　　容	：パッド情報の取得
　表　　記	：PAD	*PadGetInfo( short idx)
　引　　数	：short	idx : PAD[] ｲﾝﾃﾞｯｸｽ
　返　　値	：−
　コメント	：基本的に、他のプログラムからコールされます。
			：この関数をコールすることで、パッド情報を得ます。
			：
　履　　歴	：Ver 1.00	2000/11/16		K.Kimura		初版
****************************************************************************** */
PAD		*PadGetInfo( short idx)
{
	if (idx > ( short)PAD_CONTROLLER_MAX)
		return ( NULL);

	return ( &Pad[ idx]);
}




