Upload
takashi-toyoshima
View
2.124
Download
4
Embed Size (px)
Citation preview
夢の続きを語ろうよ
Emscriptenの逆襲
sun6925 とよしま
ウェブ大好きっ子
低レイヤー大好きっ子
レトロPC大好きっ子
X68000大好きっ子
大丈夫、ウェブ業界の人です。仲良くしてください。
知ってますか?● なぜか 編集部が作ったゲーム
○ 創刊10周年記念 PRO-68K に収録(雑誌付録ディスク)
○ 編集部制作の強力インフラ
■ MAGIC2 - 3D描画ライブラリ
■ Z-MUSIC - サウンドドライバ
○ ゲーム自体、普通に面白い
実演原作@エミュレータ
あれ?ショボい!
256 x 256 ドット 16 色 ワイヤフレーム
・・・
んじゃ、高解像度化しますか
原作をウェブで
Powered by Emscripten
run68 (in C)
sion2.x(Binary for X68k)
実行
JavaScript VM
実行
互換レイヤー(in JavaScript)
DOS/IOCSMAGIC
Z-MUSICGVRAM I/O
<iframe>
zmusic.x(Binary for X68k)
非同期RPC化
ここで気合ハイレゾ化するぞ!
X68Sound.dll (in C++)
run68 (in C)
高解像度+16:9化
256 pixel
256 lines
ピクセルアスペクト比
4:3 1080 lines
1440 pixel
4:3
1920 pixel
16:9
アスペクト比補正+ベクトル拡大
+本来見えていなかった部分の表示
ワイヤーフレームは楽勝
ビットマップ文字のベクターフォント置き換え
一部の文字(4×6サイズ)が画像だった
● 仕方ないのでGVRAMのアクセスパタンから文字推定
{ “111010101110101010100000”: 64, ... }
文字コード64 A
内部で使ってる主な技術
● HTML5 Canvas(2D)○ WebGLは使わずにJavaScriptで座標変換計算
● Web Audio API○ FM音源と音響処理(リバーブ)
● Web App Manifest○ モバイルでホームスクリーン追加
● Gamepad API / TouchEvent
● WebFonts
Emscriptenまめ知識〜その1
描画ループにrequestAnimationFrameを使う
❏ emscripten_set_main_loop()を使いましょうvoid emscripten_set_main_loop(em_callback_func func, int fps, int simulate_infinite_loop)
❏ fpsに0を指定するとrequestAnimationFrameが使われる
❏ それ以外の値だとsetTimeoutを使うので注意❏ 失敗談:知らずにsetTimeoutを書き換えて中からrAF呼んでた
❏ simulate_infinite_loop=1でこの関数から戻らない
Emscriptenまめ知識〜その2
常駐するサービス・ライブラリを作る
❏ emscripten_exit_with_live_runtime()で常駐void emscripten_exit_with_live_runtime(void)
❏ ひとまず実行終了
❏ ただしatexit()系やリソース解放処理は走らない
❏ JavaScriptからC/C++の関数を継続して呼び出し可能
❏ 空のmain()から呼べば共有ライブラリっぽい物が作れる
Emscriptenまめ知識〜その3
JavaScriptから呼び出せる関数を(確実に)作る
❏ リンク時に-s EXPORTED_FUNCTIONS="..."❏ "..."にはmainを含めた関数のリストを渡す
例:"['_main', '_myAPI1', '_myAPI2']"
❏ 関数名は"_"のプレフィクスが付くので注意
❏ 数値以外は直接渡せない点に注意❏ C/C++側のメモリ空間はModule.HEAPU8等でアクセス
❏ Module.cwrap()やWebIDL-Binderなどの道具はある
Emscriptenまめ知識〜その4
JavaScriptのライブラリを呼び出す
❏ リンク時に--js-library myLibrary.jsで組み込む❏ 渡すJavaScriptは特定の方法で記述されている必要がある
mergeInto(LibraryManager.library, { myFunc: function(a, b) { // ここから外の世界は直接触れる(this==Window) console.info(‘hello my func’); return a + b; }, // 以下、同様に関数を定義});
❏ 登録なしでCから呼ぶとundefined symbolで実行時abort
Emscriptenまめ知識〜その5
実行開始を遅延させる
❏ preInit内でaddRunDependency()を呼ぶ❏ 対応するremoveRunDependency()が呼ばれるまで待つ
❏ WebFonts読み込みを待つ例preInit: function() { Module.addRunDependency("fonts"); document.fonts.ready.then(function() { Module.removeRunDependency("fonts"); });},
質問など