# 機能設計書 70-描画品質制御

## 概要

本ドキュメントは、K-Shoot MANIA における描画品質制御機能の設計を記述する。lowquality 変数による 3 段階（HIGH / MEDIUM / SMALL）のテクスチャ解像度スケーリングと、bg 変数による背景描画レベル（HIDE / STANDARD / ANIME）の制御を行い、描画負荷を調整する。

### 本機能の処理概要

**業務上の目的・背景**：リズムゲームではフレームレートの安定が操作性に直結するため、プレイヤーの環境に応じて描画品質を段階的に調整できる必要がある。描画品質制御により、低スペック環境でも安定した動作を実現しつつ、高スペック環境では高品質な描画を提供する。

**機能の利用シーン**：オプション設定画面で描画品質（LARGE / MEDIUM / SMALL）を変更する。設定変更後、タイトル画面に戻る際にテクスチャキャッシュの再構築が行われる。プレイ画面では ra 変数（解像度スケーリング係数）を通じて、全ての描画座標とバッファサイズがスケーリングされる。

**主要な処理内容**：
1. lowquality 変数による解像度スケーリング係数 ra の算出（ra = max(powf(2, lowquality), 1)）
2. ra を用いたテクスチャバッファサイズの縮小（幅/ra, 高さ/ra）
3. ra を用いた描画座標のスケーリング（座標/ra）
4. bg 変数による背景描画レベルの制御（bg=0: 非表示, bg>=1: 背景画像, bg>=2: レイヤーアニメーション）
5. レーンオブジェクトの透過度制御（bg=0 でエフェクト値変更）
6. オプション設定画面での lowquality / bg の変更操作
7. config.ini への設定保存・読み込み
8. 設定変更時のテクスチャキャッシュ再構築

**関連システム・外部連携**：config.ini への設定保存・読み込み。オプション設定画面（option.hsp）での設定変更 UI。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 5 | ゲームプレイ画面 | 主画面 | play_graphics.hsp / play_draw_frame.hsp による ra 変数を用いたテクスチャスケーリングと描画座標計算 |
| 8 | オプション設定画面 | 設定画面 | lowquality / bg 変数の変更操作と表示ラベル |
| 1 | タイトル画面 | 処理画面 | テクスチャキャッシュの再構築（imgrefresh=1 時） |

## 機能種別

設定変更 / 描画制御 / リソース管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| lowquality | int | Yes | 描画品質レベル（0=HIGH, 1=MEDIUM, 2=SMALL） | 0, 1, 2 |
| bg | int | Yes | 背景描画レベル（0=HIDE, 1=STANDARD, 2=ANIME） | 0, 1, 2 |

### 入力データソース

config.ini の `lowquality=` および `background=` パラメータ。オプション設定画面での左右キー操作。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ra | int | 解像度スケーリング係数（1, 2, 4） |
| lowquality | int | 描画品質レベル |
| bg | int | 背景描画レベル |

### 出力先

config.ini（lowquality / background の保存）。テクスチャバッファ（スケーリング後のサイズで再構築）。

## 処理フロー

### 処理シーケンス

```
1. 初期化 (kshootmania.hsp)
   1-1. デフォルト値設定: lowquality=1, highquality=0, bg=1
2. config.ini 読み込み (kshootmania.hsp)
   2-1. "lowquality=" → lowquality変数に代入（504-505行目）
   2-2. "background=" → bg変数に代入（525-526行目）
3. テクスチャキャッシュ構築 (title.hsp)
   3-1. ra = max(powf(2, lowquality), 1)
        - lowquality=0: ra=1（等倍）
        - lowquality=1: ra=2（1/2解像度）
        - lowquality=2: ra=4（1/4解像度）
   3-2. チップBTバッファ: buffer 53+.., 80/ra, 40/ra
   3-3. 2Dレーンバッファ: buffer 5, vw/ra, vh/ra
   3-4. 加算レーンバッファ: buffer 51, vw/ra, vh/ra
   3-5. 倍幅レーンバッファ: buffer 168, vw/ra*2, vh/ra
   3-6. ra!=1 の場合: zoomtarget 配列の各バッファを gzoom で縮小
   3-7. FXロングバッファ: buffer 150, 82/ra*4, vh/ra
   3-8. BTロングバッファ: buffer 151, 80/ra*4, vh/ra
   3-9. レーザーカーソルバッファ: buffer 152, 44/ra*4, 200/ra
4. プレイ画面描画 (play_draw_frame.hsp)
   4-1. 全座標を /ra でスケーリング
   4-2. gcopy のサイズ指定を /ra でスケーリング
   4-3. center_split_px = int(center_split_now * bt_width) / 2 / ra
5. 背景描画制御 (play_graphics.hsp)
   5-1. bg>=1: 背景画像の読み込みとテクスチャ登録
   5-2. bg>=2: レイヤーアニメーションGIFの読み込み
   5-3. bg=0: レーンの setefx 値を 255（半透明化）に設定
6. オプション設定画面 (option.hsp)
   6-1. selnow=4 + 左キー: lowquality++ (最大2)
   6-2. selnow=4 + 右キー: lowquality-- (最小0)
   6-3. selnow=5 + 左キー: bg-- (最小0)
   6-4. selnow=5 + 右キー: bg++ (最大2)
   6-5. Esc押下時: lowquality!=lowqualityp → imgrefresh=1 → キャッシュ再構築
7. config.ini 保存 (kshootmania.hsp)
   7-1. "lowquality=" + lowquality（1382-1383行目）
   7-2. "background=" + bg（1406-1407行目）
```

