# 帳票設計書 2-背景画像キャッシュ

## 概要

本ドキュメントは、K-ShootMANIAのプレイ画面で使用する背景画像を事前計算し、JPEG形式でキャッシュディレクトリに保存する「背景画像キャッシュ」機能の帳票設計書である。ゲーム起動時のロード高速化を目的として、元画像を適切なサイズにリサイズしてキャッシュする。

### 本帳票の処理概要

本帳票は、プレイシーン開始時に背景画像の読み込み・リサイズ処理を行い、その結果をJPEG形式でキャッシュディレクトリに保存する機能を提供する。2回目以降はキャッシュファイルの存在チェックにより再生成をスキップし、高速な読み込みを実現する。

**業務上の目的・背景**：音楽ゲームでは楽曲ごとに異なる背景画像が使用される。背景画像の元データは720x640ピクセル等の固定サイズだが、画面サイズに合わせたリサイズ処理が毎回必要になる。この処理コストを初回のみに限定し、キャッシュ済みのリサイズ画像を再利用することで、2回目以降のプレイ開始を高速化する。

**帳票の利用シーン**：プレイシーン初期化時に背景画像を読み込む際、キャッシュが存在しない場合に自動生成される。プレイヤーが楽曲を初めて選択した時、またはキャッシュディレクトリが削除された後の再生成時に利用される。

**主要な出力内容**：
1. 通常ゲージ用背景画像（bgname+"0.jpg"）- ゲージ70%未満の背景
2. クリア済ゲージ用背景画像（bgname+"1.jpg"）- ゲージ70%以上の背景
3. 外部指定背景画像のキャッシュ（playbg0.jpg, playbg1.jpg）- KSHファイルでカスタム背景が指定された場合

**帳票の出力タイミング**：プレイシーン初期化時のloadBGGraphics関数呼び出し時。キャッシュファイルが存在しない場合のみ生成される（exist命令によるファイル存在チェック）。

**帳票の利用者**：K-ShootMANIAのランタイムエンジンが内部的に利用する。プレイヤーが直接操作することはないが、キャッシュディレクトリの手動削除によりキャッシュを再生成できる。

## 帳票種別

画像出力（JPEG画像キャッシュ）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| - | プレイシーン初期化 | SCENE_PLAY（play_init.hsp） | loadBGGraphics呼び出し時に自動生成 |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | JPEG（image/jpeg） |
| 用紙サイズ | 該当なし |
| 向き | 横 |
| ファイル名 | cache/bg/{bgname}0.jpg, cache/bg/{bgname}1.jpg または cache/playbg0.jpg, cache/playbg1.jpg |
| 出力方法 | ローカルファイルシステムへの直接書き出し |
| 文字コード | 該当なし（バイナリ画像） |

### JPEG固有設定

| 項目 | 内容 |
|-----|------|
| 画像サイズ | getsize(900) x getsize(800) ピクセル（画面サイズ依存の動的計算値） |
| 元画像サイズ | 720 x 640 ピクセル |
| リサイズ方式 | alStretchScreenToImage による拡大縮小 |

## 帳票レイアウト

### レイアウト概要

背景画像は3Dオブジェクトとしてプレイシーンのレーン背後に表示される。各楽曲に0番（通常状態）と1番（クリア状態）の2枚が存在する。

```
+-------------------------------------------+
|                                           |
|    背景画像（bgname0.jpg）                 |
|    - 通常ゲージ時の背景                     |
|    - 720x640 -> getsize(900)xgetsize(800)  |
|                                           |
+-------------------------------------------+

+-------------------------------------------+
|                                           |
|    背景画像（bgname1.jpg）                 |
|    - クリアゲージ時の背景                   |
|    - 720x640 -> getsize(900)xgetsize(800)  |
|                                           |
+-------------------------------------------+
```

### ヘッダー部

該当なし（画像ファイルのため構造化されたヘッダーはない）

### 明細部

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 列幅 |
|----|-------|------|-------------|---------|-----|
| 1 | 背景画像0 | 通常ゲージ状態の背景 | imgs/bg/{bgname}0.jpg | JPEG画像 | - |
| 2 | 背景画像1 | クリアゲージ状態の背景 | imgs/bg/{bgname}1.jpg | JPEG画像 | - |

### フッター部

該当なし

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| bg設定が1以上 | config.iniのbackground設定が1以上であること | Yes |
| キャッシュ未生成 | cache/bg/{bgname}0.jpg が存在しないこと（strsize=-1） | Yes（再生成条件） |
| 元画像存在 | imgs/bg/{bgname}0.jpg および imgs/bg/{bgname}1.jpg が存在すること | Yes |

