# 帳票設計書 4-ゲーム設定ファイル

## 概要

本ドキュメントは、K-ShootMANIAのゲーム設定情報（画面サイズ、キー設定、プレイヤー名、ハイスピード、音声設定等）をINI形式でconfig.iniに保存する「ゲーム設定ファイル」の帳票設計書である。アプリケーション終了時やオプション変更時に現在の設定値を永続化する。

### 本帳票の処理概要

本帳票は、K-ShootMANIAの各種設定値をテキスト形式のINIファイルとして保存する。起動時にconfig.iniを読み込み、ゲーム終了時やオプション画面からの遷移時に更新された設定値を書き戻す。

**業務上の目的・背景**：音楽ゲームでは、キーバインド、画面サイズ、ハイスピード設定、音声設定など多数のユーザー固有設定が存在する。これらの設定をセッションをまたいで永続化するため、テキスト形式のINIファイルに保存する必要がある。起動時に読み込み・終了時に書き出しというシンプルなファイルI/Oで実現している。

**帳票の利用シーン**：ゲームの初回起動時にデフォルト設定ファイルが自動生成される。オプション画面での設定変更後やゲーム正常終了時に設定値が保存される。次回起動時にこの設定ファイルが読み込まれ、前回の設定が復元される。

**主要な出力内容**：
1. キーバインド設定（key, key2, joy, joy2）
2. 画面設定（fullscr, windowsize, fullscrsize）
3. プレイ設定（hispeed, bt_mode, fx_mode, laser_mode, effratetype, background）
4. 出力設定（output, output_path, output_downscale）
5. 音声・入力設定（mastervol, mouse_sensitivity, switchlaser, laserinput）
6. ユーザー情報（currentplayer, currentdir, currentitem, currentlevel, currentlang）

**帳票の出力タイミング**：kshootmania.hsp内の*confsave サブルーチンが呼び出された時。具体的にはオプション画面からの離脱時やゲーム正常終了時に呼ばれる。また、初回起動時にconfig.iniが存在しない場合は空のファイルが生成される（kshootmania.hsp:391-395行目）。

**帳票の利用者**：ゲーム起動時のランタイムエンジン（設定読み込み）。プレイヤーは間接的にオプション画面を通じて設定を変更する。上級者はテキストエディタで直接編集することも可能。

## 帳票種別

設定ファイル出力（INIテキスト形式）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| - | オプション画面 | SCENE_OPTION（option.hsp） | 設定変更後にsaveConfig呼び出し |
| - | 各シーン遷移時 | kshootmania.hsp内のメインループ | *confsaveサブルーチン呼び出し |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | INIテキスト（key=value形式） |
| 用紙サイズ | 該当なし |
| 向き | 該当なし |
| ファイル名 | config.ini（アプリケーションルートディレクトリ直下） |
| 出力方法 | HSPのnotesave命令によるテキスト保存 |
| 文字コード | Shift_JIS（HSPのデフォルト） |

## 帳票レイアウト

### レイアウト概要

INI形式のテキストファイルで、各行が「key=value」形式の設定エントリとなる。セクション区切りはなく、フラットなキーバリュー構造。

```
key=90,88,46,192,65,186,37,39,38,40,32,13,76,9
key2=0,0,0,0,0,0,0,0,0,0,0,0,0,0
fullscr=0
windowsize=720,480
hispeed=x10
output=0
output_path=
output_downscale=1
currentplayer=PLAYER
mastervol=100
...
```

### ヘッダー部

該当なし（INIファイルにヘッダーはない）

