# Shinobi Library

English

### Ver 1.00

1998/10/4

# ペリフェラルデータ取得関数

目次

## 0. 概要

### 0.1 コントローラデータの取得

デバイスデータの取得
  デバイスデータを取得するには、関数pdGetPeripheral()を使用します。

  こうして取得した構造体のメンバを参照するだけで、容易にコントローラの入力を得ることができます。

## 1. データ仕様

### 1.1 構造体仕様

PDS_PERIPHERAL構造体

## PDS_PERIPHERAL

定義

      typedef struct {
      	Uint32 id;
      	Uint32 support;
      	Uint32 on;
      	Uint32 off;
      	Uint32 press;
      	Uint32 release;
      	Uint16 r;
      	Uint16 l;
      	Sint16 x1;
      	Sint16 y1;
      	Sint16 x2;
      	Sint16 y2;
      	Sint8* name;
      	void* extend;
      	Uint32 old;
      } PDS_PERIPHERAL;

説明
  コントロールパッドの状態を格納する構造体です。

メンバ

  id | デバイスID
  support | ボタン・レバーのサポート状態
  on | デジタルボタン状態
  off | デジタルボタン状態(反転)
  press | デジタルボタンダウンエッジ状態
  release | デジタルボタンアップエッジ状態
  r | アナログ軸Rの値(0〜255)
  l | アナログ軸Lの値(0〜255)
  x1 | アナログ軸X1の値(-128〜127)
  y1 | アナログ軸Y1の値(-128〜127)
  x2 | アナログ軸X2の値(-128〜127)
  y2 | アナログ軸Y2の値(-128〜127)
  name | デバイス名称
  extend | 拡張データアドレス(未使用)
  old | 予約

参照
  pdGetPeripheral()

PDS_PERIPHERALINFO構造体

## PDS_PERIPHERALINFO

定義

       typedef struct {
         Uint32 type;
         Uint32 reserved[3];
         Uint8 is_root;
         Uint8 area_code;
         Uint8 connector_dir[2];
         Sint8 product_name[32];
         Sint8 license[64];
         Uint16 stdby_pow;
         Uint16 max_pow;
       } PDS_PERIPHERALINFO;

説明
  ペリフェラルの固有情報を格納する構造体です。

メンバ

  type | ペリフェラルのタイプ
  reserved[3] | 予約
  is_root | ルートデバイスフラグ
  area_code | エリアコード
  connector_dir[2] | 拡張コネクタの向き
  product_name[32] | 製品名
  license[64] | ライセンス文字列
  stdby_pow | スタンバイ消費電流
  max_pow | 最大消費電流

参照
  pdGetPeripheralInfo()

### 1.2 デバイスIDとデバイス名称

取得した構造体には、デバイスの種別を表すIDと、その名称が格納されています。
Maple Bus仕様では取得できるデバイスIDは複雑なフォーマットになっているため、 アプリケーションが取り扱うには不向きです。

本ライブラリではそれを簡略化し、以下のように定義します。

デバイス | デバイスID (id) | デバイス名称文字列 (name)
--- | --- | ---
標準コントロールパッド | PDD_DEV_CONTROLLER | デバイス自体が持つ製品名

### 1.3 デバイスのサポートするボタン

コントローラ系デバイスには、さまざまなデバイスが存在します。
十字キーを2つ持つもの、アナログが2チャンネルのものなど、デバイスごとに有しているボタン・レバーが異なります。
それを調べるにはメンバ「support」を参照します。

以下の表にしたがってビットアサインが決まっており、ボタン・レバーを持つ場合は1、持たない場合は0が格納されています。
コントローラ系デバイスは、十字キーA、スタートボタン、Aボタン、Bボタンを持つことが必須となっているため、 これらのボタンのみを使用してアプリケーションを組むことにより、互換性を維持することができます。

