# 機能設計書 111-量子化設定

## 概要

本ドキュメントは、K-Shoot MANIA譜面エディタにおける量子化(スナップ)設定機能の設計を記述する。ノートやオブジェクトの配置・編集時のグリッド分割数を制御する。

### 本機能の処理概要

譜面エディタでノートを配置・移動する際に、1小節あたりの分割数(量子化値)を設定し、カーソル位置をグリッドにスナップさせる機能である。

**業務上の目的・背景**：音楽ゲームの譜面制作において、ノートは拍(ビート)に合わせて正確なタイミングで配置される必要がある。量子化設定により、4分音符から192分音符まで10段階の分割粒度でグリッドスナップが可能となり、譜面制作者が意図するリズムに正確にノートを配置できるようにする。

**機能の利用シーン**：譜面制作者がエディタのツールメニューから分割数を選択する場面で利用される。Ctrl+数字キーのショートカットやマウスホイールによる切替にも対応し、制作の効率を高める。

**主要な処理内容**：
1. メニューまたはショートカットキーで量子化値(editdiv)を変更する
2. 選択された分割数に応じてメニューのチェック状態を排他的に更新する
3. ノート配置・移動時にカーソル位置をUNIT_MEASURE/editdivの倍数にスナップする
4. 描画領域の補助線表示に量子化値を反映する

**関連システム・外部連携**：外部システムとの連携はない。エディタ内部の描画・入力処理と連動する。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | 譜面エディタ | 主画面 | ツールメニュー > 量子化設定(4/8/12/16/24/32/48/64/96/192分割)の選択 |

## 機能種別

設定変更 / UI制御

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| cmd | int | Yes | コマンドID(CMD_TOOL_4~CMD_TOOL_192) | 定義済みenum値であること |

### 入力データソース

- メニュー選択(ツールメニュー > 量子化分割数)
- キーボードショートカット(Ctrl+4/8/2/6等、Ctrl+Shift+4/2/8/6/9/1)
- マウスホイール操作(editdiv_wheel制御)

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| editdiv | int | 現在の量子化分割数(4/8/12/16/24/32/48/64/96/192) |

### 出力先

- エディタ内部変数(editdiv)
- メニューのチェック状態(CheckMenuItem)
- 描画画面(グリッド線の間隔として反映)

## 処理フロー

### 処理シーケンス

```
1. ユーザーがメニュー/ショートカット/ホイールで量子化分割数を指定
   └─ CMD_TOOL_4~CMD_TOOL_192のコマンドが発行される
2. コマンドハンドラ(*OnCommand)が対応するコマンドを受信
   └─ 10個の分割数コマンドそれぞれにif分岐で対応
3. メニューのチェック状態を排他的に更新
   └─ 選択された項目に0x08(チェック)、他の9項目に0x00(未チェック)を設定
4. editdiv変数に新しい分割数を設定
   └─ editdiv=4, 8, 12, 16, 24, 32, 48, 64, 96, 192のいずれか
5. 描画を更新(gosub *draw)
   └─ グリッド線の間隔がUNIT_MEASURE/editdivに変更される
```

### フローチャート

