/*
 *  Shinobi Library
 *  Copyright (c) 1998 SEGA
 *
 *       Peripheral
 *
 *  Module  : Library Header File
 *  File    : sg_pad.h
 *  Create  : 1998-03-25
 *  Modify  : 1998-11-26
 *  Version : 1.08
 *  Note    :
 */

#ifndef _SG_PAD_H_
#define _SG_PAD_H_

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

#include <sg_xpt.h>

/*
 *  DEFINES / MACROS
 */

/******** ポート番号定数 ***************************************************/
#define PDD_PORT_A0    0                   /* ポートA0                     */
#define PDD_PORT_A1    1                   /* ポートA1                     */
#define PDD_PORT_A2    2                   /* ポートA2                     */
#define PDD_PORT_A3    3                   /* ポートA3                     */
#define PDD_PORT_A4    4                   /* ポートA4                     */
#define PDD_PORT_A5    5                   /* ポートA5                     */
#define PDD_PORT_B0    6                   /* ポートB0                     */
#define PDD_PORT_B1    7                   /* ポートB1                     */
#define PDD_PORT_B2    8                   /* ポートB2                     */
#define PDD_PORT_B3    9                   /* ポートB3                     */
#define PDD_PORT_B4   10                   /* ポートB4                     */
#define PDD_PORT_B5   11                   /* ポートB5                     */
#define PDD_PORT_C0   12                   /* ポートC0                     */
#define PDD_PORT_C1   13                   /* ポートC1                     */
#define PDD_PORT_C2   14                   /* ポートC2                     */
#define PDD_PORT_C3   15                   /* ポートC3                     */
#define PDD_PORT_C4   16                   /* ポートC4                     */
#define PDD_PORT_C5   17                   /* ポートC5                     */
#define PDD_PORT_D0   18                   /* ポートD0                     */
#define PDD_PORT_D1   19                   /* ポートD1                     */
#define PDD_PORT_D2   20                   /* ポートD2                     */
#define PDD_PORT_D3   21                   /* ポートD3                     */
#define PDD_PORT_D4   22                   /* ポートD4                     */
#define PDD_PORT_D5   23                   /* ポートD5                     */

/******** デバイスID *******************************************************/
#define PDD_DEV_NODEVICE       0x00000000  /* デバイス未接続               */
#define PDD_DEV_CONTROLLER     0x000f06fe  /* 標準コントローラ             */
#define PDD_DEV_KEYBOARD       0x01020000  /* 日本語92キーキーボード       */

/******** ボタン・レバーサポート状態 ***************************************/
#define PDD_DEV_SUPPORT_AY2   (1 << 21)    /* アナログ軸Y2を持つ           */
#define PDD_DEV_SUPPORT_AX2   (1 << 20)    /* アナログ軸X2を持つ           */
#define PDD_DEV_SUPPORT_AY1   (1 << 19)    /* アナログ軸Y1を持つ           */
#define PDD_DEV_SUPPORT_AX1   (1 << 18)    /* アナログ軸X1を持つ           */
#define PDD_DEV_SUPPORT_AL    (1 << 17)    /* アナログ軸Lを持つ            */
#define PDD_DEV_SUPPORT_AR    (1 << 16)    /* アナログ軸Rを持つ            */
#define PDD_DEV_SUPPORT_KRB   (1 << 15)    /* デジタル十字キーB右を持つ    */
#define PDD_DEV_SUPPORT_KLB   (1 << 14)    /* デジタル十字キーB左を持つ    */
#define PDD_DEV_SUPPORT_KDB   (1 << 13)    /* デジタル十字キーB下を持つ    */
#define PDD_DEV_SUPPORT_KUB   (1 << 12)    /* デジタル十字キーB上を持つ    */
#define PDD_DEV_SUPPORT_TD    (1 << 11)    /* Dボタンを持つ                */
#define PDD_DEV_SUPPORT_TX    (1 << 10)    /* Xボタンを持つ                */
#define PDD_DEV_SUPPORT_TY    (1 <<  9)    /* Yボタンを持つ                */
#define PDD_DEV_SUPPORT_TZ    (1 <<  8)    /* Zボタンを持つ                */
#define PDD_DEV_SUPPORT_KR    (1 <<  7)    /* デジタル十字キーA右を持つ    */
#define PDD_DEV_SUPPORT_KL    (1 <<  6)    /* デジタル十字キーA左を持つ    */
#define PDD_DEV_SUPPORT_KD    (1 <<  5)    /* デジタル十字キーA下を持つ    */
#define PDD_DEV_SUPPORT_KU    (1 <<  4)    /* デジタル十字キーA上を持つ    */
#define PDD_DEV_SUPPORT_ST    (1 <<  3)    /* スタートボタンを持つ         */
#define PDD_DEV_SUPPORT_TA    (1 <<  2)    /* Aボタンを持つ                */
#define PDD_DEV_SUPPORT_TB    (1 <<  1)    /* Bボタンを持つ                */
#define PDD_DEV_SUPPORT_TC    (1 <<  0)    /* Cボタンを持つ                */