ボタン・レバー | ビット位置指定用定数
--- | ---
十字キーA上 | PDD_DEV_SUPPORT_KU
十字キーA下 | PDD_DEV_SUPPORT_KD
十字キーA左 | PDD_DEV_SUPPORT_KL
十字キーA右 | PDD_DEV_SUPPORT_KR
十字キーB上 | PDD_DEV_SUPPORT_KUB
十字キーB下 | PDD_DEV_SUPPORT_KDB
十字キーB左 | PDD_DEV_SUPPORT_KLB
十字キーB右 | PDD_DEV_SUPPORT_KRB
スタートボタン | PDD_DEV_SUPPORT_ST
Aボタン | PDD_DEV_SUPPORT_TA
Bボタン | PDD_DEV_SUPPORT_TB
Cボタン | PDD_DEV_SUPPORT_TC
Xボタン | PDD_DEV_SUPPORT_TX
Yボタン | PDD_DEV_SUPPORT_TY
Zボタン | PDD_DEV_SUPPORT_TZ
Dボタン | PDD_DEV_SUPPORT_TD
アナログ軸R | PDD_DEV_SUPPORT_AR
アナログ軸L | PDD_DEV_SUPPORT_AL
アナログ軸X1 | PDD_DEV_SUPPORT_AX1
アナログ軸Y1 | PDD_DEV_SUPPORT_AY1
アナログ軸X2 | PDD_DEV_SUPPORT_AX2
アナログ軸Y2 | PDD_DEV_SUPPORT_AY2

アプリケーションは、デバイスIDとこのボタン・レバーサポート情報を参照し、適切にデータを取り扱ってください。

### 1.3.1 デジタルボタンデータ

デジタルボタン情報は、メンバon、off、press、releaseの4つのメンバに格納されており、用途によって使い分けます。
各メンバのビットごとにボタンが割り振られており、ボタンが押されていれば1、押されていなければ0となります(正論理)。
また、論理状態は初期化関数pdInitPeripheral()呼び出し時に負論理に設定することもできます。

デジタルボタン | ビット位置指定用定数
--- | ---
十字キーA上 | PDD_DGT_KU
十字キーA下 | PDD_DGT_KD
十字キーA左 | PDD_DGT_KL
十字キーA右 | PDD_DGT_KR
Aボタン | PDD_DGT_TA
Bボタン | PDD_DGT_TB
Cボタン | PDD_DGT_TC
Dボタン | PDD_DGT_TD
Xボタン | PDD_DGT_TX
Yボタン | PDD_DGT_TY
Zボタン | PDD_DGT_TZ
Lボタン | PDD_DGT_TL
Rボタン | PDD_DGT_TR
スタートボタン | PDD_DGT_ST
十字キーB上 | PDD_DGT_KUB
十字キーB下 | PDD_DGT_KDB
十字キーB左 | PDD_DGT_KLB
十字キーB右 | PDD_DGT_KRB

メンバ

Uint32 on
  ボタンが押されているとき(ボタンダウン)、対応するビットが1になります。
  押されていないボタンのビットは0になります。

Uint32 off
  onメンバをビット反転したものです。
  すなわち、ボタンが押されていないとき(ボタンアップ)、対応するビットが1になります。

Uint32 press
  ボタンが押されていない状態から、押された状態に変化したとき(ボタンダウンエッジ)、対応するビットが1になります。
  そうでないビットは0になります。

Uint32 release
  ボタンが押されている状態から、押されていない状態に変化したとき(ボタンアップエッジ)、対応するビットが1になります。
  そうでないビットは0になります。

※負論理に設定した場合、button、on、off、press、releaseのすべてのビットは反転して格納されます。

なお、デジタルLRボタン情報は、アナログLR情報からソフトウェアで擬似的に生成しています。
アナログLRボタンを持たないデバイスの場合、ビットは変化しませんので注意してください。 (デジタルLRボタンを物理的に持つデバイスはありません)

### 1.3.2 アナログ軸データ

アナログ軸情報は、メンバr,l,x1,y1,x2,y2の6つのメンバに格納されています。
未接続、およびそのボタン、レバーを持たないデバイスの場合は、センター位置と同じデータが格納されます。

メンバ | 符号 | レンジ | センター位置 | レバー/ボタン
--- | --- | --- | --- | ---
Uint16 r | 符号なし | 0〜255 | 0 | アナログRボタン
Uint16 l | 符号なし | 0〜255 | 0 | アナログLボタン
Sint16 x1 | 符号付き | -128〜0〜127 | 0 | アナログレバーX1
Sint16 y1 | 符号付き | -128〜0〜127 | 0 | アナログレバーY1
Sint16 x2 | 符号付き | -128〜0〜127 | 0 | アナログレバーX2
Sint16 y2 | 符号付き | -128〜0〜127 | 0 | アナログレバーY2

### 1.4 データ取得時のエラー

