/*
 ******************************************************************************
 *
 *      コントローラー入力の処理
 *      $Id: controllerx.c,v 1.1 2003/05/30 21:25:28 tong Exp $
 *
 ******************************************************************************
 */
#define  CONTROLLERp
#include "main.h"
#include "utility.h"
#include "bg_msgmgr.h"
#include "controller.h"
#include "controllerx.h"
extern  OSMesgQueue  serialMsgQ;
#if (USE_CIC6104 || DEBUG_CIC)
static int  __osCic6104_CartTest_is_OK = 0;
#endif

/*
 ******************************************************************************
 *   通常のコントローラの入力処理
 ******************************************************************************
 */
pad_t *normalController(void)
{
    ReadController();
    return  global_pad;
}
/*
 ******************************************************************************
 *   コントローラの自動入力処理
 *   (店頭デモの再生処理
 *    再生データが終了すれば NULL_PAD を返す)
 ******************************************************************************
 */
/* 自動入力コントローラーデータ */
static ATPYDT autoPlayDT[] = {
//#include "autopalyData.apd"
ENDofAUTOPLAY
};
ATPYDT *autoPlayDT_p = autoPlayDT;

static pad_t  NULL_PAD = {0};                /* 無効パッドデータ */
static t_pfc  repeatCnt = 0;
static int    id = 0;
static int    AtPyDtTime;
#define reset_autoPlayDataTiming()         (AtPyDtTime = 0)
#define is_firstAutoPlayTime()             (AtPyDtTime++ == 0)

// 通常のコントローラ入力処理へ戻す
pad_t *chg_normalController(void)
{
    chg_controllerProc(normalController);
    return &NULL_PAD;
}
// 自動入力のコントローラデータの読み込み
static pad_t *autoPlayProc(void)
{
    pad_t   *padInfo_P = normalController();

    if(((padInfo_P->now.button & A_BTN) == A_BTN)
       || ((padInfo_P->now.button & START) == START))
	return chg_normalController();        // 通常のコントローラへ戻す 

    if(is_firstAutoPlayTime()) {
	reset_random_i();	              // 乱数をリセットする
	reset_random_d();
    }
    if(repeatCnt <= 0) {
	++id;
	repeatCnt = getP_autoPlayDT(id)->fcnt;
	if(is_EndOfAutoPlayData(repeatCnt))
	    return chg_normalController();    // 通常のコントローラへ戻す 
    }
    --repeatCnt;
    return (pad_t *)getP_autoPlayDT(id)->data;
}
// 初期化
void init_autoPlayProc(void)
{
#if DEBUG
    if(!getP_autoPlayDT(0)) {
	PRINTF("init_autoPlayProc():自動入力のコントローラーデータへの"
	       "ポインターが NULL !!\n");
	return;
    }
#endif
    id = 0;
    repeatCnt = getP_autoPlayDT(id)->fcnt;
    reset_autoPlayDataTiming();
    chg_controllerProc(autoPlayProc);
}
#if MAKE_DEMODATA
/*
 ******************************************************************************
 *   コントローラの自動実行データの生成処理
 ******************************************************************************
 */
static int    mkCtDtSw = FALSE;
static pad_t  old_padInfo;
static int    fcnt;
// コントローラの自動実行データの生成処理のON/OFF
static void switch_autoPlayMaker(void)
{
    mkCtDtSw ^= TRUE;
    if(mkCtDtSw) {
	// 自動実行データの出力の初期化
	fcnt = 1;
	fillArea_s(&old_padInfo, sizeof(pad_t), 0);
	reset_autoPlayDataTiming();
    }
}
// コントローラの自動実行データの生成処理
static void make_autoPlayData(pad_t *padInfo_P)
{
    if(mkCtDtSw) {
	char   *data_p;

	if(is_firstAutoPlayTime()) {
	    reset_random_i();           // 乱数をリセットする
	    reset_random_d();
	}
	// コントローラの自動実行データの出力
	if(!cmpmem(padInfo_P, &old_padInfo, sizeof(pad_t))) {
	    int  i;
	    
	    osSyncPrintf("/* ｺﾝﾄﾛｰﾗ入力ﾃﾞｰﾀ */ {%d, {", fcnt);
	    data_p = (char *)&old_padInfo;
	    for(i=0; i<(int)sizeof(pad_t); i++)
		PRINTF("0x%02x,", *data_p++);
	    PRINTF("}},\n");
	    old_padInfo = *padInfo_P;
	    fcnt = 1;
	}
	else
	    ++fcnt;
	++AtPyDtTime;
    }
}
#endif    
/*
 ******************************************************************************
 *   コントローラ処理
 *   ("MAKE_DEMODATA=1"ならば, 十字キーの左を入力するとコンソールにコントロー
 *   ラーパッドの入力値が出力される)
 ******************************************************************************
 */
void Controller(GAME *Game)
{
    static PADBF    padBuff;
    CONTIF  *controllerInfo = CONTIFp_P(Game);
    pad_t   *padInfo_P;
    int     i, ctrlCnt = CONTROLLERS_COUNT;

    if(!is_normalController())
	ctrlCnt = 1;
    padInfo_P = controllerProc();
    // 入力パッド情報をバッファにコピーする
    for (i = 0; i < ctrlCnt; ++i) {
	padBuff.pad[i] = *(padInfo_P + i);
	controllerInfo->pad[i] = &padBuff.pad[i];
    }
#if 0 // 1998/3/20 otsuki
    if(is_freezeController()) {
	// パッドの入力情報をプロテクトする
	padBuff.pad[0] = NULL_PAD;
	controllerInfo->pad[0] = &padBuff.pad[0];
    }
#endif
	
#if (USE_CIC6104 || DEBUG_CIC)
    if (!__osCic6104_CartTest_is_OK) {
	padBuff.pad[0] = NULL_PAD;
	controllerInfo->pad[0] = &padBuff.pad[0];
    }
#endif
#if MAKE_DEMODATA
    if(chkTrigger(LEFT))
	start_autoPlay();              // 自動実行処理を開始させる
    make_autoPlayData(padInfo_P);      // 自動実行データの生成処理
    if(chkTrigger(RIGHT))
	switch_autoPlayMaker();        // 自動実行データの生成処理のON/OFF
#endif    
}
/*
 ******************************************************************************
 *   コントローラ入力の初期化
 ******************************************************************************
*/
void initial_Controller(GAME *Game)
{
#if (USE_CIC6104 || DEBUG_CIC)
    __osCic6104_CartTest_is_OK = osCic6104_CartTest_is_OK();
#endif
    clearArea_s(CONTIFp_P(Game), sizeof(CONTIF));
    InitController();
    chg_controllerProc(normalController);
}
