Irrlicht EngineをXbox OneのUWPに移植してみた

以前用意したビルドシステムを整理してゲームエンジンであるIrrlichtをXboxOneに移植してみた。

Irrlicht( http://irrlicht.sourceforge.net/ )は2000年代前半から開発されているゲームエンジンで、最近DX8のサポートは切ったもののソフトウェアレンダリング、スレッド不要といった古いハードウェア向けの特徴を色濃く残している。残念ながら商用ゲームでの大きなdesign winは2010年のOctodad以降無いようだが、シーンローダのような必要最低限の機能は備えている。
今回はそのソフトウェアレンダラの活用を目指して、XboxOneに移植してみた。が、FullHDを描画するにはちょっとパフォーマンス的に厳しいという事情が有り一旦OpenGL ESバックエンドを使用してANGLE上で動作させた。

移植/ビルド戦略

Irrlichtにもプラットフォームレイヤは存在するが、今回は移植層としては完全にSDL2に依存し、SDL2プラットフォーム一般で使用できるようにIrrlicht側を改造する方針を取った。SDL2側のプラットフォーム層はそれなりに使用実績もありある程度動作に確証があったのと、Win32ネイティブ版と可能な限りコードを共通化したかったため。
ビルドは今回もOSライブラリ以外の全てを静的リンクする方針としている。これはVisual Studioのgraphics debuggerを使用する上でDLL側に描画を追い出すと何故かあんまり安定しなかったのと、最終手段としてのLTCG(Link Time Code Generation -- いわゆるリンク時最適化)の可能性を残しておきたかったことに因る。
描画にはANGLEを使用する。Google本家のANGLEは今年に入ってからGLES1の実装が始まっているものの、まだ実用できる段階には無いのでGLES2フロントエンドを使用している。残念ながらGoogle本家のANGLEは依然UWPビルドが壊れているのでビルドシステム側でMSの実装を元に修正している。
SDL2では、SDL2の各APIを静的リンクするのを明示的に禁止しており、通常はSDL2を共有ライブラリとしてビルドするように要求している。このため、ソースコードを騙す方向で#defineを入れ https://github.com/okuoku/sdl2-static-cmake/blob/ee04bc39448c086d723ecc338e65c8cb81b81f2d/CMakeLists.txt#L28 ている。
Irrlichtの側はGLESブランチを使用している。GLESブランチは2008年から開発されているものの依然trunk側にはマージされておらず、trunk側のコードではGLES1/2バックエンドは使用できない。
ビルドには今回もCMakeを使用している。Irrlicht側のブランチ事情もあり、今回はIrrlichtのMakefileをCMake上でパースしてビルド用のデータを生成する( https://github.com/okuoku/irrlicht-cmake/blob/ffc3bf2e950e5ab6e81f744cac345507887240a0/CMakeLists.txt#L40 )方針としている。これを行うことで、ファイル構成が異なるtrunkとOpenGLESブランチの両方を1つのCMakeLists.txtでサポートすることができる。当然、Irrlicht側のMakefileの書き方には依存してしまうが。。
SDL2サポートはIrrlichtに元々存在するSDL1サポートを元にSDL2向けに改造している。IrrlichtではOpenGLコンテキストの管理を自前で実施している(CEGLManager、CWGLManager 等)が、これはSDL上では不要なので特に何もせずflipのみを行うCSDLContextManager( https://github.com/okuoku/irrlicht-generic-sdl/blob/af608e1362f7d50fce3846cf43f023fc9cbd6680/source/Irrlicht/CIrrDeviceSDL2.cpp#L38 )を用意している。
IrrlichtはSDLをサポートしているものの、特に純粋なSDLプラットフォームというのを想定していないため、GENERIC_SDL1_PLATFORMとGENERIC_SDL2_PLATFORMを導入し、可能な限りSDLの移植層を使用したい場合はそちらを定義するというルールにした。UWPはWin32のある種サブセットであるため、いくつかのWin32にあった機能が欠けている。

パッケージング

パッケージにファイルアセットを含める上手い方法はよくわからなかった。CMakeでは.appxmanifestやリソースファイルもexecutableのソースとして追加する方向としており、更にそれらのソースコードプロパティを適切に設定することでリソースファイルをアセットとしてパッケージに含めることができるようになる。

これらのドキュメンテーションは見当らなかったが、CMakeのテストにはUWPアプリをビルドするVSWinStorePhone( https://gitlab.kitware.com/cmake/cmake/tree/ccd17a557cbf8ada18207a72eea78d2adcc9d752/Tests/VSWinStorePhone )があり、それを参考にした。