# 機能設計書 24-ゲームパッド対応

## 概要

本ドキュメントは、Godot Engineのゲームパッド対応機能について、その設計と実装の詳細を記述した機能設計書である。本機能は、各種ゲームコントローラー（Xbox、PlayStation、Nintendo Switch等）からの入力を検出し、ボタン押下やアナログスティック入力をゲームロジックに伝達するための機能を提供する。

### 本機能の処理概要

**業務上の目的・背景**：コンソールゲームやPCゲームにおいて、ゲームパッドは主要な入力デバイスの一つである。異なるメーカー・モデルのコントローラーを統一的なAPIで扱えるようにすることで、開発者はデバイス差異を意識せずにゲーム開発を行える。また、SDLコントローラーデータベースとの互換性により、新しいコントローラーにも対応可能となる。

**機能の利用シーン**：
- アナログスティックによるキャラクター移動・カメラ操作
- トリガーボタンによる加速・ブレーキ操作
- A/B/X/Yボタンによるアクション実行
- 振動フィードバックによる没入感向上
- 複数コントローラーによるローカルマルチプレイ

**主要な処理内容**：
1. コントローラーの接続・切断検出
2. ボタン入力の検出とマッピング
3. アナログスティック・トリガー入力の取得
4. デッドゾーン処理
5. 振動（ハプティクス）制御
6. コントローラーマッピングデータベース管理

**関連システム・外部連携**：InputMap（アクションマッピング）、DisplayServer（プラットフォーム固有のコントローラーAPI）

**権限による制御**：特に権限による制御はなし。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 36 | 入力イベント設定ダイアログ | 補助機能 | ゲームパッドボタン・スティック入力の設定 |

## 機能種別

イベント駆動処理 / デバイス管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| p_device | int | Yes | デバイスID（0〜15） | 0以上、JOYPADS_MAX未満 |
| p_button | JoyButton | Yes | ボタンID（JoyButton enum） | 有効なボタンID |
| p_axis | JoyAxis | Yes | 軸ID（JoyAxis enum） | 有効な軸ID |
| p_value | float | Yes | 軸の値 | -1.0〜1.0 |

### 入力データソース

- プラットフォーム固有のコントローラーAPI（Windows: XInput/DirectInput、Linux: evdev、macOS: IOKit）
- SDLゲームコントローラーデータベース（gamecontrollerdb.txt）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| is_joy_button_pressed | bool | 指定ボタンが押されているか |
| get_joy_axis | float | 指定軸の値（-1.0〜1.0） |
| get_joy_name | String | コントローラー名 |
| get_connected_joypads | TypedArray<int> | 接続中のデバイスID一覧 |

### 出力先

- ゲームスクリプトからのAPI呼び出し結果
- InputEventJoypadButton/InputEventJoypadMotionとしてイベント伝播

## 処理フロー

### 処理シーケンス

```
1. OSからコントローラー接続イベントを受信
   └─ joy_connection_changedシグナルを発行
2. コントローラーマッピングを適用
   └─ GUIDに基づいてmap_dbから検索
3. ボタン/軸入力をポーリング
   └─ プラットフォームAPIから取得
4. 入力をマッピングテーブルで変換
   └─ 物理ボタン→論理ボタンへ変換
5. InputEventを生成して伝播
   └─ デッドゾーン処理を適用
```

### フローチャート

