# 機能設計書 25-譜面パラメータ解析

## 概要

本ドキュメントは、KSH譜面ファイルのメタデータ行を解析し、title・artist・BPM・拍子・カメラ制御・音楽ファイルパス・ユーザー定義エフェクト等の譜面パラメータを展開する機能の設計を記述する。

### 本機能の処理概要

**業務上の目的・背景**：KSH譜面ファイルには楽曲のメタデータ（タイトル、アーティスト、BPM等）とゲームプレイに必要なパラメータ（音楽ファイルパス、背景設定、カメラ制御値等）が記述されている。これらのパラメータを正しく解析することで、プレイ画面の初期化とオーディオ再生の準備が完了する。

**機能の利用シーン**：loadKSHChartFileで読み込まれた行データ配列d[]に対して、parseKSHChartParamLines関数が呼び出され、各パラメータ行を解析する。プレイ画面の初期化フェーズで実行される。

**主要な処理内容**：
1. title=, artist=, effect=, illustrator=等の楽曲メタデータ解析
2. m=による音楽ファイルパス解析（デュアルトラック・Switch Audio対応）
3. t=によるBPM値解析、beat=による拍子解析
4. bg=, layer=による背景設定解析
5. tilt=, laserrange_l/r=等のカメラ制御パラメータ解析
6. pfiltergain=, chokkakuvol=等のレーザーエフェクトパラメータ解析
7. stop=, o=（オフセット）等のタイミング制御パラメータ解析
8. ver=によるバージョン互換性判定
9. #define_fx, #define_filterによるユーザー定義エフェクト情報の収集（詳細はNo.27参照）

**関連システム・外部連携**：BASS Audio Libraryによる音楽ファイルのストリーム作成（BASS_StreamCreateFile/BASS_StreamCreateURL）、BASS_VSTによるエフェクトDSP設定。

**権限による制御**：auto変数（オートプレイモード）によりデュアルトラックの構成が変化する。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 5 | ゲームプレイ画面 | 主画面 | 譜面パラメータの解析とプレイ初期化 |

## 機能種別

データ解析 / パラメータ設定

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| d[] | str配列 | Yes | 譜面ファイルの行データ配列 | loadKSHChartFileで展開済みであること |
| isutf8 | int | Yes | UTF-8判定フラグ | 0または1 |
| auto | int | Yes | オートプレイフラグ | 0または1 |
| dirvol | int | Yes | ディレクトリ音量設定 | 0-100 |

### 入力データソース

loadKSHChartFileで読み込まれた譜面ファイルの行データ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| csongtitle | str | 楽曲タイトル |
| csongartist | str | アーティスト名 |
| csongeffect | str | エフェクター名 |
| csongillustrator | str | イラストレーター名 |
| bpm | int | BPM値（x1000） |
| bpml[] | int配列 | BPM変化リスト |
| beatn/beatd | int | 拍子（分子/分母） |
| csongfile[] | str配列 | 音楽ファイルパスリスト |
| mid[] | int配列 | BASSストリームハンドル |
| bgname | str | 背景パターン名 |
| tilt[] | int配列 | Tilt制御データ |
| stp[] | int配列 | STOP制御データ |
| csongver | str | 譜面バージョン |

### 出力先

ゲーム内部のグローバル変数群

## 処理フロー

### 処理シーケンス

```
1. d[]配列を先頭から順にスキャン
2. 各行をStartsWith関数でパラメータ名判定
   ├─ "title=" → csongtitleに格納、UTF-8変換
   ├─ "artist=" → csongartistに格納
   ├─ "m=" → 音楽ファイルパス解析、デュアルトラック構成決定
   ├─ "t=" → BPM値解析、bpml配列に追加
   ├─ "beat=" → 拍子変更
   ├─ "bg=" → 背景パターン名
   ├─ "tilt=" → Tilt制御値
   ├─ "stop=" → STOP制御
   ├─ "ver=" → バージョン判定
   └─ "#define_fx"/"#define_filter" → ユーザー定義エフェクトバッファに蓄積
3. "--"行で小節区切り、cbcnt（小節カウント）を更新
4. 解析完了後、parseLayerNameとfixBPMErrorsを呼び出し
```

### フローチャート

