Slide 1

Slide 1 text

No content

Slide 2

Slide 2 text

奈良阪 奈良阪 ドリコム2015新卒(3年目) T yp e S cr ipt と R u by 書いてます T yp e S cr ipt / C # / P er l / R u by あたりが好き その他: 伺か / 漫画読み描き / OP アニメ愛好家 / 鉄 T w itt er: @nar az aka G it hu b: @N ar az aka np m: @nar az aka CPAN : NARA Z AKA R u byG ems: N ar az aka P ix iv: 奈良阪 M edia M ar ker: nar az aka

Slide 3

Slide 3 text

※ 注意: いわゆる「○○ やってみた」 系の発表です。 UEFI ガチ勢、C ++ガチ勢の方々 は生暖かく聞いて下さ い。

Slide 4

Slide 4 text

夏休みの自由研究の目標 ( そういうテー マでなんかやってくれって言われたので) UEFI で動くなんらかのゲー ムエンジンを作りたい

Slide 5

Slide 5 text

UEFI とは コンピュー ター で OS を立ち上げる前に動く BIOS 関係の仕様 W indows 立ち上げる前に HP とか T hink P ad とか Z OT AC とかロゴ が出てるあそこ 2010年以降の PC (M ac込み)で旧来の BIOS から徐々 に置き換わって いる OS なし状態にもかかわらず結構高水準な API が存在する← ここ重要 例: キー ボー ド, マウス, ファイルシステム, 画面表示, ネットワー ク, et c.

Slide 6

Slide 6 text

