# 機能設計書 69-ノートスキン

## 概要

本ドキュメントは、K-Shoot MANIA のプレイ画面におけるノートスキン切替機能の設計を記述する。DEFAULT と NOTE の2種類のノートスキンを coloring 変数で切替え、BTチップノートの表示スタイルを変更する。

### 本機能の処理概要

**業務上の目的・背景**：リズムゲームにおいて、ノートの視認性はプレイヤーの好みやスキルレベルによって異なる。ノートスキンの切替機能により、プレイヤーが自身に適した表示スタイルを選択できるようにすることで、プレイ体験の個別最適化を実現する。

**機能の利用シーン**：選曲画面のインラインオプション変更（sselnow=3 の項目）でノートスキンを切替える。config.ini の `noteskin=` パラメータに保存され、次回以降も設定が維持される。プレイ画面では coloring 変数の値に応じて異なるノートスプライトが使用される。

**主要な処理内容**：
1. config.ini からの `noteskin=` パラメータ読み込み（"note" → coloring=1, "default" → coloring=0）
2. 選曲画面でのノートスキン切替操作（coloring 変数の 0/1 切替）
3. 譜面読み込み時の note.i.6 フィールド設定（coloring=1 の場合、拍の位置に応じたスプライト種別を割り当て）
4. プレイ画面でのノート描画時に note.i.6 に基づくスプライト選択

**関連システム・外部連携**：config.ini への設定保存・読み込み。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 5 | ゲームプレイ画面 | 主画面 | play_graphics.hsp による DEFAULT/NOTE の2種類ノートスキン切替（coloring 変数） |
| 3 | 曲選択画面 | 設定画面 | インラインオプション変更でノートスキンを切替 |

## 機能種別

設定変更 / 描画制御

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| coloring | int | Yes | ノートスキン設定（0=DEFAULT, 1=NOTE） | 0 または 1 |

### 入力データソース

config.ini の `noteskin=` パラメータ。選曲画面のインラインオプション操作。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| coloring | int | ノートスキン設定値 |
| note.i.6 | int | 各ノートのスプライト種別（0=DEFAULT, 1=NOTE拍位置色分け） |

### 出力先

config.ini の `noteskin=` パラメータ（default / note）。note 配列のスプライト種別フィールド。

## 処理フロー

### 処理シーケンス

```
1. config.ini 読み込み (kshootmania.hsp)
   1-1. "noteskin=note" / "noteskin=NOTE" → coloring = 1
   1-2. それ以外 → coloring = 0
   1-3. デフォルト値: coloring = 0 (DEFAULT)
2. 選曲画面での切替 (select.hsp)
   2-1. sselnow=3 の項目で左右キー操作
   2-2. coloring の 0/1 を切替
3. 譜面読み込み時 (play_chart_load.hsp)
   3-1. coloring=1 の場合:
       - 拍頭のノート: note.i.6 = 1
       - 2分割位置のノート: note.i.6 = 1
       - 4分割位置のノート: note.i.6 = 1
       - それ以外: note.i.6 = 0（色分け不要）
   3-2. coloring=0 の場合:
       - 全ノート: note.i.6 = 0
4. プレイ画面での描画 (play_draw_frame.hsp)
   4-1. チップBT描画時: gcopy 53 + (距離段階*9) + note.i.6
   4-2. note.i.6=0: DEFAULT スプライト
   4-3. note.i.6=1: NOTE スプライト（拍位置色分け）
5. config.ini 保存
   5-1. coloring=1 → "noteskin=note"
   5-2. coloring=0 → "noteskin=default"
```

### フローチャート