### フローチャート

```mermaid
flowchart TD
    A[起動] --> B[デフォルト値設定]
    B --> C[config.ini読み込み]
    C --> D[ra=max powf 2 lowquality 1]
    D --> E[テクスチャキャッシュ構築]
    E --> F{ra!=1?}
    F -->|Yes| G[zoomtarget をgzoomで縮小]
    F -->|No| H[等倍のまま使用]
    G --> I[各種バッファを/raサイズで作成]
    H --> I
    I --> J[プレイ画面]
    J --> K[全座標/raでスケーリング描画]
    K --> L{オプション変更?}
    L -->|Yes| M[lowquality/bg変更]
    M --> N{lowquality変更?}
    N -->|Yes| O[imgrefresh=1]
    N -->|No| P[タイトル画面へ]
    O --> P
    P --> D
    L -->|No| Q[プレイ継続]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-70-1 | 解像度スケーリング | ra = max(powf(2, lowquality), 1) で算出。lowquality=0→ra=1, 1→ra=2, 2→ra=4 | タイトル画面初期化時 |
| BR-70-2 | テクスチャ縮小 | ra!=1 の場合、zoomtarget 配列のバッファを gzoom で 1/ra に縮小 | テクスチャキャッシュ構築時 |
| BR-70-3 | 座標スケーリング | 描画座標とサイズを /ra で除算して描画位置を計算 | プレイ画面描画時 |
| BR-70-4 | 背景描画レベル | bg=0: 背景非表示, bg>=1: 背景画像表示, bg>=2: レイヤーアニメーション表示 | プレイ画面初期化時 |
| BR-70-5 | レーン透過度制御 | bg=0 の場合 setefx 255（半透明）、bg!=0 の場合 setefx 767（通常） | レーンオブジェクト初期化時 |
| BR-70-6 | 設定変更検出 | lowquality != lowqualityp で変更を検出し、imgrefresh=1 を設定 | オプション画面 Esc 押下時 |
| BR-70-7 | デフォルト値 | lowquality=1（MEDIUM）、bg=1（STANDARD） | 初回起動時 |
| BR-70-8 | config.ini 保存形式 | "lowquality=" + 数値、"background=" + 数値 | 設定保存時 |

### 計算ロジック

**解像度スケーリング係数**:
```
ra = max(powf(2, lowquality), 1)
```
- lowquality=0: ra = max(2^0, 1) = max(1, 1) = 1（等倍）
- lowquality=1: ra = max(2^1, 1) = max(2, 1) = 2（1/2解像度）
- lowquality=2: ra = max(2^2, 1) = max(4, 1) = 4（1/4解像度）

**レーンエフェクト値計算**:
```
setefx obj_lane, 767 - 512 * (bg=0), 0, 0
```
- bg=0: 767 - 512 = 255（半透明）
- bg!=0: 767 - 0 = 767（通常描画）

**バッファサイズ計算例（チップBT）**:
```
buffer 53+cnt2*9+cnt, 80/ra, 40/ra
gzoom 80/ra, kar.cnt2/ra, 2, 80*cnt, 0, 80, 14, 1
```

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

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

| 操作 | 対象ファイル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 読み込み | config.ini | SELECT | lowquality= / background= パラメータの読み取り |
| 保存 | config.ini | UPDATE | lowquality= / background= パラメータの更新 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 範囲外の値 | lowquality が 0-2 以外 | オプション画面でクランプ処理（max 0, min 2） |
| - | 範囲外の値 | bg が 0-2 以外 | オプション画面でクランプ処理（max 0, min 2） |

### リトライ仕様

該当なし。

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

該当なし。

## パフォーマンス要件

本機能はパフォーマンス最適化そのものを目的とする。lowquality=2（SMALL）ではテクスチャサイズが 1/4 になるため、VRAM 消費量が約 1/16（面積比）に削減される。描画時の gcopy / gzoom は座標計算に /ra を含むが、整数除算のため処理負荷は無視できる。

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

該当なし。

## 備考

- highquality 変数（kshootmania.hsp 282行目、デフォルト値 0）は config.ini に保存されるが、プレイ画面の描画処理では参照されていない。将来的な拡張用と推測される
- zoomtarget 配列（kshootmania.hsp 232行目）はキャッシュ再構築時に縮小対象となるバッファ番号を定義: 1(FXロング), 42(BTロング), 47(レーン), 9(判定), 44(FXチップ判定), 43(FXチップ), 15(小節線), 34(レーンライト), 186(FXチップSE)
- zoomtype 配列（kshootmania.hsp 233行目）は縮小方式を定義: 0=幅高さ両方縮小、1=幅のみ縮小
- 左キーで lowquality が増加（品質低下）、右キーで減少（品質向上）という、直感に反する操作設計になっている
- オプション画面の表示ラベルは lang.3.3/lang.3.4/lang.3.5 で国際化対応されている（LARGE/MEDIUM/SMALL）

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | kshootmania.hsp | `kshootmania.hsp` | **282-283行目**: `highquality=0`, `lowquality=1` のデフォルト値設定 |
| 1-2 | kshootmania.hsp | `kshootmania.hsp` | **296行目**: `bg=1` のデフォルト値設定 |
| 1-3 | kshootmania.hsp | `kshootmania.hsp` | **230-233行目**: zoomtarget / zoomtype 配列の定義（縮小対象バッファとその方式） |

**読解のコツ**: lowquality は 0 が最高品質、2 が最低品質。ra は 2^lowquality で算出されるスケーリング係数で、全バッファサイズと全描画座標を /ra で除算することで解像度を下げる。bg は 0=非表示, 1=背景画像, 2=背景+レイヤーアニメーションの 3 段階。

#### Step 2: 設定読み込み・保存を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | kshootmania.hsp | `kshootmania.hsp` | **504-505行目**: config.ini からの `lowquality=` 読み込み |
| 2-2 | kshootmania.hsp | `kshootmania.hsp` | **525-526行目**: config.ini からの `background=` 読み込み |
| 2-3 | kshootmania.hsp | `kshootmania.hsp` | **1382-1383行目**: config.ini への lowquality 保存 |
| 2-4 | kshootmania.hsp | `kshootmania.hsp` | **1406-1407行目**: config.ini への background 保存 |

**主要処理フロー**:
1. **504行目**: `StartsWith(confstr.cnt, "lowquality=")` で設定行を検出
2. **505行目**: `lowquality=int(strmid(confstr.cnt,11,1))` で 1 文字の数値を取得

#### Step 3: テクスチャキャッシュ構築を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | title.hsp | `src/scene/title.hsp` | **16行目**: `ra=max(powf(2,lowquality),1)` で解像度スケーリング係数を算出 |
| 3-2 | title.hsp | `src/scene/title.hsp` | **97行目**: チップBTバッファの作成（80/ra x 40/ra） |
| 3-3 | title.hsp | `src/scene/title.hsp` | **133-136行目**: 2Dレーンバッファの作成（vw/ra x vh/ra） |
| 3-4 | title.hsp | `src/scene/title.hsp` | **139-159行目**: ra!=1 の場合の zoomtarget 一括縮小処理 |
| 3-5 | title.hsp | `src/scene/title.hsp` | **162-185行目**: FXロング/BTロング/レーザーカーソルバッファの縮小 |

**主要処理フロー**:
1. **16行目**: ra の算出
2. **97行目**: 各バッファサイズに /ra を適用
3. **139行目**: `if(ra!=1)` でスケーリングが必要か判定
4. **141-158行目**: zoomtarget 配列の各バッファを gzoom で縮小。zoomtype=0 は幅高さ両方、zoomtype=1 は幅のみ縮小

#### Step 4: プレイ画面での描画適用を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | play_draw_frame.hsp | `src/scene/play/play_draw_frame.hsp` | **4行目**: `center_split_px = int(...) / 2 / ra` で座標スケーリング |
| 4-2 | play_draw_frame.hsp | `src/scene/play/play_draw_frame.hsp` | **260行目**: チップBT描画で `40/ra, 40/ra` のサイズ指定 |
| 4-3 | play_draw_frame.hsp | `src/scene/play/play_draw_frame.hsp` | **100行目**: FXロング描画で座標とサイズに /ra 適用 |

#### Step 5: 背景描画レベル制御を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | play_graphics.hsp | `src/scene/play/play_graphics.hsp` | **51行目**: `if(bg>=1)` で背景画像の読み込み判定 |
| 5-2 | play_graphics.hsp | `src/scene/play/play_graphics.hsp` | **127行目**: `if(bg>=2)` でレイヤーアニメーションの読み込み判定 |
| 5-3 | play_graphics.hsp | `src/scene/play/play_graphics.hsp` | **193行目**: `setefx obj_lane,767-512*(bg=0),0,0` でレーン透過度の制御 |

#### Step 6: オプション設定画面を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 6-1 | option.hsp | `src/scene/option.hsp` | **52行目**: `lowqualityp=lowquality` で変更前値を保持 |
| 6-2 | option.hsp | `src/scene/option.hsp` | **241-242行目**: 左キーで `lowquality++`、最大 2 でクランプ |
| 6-3 | option.hsp | `src/scene/option.hsp` | **392-393行目**: 右キーで `lowquality--`、最小 0 でクランプ |
| 6-4 | option.hsp | `src/scene/option.hsp` | **544-546行目**: 表示ラベル（LARGE/MEDIUM/SMALL） |
| 6-5 | option.hsp | `src/scene/option.hsp` | **1089行目**: `lowquality!=lowqualityp` で変更検出、imgrefresh=1 設定 |

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

```
kshootmania.hsp (起動時)
    |
    +-- デフォルト値設定
    |       +-- lowquality=1, highquality=0, bg=1
    |
    +-- config.ini 読み込み
    |       +-- lowquality= → lowquality変数
    |       +-- background= → bg変数
    |
    +-- title.hsp (タイトル画面)
    |       +-- ra = max(powf(2, lowquality), 1)
    |       +-- チップBTバッファ構築 (80/ra x 40/ra)
    |       +-- 2Dレーンバッファ構築 (vw/ra x vh/ra)
    |       +-- zoomtarget 一括縮小 (ra!=1 の場合)
    |       +-- FXロング/BTロング/レーザーバッファ構築
    |
    +-- play_graphics.hsp (プレイ初期化)
    |       +-- loadBGGraphics: bg>=1 で背景画像ロード
    |       +-- loadLayerGraphics: bg>=2 でレイヤーアニメロード
    |       +-- initLaneObject: bg=0 で半透明レーン
    |
    +-- play_draw_frame.hsp (プレイ描画)
    |       +-- 全座標/ra でスケーリング
    |       +-- gcopy サイズ/ra でスケーリング
    |
    +-- option.hsp (オプション画面)
    |       +-- lowquality 増減 (0-2)
    |       +-- bg 増減 (0-2)
    |       +-- 変更検出 → imgrefresh=1
    |
    +-- config.ini 保存
            +-- lowquality= + 値
            +-- background= + 値
