# 機能設計書：270-imgui_impl_allegro5

## 1. 機能概要

### 1.1 機能名
Allegro5バックエンド（レンダラー + プラットフォーム統合）

### 1.2 機能説明
Allegro 5ライブラリを使用したDear ImGuiのレンダリングおよびプラットフォーム統合バックエンド。Allegro 5はウィンドウ、入力、グラフィックスなどを扱うクロスプラットフォーム汎用ライブラリであり、本バックエンドはレンダラーとプラットフォームの両方の機能を単一ファイルで提供する統合型バックエンドである。

### 1.3 対応機能フラグ
| フラグ | 対応状況 | 説明 |
|--------|----------|------|
| ImGuiBackendFlags_HasMouseCursors | 対応 | マウスカーソル形状変更をサポート |
| ImGuiBackendFlags_RendererHasTextures | 対応 | 動的フォントアトラス更新をサポート |

### 1.4 制限事項
- **レンダラーの最適化不足**: インデックスバッファのアンインデックス化と頂点形式の手動変換が必要
- **ゲームパッド未対応**: ゲームパッド入力機能は未実装
- **32ビットパックカラー未対応**: Allegro 5は32ビットパックカラーをサポートしないため、4つのfloatへの変換が必要

## 2. インターフェース設計

### 2.1 公開API

```cpp
// 初期化・終了
bool ImGui_ImplAllegro5_Init(ALLEGRO_DISPLAY* display);
void ImGui_ImplAllegro5_Shutdown();

// フレーム処理
void ImGui_ImplAllegro5_NewFrame();
void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data);

// イベント処理
bool ImGui_ImplAllegro5_ProcessEvent(ALLEGRO_EVENT* event);

// ディスプレイ設定
void ImGui_ImplAllegro5_SetDisplay(ALLEGRO_DISPLAY* display);

// デバイスオブジェクト管理
bool ImGui_ImplAllegro5_CreateDeviceObjects();
void ImGui_ImplAllegro5_InvalidateDeviceObjects();

// テクスチャ更新（上級者向け）
void ImGui_ImplAllegro5_UpdateTexture(ImTextureData* tex);
```

### 2.2 データ構造

#### ImGui_ImplAllegro5_Data（行98-112）
```cpp
struct ImGui_ImplAllegro5_Data
{
    ALLEGRO_DISPLAY*            Display;            // 現在のディスプレイ
    ALLEGRO_BITMAP*             Texture;            // フォントテクスチャ（互換用）
    double                      Time;               // 時間計測用
    ALLEGRO_MOUSE_CURSOR*       MouseCursorInvisible; // 非表示カーソル
    ALLEGRO_VERTEX_DECL*        VertexDecl;         // カスタム頂点宣言
    char*                       ClipboardTextData;  // クリップボードデータ
    ImGuiMouseCursor            LastCursor;         // 前回のカーソル形状

    ImVector<ImDrawVertAllegro> BufVertices;        // 頂点変換バッファ
    ImVector<int>               BufIndices;         // インデックス変換バッファ
};
```

#### ImDrawVertAllegro（行84-89）
```cpp
struct ImDrawVertAllegro
{
    ImVec2          pos;    // 位置座標
    ImVec2          uv;     // テクスチャ座標
    ALLEGRO_COLOR   col;    // 色（4 float形式）
};
```

### 2.3 テクスチャID仕様
- **型**: `ALLEGRO_BITMAP*`
- **使用法**: Allegro 5のビットマップポインタを直接ImTextureIDとして使用

## 3. 処理フロー

### 3.1 初期化フロー
```
ImGui_ImplAllegro5_Init(display)
    |
    +-- ImGuiIO& io = ImGui::GetIO()
    |
    +-- ImGui_ImplAllegro5_Data* bd = IM_NEW(...)
    |
    +-- io.BackendPlatformUserData = bd
    |
    +-- io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors
    |
    +-- io.BackendFlags |= ImGuiBackendFlags_RendererHasTextures
    |
    +-- ImGui_ImplAllegro5_SetDisplay(display)
    |       |
    |       +-- bd->Display = display
    |       |
    |       +-- カスタム頂点宣言の作成（al_create_vertex_decl）
    |
    +-- クリップボードハンドラの設定（Allegro 5.1.12以降）
```