Maple Busプロトコルにおけるデバイスとの通信時に、何らかのエラーが発生する場合があります。
その場合、ボタン等の正常なデータが得られないため、構造体は下の表のような値に設定されます。

メンバ | 設定値
--- | ---
id,name,extend | 前回の値
デジタルボタン | すべてボタンが押されていない状態
アナログ軸 | センター位置

エラーが発生したかどうかは、関数pdGetPeripheralError()で調べることができます。

エラーコード | 内容
--- | ---
PDD_ERR_OK | エラーなし
PDD_ERR_RETRY | ボタンデータが正常に取得できませんでした
PDD_ERR_GENERIC | 未定義エラー

エラーが発生した場合は、ライブラリでは回復手段が存在しません。アプリケーションで適切な処理を行ってください。

### 1.5 ペリフェラルの種類

PDS_PERIPHRALINFO構造体の「type」メンバには、ペリフェラルがどのような機能を持っているかが格納されています。

ビット位置指定マクロ | 持っている機能
--- | ---
PDD_DEVTYPE_CONTROLLER | コントローラ
PDD_DEVTYPE_STORAGE | バックアップRAM
PDD_DEVTYPE_LCD | モノクロ液晶
PDD_DEVTYPE_TIMER | タイマ
PDD_DEVTYPE_SOUNDINPUT | 音声入力
PDD_DEVTYPE_ARGUN | GUN
PDD_DEVTYPE_KEYBOARD | キーボード

### 1.6 ルートデバイスフラグ

PDS_PERIPHRALINFO構造体の「is_root」メンバは、ペリフェラルがポートA〜Dに直接接続されている場合に1となり、コントローラ等の拡張コネクタに接続されている場合(VMS等)には0となります。
PDD_PORT_A0/B0/C0/D0の場合は常に1となり、それ以外は常に0となります。

### 1.7 エリアコード

PDS_PERIPHRALINFO構造体の「area_code」メンバには、そのペリフェラルの仕向地が格納されています。

ビット位置指定マクロ | 仕向地
--- | ---
PDD_DEVAREA_USA | 北アメリカ地区
PDD_DEVAREA_JAPAN | 日本地区
PDD_DEVAREA_ASIA | アジア地区
PDD_DEVTYPE_EUROPE | ヨーロッパ地区

### 1.8 拡張コネクタ方向

PDS_PERIPHRALINFO構造体の「connector_dir」メンバは、そのペリフェラルがルートデバイス（ポートに直接接続される）である場合、拡張コネクタが付いている方向を表します。

指定マクロ | コネクタ方向
--- | ---
PDD_CONDIR_TOPSIDE | 上側
PDD_CONDIR_BOTTOMSIDE | 下側
PDD_CONDIR_LEFTSIDE | 左側
PDD_CONDIR_RIGHTSIDE | 右側

標準コントローラの場合は、コネクタは２個とも上向きとなっています。

### 1.9 製品名

PDS_PERIPHRALINFO構造体の「product_name」メンバは、 そのペリフェラルの製品名が格納されています。
標準コントローラの場合は、"Dreamcast Controller<スペース...>"となります。

### 1.10 ライセンス文字列

PDS_PERIPHRALINFO構造体の「license」メンバには、そのペリフェラルのライセンス文字列が格納されています。

## 2. 関数仕様

### 2.1関数一覧

関数 | 機能
--- | ---
pdGetPeripheral | コントローラのボタン状態を取得する
pdGetPeripheralError | コントローラに関するエラーを取得する
pdExecPeripheralServer | ペリフェラルデータ取得サーバ関数
pdGetPeripheralInfo＜新規＞ | ペリフェラル情報の取得
pdTmrAlarm＜新規＞ | アラームを鳴らす

### 2.2 関数API

## pdGetPeripheral

［関数］
  const PDS_PERIPHERAL* pdGetPeripheral(Uint32 port)
［入力］

port
  ポート番号(PDD_PORT_A0/B0/C0/D0)

［出力］
  なし
［戻値］
  PDS_PERIPHERAL構造体のアドレス
［機能］
  ペリフェラルデータを取得します。
［参照］
  PDS_PERIPHERAL構造体
［使用例］
  const PDS_PERIPHERAL* per;

  per = pdGetPeripheral(PDD_PORT_A0);

  if (per->press & PDD_DGT_ST) {
  /* スタートボタンが押された */
  :
  :
  }

## pdGetPeripheralError