```

### データフロー図

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

config.ini            ───>  ┌──────────────────────┐
  lowquality=x               |  設定読み込み         |      lowquality (0/1/2)
  background=x               └──────────────────────┘      bg (0/1/2)

lowquality            ───>  ┌──────────────────────┐
                             |  タイトル画面         |      ra (1/2/4)
                             |  ra=max(powf(2,lq),1) |  ──> テクスチャバッファ
                             └──────────────────────┘      (サイズ/ra)

ra                    ───>  ┌──────────────────────┐
                             |  プレイ画面描画       |  ──> 画面描画
                             |  座標/ra, サイズ/ra   |      (スケーリング済み)
                             └──────────────────────┘

bg                    ───>  ┌──────────────────────┐
                             |  プレイ初期化         |  ──> 背景テクスチャ
                             |  bg>=1: 背景画像      |      レーン透過度
                             |  bg>=2: レイヤーアニメ |
                             └──────────────────────┘

オプション操作        ───>  ┌──────────────────────┐
  左右キー                   |  オプション画面       |  ──> lowquality/bg更新
                             |  lowquality/bg増減    |      imgrefresh=1
                             └──────────────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| kshootmania.hsp | `kshootmania.hsp` | ソース | lowquality/bg デフォルト値設定（282-283, 296行目）、config.ini 読み込み（504-505, 525-526行目）、保存（1382-1383, 1406-1407行目）、zoomtarget/zoomtype 定義（230-233行目） |
| title.hsp | `src/scene/title.hsp` | ソース | ra 算出（16行目）、テクスチャキャッシュ構築（85-195行目） |
| play_draw_frame.hsp | `src/scene/play/play_draw_frame.hsp` | ソース | ra による座標・サイズスケーリング（全行にわたり /ra 適用） |
| play_graphics.hsp | `src/scene/play/play_graphics.hsp` | ソース | bg による背景画像ロード（51-124行目）、レイヤーアニメロード（127-169行目）、レーン透過度制御（193行目） |
| option.hsp | `src/scene/option.hsp` | ソース | lowquality/bg の変更操作（241-242, 392-393行目）、表示ラベル（544-546行目）、変更検出（52, 1089行目） |
| config.ini | `config.ini` | 設定 | lowquality= / background= パラメータの保存先 |