### 3.2 フレーム更新フロー
```
ImGui_ImplAllegro5_NewFrame()
    |
    +-- デバイスオブジェクトの遅延作成
    |       |
    |       +-- ImGui_ImplAllegro5_CreateDeviceObjects()
    |               |
    |               +-- 非表示マウスカーソル作成
    |
    +-- ディスプレイサイズ取得
    |       |
    |       +-- al_get_display_width/height
    |       |
    |       +-- io.DisplaySize = ImVec2(w, h)
    |
    +-- 時間ステップ計算
    |       |
    |       +-- al_get_time()
    |       |
    |       +-- io.DeltaTime計算
    |
    +-- PrintScreen特殊処理（Windows）
    |
    +-- ImGui_ImplAllegro5_UpdateMouseCursor()
```

### 3.3 レンダリングフロー
```
ImGui_ImplAllegro5_RenderDrawData(draw_data)
    |
    +-- 最小化チェック
    |
    +-- テクスチャ更新処理
    |       |
    |       +-- ImGui_ImplAllegro5_UpdateTexture()
    |
    +-- Allegro状態バックアップ
    |       |
    |       +-- al_get_current_transform
    |       +-- al_get_current_projection_transform
    |       +-- al_get_clipping_rectangle
    |       +-- al_get_blender
    |
    +-- ImGui_ImplAllegro5_SetupRenderState()
    |       |
    |       +-- al_set_separate_blender（ブレンディング設定）
    |       +-- al_orthographic_transform（正射影行列）
    |
    +-- for each ImDrawList:
    |       |
    |       +-- 頂点変換（ImDrawVert → ImDrawVertAllegro）
    |       |       |
    |       |       +-- DRAW_VERT_IMGUI_TO_ALLEGRO マクロ
    |       |       +-- al_map_rgba による色変換
    |       |
    |       +-- インデックス変換（16bit → 32bit、必要時）
    |       |
    |       +-- for each ImDrawCmd:
    |               |
    |               +-- ユーザーコールバック処理
    |               |
    |               +-- クリッピング矩形計算
    |               |
    |               +-- al_set_clipping_rectangle
    |               |
    |               +-- al_draw_indexed_prim / al_draw_prim
    |
    +-- Allegro状態リストア
```

### 3.4 テクスチャ更新フロー
```
ImGui_ImplAllegro5_UpdateTexture(tex)
    |
    +-- WantCreate:
    |       |
    |       +-- al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP)
    |       +-- al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE)
    |       +-- al_create_bitmap → CPUビットマップ作成
    |       +-- al_lock_bitmap → ピクセルデータ書き込み
    |       +-- al_unlock_bitmap
    |       +-- al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP)
    |       +-- al_clone_bitmap → GPUビットマップへ変換
    |       +-- al_destroy_bitmap（CPUビットマップ破棄）
    |       +-- tex->SetTexID / SetStatus
    |
    +-- WantUpdates:
    |       |
    |       +-- al_lock_bitmap_region → 部分ロック
    |       +-- ピクセルデータコピー
    |       +-- al_unlock_bitmap
    |       +-- tex->SetStatus(ImTextureStatus_OK)
    |
    +-- WantDestroy:
            |
            +-- al_destroy_bitmap
            +-- tex->SetTexID(ImTextureID_Invalid)
            +-- tex->SetStatus(ImTextureStatus_Destroyed)
```

