tl;dr;
emscripten-portsのsdl2の問題で音楽ファイルを読み込ませられない
Music::from_static_bytesなどを用いてWebAssembly(wasm)に予め読み込ませておけば動く
C、C++バインディングのrustのライブラリを使う場合、emscriptenを使わざるをえないと思われる
はじめに
mac上の環境をぶっ壊したのでdocker上に再構築する羽目になっているr-chaser53です。正直ほとんど進捗できなかったのでrust-sdl2を使ったアプリをwasmに変換した際のtipsを書こうと思います(※1)。
無理やり音楽ファイルを読み込ませる
rust-sdl2で任意のpathの音楽ファイルを読み込ませたい場合、以下のようになります。
sdl2::mixer::Music::from_file(path).unwrap();
本来ならば変数pathからメタデータを生成しSDL.rwopsというオブジェクトに格納するようなのですが、肝心のSDL.rwopsオブジェクトは[null]と最初に宣言した時のままです。値が代入されてません(※2)。そのまま実行するとnullのrwopsオブジェクトのfilenameを参照しようとして処理が進みません。以下のようなハックで動かすこともできたのですが、正直微妙なところです。そもそもファイルを読み込ませること自体に問題があるのかと思いましたが、マップを読み込ませる処理自体は問題なく動いています。おそらくそちらに問題はないでしょう。
Module['preRun'] = function () {
FS.createPreloadedFile(
'/',
'filepath',
'/filepath',
true, false);
SDL.rwops = [{ filename: 'filepath'}];
}
予め読み込ませてみる
rust-sdl2は以下のようにコンパイル時に音楽データを取り込んでしまうmethodも提供しています。
sdl2::mixer::Music::from_static_bytes(include_bytes!("filepath"));
こちらは問題なく読み込んでくれるようです。コンパイル後にファイルが指定できないですし、音楽ファイルの分だけファイルが大きくなってしまうのも芳しくありません。しかし複数の音楽ファイルを読み込ませた場合、上のハックではとてもメンテできそうにありません。諦めてこちらを使うのが妥当なのではないでしょうか。
emscriptenとrustとc, c++バインディング
備考
※1 2017/12/17 rust-sdl2 version 0.31 現在
※2 ソースを追ってみると「throw ‘Mix_QuerySpec: TODO’」とか書いていて「そっか…」てなります
※3 調査不足で設定や書き方次第では「wasm32-unknown-unknown」でもc、c++バインディングのwasmを生成できてほしいと正直思っています