# 機能設計書 78-NEW RECORD表示

## 概要

ハイスコア更新時にNEW RECORDフラグと差分スコアを表示する機能の設計書である。

### 本機能の処理概要

プレイ結果が既存のハイスコアを上回った場合、結果画面で「NEW RECORD」の通知と差分スコア(更新幅)をアニメーション付きで表示する。スコアファイル(.ksc)から過去のベストスコアを読み込み、今回のスコアと比較して差分を算出する。

**業務上の目的・背景**：プレイヤーのモチベーション向上のため、ハイスコア更新時に視覚的なフィードバックを提供する。差分スコアにより、どれだけ記録を更新したかを明確に表示する。

**機能の利用シーン**：結果画面(SCENE_RESULT)で、今回のプレイスコアが同一設定条件(ゲージタイプ/TURN/ノートモード)での過去最高スコアを超えた場合に表示される。初回プレイ時は差分=今回のスコアとなる。

**主要な処理内容**：
1. スコアファイル(.ksc)から同一設定条件のベストスコア(totalscorep)を読み込む
2. 差分(diff = totalscore - totalscorep)を計算する
3. diff > 0の場合、result_newrecord.png(Image36/37)を使用してNEW RECORD通知を表示する
4. 差分スコアを8桁ゼロパディングでImage37上に描画する
5. フェードイン/フェードアウトアニメーションで表示する(350ms後に表示開始、150msかけてフェードイン)
6. Enter/Escキーで表示を早送り(diffendt = t)可能

**関連システム・外部連携**：スコアファイル(.ksc)の読み書き。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 6 | リザルト画面 | 主画面 | ハイスコア更新時(diff>0)のNEW RECORDフラグ・差分スコア表示 |
| 7 | コースリザルト画面 | 参照画面 | コースハイスコア更新時のNEW RECORD表示 |

## 機能種別

比較処理・画面表示処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| totalscore | int | Yes | 今回の合計スコア | 0〜10,000,000 |
| totalscorep | int | Yes | 過去のベストスコア(同一条件) | 0以上 |
| diff | int | Yes | 差分スコア(totalscore - totalscorep) | 整数値 |
| effratetype | int | Yes | ゲージタイプ | -1,0,1 |
| turn | int | Yes | TURN設定 | 0-4 |
| shortmode/longmode/analogmode | int | Yes | ノートモード設定 | 0-3 |

### 入力データソース

スコアファイル(`score/プレイヤー名/楽曲ディレクトリ/譜面名.ksc`)から読み込まれる既存スコアデータ。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| diff | int | 差分スコア(表示用) |
| Image37 | Image | NEW RECORD画像(差分スコア描画済み) |

### 出力先

結果画面上にフェードアニメーション付きで表示される。

## 処理フロー

### 処理シーケンス

```
1. ベストスコア読み込み
   ├─ スコアファイル(.ksc)のexist確認
   ├─ noteload でファイル内容読み込み
   ├─ 設定条件文字列(stat5_)と一致する行を検索
   └─ scorestat2.0 からベストスコア(totalscorep)を取得

2. 差分計算
   ├─ ファイルが存在する場合: diff = totalscore - totalscorep (>0の場合のみ)
   └─ ファイルが存在しない場合: diff = totalscore

3. NEW RECORD画像生成(diff > 0の場合)
   ├─ Image36(result_newrecord.png)をImage37にコピー
   ├─ 差分スコアを8桁ゼロパディングで描画
   └─ Image10の数値フォントで各桁を描画

4. アニメーション表示
   ├─ 表示開始: diffstartt + 350ms後
   ├─ フェードイン: 150ms
   ├─ 表示中: diffendt まで
   └─ フェードアウト: 150ms
```

### フローチャート