/******** ボタン定数 *******************************************************/
#define PDD_DGT_TL    (1 << 17)            /* Lボタン(エミュレーション)    */
#define PDD_DGT_TR    (1 << 16)            /* Rボタン(エミュレーション)    */
#define PDD_DGT_KRB   (1 << 15)            /* デジタル十字キーB右          */
#define PDD_DGT_KLB   (1 << 14)            /* デジタル十字キーB左          */
#define PDD_DGT_KDB   (1 << 13)            /* デジタル十字キーB下          */
#define PDD_DGT_KUB   (1 << 12)            /* デジタル十字キーB上          */
#define PDD_DGT_TD    (1 << 11)            /* Dボタン                      */
#define PDD_DGT_TX    (1 << 10)            /* Xボタン                      */
#define PDD_DGT_TY    (1 <<  9)            /* Yボタン                      */
#define PDD_DGT_TZ    (1 <<  8)            /* Zボタン                      */
#define PDD_DGT_KR    (1 <<  7)            /* デジタル十字キーA右          */
#define PDD_DGT_KL    (1 <<  6)            /* デジタル十字キーA左          */
#define PDD_DGT_KD    (1 <<  5)            /* デジタル十字キーA下          */
#define PDD_DGT_KU    (1 <<  4)            /* デジタル十字キーA上          */
#define PDD_DGT_ST    (1 <<  3)            /* スタートボタン               */
#define PDD_DGT_TA    (1 <<  2)            /* Aボタン                      */
#define PDD_DGT_TB    (1 <<  1)            /* Bボタン                      */
#define PDD_DGT_TC    (1 <<  0)            /* Cボタン                      */

/******** エラー定数 *******************************************************/
#define PDD_ERR_OK       0x00000000        /* エラーなし                   */
#define PDD_ERR_RETRY    0xff0000fc        /* Transmit Againによるリトライ */
#define PDD_ERR_GENERIC  0xff000000        /* 未定義エラー                 */

/******** 論理モード定数 ***************************************************/
#define PDD_PLOGIC_ACTIVE    0             /* 正論理(デフォルト)           */
#define PDD_PLOGIC_NEGATIVE  1             /* 負論理                       */

/******** Maple モード定数 *************************************************/
#define PDD_MODE_TYPE_A      1             /* MapleタイプA(SET4用)         */
#define PDD_MODE_TYPE_B      0             /* MapleタイプB(SET5以降用)     */


/*
 *  PERIPHERAL INFO
 */

/******** ペリフェラルタイプ ***********************************************/
#define PDD_DEVTYPE_CONTROLLER   (1 << 0)  /* 標準コントローラ             */
#define PDD_DEVTYPE_STORAGE      (1 << 1)  /* ストレージ                   */
#define PDD_DEVTYPE_LCD          (1 << 2)  /* LCD                          */
#define PDD_DEVTYPE_TIMER        (1 << 3)  /* タイマ                       */
#define PDD_DEVTYPE_SOUNDINPUT   (1 << 4)  /* 音声入力                     */
#define PDD_DEVTYPE_ARGUN        (1 << 5)  /* AR-Gun                       */
#define PDD_DEVTYPE_KEYBOARD     (1 << 6)  /* キーボード                   */
#define PDD_DEVTYPE_LIGHTGUN     (1 << 7)  /* Light-Gun                    */
#define PDD_DEVTYPE_VIBRATION    (1 << 8)  /* 振動デバイス                 */

