[前へ] [目次へ] [次へ]

FGES With FGLの仕組み

FGES With FGL はFGES Full版とゲーム作成用ライブラリFGLを連携させた実装です。
FGES Full版はこの実装のスクリプトエンジンとして使用するために設計されました。

●基本機構

FGES With FGL では、ベースとしてC++で記述されたFGLが動作し、
FGESはそのスクリプトエンジンとして従属的に動作します。

OSとのやり取りやOSレベルのウィンドウ制御はFGL側の制御となり、
仮にFGES上でスクリプトが処理を返さなくても、全体がフリーズしないようになっています。

またFGESの実行速度は決して速くはないため、
C++コードのみで処理を進行する「ネイティブ論理フレーム」と
FGESスクリプトを実行する「スクリプト論理フレーム」、
そして描画処理を行う「描画フレーム」に処理が分けられています。
ここで「スクリプト論理フレーム」についてはFGL側の判断で中断したり、
スキップすることができるようになっており、
FGESスクリプトの処理遅延を検出すると「ネイティブ論理フレーム」と
「描画フレーム」を自動的に割り込ませ、全体の処理落ちを軽減します。

また、「スクリプト論理フレーム」ごとにアクティブなFGESスレッドに一回づつ
実行権が付与されることを利用し、 pause を使用して時間待ちすることができます。

なお、全体の処理落ちが検出された場合に「描画フレーム」もスキップ(いわゆるフレームドロップ)したり、
画面の更新が不要な場合は該当部分または「描画フレーム」そのものをスキップするなど負荷軽減機能が実装されています。

これらの動作状態はメインウィンドウのタイトルバーで毎秒報告されます。
ここで「FPS」は直近一秒の描画フレーム処理数を示し、
「WAIT」は更新時のフレーム全体の処理待ち数を示し、
「DROP」は直近一秒にFGESスクリプト原因でスキップしたフレーム数を示します。

「WAIT」に値が常に入る場合慢性的な処理落ち状態であることを示し、
「WAIT」が10に達すると「描画フレーム」をスキップして動作の維持を試みます。

「DROP」はFGES上の「ゲームシステムスレッド」「ゲームフレーム後スレッド」が時間内に完了できない時にカウントされます。
「ゲームシステムスレッド」は全体の進行上必須の処理を行うスレッドとして扱われ、
このスレッドのタスクが完了しない限り他のFGESスレッドや「ネイティブ論理フレーム」「描画フレーム」は実行されません。
「ゲームシステムスレッド」はどうしても必要な処理のみを行い、できるだけ早く完了するようにしてください。
「ゲームシステムスレッド」で実行されるトリガーから急ぎでない処理を行う場合は、
他のFGESスレッドコンテキストで処理するように HThread::Call などのスレッド越え呼び出しを使用してください。

「ゲームフレーム後スレッド」はフレーム終了時に行う必須の処理を行うスレッドとして扱われ、
フレーム処理が途中で中断されなかったフレームの最後に処理が開始されます。
「ゲームフレーム後スレッド」の処理が開始された場合、スレッドのタスクが完了しない限り
他のFGESスレッド(ゲームシステムスレッドを含みます)や「ネイティブ論理フレーム」「描画フレーム」は実行されません。
「ゲームフレーム後スレッド」はどうしても必要な処理のみを行い、できるだけ早く完了するようにしてください。

なおFGESから見える入力の更新は「ネイティブ論理フレーム」の担当であるため、
「ゲームシステムスレッド」「ゲームフレーム後スレッド」で入力まで待機するようなコードを記述するとハマりますのでご注意ください。

●起動

FGES With FGL が起動されると、 script フォルダの fgs/system.fges および main.fges がコンパイルされ、
グローバルメソッド Game_Startup (戻り値、引数ともなし)がFGS初期化スレッドで呼び出されます。
この処理が行われている時点では FGES With FGL はまだ完全に起動していないため、FGESスクリプトデバッガが使用できません。
さらに、このメソッドは制限時間内に完了しなければならず、最初に実行するシーンを登録することが目的です。
このメソッドでは基本的な初期化および GameSystem::CallScene で初期シーンを登録する処理のみを行い、速やかに完了させてください。

●シーン

FGES With FGL におけるシーンは、状況に合わせた処理を規定するものです。
シーンは INativeScene インターフェイスをサポートするシーンクラスによって定義され、
画面上に展開するウィンドウなどはシーンごとに管理されます。