### 明細部（設定項目一覧）

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 備考 |
|----|-------|------|-------------|---------|------|
| 1 | key | キーバインド（第1セット、14キー） | key配列 | カンマ区切り整数 | BT4+FX2+方向4+Space+Enter+L+Tab |
| 2 | key2 | キーバインド（第2セット、14キー） | key2配列 | カンマ区切り整数 | 代替キー設定 |
| 3 | fullscr | フルスクリーン有効化 | fullscr変数 | 0/1 | 0=ウィンドウ,1=フルスクリーン |
| 4 | windowsize | ウィンドウサイズ | windowsize配列 | W,H形式 | 例: 720,480 |
| 5 | fullscrsize | フルスクリーンサイズ | fullscrsize配列 | W,H形式 | |
| 6 | assisttick | アシストティック有効化 | assisttick変数 | 0/1 | |
| 7 | highquality | 高品質描画 | highquality変数 | 0/1 | |
| 8 | lowquality | 低品質描画 | lowquality変数 | 0/1 | |
| 9 | bt_mode | BTノーツモード | shortmodedef変数 | 整数 | 0=ON,1=OFF,2=AUTO,3=HIDE |
| 10 | fx_mode | FXノーツモード | longmodedef変数 | 整数 | 同上 |
| 11 | laser_mode | レーザーモード | analogmodedef変数 | 整数 | 同上 |
| 12 | hispeed | ハイスピード設定 | hsr/hsc/hsm/hsa/hso | 型プレフィックス+値 | x10, C200, m300等 |
| 13 | viewtiming | タイミング表示 | vtiming変数 | 0/1 | |
| 14 | currentplayer | 現在のプレイヤー名 | players.cplayer | 文字列 | |
| 15 | background | 背景表示レベル | bg変数 | 0/1/2 | 0=OFF,1=ON,2=アニメ |
| 16 | backgroundmovie | 動画背景 | vmov変数 | 0/1 | |
| 17 | noteskin | ノーツスキン | coloring変数 | "note"/"default" | |
| 18 | laserinput | レーザー入力方式 | analoginput変数 | 整数 | 0-4 |
| 19 | output | スクリーンショット出力 | output変数 | 0/1 | |
| 20 | output_path | 出力先パス | outputpath変数 | 文字列 | |
| 21 | output_downscale | ダウンスケール | outputds変数 | 1/2/4 | |
| 22 | disableime | IME無効化 | disableime変数 | 0-3 | |
| 23 | globaloffset | グローバルオフセット | globaloffset_config変数 | 整数(ms) | |
| 24 | hidemousecursor | マウスカーソル非表示 | hidem変数 | 0/1 | |
| 25 | mastervol | マスターボリューム | mastervol変数 | 0-100 | |
| 26 | mouse_directionx | マウスX方向 | mx変数 | 0/1 | |
| 27 | mouse_directiony | マウスY方向 | my変数 | 0/1 | |
| 28 | mouse_sensitivity | マウス感度 | msen変数 | 整数 | |
| 29 | switchlaser | レーザー左右入れ替え | analogsw変数 | 0/1 | |
| 30 | joy | ジョイスティック設定1 | joykey配列 | カンマ区切り | 14ボタン分 |
| 31 | joy2 | ジョイスティック設定2 | joykey配列 | カンマ区切り | |
| 32 | currentlang | 表示言語 | clang変数 | 文字列 | "Japanese"等 |
| 33 | currentdir | 現在のディレクトリ | dir_confsave変数 | 文字列 | 楽曲選択位置の保存 |
| 34 | currentitem | 現在の選択項目 | selnow_confsave変数 | 整数 | |
| 35 | currentlevel | 現在の難易度 | levnow変数 | 整数 | |
| 36 | showalldir | 全ディレクトリ表示 | valldir変数 | 0/1 | |
| 37 | closekey | 終了キー | closekey変数 | 整数 | |
| 38 | mselview | 楽曲選択表示方式 | sorttype変数 | "directory"/"level" | |
| 39 | laserdelay | レーザー遅延 | analogdelay_config変数 | 整数 | |
| 40 | usenumpad | テンキー使用 | usenumpad変数 | 0/1 | |
| 41 | hispeedtype | 表示するHiSpeed種別 | vhstype配列 | カンマ区切り文字列 | x,C,m,a,O |
| 42 | inputdelay | 入力遅延 | judgedelay_config変数 | 整数 | |
| 43 | vsync | 垂直同期 | vsync変数 | 0/1 | |
| 44 | esckey_bt3 | ESCキーBT3割り当て | esc_bt3変数 | 0/1 | |
| 45 | hideitem_all | 全項目非表示 | hidealldir変数 | 0/1 | |
| 46 | ir_sign_in_cursor | IR選択カーソル | ir_selnow変数 | 整数 | |

### フッター部

該当なし

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| *confsaveサブルーチン呼び出し | 設定保存のタイミングで呼ばれること | Yes |
| config.ini初回作成 | ファイル不存在時に空ファイルを作成 | Yes（初回のみ） |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| 1 | 既存config.iniの行順序 | 維持 |

### 改ページ条件

該当なし

## データベース参照仕様

### 参照テーブル一覧

本帳票はデータベースを使用しない。全てHSPのグローバル変数から値を取得する。

| データ構造名 | 用途 | 備考 |
|-----------|------|---------|
| confstr配列 | 既存config.iniの行配列 | noteload後にsplitで分割 |
| confex配列 | 各設定項目の存在フラグ | 未存在項目の追加判定に使用 |
| confs文字列 | 保存用文字列バッファ | key=value形式で構築後notesaveで保存 |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| hispeed文字列 | hsc/hsm/hsa/hso判定後にプレフィックス付加 | 該当なし | "x"+hsr, "C"+hsc, "m"+hsm, "a"+hsa, ""+hso |
| hispeedtype文字列 | vhstype配列の各要素が1の場合に対応文字をカンマ区切りで連結 | 該当なし | 空の場合"x,O"がデフォルト |
| mselview文字列 | sorttype=0なら"directory"、それ以外は"level" | 該当なし | |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[*confsave呼び出し] --> B[既存config.ini読み込み]
    B --> C[confstr配列に分割]
    C --> D[confex配列で存在チェック]
    D --> E[各行をループ処理]
    E --> F{既存キーと一致?}
    F -->|Yes| G[現在の変数値で上書き]
    F -->|No| H[元の行をそのまま保持]
    G --> I[confs文字列に追記]
    H --> I
    I --> J{全行処理完了?}
    J -->|No| E
    J -->|Yes| K[未存在キーの追加]
    K --> L[改行の重複除去]
    L --> M[notesave config.ini]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| config.ini不存在 | 初回起動時 | なし | 空ファイルをnotesaveで自動生成（391-395行目） |
