DEKI/ENGINE ドキュメント
Deki 0.19.0
組み込みディスプレイとデスクトップのためのモジュール式 C++ 2D エンジン
読み取り中…
検索中…
一致する文字列を見つけられません
プラットフォーム

プラットフォームとは、プロジェクトのビルド対象の 1 つです。ボード、デスクトップシミュレーター、ゲーム機などがあります。このページでは、プラットフォームが何でできているか、プラットフォームがどこから来るか、パッケージがボードをどう提供するか、プロジェクトがボードを使い始めた後にそのボードがどうなるかを説明します。

プラットフォームとは

プロジェクトの platforms/ 以下にある、プラットフォームの id を名前とするディレクトリです。

<project>/platforms/<id>/<id>.json the platform
<project>/platforms/<id>/boot.scene the scene a build of it boots
<project>/platforms/<id>/origin.json only if it came from a package (see below)

JSON にはエディターが知る必要のあることが書かれており、ビルドの方法については何も書かれていません。

キー 意味
id, displayName id はディレクトリ名でもあります。
framework どのビルドバックエンドでビルドするか (espidf、native、...)。デフォルトはありません。指定のないプラットフォームにはバックエンドがなく、ビルドがそのことを伝えます。
frameworkOptions そのバックエンド独自の設定です。チップ、フラッシュのサイズ、sdkconfig の行、ピンなど。エディターはこれを保持するだけで読み取りはしません。バックエンドがビルド時に検証します。
family 説明用のみです。ケーパビリティ family:<x> になります。
screenWidth, screenHeight, colorFormat このターゲットが持つ画面です。エディターはこれをプレビューし、デスクトップシミュレーターはこのサイズのウィンドウを開きます。自動に設定された画像は、このターゲット向けに colorFormat で保存されます。デバイスはディスプレイ自身のサイズとフォーマットで描画します。screens.md を参照してください。
externalMemorySize 内部ヒープ以外のメモリのバイト数 (マイクロコントローラーでは PSRAM)。パッケージに memory:external を与えます。
provides ターゲットがパッケージに提供できるもの: wifi、spi、desktop-os、...
requiresPackages シーンが何を使うかに関係なく、ターゲットが常に必要とするパッケージです。通常はそのハードウェア抽象化レイヤーです。
defines, cFlags, cxxFlags, linkFlags ゲーム自体のコードのコンパイラー設定です。
bootScene プロジェクトからの相対パスで示したブートシーンのパスです。
assetStorage ビルドがゲームのアセットを置く場所: internal (デフォルト) または external。後述します。

ブートシーンには Deki::PlatformSetupComponent があり、その setupComponents リストには、ハードウェアを立ち上げるセットアップの手順が順番に並んでいます。電源ピン、ディスプレイ、I2C バス、タッチなどです。各項目は {id, typeId} で、手順を持つ子オブジェクトの id と、手順の修飾クラス名のハッシュ (Deki::HashString) です。typeId が間違っていても失敗はせず、その手順が黙って実行されないだけです。エディターのテストの ShippedPlatformTemplates は、パッケージが提供するすべてのブートシーンを検査します。

アセットの置き場所

ビルドはゲームのアセットを 2 つの場所のどちらかに置きます。

  • 内部ストレージ (デフォルト): デバイスの一部です。ビルドがアセットを持ち、ブートシーンの隣の assets/ (実行時は F:/assets/) に置きます。ESP32 ではフラッシュがこれにあたります。データパーティションがチップの残りを使い (16 MB のボードで約 13 MB)、ゲームが収まらなければビルドは失敗します。デスクトップシミュレーターと Tactility のアプリも同じように動作します。
  • 外部ストレージ: 取り外し可能な SD カードです。ビルドが持つのはブートシーンと project_data.bin だけです。SD カードへのデプロイ パネルがアセットをカードにコピーし、カードがマウントされるとカードのストレージパッケージがそれらを読み込みます (S:/)。

外部を選べるのは、external-storage を provides するプラットフォームだけです。プラットフォームエディターは、そのようなプラットフォームにだけこの選択肢 (ストレージ > アセットの保存先) を表示します。外部は、フラッシュに収まらないほど大きいゲームにだけ選んでください。外部ストレージを選んでスロットにカードがなければ、ゲームにはアセットがありません。LilyGO T-Deck Plus は選択できますが、指定しない限りアセットはフラッシュに置かれます。