［関数］
  Sint32 pdGetPeripheralError(Uint32 port)
［入力］
  port ...ポート番号(PDD_PORT_A0/B0/C0/D0)
［出力］
  なし
［戻値］

0
  エラーなし
負
  エラー値(PDD_ERR_XXXX)

［機能］
  コントローラデータ取得に関するエラーコードを取得します。
［使用例］
  Sint32 err;

  err = pdGetPeripheralError(PDD_PORT_B0);

## pdExecPeripheralServer

［関数］
  void pdExecPeripheralServer( void )
［入力］
  なし
［出力］
  なし
［戻値］
  なし
［機能］
  そのフレームでのペリフェラルデータを作成します。
［備考］
  本関数は、njWaitVSync関数内で呼ばれています。これは、フレーム同期(2 Intで動作するアプリなら、2 Intに一回データを取得することで、ボタンのエッジを正しく取得するため)で動作させるためです。
  もし、sbInitSystemで指定した同期フレーム数以外のタイミングでペリフェラルデータの取得を行いたい場合のみご利用ください。その場合、取得されるPDS_PERIPHERAL構造体のpress、releaseメンバについてはデータの内容は保証できません。

## pdGetPeripheralInfo

［関数］
  const PDS_PERIPHERALINFO* pdGetPeripheralInfo(Uint32 port)
［入力］
  port
    ポート番号(PDD_PORT_A0-A2/B0-B2/C0-C2/D0-D2)
［出力］
  なし
［戻り値］
  PDS_PERIPHERALINFO構造体のアドレス
［機能］
  ペリフェラルの固有情報を取得します。
［参照］
  PDS_PERIPHERALINFO構造体、PDS_PERIPHERAL構造体
［使用例］

        const PDS_PERIPHERALINFO* info;
        info = pdGetPeripheralInfo(PDD_PORT_A1);

        if (info->type & PDD_DEVTYPE_LCD) {
          /* このペリフェラルは液晶を持っている */
                 :
        }
        if (info->area_code & PDD_DEVAREA_USA) {
          /* このペリフェラルは北アメリカ向けである */
                 :
        }
        /* 製品名とライセンスを表示する */
        njPrintC(NJM_LOCATION(0, 0), info->product_name);
        njPrintC(NJM_LOCATION(0, 1), info->license);

［備考］
  本関数を使用せずとも、PDS_PERIPHERAL構造体にもメンバが追加されていますので、従来のpdGetPeripheral()を用いて以下のように同様の処理が可能です。

        const PDS_PERIPHERAL* per;

        per = pdGetPeripheral(PDD_PORT_A1);

        if (per->info->type & PDD_DEVTYPE_LCD) {
          /* このペリフェラルは液晶を持っている */
             :
        }
        if (per->info->area_code & PDD_DEVAREA_USA) {
          /* このペリフェラルは北アメリカ向けである */
             :
        }
        /* 製品名とライセンスを表示する */
        njPrintC(NJM_LOCATION(0, 0), per->info->product_name);
        njPrintC(NJM_LOCATION(0, 1), per->info->license);

## pdTmrAlarm

［関数］
  Sint32 pdTmrAlarm( Uint32 port, Uint8* data )
［入力］

port
  ボート番号(PDD_PORT_A1/A2/B1/B2/C1/C2/D1/D2)
data
  アラームデータ(4バイト)
  アラームデータ4バイトのうち上位2バイトは、ブザー1、下位2バイトはブザー2を意味しています。
  現在ブザー1のみの対応となっていますので、ブザー2は使わないで下さい。
  ブザーの音を鳴らさないようにするには、2バイトのデータのいずれにも00hを入れてください。

［出力］
  なし
［戻値］

PDD_TMRERR_OK
  時刻取得要求成功
PDD_TMRERR_NO_TIMER
  タイマを持つデバイスが接続されていない
PDD_TMRERR_BUSY
  デバイスはBUSY状態

［機能］
  VMSのような、タイマを持つデバイスのアラームを鳴らします。
［使用例］

        Uint8  data[4];
        Uint32 ret;

        data[0] = 0xc0;
        data[1] = 0x80;
        data[2] = 0x00;
        data[3] = 0x00;

        ret = pdTmrAlarm(PDD_PORT_A1, data);

        if (ret != PDD_TMRERR_OK) {
          /* 鳴らせなかった */
        }

［備考］

オーバービューに戻る