モチベー ション ‑ 個人的に「 どこでも動く」 プログラムが至高という想い ‑ 近年の PC にはあまねく UEFI が載っている ‑ UEFI で実装すれば OS という枷を超えてどこでも動く ‑ JVM なんかメじゃないぜ( 無理 ‑ 最近 C ++触ってなかったのでリハビリしておきたい

Slide 7

Slide 7 text

参考資料 C 92(コミケ)新刊: フルスクラッチで作る!UEFI ベアメタルプログラミング (大神 祐真) http://yu ma.ohgami.jp/ ※ ベアメタルプログラミング: OS を使わない、 ハー ドウェア上の低レイヤー のプログラミング ※ この資料上では仕様からヘッダファイルを起こすところまで自作していますが、 さす がにきついので EDK II 由来のヘッダファイル群 kiz nit/u efi‑headers を利用しました。 リファレンスとしては P hoenixW iki が割と見やすいと思います。

Slide 8

Slide 8 text

UEFI ベアメタルプログラミング OS なし libc/libc++ではない(POSI X標準ではない)独自の API ベー ス C ++ (参考資料では C ) ファイルシステムは FA T (USB フラッシュメモリに入れる) 動作確認は QEMU 最近の PC (M ac系含む)には載ってるので一応ある程度動作するはず

Slide 9

Slide 9 text

実装したもの とりあえず UEFI の API をラップ C ons ole(wr it e L ineとか), F ile S yst em(r ead, r eaddir 等) ゲー ムに要りそうなやつ 描画系(1dot、 矩形、 円形、 画像描画) 入力系( get c相当他、 on K eyP r ess、 on M ous e*) 簡易イベントルー プ ゲー ムに要りそうなやつで付随して必要になったもの p ng等一般画像形式読み込みライブラリの統合 st dlib.hとstr ing.hの一部(mallocとか) フォント ゲー ム本体 簡易シー ンマネー ジャー( 諸事情によりマクロ) ノベルゲー ムシナリオインター プリター マウスカー ソル描画

Slide 10

Slide 10 text

大体こんなん こういうシナリオファイルと画像を入れておけばマウスキー ボー ドポチ ポチで読み進められるノベルゲー # b g _ s c h o o l . p n g ( 背景ファイル) : R 0 = s u r f a c e 0 . p n g ( 人物0 のファイルを右に描画) : L 1 = s u r f a c e 1 0 . p n g ( 人物1 のファイル左に描画) @ ねぷ ( 名前欄) > はろー ( セリフ) ‐ ( ここまでが1 セリフ) : R 0 = s u r f a c e 1 . p n g > にゅー わー るど ‐

Slide 11

Slide 11 text

アレのパクリスプラッシュ

Slide 12

Slide 12 text

マウスクリックでも動きます

Slide 13

Slide 13 text

ポチポチすすめる ADV

Slide 14

Slide 14 text

ポチポチすすめる ADV

Slide 15

Slide 15 text

ポチポチすすめる ADV

Slide 16

Slide 16 text

C onsole(write L ineとか), F ile S ystem(read, readdir等) st dout とst derr の別はないが文字は出せるので普通にラッパを実装 op en, r ead, r eaddir, clos eの流れは大体一緒 op endir とop enの区別がなくて一緒くたに処理する なお文字列は w c h a r _ t * 相当の C H A R 1 6 * = E F I _ S T R I N G (UTF 16LE ) パス区切りは FA T っぽく \ \ ( E F I _ S T R I N G ) L " f o n t s \ \ 3 3 . p n g "

Slide 17

Slide 17 text

描画系 1ドットごと色変更と、 ビットマップをバルク転送する B lt() API 矩形、 円形描画、 画像描画( 透過色対応) など実装 参考に読んだ記事では EDK II では透過対応が完全ではないとのこ と。 ( まあ見るからに重い処理だし……) 入力系 待ちなしでキー 入力とマウスが受けられる イベントルー プ中差分把握を実装してon M ous e L eftC lick等も実装 QEMU だとマウスが効かなかったので実機確認のみになった

Slide 18

Slide 18 text

イベントルー プ 複数のイベントを待ち受けできる API が存在するので、w hile(tru e) ルー プ内でイベント番号でsw it chして処理できる 今回は30fps で発生するイベントとキー ボー ド入力イベントをとっ てます マウスカー ソル 1フレー ムごとに、 描画する領域色を保存して描画して前にいた場 所の色を戻すみたいなことをしている オフスクリー ンレンダリングやレイヤー 利用していないので、 タイ ミングによっては色が乱れる 画像、 フォント、 libc、 シー ンマネー ジャー このあと述べます

Slide 19

Slide 19 text

直面した問題・ ハマりどころ (UEFI だから、 というより制約下のフルスクラッチ風味 C /C ++開発故と いうものが多いです)

Slide 20

Slide 20 text

libc/libc++相当が使えない クロスコンパイラ氏、 そういうものを用意してくれてはいない。 最終的に m a l l o c , f r e e , r e a l l o c , a b s , i t o a ( s t d l i b . h ) m e m s e t , m e m c p y , s t r n c p y , s t r c p y , s t r c a t , s t r l e n ( s t r i n g . h ) を自前で書くことに……。 / / 例: m a l l o c v o i d * m a l l o c ( U I N T N s i z e ) { v o i d * p t r ; E F I _ S T A T U S S t a t u s = l i b c : : B o o t S e r v i c e s ‐ > A l l o c a t e P o o l ( E f i L o a d e r D a t a , s i z e , & p t r ) ; r e t u r n S t a t u s = = E F I _ S U C C E S S ? p t r : n u l l p t r ; } フルスクラッチ風味とかこだわらず単に UEFI アプリケー ションを作りたいだけなら、 EDK II という SDK を使うとこの辺には困らないはず。

Slide 21

Slide 21 text

画像処理系等のライブラリ stb の導入 やっぱ画像なら PNG を読みたい。 フォントも使いたい。 しかし前提としてlibcがないのでlibp ngとかは無謀そう。 stb ‑ single‑file public domain libraries for C /C ++ (nothings/stb) 画像、 音声、 タイルマップ、 フォント周りとかが揃ったシングルファイ ルヘッダー 構成かつ他への依存がないライブラリがあった。 神か。

Slide 22

Slide 22 text

画像処理系等のライブラリ stb の導入(続き) #inclu de // 自前libc #define STB _IMAGE _IMPLEMENT A TION #define STBI _ASSERT (x) // assert.h がないので無視 #define STBI _NO _STDIO // stdio.h がないのではずす #define STBI _NO _LINEAR // math.h がないのではずす #define STBI _NO _HDR // math.h がないのではずす #define STBI _ONL Y_PNG #define STBI _MALLOC (sz) malloc(sz) // 自前malloc, free, realloc #define STBI _FREE (p) fr ee(p) #define STBI _REALLOC _SI Z ED (p,oldsz,newsz) r ealloc_s iz ed(p,oldsz,newsz) #inclu de // stbの画像処理系本体 制約の強い環境も考えてくれてる良いライブラリだ……

Slide 23

Slide 23 text

画像処理系等のライブラリ stb の導入(続き) 画像読み込み系のst b_image.hは導入できた 画像リサイズ系のst b_image_r es iz e.hはmath.hが必要 フォント処理系のst b_tru etyp e.hもmath.hががっつり必要 → mat h.h実装がないと画像リサイズ不可&フォントは別で用意する必要

Slide 24

Slide 24 text

reallocをまともに実装すると実は大変 st b導入に際し r e a l l o c が必要になったが…… ネイティブ API は m a l l o c 相当の A l l o c a t e P o o l と f r e e 相当 の F r e e P o o l しかない この制約下での r e a l l o c は f r e e → m a l l o c か、 最初にメモリ位置 指定までできる A l l o c a t e P a g e s を使うしかなさそう。 どちらにしても、 現在どのポインタがどのサイズを持っているかとい う情報を保持せねばならない。 ↑ 大変 (EDK II では頑張って実装していた。) (st bにはサイズ情報を追加で渡すr ealloc_s iz edという拡張呼び出しが用 意されていたのでなんとか事なきを得た。)

Slide 25

Slide 25 text

失われた math.h を求めて 1. フォントやリサイズを使うためにはmat h.hが必要 2. ヘッダー ファイルとしてのmat h.hは使えるのだが、UEFI クロスコ ンパイル環境だと実装がなさそう? 3. 「 mat h.h 実装」[検索] 4. どうやらfdlibmというライブラリがもとになっているらしい? 5. fdlibmは古く、W ebでファイルを配ってるだけなので導入しにくさ 6. ただし M akefileがめっちゃシンプルで良い 7. G it hu bにあるのだと J ulia L ang/openlibm が使いやすそう 8. 結局時間切れにより導入には至らず

Slide 26

Slide 26 text

フォントの用意 前提: BIOS に日本語フォントはなく、ttf、 otfは使えない → フォントを PNG にして都度読み込み 1. フォントを用意 JF ドット K app a20‑0213 2. t ar lety/tt f2p ngがフォントが対応している文字ごとに1つずつテキス トファイルに出してくれるのでその部分だけ使う( 他部分は古くて 動かなかった) 3. テキストファイル全部をさらって I mage M agickでp ngにする c o n v e r t ‐ b a c k g r o u n d n o n e ‐ f i l l b l a c k + a n t i a l i a s ‐ f o n t J F ‐ D o t ‐ K a p p a 2 0 ‐ 0 2 1 3 . t t f ‐ p o i n t s i z e 2 0 l a b e l : @ # { t e x t _ f i l e } f s / f o n t s / 文字コー ド数値. p n g " 4. UEFI では FA T ファイルシステム上においたファイルが普通に読める ので頑張って1文字ごと表示時に画像読みまくって描画

Slide 27

Slide 27 text

フォントの用意( ボツ案) UEFI では FA T ファイルシステム上においたファイルが普通に読める ので頑張って1文字ごと表示時に読みまくって描画 1. 控えめに言って酷い 2. 昔のコンピュー タの日本語フォント ROM よろしくデー タを全部 st at icに持ってしまうのはどうか? 3. p ngからむりやりデー タのcpp ファイルを生成↓ c o n s t p n g = P N G . s y n c . r e a d ( i m a g e . r e a d F i l e S y n c ( ) ) ; . . . f o n t s S t r + = ` s t a t i c U I N T 8 c f o n t _ $ { c h a r C o d e } _ a l p h a [ ] { ` ; f o r ( l e t i = 0 ; i < l e n g t h ; + + i ) { f o n t s S t r + = ` $ { p n g . d a t a [ i * 4 + 3 ] } , ` ; } f o n t s S t r + = ` } ; \ n ` ; バイナリが8MB くらいになって、 起動失敗したので断念

Slide 28

Slide 28 text

C ++はlib(std)c++がないとクラス関連機能が 色々 使えない シー ンをしようとクラスを作ったところで判明。 まずnew 演算子の参照がないと怒られるのでnew できない → v o i d * o p e r a t o r n e w ( U I N T N s i z e ) { r e t u r n m a l l o c ( s i z e ) ; } など定義することで一応解決はできる v irtu al関係はlibc++が型解決を受け持っているらしく使えない → cxx abi.hで定義されててる__class_typ e_infoまたは __v mi_class_typ e_infoと言うクラスがないと実現できないっぽい。 C ++は言語組み込みでクラスの全挙動をサポー トしているわけではなく、 インター フェー スだけ用意して実装は本質的に自前でやる必要がある…… だと……ッ!?

Slide 29

Slide 29 text

なおvirtualが使えないと…… シー ンマネー ジャー を作ろうとしたんですが…… / / 親クラス = n e w 子クラス( ) S c e n e * s c e n e = n e w S t a r t S c e n e ( ) ; s c e n e ‐ > u p d a t e ( ) ; この u p d a t e ( ) が子クラス S t artS ceneのものを指せないので、 無理矢理 ダウンキャストするなどしかない……? 今回はマクロで定数定義してsw it chで分岐するなど無理矢理対応し た……。 # d e f i n e s c e n e I d ( C l a s s ) C l a s s # # I d # d e f i n e d e l r a r e S c e n e ( C l a s s ) s t a t i c C l a s s * C l a s s # # _ o b j # d e f i n e i n i t S c e n e ( C l a s s ) C l a s s # # _ o b j = n e w C l a s s ( ) # d e f i n e s c e n e C a s e ( C l a s s ) c a s e C l a s s # # I d : \ C l a s s # # _ o b j ‐ > u p d a t e ( ) ; + + C l a s s # # _ o b j ‐ > t i c k ; b r e a k ; # d e f i n e c h a n g e S c e n e ( C l a s s ) c u r r e n t S c e n e I d = C l a s s # # I d

Slide 30

Slide 30 text

60fpsが出ない 多くのゲー ムにおいて最大の障害 単純な w h i l e ( t r u e ) ; ではなくタイマー で描画スピー ドを調整でき はするが……? C or e i7が載ってる PC の QEMU では元気に60fps 出してくれる Z BO X CI 320だと30fpsもでない → 早期に認識していたので、 その辺関係ないノベルゲー に絞った やり方が間違っていたりするだろうか……?

Slide 31

Slide 31 text

M acで立ち上げると FA T が読めなさそう? 会社の M acでも立ち上げてみたけれど、 画像とかが USB メモリから 読めてなさそうだった UEFI 、FA T 読めるはずだけど、 仕様上実装必須ではないのか? 「 どこでも動く」 の障害になりそう

Slide 32

Slide 32 text

解像度変更すると画面上の各ピクセルを表す ポインタ位置がバグる 解像度変更の API があるのだけれど、 画面上の色を表すポインタが 画面上シー ケンシャルにならない UEFI 起動すると解像度変更しなくてもディスプレイ最大に合わせて くれるのであまり意識しなくて良い事項ではある

Slide 33

Slide 33 text

描画の微妙な問題? 描画系(GRAPHICS _OUTPUT _PROTOCOL ) の API コー ル、 関数を またいで呼ばれると描画処理が行われない場合がある? とりあえず同じトコにまとめちゃったりしてうやむや解決したので 定かではないです。

Slide 34

Slide 34 text

課題( 積み残し) UEFI で動くなんらかのゲー ムエンジンを作りたい mat h.hを入れてフォントとリサイズしたい レイヤー 管理等がなくベタ描画なのでチラつくし面倒 イベントルー プまではなんとかしたが、 シー ン管理とかは大分微妙 最後突貫工事でなんとかノベルゲー にしたのでライブラリの形には 整っていない ……思ったより意外と積み残しが少ない? ライブラリ化だけなんとかしてこのまんまギッハブに投げてもいい……?

Slide 35

Slide 35 text

まとめ UEFI で動くなんらかのゲー ムエンジンを作りたい ゲー ムエンジンではなく単体のゲー ムができました 主に強い制限状況下での C ++コー ディングで、C ++の基盤を垣間見 ることができました ゲー ムエンジンっぽい部分は一応分けてあるのでなんとかして公開 したいですね