# 機能設計書 2-選曲画面

## 概要

K-Shoot MANIAの曲選択画面の機能設計書である。曲リスト表示、難易度選択、ソート切替、お気に入り管理、コースモード、プレビューBGM再生など多数の選曲関連機能を統合的に提供する画面である。

### 本機能の処理概要

選曲画面は、ユーザーがプレイする楽曲を選択するためのメイン画面であり、K-Shoot MANIAのゲームフロー全体の中核を担う。楽曲のブラウジング、難易度選択、各種オプション変更、プレビュー再生など、多岐にわたる機能を1つの画面に集約している。

**業務上の目的・背景**：音楽ゲームにおいて最も頻繁に使用される画面であり、ユーザーが楽曲を効率的に探索・選択できることがゲーム体験の中心となる。フォルダ構造のブラウジング、ソート、アルファベットジャンプ等により大量の楽曲コレクションからの探索を支援する。

**機能の利用シーン**：タイトル画面からIRサインイン経由で遷移、またはリザルト画面からの復帰時に表示される。ユーザーは楽曲を選択してEnterキーでプレイを開始する。Escキーでタイトル画面に戻る。

**主要な処理内容**：
1. 楽曲ディレクトリのスキャンと曲リスト生成（*refreshfilelist）
2. 曲リストのスクロール表示と選択カーソル管理
3. 4段階難易度（Light/Challenge/Extended/Infinite）の切替
4. 通常順/レベル順のソート切替
5. FXキー長押しによるアルファベットジャンプナビゲーション
6. お気に入りの登録・解除
7. サブフォルダのネスト表示とディレクトリ移動
8. コースモード（.kcoファイル）の選択
9. スコア・メダル・グレードの表示
10. ジャケット画像の読み込みと表示
11. プレビューBGMの自動フェード再生
12. BPM・レベル等の楽曲情報表示
13. プレイヤー切替（BT1+BT2+方向キー）
14. インラインオプション変更（HiSpeed、ゲージタイプ等）
15. キーボードショートカット（Ctrl+C/E/O/I）
16. 自動デモ再生

**関連システム・外部連携**：BASS Audio Library（BGM・プレビュー再生）、ファイルシステム（楽曲ディレクトリスキャン）、クリップボード（パスコピー）、IR連携（IRページ表示）

**権限による制御**：特になし。全ユーザーが同一の操作が可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 3 | 曲選択画面 | 主画面 | 曲リスト表示・ディレクトリブラウジング・キー入力処理を統合する選曲画面の主処理 |
| 1 | タイトル画面 | 遷移元/遷移先 | Escキー押下でタイトル画面(SCENE_TITLE)へ遷移 |
| 5 | ゲームプレイ画面 | 遷移先 | 楽曲選択・Enter決定後にSCENE_BEFORE_PLAY経由でプレイ画面へ遷移 |

## 機能種別

画面表示・データ検索・ファイル参照・シーン遷移制御

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| dirp | str | No | 前回選択ディレクトリパス | config.iniから復元 |
| selp | int | No | 前回選択位置 | config.iniから復元 |
| levnow | int | No | 前回選択難易度 | 0-3 (Light/Challenge/Extended/Infinite) |
| sorttype | int | No | ソート方式 | 0(通常) / 1(レベル順) |
| cplayer | int | No | 現在のプレイヤー番号 | 0 - playersnum-1 |
| mastervol | int | No | マスターボリューム | 0-100 |

### 入力データソース

- songs/ディレクトリ配下の.kshファイル群
- courses/ディレクトリ配下の.kcoファイル群
- score/プレイヤー名/ディレクトリ配下のスコアファイル
- config.ini：前回の選曲状態保持

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| scene | int | 遷移先シーンID（SCENE_BEFORE_PLAY / SCENE_TITLE） |
| cnotesfile | str | 選択された譜面ファイルパス |
| csongdir | str | 選択された楽曲ディレクトリ |
| iscourse | int | コースモードフラグ（0/1） |
| levnow | int | 選択された難易度 |

### 出力先

- 画面表示（曲リスト、ジャケット画像、楽曲情報、スコア・メダル）
- グローバル変数（scene, cnotesfile, csongdir等）

## 処理フロー

### 処理シーケンス