```mermaid
flowchart TD
    A[ユーザー操作] --> B{入力方法}
    B -->|メニュー選択| C[CMD_TOOL_N発行]
    B -->|Ctrlショートカット| C
    B -->|ホイール| D[現在値から次/前の分割数を計算]
    D --> C
    C --> E[CheckMenuItemで排他チェック更新]
    E --> F[editdiv = N]
    F --> G[gosub *draw]
    G --> H[グリッド線が新分割数で再描画]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-111-01 | 排他的選択 | 量子化値は同時に1つのみ選択可能 | 常時 |
| BR-111-02 | デフォルト値 | 初期状態では16分割が選択される | エディタ起動時 |
| BR-111-03 | 循環切替 | ホイール操作で192の次は4、4の前は192に循環する | ホイール操作時 |
| BR-111-04 | グリッドスナップ | ノート配置位置はUNIT_MEASURE/editdivの倍数に丸められる | ノート配置時 |

### 計算ロジック

- スナップ位置計算: `cc = stat2 + (cc - stat2) / (UNIT_MEASURE / editdiv) * (UNIT_MEASURE / editdiv)` (10331行目)
- UNIT_MEASUREは192固定(1小節の内部分解能)

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

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

データベース操作はない。設定値はconfig.ini経由でファイルに永続化されない(セッション内のみ有効)。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | - | 異常値の量子化分割数 | 発生しない(コマンドIDで値が固定されるため) |

### リトライ仕様

リトライ処理はない。

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

トランザクション管理はない。

## パフォーマンス要件

量子化値の変更は即座に描画に反映される必要がある。描画更新はgosub *drawにより同期的に実行される。

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

セキュリティに関する考慮事項はない。

## 備考

- UNIT_MEASURE定数は192であり、192分割が最大分解能となる
- 量子化値は4, 8, 12, 16, 24, 32, 48, 64, 96, 192の10段階で、すべて192の約数である
- ツールバーにも量子化状態を示すアイコンが表示される(BUF_QUANTIZE画像から取得)

---

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

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

### 推奨読解順序

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

量子化設定で扱う変数は少数であり、グローバル変数として管理される。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | kshooteditor.hsp | `kshooteditor.hsp` | **393行目**: `editdiv=16` - 量子化分割数のデフォルト値定義 |
| 1-2 | kshooteditor.hsp | `kshooteditor.hsp` | **337行目**: `editdiv_wheel=0` - ホイール操作用の制御変数 |
| 1-3 | kshooteditor.hsp | `kshooteditor.hsp` | **198行目**: `#define BUF_QUANTIZE 22` - 量子化アイコン表示用バッファID |

**読解のコツ**: HSP言語では`#enum`で連番の定数を定義する。CMD_TOOL_4からCMD_TOOL_192までが102~111行目で順番に定義されている。

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

コマンドハンドラ(*OnCommand)が量子化設定の変更起点となる。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | kshooteditor.hsp | `kshooteditor.hsp` | **102-111行目**: CMD_TOOL_4~CMD_TOOL_192のenum定義 |
| 2-2 | kshooteditor.hsp | `kshooteditor.hsp` | **749-758行目**: メニュー項目の追加(addmenu) |
| 2-3 | kshooteditor.hsp | `kshooteditor.hsp` | **6818-6947行目**: コマンドハンドラでの分岐処理 |

**主要処理フロー**:
1. **102-111行目**: CMD_TOOL_4~CMD_TOOL_192のenum定数定義
2. **749-758行目**: ツールメニューへの量子化分割数メニュー項目追加
3. **6818-6947行目**: 各分割数コマンドに対応するeditdiv設定とメニューチェック状態の排他更新
4. **10296-10316行目**: マウスホイールによる量子化値の循環切替処理

#### Step 3: スナップ計算処理を理解する

ノート配置時のグリッドスナップ計算を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | kshooteditor.hsp | `kshooteditor.hsp` | **10326-10331行目**: カーソル位置のスナップ計算式 |
| 3-2 | kshooteditor.hsp | `kshooteditor.hsp` | **2049-2058行目**: editdiv値からBUF_QUANTIZEアイコンインデックスへの変換 |
| 3-3 | kshooteditor.hsp | `kshooteditor.hsp` | **832行目**: 量子化アイコン画像のロード |

**主要処理フロー**:
- **10331行目**: `cc=stat2+(cc-stat2)/(UNIT_MEASURE/editdiv)*(UNIT_MEASURE/editdiv)` - カーソル位置をグリッドにスナップする核心計算

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

```
*OnCommand (2191行目)
    |
    +-- CMD_TOOL_4~CMD_TOOL_192 (6818-6947行目)
    |       |
    |       +-- CheckMenuItem (メニューチェック排他更新)
    |       +-- editdiv = N (分割数設定)
    |       +-- gosub *draw (描画更新)
    |
    +-- ホイール操作 (10296-10316行目)
            |
            +-- editdivから次/前の分割数に対応するCMDを計算
            +-- acmd = CMD_TOOL_N
            +-- gosub *OnCommand
```

### データフロー図

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

メニュー選択 --------+
ショートカットキー ---+--> CMD_TOOL_N --> editdiv設定 --> グリッド描画更新
ホイール操作 --------+                                    メニューチェック更新
                                                          ノート配置スナップ
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| kshooteditor.hsp | `kshooteditor.hsp` | ソース | エディタ本体。量子化設定のコマンド定義・ハンドリング・描画を含む |
| quantize.gif | `quantize.gif` | リソース | 量子化分割数表示用のアイコン画像(16x16px x 10種) |
