# 機能設計書 72-スクリーンショット出力

## 概要

プレイ画面をPNG形式の連番ファイルとして出力するスクリーンショット機能の設計書である。

### 本機能の処理概要

プレイ中の画面をフレーム単位でキャプチャし、PNG形式の連番画像ファイルとして指定ディレクトリに出力する機能である。動画制作等のオフライン利用を想定したフレーム単位の画像出力を提供する。

**業務上の目的・背景**：プレイ動画の作成や、プレイの記録・分析のために、ゲーム画面をフレーム単位でキャプチャして静止画として保存する必要がある。output変数を有効にすることで、毎フレームの画面をPNG連番で出力できる。

**機能の利用シーン**：output変数が0以外(出力モード有効)の場合に、毎フレームの描画結果がPNG連番ファイルとして保存される。動画編集ソフトで連番画像を読み込み、プレイ動画として結合する用途を想定している。

**主要な処理内容**：
1. hgcapture2命令でプレイ画面のフレームバッファをキャプチャする
2. alSelectImage/alCopyScreenToImageで画像オブジェクトにコピーする
3. outputds(ダウンスケール倍率)が1より大きい場合、alStretchImageToImageで縮小する
4. 連番のファイル名(6桁ゼロパディング)を生成する
5. alSaveFileでPNG形式でoutputpathディレクトリに保存する

**関連システム・外部連携**：artlet2d(alXxx系関数)による画像処理・ファイル保存機能を利用する。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 5 | ゲームプレイ画面 | 主画面 | play_draw_frame.hspによるPNG連番出力スクリーンショット機能 |

## 機能種別

ファイル出力処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| output | int | Yes | 出力モード(0:無効, 1以上:有効) | 0以上の整数 |
| outputds | int | Yes | ダウンスケール倍率(1:等倍, 2以上:縮小) | 1以上の整数 |
| outputpath | string | Yes | 出力先ディレクトリパス | 有効なパス |
| scrsize_w | int | Yes | 画面幅(ピクセル) | 正の整数 |
| scrsize_h | int | Yes | 画面高さ(ピクセル) | 正の整数 |
| cnt | int | Yes | フレームカウンタ(ループ内のカウント変数) | 0以上の整数 |

### 入力データソース

プレイ画面のフレームバッファ(ウィンドウID 0)からhgcapture2命令で画面データを取得する。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| PNG画像ファイル | file | outputpath + 連番6桁ゼロパディング + cnt + ".png"形式の画像ファイル |

### 出力先

outputpath変数で指定されたディレクトリにPNGファイルとして出力される。ファイル名は6桁のゼロパディング連番となる。

## 処理フロー

### 処理シーケンス

```
1. saveFrameImage (フレーム画像保存)
   ├─ gsel 0 でメインウィンドウを選択
   ├─ hgcapture2 で画面全体をキャプチャ
   ├─ alSelectImage 50 で画像バッファ50を選択
   ├─ alCopyScreenToImage で画面を画像バッファにコピー
   ├─ outputds > 1 の場合:
   │   └─ alStretchImageToImage で縮小処理
   ├─ alSelectImage 50 で再選択
   ├─ 連番ファイル名を6桁ゼロパディングで生成
   └─ alSaveFile でPNG形式で保存
```

### フローチャート