/******** エリアコード *****************************************************/
#define PDD_DEVAREA_USA          (1 << 0)  /* 北アメリカ地区               */
#define PDD_DEVAREA_JAPAN        (1 << 1)  /* 日本地区                     */
#define PDD_DEVAREA_ASIA         (1 << 2)  /* アジア地区                   */
#define PDD_DEVAREA_EUROPE       (1 << 3)  /* ヨーロッパ地区               */
#define PDD_DEVAREA_RESERVED1    (1 << 4)  /* 予約地区1                    */
#define PDD_DEVAREA_RESERVED2    (1 << 5)  /* 予約地区2                    */
#define PDD_DEVAREA_RESERVED3    (1 << 6)  /* 予約地区3                    */
#define PDD_DEVAREA_RESERVED4    (1 << 7)  /* 予約地区4                    */

/******** コネクタの向き ***************************************************/
#define PDD_CONDIR_TOPSIDE       0         /* 上                           */
#define PDD_CONDIR_BOTTOMSIDE    1         /* 下                           */
#define PDD_CONDIR_LEFTSIDE      2         /* 左                           */
#define PDD_CONDIR_RIGHTSIDE     3         /* 右                           */


/*
 *  TYPEDEFS
 */

/******** ペリフェラル情報構造体 *******************************************/
typedef struct {
	Uint32 type;                /* ペリフェラルのタイプ                    */
	Uint32 reserved[3];         /* 予約                                    */
	Uint8 is_root;              /* ルートデバイスかどうかを表す            */
	Uint8 area_code;            /* エリアコード                            */
	Uint8 connector_dir[2];     /* コネクタの向き                          */
	char product_name[32];      /* 製品名                                  */
	char license[64];           /* ライセンス                              */
	Uint16 stdby_pow;           /* スタンバイ消費電流                      */
	Uint16 max_pow;             /* 最大消費電流                            */
} PDS_PERIPHERALINFO;

/******** ペリフェラルデータ構造体 *****************************************/
typedef struct {
	Uint32 id;                            /* デバイスID                    */
	Uint32 support;                       /* ボタンのサポート情報          */
	Uint32 on;                            /* 現在押されているボタン        */
	Uint32 off;                           /* 現在放されているボタン        */
#ifdef USE_UNION
	union {
		Uint32 push;                      /* 現在押された瞬間にあるボタン  */
#endif
		Uint32 press;
#ifdef USE_UNION
	};
#endif
#ifdef USE_UNION
	union {
		Uint32 pull;                      /* 現在放された瞬間にあるボタン  */
#endif
		Uint32 release;
#ifdef USE_UNION
	};
#endif
	Uint16 r;                             /* 軸データR     (     0〜255  ) */
	Uint16 l;                             /* 軸データL     (     0〜255  ) */
	Sint16 x1;                            /* 軸データX1    (  -128〜127  ) */
	Sint16 y1;                            /* 軸データY1    (  -128〜127  ) */
	Sint16 x2;                            /* 軸データX2    (  -128〜127  ) */
	Sint16 y2;                            /* 軸データY2    (  -128〜127  ) */
	char* name;                           /* デバイス名称                  */
	void* extend;                         /* 拡張データアドレス            */
	Uint32 old;                           /* 予約                          */
	PDS_PERIPHERALINFO* info;             /* ペリフェラル情報へのポインタ  */
} PDS_PERIPHERAL;


void pdInitPeripheral(Sint32 logic, void* recvbuf, void* sendbuf);
void pdExitPeripheral(void);
void pdExecPeripheralServer(void);
const PDS_PERIPHERAL* pdGetPeripheral(Uint32 port);
Sint32 pdGetPeripheralError(Uint32 port);
const PDS_PERIPHERALINFO* pdGetPeripheralInfo(Uint32 port);
void pdSetMode(Sint32 mode);
Sint32 pdGetMode(void);
void pdSetOptimize(Uint32 count);
Uint32 pdGetOptimize(void);

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* _SG_PAD_H_ */