project_data.bin がこの選択を記録するので、エンジンはどこを探せばよいかわかります。

ボードをシミュレートする

バックエンドにシミュレーターがあるボード (ESP32 や ESP32-S3 では QEMU) は、シミュレーター上で動くようにビルドできます。ビルドパネルで QEMU でシミュレート にチェックを入れ、ビルドしてから 実行 します。コマンドラインからは次のようにします。

DekiEditor --build-firmware --deploy --simulate --platform lilygo_t_deck_plus <project>

シミュレーション用のビルドは、ボードのブートシーンのすべての手順をそのまま残し、その後にシミュレーター自身の手順 (QEMU の画面) を追加します。これはビルドディレクトリ以下のコピー (generated/build/<platform>_qemu/simulation/boot.scene) で行われます。シミュレーターで手順を別の方法で実行する必要がある場合は、コピーにそう書かれます。たとえば、SPI で接続された SD カードは QEMU の SD ホストに移されます。ビルドログには各変更が記載されます。プラットフォームの boot.scene、その通常のビルド、ボードに書き込まれるファームウェアは変更されず、シミュレーターが必要とするものはそれらにコンパイルされません。

シミュレートされたボードには、ビルドごとに simulation/sd_card に新しく作られる SD カードがあります。アセットをカードに置くターゲットでは、SD カードへのデプロイ パネルがコピーするのと同じアセットが入ります。内部に置くターゲットでは空です。

バックエンドは ITargetBuilder::SupportsSimulation、GetSimulatorName、MakeSimulationBootScene (deki-editor/build/SimulationBootScene.h の AddSimulationSteps を併用) でこれを提供し、残り (独自のビルドディレクトリ、カード、デプロイの動作) については BuildOptions::simulate を読み取ります。

プラットフォームの提供元

ビルドパネルのターゲット一覧は 3 つの提供元から成り、後のものが前のものを上書きします。

  1. ~/.deki-editor/board-packs/ 以下のボードパック。
  2. プロジェクトにインストールされたパッケージ: すべての <package>/platforms/<id>/。
  3. プロジェクト自身の platforms/。

パッケージをインストールまたは削除すると、一覧はすぐに更新されます。

パッケージでボードを提供する

パッケージ内にボードごとに 1 つのディレクトリを置きます。

deki-lilygo-boards/
├── package.json
└── platforms/
├── lilygo_t_deck_plus/
│ ├── lilygo_t_deck_plus.json
│ └── boot.scene
└── lilygo_t_display_s3_amoled/
├── lilygo_t_display_s3_amoled.json
└── boot.scene

仕組みはこれだけです。パッケージにコードは必要ありません。package.cmake もエントリーポイントも不要です。ボードをインストールすると一緒にインストールされるように、package.json の requires には、ボードのブートシーンが使うパッケージを列挙してください。また、各プラットフォームは requiresPackages にハードウェア抽象化レイヤーを改めて書いてください。

検査されるルール:

  • ディレクトリ名がプラットフォームの id で、JSON はその中の <id>.json です。名前は単純なものでなければならず、パスのように見えるものはスキップされます。
  • インストール済みの 2 つのパッケージが同じ id を提供するとエラーになり、誰かがそれを選んだときに報告されます。id にはベンダー名を接頭辞として付けてください (lilygo_...)。
  • defines に DEKI_PACKAGE_* や DEKI_FEATURE_* を指定してはいけません。 ビルドにどのパッケージが含まれるかは、リゾルバーが決めることです。常にパッケージを必要とするボードは、requiresPackages でそう示します。
  • bootScene はパッケージではなくプロジェクトからの相対パスです: platforms/<id>/boot.scene。ビルドされるのは採用されたコピーです。

他のパッケージを必要とする機能

パッケージの機能は、それ自体が必要とするパッケージを、機能の requires に指定できます。

{ "id": "trackball", "componentTypes": ["TrackballComponent"],
"requires": ["deki-gpio"] }

これらはパッケージと一緒にはインストールされません。その機能を使うボードまたはプロジェクトが持ち込みます。T-Deck には I2C バスとピンがあるので deki-lilygo-boards は deki-i2c と deki-gpio を必要とし、それによって deki-input のキーボードとトラックボールがビルドされます。deki-input をインストールしたデスクトップのプロジェクトは、どちらも取り込みません。