```mermaid
flowchart TD
    A[saveFrameImage開始] --> B[gsel 0 - メインウィンドウ選択]
    B --> C[hgcapture2 - 画面キャプチャ]
    C --> D[alSelectImage 50]
    D --> E[alCopyScreenToImage]
    E --> F{outputds > 1?}
    F -->|Yes| G[alStretchImageToImage - 縮小]
    F -->|No| H[alSelectImage 50]
    G --> H
    H --> I[連番ファイル名生成 - 6桁ゼロパディング]
    I --> J[alSaveFile - PNG保存]
    J --> K[return]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-72-01 | ゼロパディング | ファイル名は6桁のゼロパディング(例: 000001.png) | ファイル名生成時 |
| BR-72-02 | ダウンスケール | outputdsが1より大きい場合、幅と高さをoutputdsで除算した解像度で保存 | outputds > 1 |
| BR-72-03 | 画像フォーマット | 出力フォーマットは常にPNG("image/png") | ファイル保存時 |
| BR-72-04 | 動画再生抑止 | output != 0の場合、動画再生(vmov)は抑止される | 出力モード有効時 |

### 計算ロジック

- 出力解像度: `alGetWidth()/outputds` x `alGetHeight()/outputds`
- ファイル名パディング: `max(6-strlen(cnt文字列), 0)` 個のゼロを前置

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

該当なし（ファイル出力処理のため）。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 書き込みエラー | outputpathが無効または書き込み権限なし | 明示的なエラー処理はない |
| - | ディスク容量不足 | 連番出力でディスク容量が不足 | 明示的なエラー処理はない |

### リトライ仕様

リトライ処理は実装されていない。

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

該当なし。

## パフォーマンス要件

- 毎フレームのPNG出力はI/O負荷が高いため、リアルタイム再生には影響を与える可能性がある
- outputモード時はFPS表示やタイミング調整値の表示が抑止される(output=0条件による制御)

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

- outputpathで指定された任意のディレクトリにファイルが出力される
- 大量のファイルが生成されるため、ディスク容量の監視が必要

## 備考

- output変数が有効な場合、動画再生(cmovfile関連)やFPS表示等の一部機能が抑止される
- 画像バッファID 50がスクリーンショット用の一時バッファとして使用される
- artlet2d(alpng.dll)のalSaveFile関数を使用してPNGエンコードを行う

---

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

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

### 推奨読解順序

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

本機能で使用される変数を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | kshootmania.hsp | `kshootmania.hsp` | output, outputds, outputpath変数の定義・初期化箇所を確認する |

**読解のコツ**: HSP3ではalXxx系関数はartlet2dプラグイン(alpng.dll)が提供する画像処理関数群である。hgcapture2は3D描画結果を2Dバッファにキャプチャするhgimg3の関数である。

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

画像保存処理の関数を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | play_draw_frame.hsp | `src/scene/play/play_draw_frame.hsp` | saveFrameImage関数(1166-1181行目)でキャプチャ・保存処理を理解する |

**主要処理フロー**:
1. **1167行目**: `gsel 0` - メインウィンドウ(ID:0)を選択
2. **1168行目**: `hgcapture2 0,0,0,scrsize_w,scrsize_h,0,0` - 画面全体をキャプチャ(3D描画結果を2Dバッファに転送)
3. **1169行目**: `alSelectImage 50` - 画像バッファ50を選択
4. **1170行目**: `alCopyScreenToImage 0,50` - 画面の内容を画像バッファにコピー
5. **1171-1173行目**: ダウンスケール処理 - outputds>1の場合、alStretchImageToImageで元画像を縮小
6. **1174行目**: `alSelectImage 50` - 再度画像バッファ50を選択
7. **1175-1179行目**: ファイル名のゼロパディング処理 - cntの桁数に応じて先頭に"0"を追加して6桁に揃える
8. **1180行目**: `alSaveFile outputpath+stat2+cnt+".png", "image/png",0,0,alGetWidth()/outputds,alGetHeight()/outputds` - PNG形式でファイル保存

#### Step 3: 出力モードの影響範囲を理解する

output変数による他機能への影響を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | play_draw_frame.hsp | `src/scene/play/play_draw_frame.hsp` | drawFrame関数内のoutput変数による条件分岐(1049行目等) |
| 3-2 | play_video.hsp | `src/scene/play/play_video.hsp` | output=0条件による動画再生の抑止(2行目, 16行目) |

**主要処理フロー**:
- **1049行目**: `if(output=0)` - FPS表示やタイミング調整値の表示はoutput=0の場合のみ
- **1116行目**: `if(...adjmode!=1)&(output=0)` - プレイ結果表示もoutput=0の場合のみ
- **1137行目**: `if(...output=0)` - プレイ終了フェードアウトもoutput=0条件あり

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

```
drawFrame (描画フレーム - 毎フレーム呼び出し)
    │
    └─ (描画完了後)
           │
           └─ saveFrameImage (output != 0 の場合呼び出し)
                  ├─ hgcapture2 (画面キャプチャ)
                  ├─ alCopyScreenToImage (画像バッファコピー)
                  ├─ alStretchImageToImage (ダウンスケール - 条件付き)
                  └─ alSaveFile (PNG保存)
```

### データフロー図

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

プレイ画面             ──▶ hgcapture2               ──▶ 2Dバッファ
(3D描画結果)                (画面キャプチャ)
                              │
2Dバッファ             ──▶ alCopyScreenToImage     ──▶ 画像バッファ50
                              │
画像バッファ50         ──▶ alStretchImageToImage   ──▶ 縮小画像(条件付き)
outputds                      │
                              │
outputpath + cnt       ──▶ alSaveFile              ──▶ PNG連番ファイル
                              ("image/png")              (outputpath/000001.png等)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| play_draw_frame.hsp | `src/scene/play/play_draw_frame.hsp` | ソース | saveFrameImage関数の定義(1166-1181行目) |
| play_video.hsp | `src/scene/play/play_video.hsp` | ソース | output変数による動画再生抑止の参照 |
| kshootmania.hsp | `kshootmania.hsp` | ソース | output, outputds, outputpath等の変数定義 |