```mermaid
flowchart TD
    A[スコアファイル読み込み] --> B{ファイル存在?}
    B -->|Yes| C[同一条件のベストスコア検索]
    B -->|No| D[diff = totalscore]
    C --> E{totalscore > totalscorep?}
    E -->|Yes| F[diff = totalscore - totalscorep]
    E -->|No| G[diff = 0]
    F --> H{diff > 0?}
    D --> H
    G --> H
    H -->|Yes| I[NEW RECORD画像生成]
    H -->|No| J[表示なし]
    I --> K[アニメーション表示]
    K --> L[フェードイン 150ms]
    L --> M[表示中]
    M --> N[フェードアウト 150ms]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-78-01 | 同一条件比較 | ゲージタイプ+TURN+ノートモードの組み合わせが一致するスコアと比較 | スコア比較時 |
| BR-78-02 | 初回プレイ | スコアファイルが存在しない場合はdiff = totalscore(全額が差分) | 初回プレイ時 |
| BR-78-03 | auto/adjmode除外 | auto=1またはadjmode=1の場合はスコア保存・NEW RECORD判定を行わない | 常時 |
| BR-78-04 | アニメーションタイミング | 楽曲アンロック演出がある場合は+2500ms後に表示開始 | completedlist != "" |

### 計算ロジック

- 差分スコア: `diff = totalscore - max(同一条件のベストスコア)`
- フェードイン透明度: `1.0 * (t - diffstartt - 350) / 150`
- フェードアウト透明度: `1.0 - (t - diffendt) / 150`
- 表示終了時間: `diffstartt = time_scene_start + 3000 + 2000*(completedlist!="")`

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

該当なし（ファイルベースのスコアデータ参照）。

## エラー処理

特になし。

### リトライ仕様

リトライ処理は不要。

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

該当なし。

## パフォーマンス要件

特になし。

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

特になし。

## 備考

- 設定条件文字列(stat5_)のフォーマット: "ゲージタイプ,TURN,ノートモード2,ショートモード,ロングモード,アナログモード"
- HARDゲージの場合、同じ条件での通常ゲージスコアも保持される(stat5_2)
- Enter/Escキーで表示中のNEW RECORDアニメーションを早送り可能(diffendt = t で即座にフェードアウト開始)
- FX-L+FX-R同時長押しでもdiffstartt/diffendtが更新され再表示される

---

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

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

### 推奨読解順序

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

スコアファイルのフォーマットを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | result.hsp | `src/scene/result.hsp` | stat5_変数(設定条件文字列)の生成(351-373行目)を確認する |

**読解のコツ**: .kscファイルは「設定条件=スコアデータ」形式の行テキストファイルである。同一譜面で設定条件ごとに別行が記録される。

#### Step 2: スコア比較ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | result.hsp | `src/scene/result.hsp` | 377-435行目のスコアファイル読み込みとベストスコア比較を理解する |

**主要処理フロー**:
1. **377行目**: `exist` でスコアファイルの存在確認
2. **384-385行目**: `noteload` でファイル内容読み込み
3. **392-394行目**: stat5_(設定条件)と一致する行の検索
4. **396行目**: `totalscorep=max(int(scorestat2.0),totalscorep)` - ベストスコアの取得
5. **432-434行目**: `diff=totalscore-totalscorep` - 差分計算
6. **435行目**: ファイル未存在時は `diff=totalscore`

#### Step 3: NEW RECORD画像生成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | result.hsp | `src/scene/result.hsp` | 489-502行目のNEW RECORD画像生成を理解する |

#### Step 4: アニメーション表示を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | result.hsp | `src/scene/result.hsp` | 712-726行目のフェードイン/アウトアニメーションを理解する |

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

```
on_update_result (結果画面更新)
    │
    ├─ スコアファイル読み込み (377-435行目)
    │      ├─ exist (ファイル存在確認)
    │      ├─ noteload (内容読み込み)
    │      └─ ベストスコア比較
    │
    ├─ NEW RECORD画像生成 (489-502行目)
    │      ├─ alCopyImageToImage (Image36 → Image37)
    │      └─ alStretchImageToImage (Image10 → Image37: 差分数値描画)
    │
    └─ アニメーション表示ループ (712-726行目)
           ├─ alCopyModeAlpha (フェードイン/アウト)
           └─ alCopyImageToScreen (Image37 → 画面)
```

### データフロー図

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

スコアファイル(.ksc) ──▶ ベストスコア読み込み      ──▶ totalscorep
                              │
totalscore           ──▶ 差分計算                  ──▶ diff
totalscorep               (totalscore-totalscorep)

diff                 ──▶ NEW RECORD画像生成        ──▶ Image37
Image36(テンプレート)      (差分数値描画)

Image37              ──▶ アニメーション表示         ──▶ 結果画面表示
                          (フェードイン/アウト)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| result.hsp | `src/scene/result.hsp` | ソース | NEW RECORD判定・表示の主要処理 |
| result_newrecord.png | `imgs/result_newrecord.png` | リソース | NEW RECORD通知画像テンプレート |
| kshootmania.hsp | `kshootmania.hsp` | ソース | 定数・変数の定義 |
