# 画面設計書 3-曲選択画面

## 概要

本ドキュメントは、K-Shoot MANIA の曲選択画面の設計仕様を記述する。プレイする楽曲を選択するメインUIであり、最大規模の画面（4,991行）を持つ。ディレクトリブラウジング、難易度選択、コース選択、お気に入り管理、検索・フィルタリング機能を含む。

### 本画面の処理概要

曲選択画面はプレイする楽曲を選択するための中核画面であり、楽曲の一覧表示、難易度選択、スコア表示、プレビュー再生など多数の機能を統合している。

**業務上の目的・背景**：K-Shoot MANIAのメインフローにおいて、楽曲選択はプレイ開始の直前ステップであり、プレイヤーがどの楽曲・どの難易度をプレイするかを決定する重要な画面である。フォルダ構造によるディレクトリブラウジング、お気に入り管理、ソート・フィルタリング機能により、大量の楽曲から効率的に選曲できるようにしている。

**画面へのアクセス方法**：IRサインイン画面からログイン/スキップ後に遷移する。またはリザルト画面・コースリザルト画面から復帰する。

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

**画面遷移**：
- 遷移先：タイトル画面（ESCキー、行183-184）、プレイ前処理画面（Enter決定、行1653/1704）
- 遷移元：IRサインイン画面（ログイン/スキップ後）、リザルト画面（通常終了）、コースリザルト画面（コース完了）

**権限による表示制御**：特になし。プレイヤー切替（cplayer変数）により表示スコアが切り替わる。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 2 | 選曲画面 | 主機能 | 曲リスト表示・ディレクトリブラウジング・キー入力処理を統合する選曲画面の主処理 |
| 8 | 曲リスト表示 | 主機能 | refreshfilelistサブルーチンで楽曲一覧を生成し、スクロール可能なリストとして描画 |
| 9 | 難易度選択 | 主機能 | 方向キー左右・アナログ入力によるLight/Challenge/Extended/Infiniteの4段階難易度切替 |
| 10 | ソート切替 | 主機能 | FXキー同時押し(fxkey.0+fxkey.1=2)による通常順/レベル順のソート方式切替 |
| 11 | アルファベットジャンプ | 主機能 | FXキー長押し+選曲操作による先頭文字ジャンプナビゲーション |
| 12 | お気に入り管理 | 主機能 | Favoriteファイル(.fav)の読み書きによる楽曲のお気に入り登録・解除 |
| 13 | サブフォルダ対応 | 主機能 | sndirstat配列によるネスト構造のフォルダ表示・BackSpaceキーでの親ディレクトリ移動 |
| 14 | コースモード | 主機能 | コースファイル(.kco)選択時のSCENE_BEFORE_PLAYへの遷移によるコースモード開始 |
| 15 | スコア・メダル表示 | 主機能 | refreshscoreサブルーチンによる既存スコア・メダル・グレードの読み込みと表示 |
| 16 | ジャケット画像表示 | 主機能 | refreshjacketサブルーチンによる選択中楽曲のジャケット画像読み込み・表示 |
| 17 | プレビューBGM再生 | 主機能 | BASS_StreamCreateFile/URLによるプレビューBGM再生・フェードイン/アウト制御 |
| 18 | 楽曲情報表示 | 主機能 | refreshsonginfoサブルーチンによるBPM・レベル・難易度ラベルの表示 |
| 19 | プレイヤー切替 | 補助機能 | BT1+BT2+方向キーによるcplayer変数切替とスコア・楽曲情報のリロード |
| 20 | インラインオプション変更 | 補助機能 | 曲選択画面上でのHiSpeed・effratetype・turnの直接変更 |
| 21 | キーボードショートカット | 補助機能 | Ctrl+C/E/O/Iのショートカット処理 |
| 22 | 自動デモ再生 | 補助機能 | Shiftキー長押し(autodemo変数)による自動デモ再生開始 |
| 58 | キーボード入力 | 補助機能 | 方向キー・Enter・Esc・Home・End・PageUp/Down等のキーボード入力 |
| 59 | ジョイスティック入力 | 補助機能 | getjoykeystatによるジョイスティックボタン入力 |
| 60 | アナログ入力 | 補助機能 | マウス(XY)・PowerMate・アナログスティック・スライダー等6種類のアナログ入力方式対応 |
| 42 | 音量制御 | 補助機能 | BASS_ChannelSetAttributeによるBGM・SE・プレビュー音のマスターボリューム適用 |
| 7 | シーン遷移管理 | 遷移先機能 | Enter/Escキー押下による各シーンへの遷移 |
| 3 | プレイ画面 | 遷移先機能 | 楽曲選択・Enter決定後にSCENE_BEFORE_PLAY経由でゲームプレイ画面へ遷移 |
| 1 | タイトル画面 | 遷移先機能 | Escキー押下でタイトル画面(SCENE_TITLE)へ遷移 |