```
1. 選曲画面初期化
   ├─ IME無効化
   ├─ 楽曲ディレクトリ移動
   ├─ 曲リスト生成（*refreshfilelist）
   ├─ 前回選択位置の復元
   ├─ スコア読み込み（*reloadscore / *refreshscore）
   ├─ ジャケット画像読み込み（*refreshjacket）
   └─ 楽曲情報取得（*refreshsonginfo）
2. 選曲メインループ
   ├─ 入力処理
   │   ├─ 上下キー：曲リストスクロール
   │   ├─ 左右キー：難易度切替
   │   ├─ FX同時押し：ソート切替
   │   ├─ FXキー離し：アルファベットジャンプ
   │   ├─ Home/End：リスト先頭/末尾移動
   │   ├─ PageUp/Down：8曲単位スクロール
   │   ├─ Enter：楽曲決定
   │   ├─ Esc/BackSpace：ディレクトリ戻り / タイトル戻り
   │   ├─ Ctrl+C/E/O/I：ショートカット
   │   └─ アナログ入力：マウス/スティック/スライダー
   ├─ 描画処理
   │   ├─ 背景描画
   │   ├─ 曲リスト描画
   │   ├─ 楽曲情報パネル描画
   │   ├─ ジャケット画像描画
   │   └─ スコア・メダル描画
   └─ プレビューBGM制御
3. シーン遷移
   ├─ Enter決定 → SCENE_BEFORE_PLAY
   └─ Esc → SCENE_TITLE
```

### フローチャート

```mermaid
flowchart TD
    A[選曲画面開始] --> B[初期化処理]
    B --> C[曲リスト生成]
    C --> D[メインループ]
    D --> E{入力判定}
    E -->|上下キー| F[曲リストスクロール]
    E -->|左右キー| G[難易度切替]
    E -->|FX同時押し| H[ソート切替]
    E -->|Enter| I{選択アイテム種別}
    E -->|Esc| J[タイトル画面へ]
    E -->|BackSpace| K[親ディレクトリへ]
    F --> L[リフレッシュ処理]
    G --> L
    H --> L
    L --> D
    I -->|楽曲| M[SCENE_BEFORE_PLAY]
    I -->|フォルダ| N[フォルダ移動]
    I -->|コース| O[コースモード開始]
    N --> C
    K --> C
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 難易度フォールバック | 選択難易度のデータが存在しない場合、隣接する難易度に自動フォールバック | 楽曲選択変更時 |
| BR-02 | ソート切替 | FXキー同時押しで通常順⇔レベル順を切替（sorttype変数） | fxkey.0+fxkey.1=2 |
| BR-03 | 曲リスト循環 | 曲リスト末尾を超えたら先頭に、先頭を下回ったら末尾に循環 | 上下スクロール時 |
| BR-04 | プレイヤー切替 | BT1+BT2+方向キーでプレイヤーを切替え、スコアデータを再読み込み | btkey.1+btkey.2=2 |
| BR-05 | 自動デモ再生 | Shift長押しでautodemo開始、auto=1設定でオートプレイモード | shift_key長押し |
| BR-06 | コースモード判定 | 選択アイテムがコースファイル(.kco)の場合はコースモードで遷移 | minfo.selnow.0.0=4 |

### 計算ロジック

特になし（主にUI制御・ファイル操作処理）。

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

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

本機能ではデータベース操作は行わない。ファイルベースのスコア管理のみ。

| 操作 | 対象ファイル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| スコア読み込み | score/{player}/*.ksc | SELECT相当 | プレイヤー別スコアファイルの読み込み |
| 設定保存 | config.ini | UPDATE相当 | 選曲状態(currentdir/currentitem/currentlevel)の保持 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ディレクトリ不在 | 保存されたdirpが存在しない | dir=""にリセットしてルートから再表示 |
| - | スコアファイル不在 | プレイヤーのスコアファイルが存在しない | スコア0として表示 |
| - | ジャケット画像不在 | 楽曲にジャケット画像が含まれない | "Now Printing"画像を代替表示 |

### リトライ仕様

リトライ処理は実装されていない。

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

トランザクション処理は適用されない。

## パフォーマンス要件

- 曲リスト生成（*refreshfilelist）は楽曲数に比例する処理時間
- SONG_MAX=8192が楽曲数の上限
- ジャケット画像は選択変更時に非同期的に読み込み
- プレビューBGMはフェードイン/アウト制御による滑らかな切替

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

特になし。ローカルファイルシステムのみアクセス。

## 備考

- 選曲画面はK-Shoot MANIAの中で最もコード量が多いファイル（select.hsp）
- 6種類のアナログ入力方式（キーボード/PowerMate/マウス/アナログスティック/スライダー/Z軸）に対応

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | kshootmania.hsp | `kshootmania.hsp` | SONG_MAX=8192、SELSLIDER_MAX=4、LEVSLIDER_MAX=8 等の定数定義 |

**読解のコツ**: HSPの配列 `minfo.selnow.levm.0` は多次元配列アクセスで、曲リスト内の楽曲情報を格納。`minfostr` は文字列版。minfo第1次元が曲インデックス、第2次元が難易度(0-3)、第3次元がプロパティ番号。

- **25行目**: `#define SONG_MAX 8192` - 楽曲数上限
- **26-27行目**: `SELSLIDER_MAX=4`, `LEVSLIDER_MAX=8` - アナログ入力の感度定数

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | select.hsp | `src/scene/select.hsp` | start_selectサブルーチンの初期化（1-153行目） |