### 3.5 イベント処理フロー
```
ImGui_ImplAllegro5_ProcessEvent(ev)
    |
    +-- ALLEGRO_EVENT_MOUSE_AXES:
    |       +-- io.AddMousePosEvent
    |       +-- io.AddMouseWheelEvent
    |
    +-- ALLEGRO_EVENT_MOUSE_BUTTON_DOWN/UP:
    |       +-- io.AddMouseButtonEvent
    |
    +-- ALLEGRO_EVENT_TOUCH_MOVE:
    |       +-- io.AddMousePosEvent
    |
    +-- ALLEGRO_EVENT_TOUCH_BEGIN/END/CANCEL:
    |       +-- io.AddMouseButtonEvent
    |
    +-- ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY:
    |       +-- io.AddMousePosEvent(-FLT_MAX, -FLT_MAX)
    |
    +-- ALLEGRO_EVENT_KEY_CHAR:
    |       +-- io.AddInputCharacter
    |
    +-- ALLEGRO_EVENT_KEY_DOWN/UP:
    |       +-- ImGui_ImplAllegro5_UpdateKeyModifiers
    |       +-- ImGui_ImplAllegro5_KeyCodeToImGuiKey
    |       +-- io.AddKeyEvent
    |       +-- io.SetKeyEventNativeData
    |
    +-- ALLEGRO_EVENT_DISPLAY_SWITCH_OUT/IN:
            +-- io.AddFocusEvent
```

## 4. 技術的特性

### 4.1 頂点変換の仕組み
Allegro 5は32ビットパックカラー（ImU32）を直接サポートしないため、頂点ごとに色変換が必要：

```cpp
#define DRAW_VERT_IMGUI_TO_ALLEGRO(DST, SRC) { \
    (DST)->pos = (SRC)->pos; \
    (DST)->uv = (SRC)->uv; \
    unsigned char* c = (unsigned char*)&(SRC)->col; \
    (DST)->col = al_map_rgba(c[0], c[1], c[2], c[3]); \
}
```

### 4.2 インデックス描画対応
Allegro 5.2.5以降ではal_draw_indexed_primが使用可能：

```cpp
#define ALLEGRO_HAS_DRAW_INDEXED_PRIM \
    ((ALLEGRO_VERSION_INT & ~ALLEGRO_UNSTABLE_BIT) >= ((5 << 24) | (2 << 16) | (5 << 8)))
```

- **5.2.5以降**: `al_draw_indexed_prim`使用（効率的）
- **5.2.5未満**: `al_draw_prim`使用（頂点展開が必要）

### 4.3 クリップボード対応
Allegro 5.1.12以降でクリップボードをサポート：

```cpp
#define ALLEGRO_HAS_CLIPBOARD \
    ((ALLEGRO_VERSION_INT & ~ALLEGRO_UNSTABLE_BIT) >= ((5 << 24) | (1 << 16) | (12 << 8)))
```

### 4.4 ブレンディング設定
```cpp
al_set_separate_blender(
    ALLEGRO_ADD,             // カラー演算
    ALLEGRO_ALPHA,           // ソースカラー
    ALLEGRO_INVERSE_ALPHA,   // デストカラー
    ALLEGRO_ADD,             // アルファ演算
    ALLEGRO_ONE,             // ソースアルファ
    ALLEGRO_INVERSE_ALPHA    // デストアルファ
);
```

### 4.5 カスタム頂点宣言
```cpp
ALLEGRO_VERTEX_ELEMENT elems[] = {
    { ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, offsetof(ImDrawVertAllegro, pos) },
    { ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, offsetof(ImDrawVertAllegro, uv) },
    { ALLEGRO_PRIM_COLOR_ATTR, 0, offsetof(ImDrawVertAllegro, col) },
    { 0, 0, 0 }
};
```

## 5. 入力処理

### 5.1 マウスカーソルマッピング
| ImGuiMouseCursor | ALLEGRO_SYSTEM_MOUSE_CURSOR |
|------------------|------------------------------|
| TextInput | ALLEGRO_SYSTEM_MOUSE_CURSOR_EDIT |
| ResizeAll | ALLEGRO_SYSTEM_MOUSE_CURSOR_MOVE |
| ResizeNS | ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_N |
| ResizeEW | ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_E |
| ResizeNESW | ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NE |
| ResizeNWSE | ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NW |
| Wait | ALLEGRO_SYSTEM_MOUSE_CURSOR_BUSY |
| Progress | ALLEGRO_SYSTEM_MOUSE_CURSOR_PROGRESS |
| NotAllowed | ALLEGRO_SYSTEM_MOUSE_CURSOR_UNAVAILABLE |

### 5.2 キーマッピング
`ImGui_ImplAllegro5_KeyCodeToImGuiKey`関数（行359-470）で、ALLEGRO_KEYコードからImGuiKeyへの完全なマッピングを提供。