### ソート順

該当なし（固定2ファイル出力）

### 改ページ条件

該当なし

## データベース参照仕様

### 参照テーブル一覧

本帳票はデータベースを使用しない。以下の変数とファイルを参照する。

| データ構造名 | 用途 | 備考 |
|-----------|------|---------|
| bgname | 背景画像名 | KSHファイルのbg=パラメータから取得 |
| bg | 背景表示レベル | config.iniのbackground設定（0=OFF, 1=ON, 2=アニメーション付き） |
| dir_default | アプリケーションルートディレクトリ | 各パスの基底 |
| scrsize_h | 画面高さ | 解像度計算に使用 |

### テーブル別参照項目詳細

#### 元画像ファイル

| 参照項目（ファイル名） | 帳票項目との対応 | 取得条件 | 備考 |
|-------------------|----------------|---------|------|
| imgs/bg/{bgname}0.jpg | 通常背景キャッシュの元画像 | ファイル存在チェック（exist命令） | 存在しない場合bgname="desert"にフォールバック |
| imgs/bg/{bgname}1.jpg | クリア背景キャッシュの元画像 | ファイル存在チェック（exist命令） | 存在しない場合bgname="desert"にフォールバック |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| キャッシュ画像幅 | getsize(900) = 900*scrsize_h/480 の2のべき乗に切り上げた値 | getsize関数依存 | 画面サイズに比例 |
| キャッシュ画像高さ | getsize(800) = 800*scrsize_h/480 の2のべき乗に切り上げた値 | getsize関数依存 | 画面サイズに比例 |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[loadBGGraphics呼び出し] --> B{bg >= 1 ?}
    B -->|No| Z[終了 - 背景なし]
    B -->|Yes| C{元画像存在チェック}
    C -->|両方存在| D[stat3=0: 通常パス]
    C -->|片方以上不存在| E[bgname分割チェック]
    E -->|セミコロン区切り| F[bgname2配列に分割]
    E -->|ファイル不存在| G[bgname=desert にフォールバック]
    F --> H[stat3=1: 外部パス]
    D --> I[cache/bgディレクトリ確認・作成]
    G --> I
    I --> J{キャッシュファイル存在?}
    J -->|Yes| K[キャッシュからtexload]
    J -->|No| L[元画像をpicload]
    L --> M[alCreateImage でリサイズ用Image作成]
    M --> N[alStretchScreenToImage でリサイズ]
    N --> O[alSaveFile でJPEG保存]
    O --> P[alDeleteImage でImage解放]
    P --> K
    H --> Q[外部画像をpicload]
    Q --> R[alStretchScreenToImage + alSaveFile]
    R --> S[texload でテクスチャ化]
    K --> T[addspr でスプライト登録]
    T --> U[regobj obj_bg でオブジェクト登録]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| 元画像不存在 | imgs/bg/配下に指定背景画像がない | なし（サイレント） | bgname="desert"にフォールバック |
| 外部画像不存在 | KSHで指定されたカスタム背景が見つからない | なし（サイレント） | bgname="desert"にフォールバック |
| キャッシュディレクトリ不存在 | cache/bgディレクトリが未作成 | なし（サイレント） | mkdir で自動作成 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 楽曲あたり2ファイル（通常+クリア背景） |
| 目標出力時間 | 初回キャッシュ生成: 数百ms、2回目以降: キャッシュ読み込みのみ |
| 同時出力数上限 | 2（背景0と背景1） |

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

- キャッシュファイルはアプリケーションディレクトリ内のcache/bgサブディレクトリに限定される
- 外部指定パスの場合もKSHファイル内の設定値に基づくためユーザー入力によるパストラバーサルのリスクは低い
- JPEG圧縮により元画像の厳密な画質は保持されないが、背景表示用途では十分な品質

## 備考

- bgパラメータにセミコロン区切りで2つのパスが指定された場合、それぞれを背景0と背景1として扱う（play_graphics.hsp:58-66）
- 外部画像パスの場合はcache/playbg0.jpg, cache/playbg1.jpgとして保存される（play_graphics.hsp:109,117）
- 背景画像は3Dスプライトとしてmod_bg0, mod_bg1に登録され、ゲージ状態に応じて切り替わる

---

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

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

### 推奨読解順序

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