シーンに指定するオブジェクトはローカル変数か #New で作成したオブジェクトでなければならず、
シーンに指定した時点でメモリ管理がシステムに移譲され、シーン終了時にオブジェクトは消滅します。

シーンの操作には Call Change End の3つがあり、
Call をゲームスレッドで行った場合、操作したゲームスレッドを一時停止し、
他のゲームスレッドのタスクの終了を待った後、現在のシーンの状態をそのままに指定したシーンを開始します。
ゲームスレッド以外で Call を行った場合、タスクの同期をせずに指定したシーンを開始します。
この動作は初期シーンを登録するためのもので、ゲーム実行中はゲームスレッド上でのみこの操作をすべきです。
この時開始したシーンが End で終了すると Call を実行したシーンとゲームスレッドが再開されます。
開始したシーンが Change で変更された場合、その変更されたシーンが指定したシーンとして扱われます。
再開後シーンに指定したオブジェクトは既に存在しないことに注意してください。

Change は全ゲームスレッドのタスクの終了を待った後、現在のシーンを終了して指定したシーンを開始します。
この操作はどのスレッドから呼び出しても処理はすぐに戻ります。

End は全ゲームスレッドのタスクの終了を待った後、現在のシーンを終了します。
シーンの終了後、 Call によって停止されているシーンがある場合、そのシーンの実行が再開されます。
停止されているシーンがなく、この操作によって全てのシーンが終了した場合、
システムロードが予約されていると予約されているファイルのロード処理が開始されます。
システムロードが予約されていない場合、ゲームプロセスは終了します。

   ●シーンハンドラ

   シーンハンドラはシーン開始時、シーン実行中の毎フレーム、シーン終了時、セーブ、ロード、サイズ変更、アイドルの7種類あり、
   基本的にそれぞれ対応するタイミングでゲームシステムスレッドコンテキストで呼び出されます。
   ただしアイドルハンドラに限り、ゲームメインスレッドコンテキストで呼び出されます。
   これはアイドルハンドラがゲームタスクがない場合の処理(RPGでの自由移動操作など)を行うことが想定されているためです。
   
   シーンハンドラは明示的に登録する必要があり、登録されていない場合は呼び出されません。
   アイドルハンドラ以外のハンドラはゲームシステムスレッドで実行されるため、不要な場合は登録しないでください。
   なお、シーン終了時の呼び出しはタスク終了待ち後、シーンが終了する直前で行われます。

●グラフィック

FGES With FGL におけるグラフィックはビットマップ、ドローリソース、ウィンドウを組み合わせて使用します。

ビットマップは一枚の画像と対応し、編集可能な Bitmap クラスと素材キャッシュに特化した CacheBitmap クラスがあります。
これらのビットマップは内部的に参照カウントを持っており、
同じビットマップを複数のFGESオブジェクトで共有することができます。
また、ビットマップは全てのFGESオブジェクトから切り離されるまで解放されないため、
ビットマップ共有を行っている場合は最初にビットマップを作成したオブジェクトを消滅させても問題ありません。
なお、ビットマップ単体では画面に表示することができないため、
ドローリソース経由、または直接的にウィンドウに関連付けて表示します。

ドローリソースは描画方法および描画に必要な設定情報を保持するオブジェクトです。
ドローリソースは INativeDrawResource インターフェイスをサポートし、
C++レベルで設定された通りの描画処理を行うことができます。
また、ドローリソースが消滅するとそのドローリソースへの関連付けは強制解除されます。
ビットマップと異なり描画元になるドローリソースは用済みになるまで維持しなければいけません。
なお、ドローリソース単体では画面に表示することができないため、オブジェクトをウィンドウに関連付けて表示します。

ウィンドウは画面上に描画したり、操作を受け取るためのオブジェクトです。
ウィンドウは INativeWindow インターフェイスをサポートし、C++レベルで描画や操作を行うことができます。
ウィンドウはシーンごとに管理され、実行中のシーン以外で作成されているウィンドウは非表示になり、操作もできません。
また、 FGES With FGL で画面上に描画する手段はウィンドウだけで、ウィンドウが存在しない領域は画面情報の書き換え自体が行われません。
そのため、原則として全てのシーンでは画面全体の背景となるウィンドウを最低一つ作成することになります。

●入力