| 書き込み失敗 | ファイルシステムの権限問題 | OS依存 | HSPランタイムのエラー処理に委任 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 1ファイル（約46項目） |
| 目標出力時間 | 即座（テキスト書き出しのみ） |
| 同時出力数上限 | 1 |

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

- config.iniはアプリケーションルートディレクトリに保存され、プレーンテキスト形式のため誰でも読み書き可能
- パスワードや認証情報は含まれない
- output_path設定にはユーザーが任意のパスを指定できるが、実際の出力先として使用されるのはスクリーンショット機能のみ
- IR（インターネットランキング）関連のir_sign_in_cursor設定はカーソル位置のみで認証情報は含まれない

## 備考

- *confsaveサブルーチンは既存のconfig.iniの行順序を維持しつつ、値のみを更新する設計になっている
- 未存在の設定キーは末尾に自動追加される（confex配列の0判定による追加処理）
- 三重改行の除去処理が含まれる（1494行目: strrep confs,"\n\n\n","\n"）
- config.iniの読み込みはkshootmania.hspの416-600行目付近で行われる

---

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

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

### 推奨読解順序

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

config.iniの設定項目に対応するグローバル変数を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | kshootmania.hsp | `kshootmania.hsp` | 270-345行目: 各設定変数のデフォルト値定義 |

**読解のコツ**: HSP3では全てグローバル変数として管理される。変数名と config.ini のキー名は必ずしも一致しない（例: bg変数 ↔ background=キー）。

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

config.iniの読み込みとパース処理を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | kshootmania.hsp | `kshootmania.hsp` | 390-395行目: config.ini不存在時の初期ファイル生成 |
| 2-2 | kshootmania.hsp | `kshootmania.hsp` | 416-600行目: noteload後のStartsWith条件分岐による値パース |

**主要処理フロー**:
1. **390行目**: exist "config.ini" でファイル存在チェック
2. **392-394行目**: 不存在時に空のnotesaveで初期ファイル作成
3. **416行目**: noteload "config.ini" で読み込み
4. **417行目**: split confs,"\n",confstr で行分割
5. **418-600行目**: 各行のStartsWith判定で設定値を変数に代入

#### Step 3: 設定保存処理を理解する

*confsaveサブルーチンの構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | kshootmania.hsp | `kshootmania.hsp` | 1310-1500行目: *confsaveサブルーチン。confex配列による存在チェック→各キーの値更新→未存在キーの追加→notesave |

**主要処理フロー**:
- **1310-1350行目**: confex配列で各キーの存在フラグを設定
- **1356行目**: repeat length(confstr)+ex でループ（既存行+追加行）
- **1368-1492行目**: StartsWith判定とcex判定の分岐で値を更新
- **1494行目**: strrep confs,"\n\n\n","\n" で三重改行除去
- **1497行目**: chdir dir_default でルートディレクトリに移動
- **1498行目**: notesave "config.ini" で保存

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

```
kshootmania.hsp (メインループ/シーン管理)
    |
    +-- [起動時] config.ini読み込み (416-600行目)
    |       |
    |       +-- exist "config.ini"
    |       +-- noteload "config.ini"
    |       +-- split → confstr配列
    |       +-- StartsWith条件分岐で各変数に代入
    |
    +-- [終了時/オプション変更時] gosub *confsave (1310-1500行目)
            |
            +-- confex配列で存在チェック
            +-- 各行の値を現在の変数値で更新
            +-- 未存在キーを追加
            +-- notesave "config.ini"
```

### データフロー図

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

config.ini          kshootmania.hsp                 config.ini
(前回の設定)  --->    読み込み (416-600行目)  --->     (更新済み設定)
                      |
                      v
                    グローバル変数群
                    (key, fullscr, hispeed, bg, ...)
                      |
                    オプション画面等で変更
                      |
                      v
                    *confsave (1310-1500行目)
                      |
                    notesave "config.ini"
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| kshootmania.hsp | `kshootmania.hsp` | ソース | config.iniの読み込み（416-600行目）と保存（*confsaveサブルーチン1310-1500行目） |
| option.hsp | `src/scene/option.hsp` | ソース | オプション画面での設定変更UI。変更後にconfsaveを呼び出す |
| config.ini | `config.ini` | 設定 | ゲーム設定の永続化ファイル |