主要なマッピング例：
- `ALLEGRO_KEY_TAB` → `ImGuiKey_Tab`
- `ALLEGRO_KEY_ENTER` → `ImGuiKey_Enter`
- `ALLEGRO_KEY_ESCAPE` → `ImGuiKey_Escape`
- `ALLEGRO_KEY_A-Z` → `ImGuiKey_A-Z`
- `ALLEGRO_KEY_F1-F12` → `ImGuiKey_F1-F12`

### 5.3 修飾キー処理
```cpp
static void ImGui_ImplAllegro5_UpdateKeyModifiers()
{
    ALLEGRO_KEYBOARD_STATE keys;
    al_get_keyboard_state(&keys);
    io.AddKeyEvent(ImGuiMod_Ctrl, al_key_down(&keys, ALLEGRO_KEY_LCTRL) || ...);
    io.AddKeyEvent(ImGuiMod_Shift, al_key_down(&keys, ALLEGRO_KEY_LSHIFT) || ...);
    io.AddKeyEvent(ImGuiMod_Alt, al_key_down(&keys, ALLEGRO_KEY_ALT) || ...);
    io.AddKeyEvent(ImGuiMod_Super, al_key_down(&keys, ALLEGRO_KEY_LWIN) || ...);
}
```

### 5.4 タッチスクリーンサポート
- `ALLEGRO_EVENT_TOUCH_MOVE`: マウス位置として処理
- `ALLEGRO_EVENT_TOUCH_BEGIN/END/CANCEL`: 主タッチのみマウスボタン0として処理

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

### 6.1 推奨読解順序

1. **データ構造の理解**
   - `ImDrawVertAllegro`（行84-89）: カスタム頂点形式
   - `ImGui_ImplAllegro5_Data`（行98-112）: バックエンドデータ

2. **初期化フロー**
   - `ImGui_ImplAllegro5_Init`（行472-496）: バックエンド初期化
   - `ImGui_ImplAllegro5_SetDisplay`（行519-544）: ディスプレイ設定と頂点宣言作成

3. **レンダリング処理**
   - `ImGui_ImplAllegro5_SetupRenderState`（行119-137）: レンダリング状態設定
   - `ImGui_ImplAllegro5_RenderDrawData`（行140-242）: メイン描画処理
   - `DRAW_VERT_IMGUI_TO_ALLEGRO`マクロ（行95）: 頂点変換

4. **テクスチャ管理**
   - `ImGui_ImplAllegro5_UpdateTexture`（行257-318）: テクスチャ作成・更新・破棄

5. **入力処理**
   - `ImGui_ImplAllegro5_ProcessEvent`（行562-626）: イベントハンドリング
   - `ImGui_ImplAllegro5_KeyCodeToImGuiKey`（行359-470）: キーコード変換

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

```
[アプリケーション]
    |
    +-- ImGui_ImplAllegro5_Init
    |       +-- ImGui_ImplAllegro5_SetDisplay
    |               +-- al_create_vertex_decl
    |
    +-- [メインループ]
    |       |
    |       +-- ImGui_ImplAllegro5_ProcessEvent (イベントごと)
    |       |       +-- ImGui_ImplAllegro5_UpdateKeyModifiers
    |       |       +-- ImGui_ImplAllegro5_KeyCodeToImGuiKey
    |       |
    |       +-- ImGui_ImplAllegro5_NewFrame
    |       |       +-- ImGui_ImplAllegro5_CreateDeviceObjects
    |       |       +-- ImGui_ImplAllegro5_UpdateMouseCursor
    |       |
    |       +-- [ImGuiフレーム処理]
    |       |
    |       +-- ImGui_ImplAllegro5_RenderDrawData
    |               +-- ImGui_ImplAllegro5_UpdateTexture
    |               +-- ImGui_ImplAllegro5_SetupRenderState
    |               +-- al_draw_indexed_prim / al_draw_prim
    |
    +-- ImGui_ImplAllegro5_Shutdown
            +-- ImGui_ImplAllegro5_InvalidateDeviceObjects
                    +-- ImGui_ImplAllegro5_UpdateTexture (WantDestroy)
```

### 6.3 データフロー図