```mermaid
flowchart TD
    A[起動] --> B[config.ini 読み込み]
    B --> C{noteskin=note?}
    C -->|Yes| D[coloring=1]
    C -->|No| E[coloring=0]
    D --> F[選曲画面]
    E --> F
    F --> G{スキン切替操作?}
    G -->|Yes| H[coloring を 0/1 反転]
    G -->|No| I[譜面読み込み]
    H --> I
    I --> J{coloring=1?}
    J -->|Yes| K[拍位置に応じて note.i.6 を設定]
    J -->|No| L[全ノート note.i.6=0]
    K --> M[プレイ画面描画]
    L --> M
    M --> N[note.i.6 でスプライト選択]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-69-1 | DEFAULT スキン | coloring=0: 全ノートが同一デザイン | noteskin=default |
| BR-69-2 | NOTE スキン | coloring=1: 拍の位置に応じてノートの色が変わる | noteskin=note |
| BR-69-3 | 拍位置判定 | 拍頭(cnt2=0)、2分割位置(cnt2%(div/2)=0)、4分割位置(cnt2%(div/4)=0)でスプライト種別を決定 | coloring=1 |
| BR-69-4 | config.ini 保存形式 | "noteskin=default" または "noteskin=note" | 設定保存時 |

### 計算ロジック

**スプライト番号計算（チップBT描画）**:
```
スプライト番号 = 53 + min(max(距離*8/vh, 0), 7) * 9 + note.i.6
```
- 53: ベーススプライトバッファ番号
- 距離に応じて0-7の8段階（奥ほど小さく）
- 9: 各段階のスプライト間隔
- note.i.6: 0=DEFAULT, 1=NOTE

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 不正な値 | noteskin= に想定外の文字列 | coloring=0 (DEFAULT) にフォールバック |

### リトライ仕様

該当なし。

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

該当なし。

## パフォーマンス要件

ノートスキンの切替は設定変更時のみ。描画時のスプライト選択はインデックス計算のみで負荷は無視できる。

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

該当なし。

## 備考

- NOTE スキンの拍位置色分けは、div（分割数）に基づいて判定される。div は譜面の量子化設定に依存する
- スプライトは距離（画面下からの距離）に応じて8段階のサイズで用意されている（遠近法表現）
- coloring 変数は kshootmania.hsp の297行目でデフォルト値 0 に初期化される

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | kshootmania.hsp | `kshootmania.hsp` | **297行目**: `coloring=0` - ノートスキンのデフォルト値（DEFAULT） |
| 1-2 | play_chart_load.hsp | `src/scene/play/play_chart_load.hsp` | **1411-1429行目**: note.i.6 フィールドへの拍位置に応じたスプライト種別設定 |

**読解のコツ**: coloring 変数は int 型で 0 (DEFAULT) と 1 (NOTE) の2値。note.i.6 はノート配列の7番目のフィールドで、描画時のスプライト選択に使用される。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | kshootmania.hsp | `kshootmania.hsp` | **534-541行目**: config.ini の `noteskin=` パラメータ解析。"note"/"NOTE" で coloring=1、それ以外で coloring=0 |

**主要処理フロー**:
1. **534行目**: `StartsWith(confstr.cnt, "noteskin=")` で設定行を検出
2. **535行目**: 9文字目以降を取得
3. **536-539行目**: "note" / "NOTE" なら coloring=1、それ以外は coloring=0

#### Step 3: 譜面読み込み時の処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | play_chart_load.hsp | `src/scene/play/play_chart_load.hsp` | **1413行目**: `if((coloring=1)&(div.cnt3!=0))` で NOTE スキン時の拍位置判定を開始 |
| 3-2 | play_chart_load.hsp | `src/scene/play/play_chart_load.hsp` | **1415-1416行目**: 拍頭（cnt2=0）で note.i.6=1 |
| 3-3 | play_chart_load.hsp | `src/scene/play/play_chart_load.hsp` | **1419-1428行目**: 2分割・4分割位置の判定 |

#### Step 4: 描画処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | play_draw_frame.hsp | `src/scene/play/play_draw_frame.hsp` | **260行目**: `gcopy 53+min(max(...))*9+note.i.6` でスプライト番号に note.i.6 を加算 |

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

```
kshootmania.hsp (起動時)
    |
    +-- config.ini 読み込み
    |       +-- "noteskin=note" → coloring=1
    |       +-- "noteskin=default" → coloring=0
    |
    +-- select.hsp (選曲画面)
    |       +-- インラインオプション → coloring 0/1 切替
    |
    +-- play_chart_load.hsp (譜面読み込み)
    |       +-- coloring=1 → note.i.6 = 拍位置に応じた値
    |
    +-- play_draw_frame.hsp (プレイ描画)
            +-- gcopy 53+...*9+note.i.6 (スプライト選択)
```

### データフロー図

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

config.ini         ───>   ┌──────────────────────┐
  noteskin=xxx             |  設定読み込み         |      coloring (0/1)
                           └──────────────────────┘

coloring           ───>   ┌──────────────────────┐
div (分割数)       ───>   |  譜面読み込み時       |      note.i.6
cnt2 (拍位置)      ───>   |  拍位置判定           |  ──> (0=DEFAULT, 1=NOTE)
                           └──────────────────────┘

note.i.6           ───>   ┌──────────────────────┐
                           |  チップBT描画         |  ──> 画面描画
                           |  gcopy 53+..+note.i.6 |      (スプライト選択)
                           └──────────────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| kshootmania.hsp | `kshootmania.hsp` | ソース | coloring 初期化（297行目）、config.ini 読み込み（534-541行目）、保存（1410-1414行目） |
| play_chart_load.hsp | `src/scene/play/play_chart_load.hsp` | ソース | note.i.6 の拍位置判定設定（1413-1429行目） |
| play_draw_frame.hsp | `src/scene/play/play_draw_frame.hsp` | ソース | チップBT描画でのスプライト選択（260行目） |
| select.hsp | `src/scene/select.hsp` | ソース | インラインオプションでのノートスキン切替（1959-1960行目） |
| config.ini | `config.ini` | 設定 | noteskin= パラメータの保存先 |