## 画面種別

一覧選択画面（楽曲リストブラウジング）

## URL/ルーティング

デスクトップアプリケーション（HSP3）のため、URLルーティングは存在しない。シーン管理はscene変数（SCENE_SELECT = 2）により制御される。

## 入出力項目

| 項目名 | 入出力 | データ型 | 説明 |
|--------|--------|----------|------|
| selnow | 内部状態 | int | 現在選択中の楽曲インデックス |
| levnow / levm | 内部状態 | int | 現在選択中の難易度（0:Light, 1:Challenge, 2:Extended, 3:Infinite） |
| mnum | 内部状態 | int | 現在表示中の楽曲数 |
| minfo | 内部状態 | int配列 | 楽曲メタデータ配列。minfo.曲番号.難易度.属性で参照 |
| minfostr | 内部状態 | string配列 | 楽曲文字列データ配列 |
| dir | 内部状態 | string | 現在のディレクトリパス |
| cplayer | 入力 | int | 現在のプレイヤー番号 |
| cnotesfile | 出力 | string | 選択された譜面ファイルパス |
| csongdir | 出力 | string | 選択された楽曲ディレクトリパス |
| iscourse | 出力 | int | コースモードフラグ（1:コース, 0:通常） |
| mpid | 内部状態 | int | プレビューBGMのBASSチャンネルID |
| autodemo | 入力/出力 | int | 自動デモ再生フラグ |

## 表示項目

| 項目名 | 表示位置 | 説明 |
|--------|----------|------|
| 背景画像 | 画面全体 | bg2.jpg（buffer 29）を背景として描画 |
| 楽曲リスト | 画面左側 | スクロール可能な楽曲一覧。曲名・アーティスト名・レベル・メダルを表示 |
| 楽曲詳細情報 | 画面右側 | 選択中楽曲のBPM・レベル・難易度ラベル・スコア・グレード |
| ジャケット画像 | 画面右上 | 選択中楽曲のジャケット画像（buffer 129） |
| スクロールバー | 画面右端 | リスト全体における現在位置を示すスクロールバー（Image 60/61） |
| 難易度カーソル | リスト内 | 選択中楽曲のアニメーション付きカーソル（buffer 26） |
| インラインオプション | 画面下部 | HiSpeed・ゲージタイプ・TURNの現在設定値 |

## イベント仕様

### 1-楽曲選択（上下キー/アナログ入力）

上下キー・Home/End・PageUp/PageDown・アナログ入力により、selnow変数を変更して楽曲リスト内を移動する。移動時にプレビューBGMの切替、ジャケット画像の再読み込み、スコア情報のリフレッシュが行われる。

### 2-難易度切替（左右キー）

方向キー左右・アナログ入力によりlevnow/levm変数を変更し、4段階の難易度（Light=0, Challenge=1, Extended=2, Infinite=3）を切り替える。選択中の楽曲に該当難易度の譜面が存在しない場合は自動的に利用可能な難易度にフォールバックする（行89-123）。

### 3-楽曲決定（Enterキー）

Enterキーまたはジョイスティックボタン11で楽曲を決定する。選択した項目のタイプに応じて処理が分岐する：
- **通常楽曲（minfo>=0）**：cnotesfile/csongdirを設定し、SCENE_BEFORE_PLAYへ遷移。iscourse=0（行1699-1729）
- **コースファイル（minfo=4）**：cnotesfileを設定し、SCENE_BEFORE_PLAYへ遷移。iscourse=1（行1647-1661）
- **ディレクトリ（minfo=-1/-5）**：サブディレクトリに移動してリストを再構築