FGES With FGL における入力は仮想コントローラ方式で、キーボード、マウス、ゲームパッドを統合して扱います。
これらの入力状態はネイティブ論理フレームで更新され、同じフレームの間は同じ入力状態が返されます。
入力状態は DOWN/UP/PRESS/DBLCLK/REPEAT があります。
DOWN は該当キーがそのフレームに押下されたことを示します。押し続けている場合は反応しません。
UP は該当キーがそのフレームに放されたことを示します。
PRESS は該当キーが現在押されていることを示します。押し続けている場合は反応し続けます。
DBLCLK は該当キーがダブルクリックされたことを示します。この状態はマウスのみ生成します。
   この状態はOSのマウスダブルクリック判定を使用するため、OSの設定で反応が変わります。
   また、この状態が反応している時は DOWN が反応しません。マウスの連打に対応する場合は両方チェックしてください。
REPEAT は該当キーを押し続けた時、一定周期で反応します。
   この状態はキーリピートのエミュレートですが、OSのキーリピート設定とは関係ありません。

また、マウス座標取得メソッドのうち、 Input クラスのものは仮想画面上の座標で返されます。
OSレベルのウィンドウサイズと仮想画面のサイズが一致しない場合、座標変換した結果を返します。
なお、返される座標は仮想画面外を指している可能性があります。
一方、ウィンドウクラスのものはそのウィンドウの左上を原点とする座標で返されます。

●サウンド

FGES With FGL におけるサウンドは4レーンの多重再生をサポートしています。
各レーンはメインBGMチャンネル、サブBGMチャンネル、MIDIレーン、効果音レーンと呼びます。

二つのBGMレーンは、Wave/MP3/Ogg Vorbis形式のサウンドをストリーミング再生できます。
ただし、MP3形式はデコード処理をOSにインストールされているデコーダに任せるため、
OSの構成によっては再生できない可能性があります。
デコーダを内部に組み込んでいるOgg Vorbis形式を使用することを推奨します。
また、ユーザー指定+再生時/スクリプト指定の音量を多重設定できます。
さらに、再生速度を10%〜1000%の範囲で変更することができます。
さらに、ループ再生を範囲指定で行うことが可能で、ファイル内のループ情報を検出できた場合それを範囲に使用できます。

MIDIレーンはSMF Type1形式のMIDIファイルを基本ノートのみ再生できます。
特定の音源を必要とするMIDIファイルは正常に再生できない可能性があります。
また、コントロールチェンジ111をループマーカとして使用します。

効果音レーンはWave/MP3/Ogg Vorbis形式のサウンドをプリロードし、ミキシング再生できます。
ただし、MP3形式はデコード処理をOSにインストールされているデコーダに任せるため、
OSの構成によっては再生できない可能性があります。
効果音レーンは再生前にデータを全てデコードしてメモリ上に保持し、
ミキサー機能により一つのレーンで複数の効果音を多重再生することができます。
ただし、ミキシング処理を高速に行うため、全ての効果音ファイルは44100Hzモノラルか、44100Hzステレオでなければいけません。
また、ミキシング時に音割れの原因になるため、効果音ファイルの音量はある程度小さめにすべきです。

●シーンデバッガ

FGES With FGL はシーン定義のデバッガを定義でき、F11キーで呼び出せます。
シーンデバッガはシーンオブジェクトにシーンデバッガとなるクラスを設定しておくことで、
該当シーンの実行中にF11キーを使用して強制割り込みすることができます。
この時、該当シーンで実行中だったゲームスレッドは全て一時停止され、
シーンデバッガ用に新しいゲームスレッド群が開始されます。

そしてシーンデバッガとして動作するシーンが終了した場合、
停止されていたゲームスレッドが全て再開されます。
シーンデバッガを使用する場合はゲームスレッド以外のスレッドの使用や、
シーンデバッガから Change によるシーン切り替えの使用は推奨されません。

●スクリプトデバッガ

FGES With FGL はスクリプトデバッガを搭載しており、F12キーで呼び出せます。
スクリプトデバッガではアクティブなスレッドの一覧、各スレッドの実行中のメソッドおよびその位置、
実行中のメソッドのソースおよび実行コードの逆アセンブルの表示、各種変数の状態一覧ができます。
また、 @@_system_state を選択することでシステム状態の概要を表示できます。


[前へ] [目次へ] [次へ]

最終更新 2019/09/03