dsp m0006 loadingScoreInit - cwtickle/danoniplus GitHub Wiki
プレイ開始前設定
概要
- 楽曲データの読込、譜面データの分解などプレイ開始前の設定を行う。
- プレイ開始前に必ず実行される。
- 楽曲データの読込・セットアップ処理と、譜面データの読込・変換処理は並行して実行され、両方の完了を待ってからプレイ画面の描画に入る。
処理の流れ
- 楽曲データのファイル名・ディレクトリ名を取得、Now Loading表示を行う ( loadMusic 関数 )
- 以下の2つの処理を並行して実行する
- 楽曲の読込・セットアップ処理 ( loadAndSetupAudio 関数 )
※iOSのみ、楽曲読込終了後に「Click to Start!」ボタンを表示し押した後に処理を再開させる ( readyToStart 関数 ) - 譜面データの読込・分解、速度変化・色変化などのデータ分解、ライフ設定などを行う ( loadChartFile, prepareScoreData 関数 )
- 楽曲の読込・セットアップ処理 ( loadAndSetupAudio 関数 )
- 両方の処理が完了したら、プレイ画面描画を行う ( mainInit 関数 )
なお、曲中リトライ・AutoRetry時は上記と異なり、executeRetry 関数による直列処理(音源読込完了 → 譜面再読込 → 譜面変換 → mainInit)となる。ローカル環境でのテストプレイ中に譜面ファイルを差し替えるケースを考慮し、リトライ時は毎回譜面データを再読込する仕様となっている。
フローチャート
- 点線はローカル時もしくはエラー時の遷移を表す。
- カスタムJs/スキンJsによる差し込み処理は水色で表記。
- 関連ページがあるボックスは青枠で表記。scoreConvert関数(赤枠)の詳細についてはページ下記を参照。
flowchart TD
load-->fork{{並行処理}};
fork-->loadAndSetupAudio;
fork-->loadChartFile;
loadAndSetupAudio-->readyToStart;
readyToStart-->|エンコード済み音源ファイルがある| setupWebAudioEncoded["setupWebAudio<br>(base64ToUint8Array)"]-->musicAfterLoaded;
loadAndSetupAudio-.->|音源取得失敗時| errAudio(["エラー(Backボタン表示)"]);
readyToStart-->loadMp3;
loadMp3-->|音源ファイルが<br>サーバー上にある| setupWebAudioUrl["setupWebAudio<br>(fetch)"]-->musicAfterLoaded;
loadMp3-.->|音源ファイルが<br>ローカルファイルにある|musicAfterLoaded;
loadChartFile-->preloading["ユーザカスタムイベント<br>(譜面ロード開始前)<br>g_customObj.preloading<br>g_skinObj.preloading"]-->prepareScoreData;
musicAfterLoaded-->join{{join}};
prepareScoreData-->join;
join-->mainInit;
subgraph loadMusic
direction TD
progress-->load;
progress-.->stall["stall検知<br>(進捗停滞)"];
progress-.->error;
end;
subgraph progress
direction TD
a1["ローダー読込状況更新"]-->b1["ユーザカスタムイベント<br>(読込中)<br>g_customObj.progress"]
end;
subgraph setupWebAudio["setupWebAudio(共通処理)"]
direction TD
sw1([start])-->sw2{"AudioBufferキャッシュに<br>ヒットするか<br>getAudioBufferFromCache"};
sw2-->|Yes| sw3["キャッシュから<br>setBuffer<br>(デコード省略)"]-->sw5([end]);
sw2-->|No| sw4["ArrayBuffer取得・デコード<br>(base64デコード or fetch)<br>取得後キャッシュへ登録<br>cacheAudioBuffer"]-->sw5;
end;
subgraph prepareScoreData
direction TD
A([start])-->C["譜面データ分割<br>(preblankFrame調整前)<br>scoreConvert"]-->D["最終フレーム数取得<br>getLastFrame"]-->E["最初の矢印データがあるフレーム数を取得<br>getFirstArrowFrame"]-->F["開始フレーム数の取得(フェードイン加味)<br>getStartFrame"]-->G["フレームごとの速度を取得<br>setSpeedOnFrame"]-->H["Motionオプション適用時の矢印別の速度を取得<br>setMotionOnFrame"]-->I["最初のフレームで出現する矢印が、<br>ステップゾーンに到達するまでのフレーム数を取得<br>getFirstArrivalFrame"]
I-->J["キーパターン(デフォルト)に対応する矢印番号を格納<br>convertReplaceNums"]
J-->R{先頭フレームが基点位置より前}
R-->|Yes| S["譜面データ分割<br>(preblankFrame調整後)<br>scoreConvert"]-->T[setSpeedOnFrame]-->U[getFirstArrivalFrame]-->V[シャッフル/アシスト設定]
R-->|No| V
V-->W["ライフ回復・ダメージ量の算出<br>calcLifeVals"]-->X_start
subgraph X["矢印・フリーズアローデータの格納<br>pushArrows"]
direction TD
x3([start])-->calcNotes_start
subgraph a3["矢印・フリーズアローの出現位置計算 / calcNotes"]
direction TD
calcNotes_start["全体速度変化の最後尾データ取得<br>getSpeedPos"]-->b4[/Loop start\]-->c4["ステップゾーンから逆算して<br>初期位置と出現フレーム数を算出<br>getArrowStartFrame"]-->d4["出現フレーム毎の矢印データを格納<br>setNotes"]-->e4[\Loop end/];
end;
e4-->b3_start
subgraph b3["個別加速データの出現位置計算"]
direction TD
b3_start["ステップゾーンから逆算して<br>初期位置と出現フレーム数を算出<br>getArrowStartFrame"]-->b5["個別加速データの格納"];
end;
b5-->c3_start
subgraph c3["個別・全体色変化のタイミング更新・データ格納 / calcDataTiming"]
direction TD
c3_start["ステップゾーンから逆算して<br>初期位置と出現フレーム数を算出<br>getArrowStartFrame"]-->b6["色変化データ格納<br>pushColors"];
end;
b6-->d3_start
subgraph d3["モーションデータのタイミング更新・データ格納 / calcDataTiming"]
direction TD
d3_start["ステップゾーンから逆算して<br>初期位置と出現フレーム数を算出<br>getArrowStartFrame"]-->b7["矢印・フリーズアローモーションデータ格納<br>pushCssMotions"];
end;
b7-->e3_start
subgraph e3["スクロール反転データのタイミング更新・データ格納 / calcDataTiming"]
direction TD
e3_start["ステップゾーンから逆算して<br>初期位置と出現フレーム数を算出<br>getArrowStartFrame"]-->b8["スクロール反転データ格納<br>pushScrollchs"];
end;
b8-->f3["歌詞表示、背景/マスク表示のフェードイン時調整処理<br>calcAnimationData"]-->g3["フレーム毎速度配列の作成"]-->y3([end]);
end;
W-->X_start
X_start-->x3
y3-->Y["メインに入る前の最終初期化処理/<br>ローカルストレージ保存処理<br>getArrowSettings"]-->L["ユーザカスタムイベント<br>(プレイ開始直前)<br>g_customObj.loading"]-->Z([end])
end;
style b1 fill:#00ffff;
style preloading fill:#00ffff;
style L fill:#00ffff;
click loadChartFile "https://github.com/cwtickle/danoniplus/wiki/fnc-c0011-loadChartFile" _blank;
style loadChartFile stroke:#0000ff,stroke-width:4px;
style C stroke:#ff0000,stroke-width:4px;
style S stroke:#ff0000,stroke-width:4px;
曲中リトライ・AutoRetry時のフロー(executeRetry)
- 通常起動時(上記フローチャート)とは異なり、並行処理ではなく直列処理となる。
- ローカル環境でのテストプレイ中に譜面ファイルを差し替えるケースを考慮し、リトライ時は毎回譜面データを再読込する。
flowchart TD
A([手動リトライ<br>またはAutoRetry条件成立])-->B{g_retryInProgress?};
B-->|true<br>多重実行| Z1(["何もしない"]);
B-->|false| C["g_retryInProgress = true"];
C-->D["g_audio.pause<br>clearTimeout<br>clearWindow"];
D-->E["musicAfterLoaded"];
E-->F["loadChartFile"];
F-->G["prepareScoreData"];
G-->H["mainInit"];
D-.->|エラー発生時| I["エラーログ出力"];
E-.->|エラー発生時| I;
F-.->|エラー発生時| I;
I-->J["g_retryInProgress = false<br>(finally)"];
H-->J2["g_retryInProgress = false<br>(finally)"];
style D stroke:#ff0000,stroke-width:2px;
scoreConvert関数部分
- データ分解時、Adjustmentの加算処理とソート処理を合わせて行っている。
- (変更なし)
flowchart TD
x([start])-->x1
y1-->y([end]);
subgraph scoreConvert
direction TD
x1([start])-->a1["Adjustmentの取得(整数・小数の分離)"]-->|矢印・フリーズアロー| b1["矢印データの分解"];
b1-->c1["矢印名からフリーズアロー名の変換<br>g_escapeStr.frzName"]-->d1["フリーズアローデータの分解"];
d1-->|速度変化| e1["全体速度変化名の末尾設定<br>(speed_data, speed_change)"];
e1-->f1["速度変化データの分解<br>setSpeedData"];
f1-->|色変化| g1["色変化データの分解<br>setColorData"]-->h1{"譜面詳細データ取得用?"};
h1-->|Yes| y1([end]);
h1-->|No| i1["全体/個別色変化のマージ処理<br>mergeColorData"];
i1-->|矢印・フリーズアローモーション| j1["矢印・フリーズアローモーションデータの分解<br>setCssMotionData"];
j1-->|スクロール反転データ| j2["スクロール反転データの分解<br>setScrollchData"];
j2-->|歌詞データ| k1["歌詞データの分解<br>makeWordData"];
k1-->|背景/マスクデータ| l1["背景/マスクデータ(プレイ画面用)の分解<br>makeBackgroundData"];
l1-->m1["背景/マスクデータ(結果画面用)の分解<br>makeBackgroundResultData"]-->y1;
end;
style scoreConvert stroke:#ff0000,stroke-width:4px;