```mermaid
flowchart TD
    A[コントローラー接続] --> B[GUIDでマッピング検索]
    B --> C{マッピング存在?}
    C -->|Yes| D[マッピング適用]
    C -->|No| E[フォールバックマッピング]
    D --> F[入力ポーリング]
    E --> F
    F --> G{入力タイプ}
    G -->|Button| H[InputEventJoypadButton生成]
    G -->|Axis| I[デッドゾーン処理]
    I --> J[InputEventJoypadMotion生成]
    H --> K[Input::parse_input_event]
    J --> K
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-24-01 | 最大接続数 | 同時接続コントローラーは最大16台 | 常時（JOYPADS_MAX = 16） |
| BR-24-02 | マッピング優先順位 | GUID完全一致 → フォールバック → 未知デバイス | 接続時 |
| BR-24-03 | デッドゾーン | デフォルト0.5、カスタマイズ可能 | 軸入力時 |
| BR-24-04 | 振動制御 | weak_magnitude、strong_magnitude、durationで制御 | 振動開始時 |

### 計算ロジック

**デッドゾーン処理**：
- |value| < deadzone の場合、0.0を返す
- それ以外は (|value| - deadzone) / (1.0 - deadzone) * sign(value)

**軸値正規化**：
- 範囲：-1.0（負方向最大）〜 0.0（中立）〜 1.0（正方向最大）
- トリガー：0.0（非押下）〜 1.0（最大押下）

## データベース操作仕様

### 操作別データベース影響一覧

データベース操作はなし。マッピングデータはmap_db（Vector<JoyDeviceMapping>）としてメモリ上で管理。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 無効なデバイスID | 未接続または範囲外のデバイスID | falseまたはデフォルト値を返却 |
| - | 未知のコントローラー | マッピングデータベースに存在しないGUID | フォールバックマッピングを使用 |

### リトライ仕様

リトライ機構はなし。接続が切断された場合はjoy_connection_changedシグナルで通知。

## トランザクション仕様

トランザクション管理は不要。入力はリアルタイムで処理。

## パフォーマンス要件

- ポーリング間隔：フレームごと（16.6ms @ 60FPS）
- 入力レイテンシ：1フレーム以内

## セキュリティ考慮事項

- デバイスIDは0〜15の範囲で制限
- 外部からの不正なデバイスIDは無視

## 備考

- SDLゲームコントローラーデータベースのカスタムマッピング追加可能
- Joy lightサポート（対応コントローラーのみ）

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

ジョイパッドの内部状態とマッピング構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | input.h | `core/input/input.h` | Joypad構造体、JoyBinding構造体、JoyDeviceMapping構造体 |
| 1-2 | input_event.h | `core/input/input_event.h` | InputEventJoypadButton、InputEventJoypadMotion |

**読解のコツ**: Joypad構造体（175-188行目）はname、uid、connected、last_buttons、last_axis等のメンバを持ち、各コントローラーの状態を保持する。

#### Step 2: エントリーポイントを理解する

コントローラー接続とマッピング処理を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | input.cpp | `core/input/input.cpp` | joy_connection_changed、_set_joypad_mapping |
| 2-2 | input.h | `core/input/input.h` | joy_button、joy_axis、joy_hat |

**主要処理フロー**:
1. **338行目**: joy_connection_changed - 接続状態変更
2. **388-390行目**: joy_button、joy_axis、joy_hat - 入力イベント処理
3. **392-393行目**: add_joy_mapping、remove_joy_mapping - マッピング管理

#### Step 3: マッピングデータベースを理解する

SDLコントローラーDBとの互換性を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | input.cpp | `core/input/input.cpp` | parse_mapping関数 |
| 3-2 | gamecontrollerdb.txt | `core/input/gamecontrollerdb.txt` | SDLマッピングデータベース |

**主要処理フロー**:
- **43-65行目**: _joy_buttons、_joy_axes配列 - SDL標準名定義
- **387行目**: parse_mapping - マッピング文字列のパース

### プログラム呼び出し階層図

```
プラットフォーム固有API
    │
    ├─ Input::joy_connection_changed
    │      └─ joy_connection_changedシグナル発行
    │
    └─ Input::joy_button / joy_axis / joy_hat
           │
           ├─ _get_mapped_button_event / _get_mapped_axis_event
           │      └─ JoyDeviceMapping参照
           │
           └─ Input::parse_input_event
                  └─ InputEventJoypadButton/Motion生成
```

### データフロー図

```
[入力]                     [処理]                          [出力]

コントローラー ────▶ プラットフォームAPI ────▶ Input シングルトン
                                                    │
                                     ┌──────────────┼──────────────┐
                                     │              │              │
                                     ▼              ▼              ▼
                              マッピング変換    デッドゾーン     状態更新
                                     │          処理            (Joypad構造体)
                                     │              │
                                     └──────┬───────┘
                                            ▼
                                   InputEventJoypad*
                                            │
                                            ▼
                                   イベント伝播/API応答
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| input.h | `core/input/input.h` | ソース | Joypad、JoyBinding、JoyDeviceMapping定義 |
| input.cpp | `core/input/input.cpp` | ソース | ジョイパッド処理実装 |
| input_event.h | `core/input/input_event.h` | ソース | InputEventJoypad*定義 |
| input_event.cpp | `core/input/input_event.cpp` | ソース | ジョイパッドイベント実装 |
| input_enums.h | `core/input/input_enums.h` | ソース | JoyButton、JoyAxis等のenum定義 |
| gamecontrollerdb.txt | `core/input/gamecontrollerdb.txt` | データ | SDLマッピングデータベース |
| godotcontrollerdb.txt | `core/input/godotcontrollerdb.txt` | データ | Godot固有マッピング |