**主要処理フロー**:
1. **1行目**: `#deffunc start_select` でサブルーチン定義
2. **11行目**: IME無効化
3. **25行目**: songsディレクトリへ移動
4. **40-43行目**: 曲リスト生成（`gosub *refreshfilelist`）
5. **45-46行目**: 前回選択位置の復元
6. **124-127行目**: スコア・ジャケット・楽曲情報の読み込み

#### Step 3: 入力処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | select.hsp | `src/scene/select.hsp` | キー入力・ソート・難易度切替（160-1300行目） |

**主要処理フロー**:
- **160-193行目**: Escキーによるタイトル画面戻り・親ディレクトリ移動
- **217-225行目**: FXキー入力取得
- **244-261行目**: FX同時押しによるソート切替（sorttype=1-sorttype）
- **265-318行目**: Ctrl+C/E/O/Iショートカット処理
- **827-975行目**: 上下キー・アナログ入力による曲リストスクロール
- **1217-1300行目**: 左右キー・アナログ入力による難易度切替

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

```
kshootmania.hsp (メインループ: 952行目)
    │
    └─ start_select (src/scene/select.hsp: 1行目)
           ├─ *refreshfilelist (曲リスト生成)
           ├─ *reloadscore (スコアファイル読み込み)
           ├─ *refreshscore (スコア表示更新)
           ├─ *refreshjacket (ジャケット画像読み込み)
           ├─ *refreshjacketdown (下スクロール時ジャケット更新)
           ├─ *refreshjacketup (上スクロール時ジャケット更新)
           ├─ *refreshsonginfo (楽曲情報表示更新)
           ├─ *getjoystat (ジョイスティック状態取得)
           ├─ *volactive (ボリューム制御)
           ├─ BASS_StreamCreateFile (プレビューBGM読み込み)
           ├─ BASS_ChannelPlay (プレビューBGM再生)
           ├─ clipset (クリップボードコピー)
           ├─ getChartIRHash (IR用ハッシュ計算)
           └─ blackout (トランジション演出)
```

### データフロー図

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

songs/*.ksh ─────────────────▶ *refreshfilelist ───────────────▶ minfo/minfostr配列
                                    │                               │
score/{player}/*.ksc ────────▶ *reloadscore ────────────────▶ スコア・メダル表示
                                    │
キーボード/ジョイスティック ──▶ 入力処理 ─────────────────────▶ selnow/levnow
   /アナログ                        │                          (選択位置/難易度)
                                    │
楽曲ジャケット画像 ──────────▶ *refreshjacket ────────────────▶ 画面描画
                                    │
楽曲プレビュー音声 ──────────▶ BASS_StreamCreateFile ──────────▶ BGM再生
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| kshootmania.hsp | `kshootmania.hsp` | ソース | メインループ・グローバル変数・定数定義 |
| select.hsp | `src/scene/select.hsp` | ソース | 選曲画面の全処理（初期化・入力・描画・遷移） |
| config.ini | `config.ini` | 設定 | 選曲状態の保持・復元 |
| sel_bgm.ogg | `se/sel_bgm.ogg` | 音声 | 選曲画面BGM |
| sel_m.wav | `se/sel_m.wav` | 音声 | 曲選択移動SE |
| sel_l.wav | `se/sel_l.wav` | 音声 | 難易度変更SE |
| sel_dir.wav | `se/sel_dir.wav` | 音声 | ディレクトリ移動SE |
| sel_enter.ogg | `se/sel_enter.ogg` | 音声 | 楽曲決定SE |
| bass.as | `src/bass.as` | ソース | BASS Audio Libraryバインディング |
| filesystem_utils.as | `src/filesystem_utils.as` | ソース | ファイルシステムユーティリティ |
| clipboard.as | `third_party/clipboard.as` | ソース | クリップボード操作 |
| ir.hsp | `src/ir.hsp` | ソース | IR連携機能 |