ビルドが機能のパッケージを取り込むのは、ターゲットがその機能を使っている間だけです。使われている機能のパッケージがない場合、その機能は何をインストールすればよいかをログに出す手順としてビルドされ、ビルドは警告を出します。機能のコードは __has_include でパッケージの有無を確認するので、どちらの場合でもコンパイルできます。

deki-lilygo-boards が手本になる例です。deki-desktop-integration は同じ方法でシミュレーターを、deki-tactility-integration は 2 つのターゲットを提供しています。

採用: プロジェクトはコピーを受け取る

パッケージのプラットフォームを選ぶと (ビルドパネルで、set_active_platform で、またはそれ向けにビルドすることで)、そのディレクトリがプロジェクトの platforms/ にコピーされます。それ以降はプロジェクトのファイルです。プラットフォームエディターで編集し、ほかのシーンと同じようにブートシーンを開き、コミットします。プロジェクトがパッケージの中からビルドすることはありません。

プロジェクトがすでに定義しているプラットフォームが採用によって上書きされることはなく、そのディレクトリにすでにあるファイルも残されます。

提供元: 編集、アップデート、復元

採用時には、プラットフォームの隣に origin.json も書き込まれます。これはパッケージ名と、採用した時点のテンプレート (プラットフォームの JSON と、それ以外の各ファイルのハッシュ) を持ちます。ほかのファイルと一緒にコミットしてください。

採用したもの、プロジェクトの現在の状態、パッケージが現在提供しているもの、のすべてがわかるので、ビルドパネルのターゲット一覧の下には次のように表示されます。

From package deki-lilygo-boards 0.17.0 - modified - update available
[Update] [Restore defaults]
  • 変更あり: プロジェクトのコピーが採用時のものと異なります。何が異なるかはホバーで確認できます。
  • アップデートあり: パッケージが採用時のものと異なるものを提供しています。
  • アップデート は、パッケージが変更したものを取り込み、プロジェクトが変更したものを残します。プラットフォームの設定は、バックエンドの frameworkOptions も含めて 1 つずつマージされます。それ以外のファイル (ブートシーンを含む) は、まるごと取り込むか残すかのどちらかです。両方が同じものを変更している場合はプロジェクトのものが残され、そのことが示されます。パッケージの版が新しい基準になるので、この確認は 1 回だけです。
  • デフォルトに戻す は、確認の後、コピーをパッケージの現在の版で置き換えます。プロジェクトにしかないファイル (アセットのサイドカー、独自のシーン) はそのまま残ります。

次のものは変更とはみなされません。エディターが JSON を独自の形式で保存し直したこと (古いファイルはバックエンドの設定を最上位に持ちますが、保存すると frameworkOptions の下に入ります) と、git による改行コードの変更です。

提供元が記録されるようになる前に採用されたプラットフォームは、パッケージが提供しているものとまだ一致していれば、次に使われたときに記録を受け取ります。異なっている場合は、それが誰の変更なのかを判断する手がかりがないため、基準をでっち上げることはしません。パッケージと異なります と表示され、復元はできますがアップデートはできません。

パッケージを削除しても、プラットフォームは残り、引き続きビルドできます。パッケージが戻るまで、その行には (未インストール) と表示されます。

採用したプラットフォームを削除すると、再び選択肢に戻ります。もう一度選ぶと、パッケージの現在の版がコピーされます。

コマンドラインから

ツール 動作
list_platforms (または --list-platforms) すべてのターゲット。パッケージ由来のものには origin が付きます: package、modified、updateAvailable、canUpdate、canRestore。
set_active_platform プロジェクトのデフォルトのターゲットを選びます。必要なら採用します。
create_platform, set_platform_provides プロジェクト独自のプラットフォームを作成または変更します。set_platform_provides は asset_storage と cxx_flags を受け取ります。
update_platform パッケージからアップデートします。taken と kept を返します。
restore_platform パッケージの版に戻します。taken を返します。
DekiEditor --tool update_platform --args '{"platform_id":"lilygo_t_deck_plus"}' <project>

コードでは

deki-editor/build/PlatformConfig.h はプラットフォームとレジストリです。deki-editor/build/PlatformTemplates.h は、このページのパッケージに関するすべて (提供されているものの検索、採用、提供元の記録、アップデートと復元) を扱います。どちらもエディターの SDK に含まれているので、パッケージのビルドバックエンドから使えます。