### 4-ESCキーによる復帰

ESCキー押下時の処理が分岐する：
- **サブフォルダ内の場合（dir!=""）**：親ディレクトリに移動してリストを再構築（行161-178）
- **ルートフォルダの場合**：SCENE_TITLEへ遷移（行180-192）。プレビューBGMを解放し、500msブラックアウト。

### 5-ソート切替

FXキー0とFXキー1の同時押し（fxkey.0+fxkey.1=2）でソート方式をトグルする（通常順/レベル順）。

### 6-お気に入り管理

楽曲選択状態で特定の操作により.favファイルへの登録/解除を行う。

### 7-キーボードショートカット

- **Ctrl+C**：選択中譜面のパスをクリップボードにコピー
- **Ctrl+E**：外部エディタを起動
- **Ctrl+O**：楽曲フォルダをエクスプローラーで開く
- **Ctrl+I**：IRページをブラウザで開く

## データベース更新仕様

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

| 操作（イベント） | 対象ファイル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 画面初期化 | songs/ディレクトリ内 | SELECT | refreshfilelistでディレクトリ走査し楽曲一覧を構築 |
| 楽曲選択切替 | score/プレイヤー名/ | SELECT | refreshscoreでスコアファイル(.ksc)を読み込み |
| 楽曲選択切替 | songs/曲ディレクトリ/ | SELECT | refreshjacketでジャケット画像を読み込み |
| 画面終了 | config.ini | UPDATE | currentdir/currentitem/currentlevel等の選択状態を保存 |

### テーブル別更新項目詳細

該当なし（ファイルベースアーキテクチャ）。

## メッセージ仕様

| メッセージID | 種別 | 表示条件 | メッセージ内容 |
|-------------|------|----------|--------------|
| lang.2.13 | エラー | 譜面ファイルが見つからない場合 | 「指定された譜面ファイルが見つかりません。」 |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| 楽曲ディレクトリが空 | 空のリストを表示 |
| 難易度の譜面が存在しない | 利用可能な難易度に自動フォールバック |
| ジャケット画像が存在しない | nowprinting画像（デフォルトジャケット）を表示 |
| プレビューBGMが存在しない | プレビュー再生をスキップ |

## 備考

- 最大規模の画面（4,991行）であり、楽曲管理・表示・入力処理が集約されている。
- 楽曲数上限はSONG_MAX=8192と定義されている。
- アナログ入力は6種類（キーボード/PowerMate/マウス/スティック/スライダー/Z軸）に対応。
- プレビューBGMはBASSライブラリのストリーミング再生を使用し、楽曲切替時にフェードイン/アウト制御を行う。
- 自動デモ再生はShiftキー長押しで開始し、曲を順番にオートプレイする機能。

---

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

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

### 推奨読解順序

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

楽曲データの管理構造を理解することが最も重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | kshootmania.hsp | `kshootmania.hsp` | 行25: SONG_MAX=8192（楽曲数上限）、行26-27: SELSLIDER_MAX/LEVSLIDER_MAX定数 |
| 1-2 | select.hsp | `src/scene/select.hsp` | minfo配列（int）とminfostr配列（string）が楽曲メタデータを管理。minfo.曲番号.難易度.属性の3次元配列 |

**読解のコツ**: minfo配列の第3次元の属性値は、楽曲タイプ（minfo.n.0.0）が重要。正値=通常楽曲、-1=ディレクトリ、-5=サブフォルダ、4=コース。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | select.hsp | `src/scene/select.hsp` | 行1: `#deffunc start_select`がエントリーポイント |

**主要処理フロー**:
1. **行1-11**: 初期化（IME無効化、変数初期化）
2. **行25-43**: ディレクトリ移動とrefreshfilelist呼び出し
3. **行45-128**: 選択状態の初期化と難易度フォールバック処理
4. **行124-127**: スコア・ジャケット・楽曲情報のリフレッシュ
5. **行154-**: メインループ（入力処理・描画・遷移判定）