```mermaid
flowchart TD
    A[d配列スキャン開始] --> B{行内容判定}
    B -->|title=| C[csongtitle設定]
    B -->|artist=| D[csongartist設定]
    B -->|m=| E[音楽ファイル解析]
    B -->|t=| F[BPM解析]
    B -->|beat=| G[拍子解析]
    B -->|bg=| H[背景設定]
    B -->|tilt=| I[Tilt設定]
    B -->|stop=| J[STOP設定]
    B -->|ver=| K[バージョン設定]
    B -->|#define_| L[エフェクト定義蓄積]
    B -->|--| M[小節カウント更新]
    B -->|その他| N[スキップ]
    C --> O{次の行?}
    D --> O
    E --> O
    F --> O
    G --> O
    H --> O
    I --> O
    J --> O
    K --> O
    L --> O
    M --> O
    N --> O
    O -->|Yes| B
    O -->|No| P[parseLayerName]
    P --> Q[fixBPMErrors]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-25-01 | BPM範囲 | BPM値は正の数で、ver>=130の場合は上限65,535.000 | t=パラメータ解析時 |
| BR-25-02 | デフォルトBPM | BPM記述がない場合はBPM=120を設定 | fixBPMErrors |
| BR-25-03 | デュアルトラック | m=で";"区切りで2ファイル指定時はデュアルトラック構成 | m=パラメータ解析時 |
| BR-25-04 | URL対応 | "http:"/"https:"で始まるm=値はストリーミング再生 | m=パラメータ解析時 |
| BR-25-05 | 音量計算 | csongvol = mvol値 * dirvol / 100 | mvol=パラメータ解析時 |
| BR-25-06 | Tilt種別 | normal/big/bigger/biggest/keep_normal/keep_bigger/keep_biggest/zeroの8種類+数値指定 | tilt=パラメータ解析時 |
| BR-25-07 | バージョン互換 | csongver未設定時はcsongvolを60%に補正 | parseKSHChartParamLines終了時 |

### 計算ロジック

BPM値の内部表現: `bpm = int(double(文字列) * 1000)`（ミリBPM単位で管理）

小節内位置計算: `(行番号+1) * UNIT_MEASURE * beatn / beatd / div[小節番号] + cbcnt`

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

本機能ではデータベース操作は発生しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 音楽ファイル不存在 | m=で指定されたファイルが見つからない | csongfile_exist=0を設定、代替ファイルを試行 |
| - | BPM記述なし | 譜面にt=が存在しない | fixBPMErrorsでBPM=120をデフォルト設定 |

### リトライ仕様

リトライは行わない。

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

トランザクション管理は不要。

## パフォーマンス要件

パラメータ解析は全行を1回走査するO(n)処理であり、通常の譜面ファイルでは即時完了する。

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

m=パラメータでURL指定によるストリーミング再生が可能であるため、信頼できるソースからの譜面ファイルのみ使用することが推奨される。

## 備考

- parseKSHChartParamLinesは小節区切り"--"も処理するため、メタデータだけでなくBPM変化等のインライン命令も解析する。
- ver=130以降でBPM上限が65,535.000に制限される。

---

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

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

### 推奨読解順序

#### Step 1: パラメータ解析関数

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | play_chart_load.hsp | `src/scene/play/play_chart_load.hsp` | parseKSHChartParamLines関数 |

**主要処理フロー**:
1. **307行目**: parseKSHChartParamLines関数定義
2. **316-324行目**: bg=, layer=の背景設定解析
3. **326-332行目**: title=の解析とUTF-8変換
4. **339-341行目**: artist=の解析
5. **393-497行目**: m=の音楽ファイルパス解析（複雑なデュアルトラック構成決定）
6. **611-614行目**: ver=のバージョン解析
7. **643-656行目**: t=のBPM値解析
8. **663-681行目**: beat=の拍子解析
9. **683-701行目**: stop=のSTOP制御解析
10. **712-743行目**: tilt=のTilt制御解析
11. **827-833行目**: #define_fx/#define_filterの蓄積

#### Step 2: 補助関数

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | play_chart_load.hsp | `src/scene/play/play_chart_load.hsp` | parseLayerName, fixBPMErrors |

**主要処理フロー**:
- **855-877行目**: parseLayerName - layer文字列のパース
- **879-893行目**: fixBPMErrors - BPM未設定時のデフォルト値設定とver>=130での上限制限

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

```
play_init
    |
    +-- loadKSHChartFile
    |
    +-- parseKSHChartParamLines (307-853行目)
    |     +-- StartsWith(d.cnt, "title=") -> csongtitle
    |     +-- StartsWith(d.cnt, "m=") -> csongfile[], mid[]
    |     +-- StartsWith(d.cnt, "t=") -> bpml[]
    |     +-- StartsWith(d.cnt, "beat=") -> beatn, beatd
    |     +-- StartsWith(d.cnt, "tilt=") -> tilt[]
    |     +-- StartsWith(d.cnt, "stop=") -> stp[]
    |     +-- "#define_fx" -> fxdefbuf_fx
    |     +-- "#define_filter" -> fxdefbuf_filter
    |     +-- parseLayerName (855行目)
    |     +-- fixBPMErrors (879行目)
    |
    +-- parseKSHChartBody (895行目〜)
```

### データフロー図

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

d[]配列 -----> parseKSHChartParamLines ----+
(行データ)         |                        |
                   +-- title= ------------> csongtitle
                   +-- artist= -----------> csongartist
                   +-- m= ----------------> csongfile[], mid[]
                   +-- t= ----------------> bpm, bpml[]
                   +-- beat= -------------> beatn, beatd
                   +-- bg= ---------------> bgname
                   +-- tilt= -------------> tilt[]
                   +-- stop= -------------> stp[]
                   +-- #define_fx ---------> fxdefbuf_fx
                   +-- ver= --------------> csongver
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| play_chart_load.hsp | `src/scene/play/play_chart_load.hsp` | ソース | parseKSHChartParamLines関数（307-853行目） |
| play_chart_load.hsp | `src/scene/play/play_chart_load.hsp` | ソース | parseLayerName（855-877行目）、fixBPMErrors（879-893行目） |
| play_audio.hsp | `src/scene/play/play_audio.hsp` | ソース | 音楽ファイルのストリーム作成 |