```
[入力イベント]
    |
    v
ImGui_ImplAllegro5_ProcessEvent
    |
    +--[マウス]-----> io.AddMousePosEvent / AddMouseButtonEvent / AddMouseWheelEvent
    |
    +--[キーボード]--> io.AddKeyEvent / AddInputCharacter
    |
    +--[タッチ]------> io.AddMousePosEvent / AddMouseButtonEvent
    |
    +--[フォーカス]--> io.AddFocusEvent


[描画データ]
    |
    v
ImDrawData
    |
    +-- Textures[] -----> ImGui_ImplAllegro5_UpdateTexture
    |                           |
    |                           +-- WantCreate: al_create_bitmap → al_clone_bitmap
    |                           +-- WantUpdates: al_lock_bitmap_region → memcpy
    |                           +-- WantDestroy: al_destroy_bitmap
    |
    +-- CmdLists[] -----> 頂点/インデックス変換
                                |
                                +-- ImDrawVert → ImDrawVertAllegro (DRAW_VERT_IMGUI_TO_ALLEGRO)
                                +-- ImDrawIdx (16bit) → int (32bit)
                                |
                                v
                        al_draw_indexed_prim / al_draw_prim
                                |
                                v
                        [Allegro 5描画出力]
```

### 6.4 関連ファイル一覧

| ファイル | 役割 | 行数 |
|----------|------|------|
| `backends/imgui_impl_allegro5.h` | ヘッダファイル（API宣言） | 45行 |
| `backends/imgui_impl_allegro5.cpp` | 実装ファイル | 699行 |

### 6.5 重要なAllegro 5 API

| API | 用途 | 使用箇所 |
|-----|------|----------|
| `al_create_bitmap` | ビットマップ作成 | UpdateTexture |
| `al_clone_bitmap` | CPU→GPUビットマップ変換 | UpdateTexture |
| `al_lock_bitmap` | ピクセルアクセス用ロック | UpdateTexture |
| `al_draw_indexed_prim` | インデックス付き描画 | RenderDrawData |
| `al_draw_prim` | 非インデックス描画（旧バージョン用） | RenderDrawData |
| `al_set_separate_blender` | ブレンディング設定 | SetupRenderState |
| `al_orthographic_transform` | 正射影変換 | SetupRenderState |
| `al_create_vertex_decl` | カスタム頂点宣言 | SetDisplay |
| `al_map_rgba` | 色変換（U32→ALLEGRO_COLOR） | 頂点変換 |
| `al_get_time` | 時間取得 | NewFrame |
| `al_get_keyboard_state` | キーボード状態取得 | UpdateKeyModifiers |
| `al_set_system_mouse_cursor` | システムカーソル設定 | UpdateMouseCursor |

## 7. 使用例

### 7.1 基本的な使用パターン

```cpp
// 初期化
ALLEGRO_DISPLAY* display = al_create_display(1280, 720);
ImGui::CreateContext();
ImGui_ImplAllegro5_Init(display);

// イベントキューの設定
ALLEGRO_EVENT_QUEUE* queue = al_create_event_queue();
al_register_event_source(queue, al_get_display_event_source(display));
al_register_event_source(queue, al_get_keyboard_event_source());
al_register_event_source(queue, al_get_mouse_event_source());

// メインループ
while (running)
{
    ALLEGRO_EVENT ev;
    while (al_get_next_event(queue, &ev))
    {
        ImGui_ImplAllegro5_ProcessEvent(&ev);
        // アプリケーションイベント処理
    }

    ImGui_ImplAllegro5_NewFrame();
    ImGui::NewFrame();

    // ImGui UI構築
    ImGui::ShowDemoWindow();

    ImGui::Render();
    al_clear_to_color(al_map_rgb(0, 0, 0));
    ImGui_ImplAllegro5_RenderDrawData(ImGui::GetDrawData());
    al_flip_display();
}

// 終了処理
ImGui_ImplAllegro5_Shutdown();
ImGui::DestroyContext();
```

### 7.2 ディスプレイ変更

```cpp
// 新しいディスプレイに切り替え
ALLEGRO_DISPLAY* new_display = al_create_display(1920, 1080);
ImGui_ImplAllegro5_SetDisplay(new_display);
```