#### Step 3: 楽曲リスト構築を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | select.hsp | `src/scene/select.hsp` | *refreshfilelistサブルーチン: ディレクトリ走査により楽曲一覧を構築。minfo/minfostr配列にデータを格納 |

#### Step 4: 楽曲決定・遷移処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | select.hsp | `src/scene/select.hsp` | 行1646-1729: Enter決定時の分岐処理。コースモード（行1647-1661）、通常楽曲（行1662-1729）の遷移 |
| 4-2 | select.hsp | `src/scene/select.hsp` | 行180-192: ESCキーによるタイトル画面への復帰処理 |

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

```
kshootmania.hsp (メインループ)
    |
    +-- start_select (src/scene/select.hsp:1)
            |
            +-- *refreshfilelist ... 楽曲リスト構築
            |       +-- dirlist ... ディレクトリ走査
            |       +-- noteload ... 譜面ファイル読み込み
            |
            +-- *reloadscore ... プレイヤー別スコア読み込み
            +-- *refreshscore ... スコア表示更新
            +-- *refreshjacket ... ジャケット画像更新
            +-- *refreshsonginfo ... 楽曲情報更新
            |
            +-- メインループ (行154-)
                    +-- *getjoystat ... ジョイスティック状態取得
                    +-- getesckey() ... ESCキー判定
                    |       +-- サブフォルダ戻り (行161-178)
                    |       +-- SCENE_TITLE遷移 (行180-192)
                    +-- Enterキー判定 ... 楽曲決定
                    |       +-- コースモード (行1647-1661)
                    |       +-- 通常楽曲 (行1662-1729)
                    |       +-- scene=SCENE_BEFORE_PLAY
                    +-- 上下キー ... selnow変更
                    +-- 左右キー ... levm変更（難易度切替）
                    +-- BASS_StreamCreateFile ... プレビューBGM再生
                    +-- *volactive ... ボリューム制御
```

### データフロー図

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

songs/ディレクトリ -------> *refreshfilelist ----------------> minfo/minfostr配列
                                                                    |
上下キー/アナログ --------> selnow変更 ----+                       v
左右キー -----------------> levm変更 ------+---> *refreshscore --> スコア表示
                                           +---> *refreshjacket -> ジャケット表示
                                           +---> *refreshsonginfo > 楽曲情報表示
                                           +---> BASS_StreamCreateFile > プレビューBGM

Enterキー ----------------> minfo分岐判定
                                |
                    +-----------+-----------+
                    |                       |
                    v                       v
              コースモード             通常楽曲
              iscourse=1              iscourse=0
              cnotesfile設定          cnotesfile設定
                    |                       |
                    v                       v
              scene=SCENE_BEFORE_PLAY

score/プレイヤー名/*.ksc --> *reloadscore --> スコアデータ表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| select.hsp | `src/scene/select.hsp` | ソース | 曲選択画面の全処理（4,991行）。start_select関数 |
| kshootmania.hsp | `kshootmania.hsp` | ソース | メインループ、定数定義、シーン管理 |
| bg2.jpg | `imgs/bg2.jpg` | リソース | 背景画像 |
| msel_0.png | `imgs/msel_0.png` | リソース | 楽曲リスト項目の基本フレーム |
| msel_0_cur.gif | `imgs/msel_0_cur.gif` | リソース | 選択カーソルアニメーション |
| msel_grade.png | `imgs/msel_grade.png` | リソース | グレード表示画像（D/C/B/A/AA/AAA） |
| msel_medal.png | `imgs/msel_medal.png` | リソース | メダル表示画像 |
| msel_level.png | `imgs/msel_level.png` | リソース | レベル数値画像 |
| msel_bar.png | `imgs/msel_bar.png` | リソース | スクロールバー画像 |
| msel_optionbg.png | `imgs/msel_optionbg.png` | リソース | インラインオプション背景 |
| nowprinting1.jpg等 | `imgs/jacket/nowprinting*.jpg` | リソース | デフォルトジャケット画像 |
| config.ini | `config.ini` | 設定 | 選択状態の保持・復元 |