背景画像に関連するグローバル変数とファイル構成を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | kshootmania.hsp | `kshootmania.hsp` | bg変数（背景表示レベル）、bgname変数（背景名）の定義箇所を確認 |

**読解のコツ**: bgname変数はKSHファイルのヘッダー部から読み込まれる。bg変数はconfig.iniのbackground=設定から読み込まれ、0=OFF, 1=ON, 2=アニメーション付きの3段階。

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

loadBGGraphics関数がどのタイミングで呼び出されるかを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | play_init.hsp | `src/scene/play/play_init.hsp` | 682行目: loadBGGraphicsの呼び出し。他のグラフィック初期化関数と並んで呼ばれる |

**主要処理フロー**:
1. **play_init.hsp:682**: loadBGGraphicsが呼び出される
2. **play_graphics.hsp:50**: loadBGGraphics関数の定義開始

#### Step 3: キャッシュ生成処理を理解する

loadBGGraphics関数の内部処理を詳細に読む。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | play_graphics.hsp | `src/scene/play/play_graphics.hsp` | 50-124行目: loadBGGraphics関数。bg>=1の場合のみ実行 |

**主要処理フロー**:
- **51行目**: bg>=1 のチェック
- **53-56行目**: 元画像（bgname0.jpg, bgname1.jpg）の存在チェック（exist命令）
- **57-74行目**: ファイル不存在時のフォールバック処理（セミコロン分割、desert指定）
- **78-79行目**: cache/bgディレクトリの存在確認と自動作成（mkdir）
- **82-83行目**: キャッシュファイルの存在チェック
- **84-89行目**: キャッシュ未生成時 - picloadで元画像読み込み、alCreateImage→alStretchScreenToImage→alSaveFileでキャッシュ保存
- **91行目**: texloadでキャッシュファイルをテクスチャとして読み込み
- **92行目**: addsprでスプライトモデルを作成
- **104-121行目**: 外部画像パスの場合の処理（cache/playbg0.jpg, playbg1.jpgとして保存）
- **122行目**: regobj obj_bg,mod_bg0 で3Dオブジェクトとして登録

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

```
start_play (play_init.hsp)
    |
    +-- loadBGGraphics (play_graphics.hsp:50)
            |
            +-- exist (元画像存在チェック)
            |
            +-- split bgname,";" (セミコロン分割チェック)
            |
            +-- mkdir "cache/bg" (ディレクトリ作成)
            |
            +-- [通常パス] exist (キャッシュ存在チェック)
            |       |
            |       +-- [キャッシュなし]
            |       |       picload (元画像読み込み)
            |       |       alCreateImage (リサイズ用Image作成)
            |       |       alStretchScreenToImage (リサイズ)
            |       |       alSaveFile (JPEG保存)
            |       |       alDeleteImage (Image解放)
            |       |
            |       +-- texload (キャッシュからテクスチャ読み込み)
            |       +-- addspr (スプライト登録)
            |
            +-- [外部パス]
            |       picload (外部画像読み込み)
            |       alStretchScreenToImage (リサイズ)
            |       alSaveFile (playbg0/1.jpgとして保存)
            |       texload (テクスチャ読み込み)
            |       addspr (スプライト登録)
            |
            +-- regobj obj_bg,mod_bg0 (3Dオブジェクト登録)
```

### データフロー図

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

imgs/bg/               play_graphics.hsp               cache/bg/
  {bgname}0.jpg  --->    loadBGGraphics (50-124行目)      {bgname}0.jpg
  {bgname}1.jpg          |                               {bgname}1.jpg
                         +-- picload                      または
外部指定画像             +-- alStretchScreenToImage       cache/
  (KSHパス)              +-- alSaveFile                    playbg0.jpg
                                                           playbg1.jpg
                                    |
                                    v
                              3Dオブジェクト
                               mod_bg0 / mod_bg1
                               obj_bg
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| play_graphics.hsp | `src/scene/play/play_graphics.hsp` | ソース | loadBGGraphics関数定義（50-124行目）。キャッシュ生成の主処理 |
| play_init.hsp | `src/scene/play/play_init.hsp` | ソース | loadBGGraphicsの呼び出し元（682行目） |
| play_draw_frame.hsp | `src/scene/play/play_draw_frame.hsp` | ソース | 背景オブジェクト（obj_bg）の描画時利用（642-672行目） |
| kshootmania.hsp | `kshootmania.hsp` | ソース | bg変数のconfig.iniからの読み込み（525-526行目） |
| config.ini | `config.ini` | 設定 | background=設定の格納先 |
