Haxeのゲームエンジン「Heaps」を使ってみる in HashLink

> 追記： bullet.hdll、bullet.lib、steam.hdll、steam.libのビルド方法を追記しました

[先日の記事](https://qiita.com/trackiss/items/436bb51240bfd72475bf)でHashLinkを使ってみた訳ですが、どうせならHeapsと一緒に使いたい！

という事で、[Heapsリポジトリ](https://github.com/HeapsIO/heaps)に載っているサンプルを動作させたいと思います。

## **Getting Started**

```haxe:Main.hx
package;

class Main extends hxd.App
{
  var bmp : h2d.Bitmap;
  
  override function init()
  {
    var tile = h2d.Tile.fromColor(0xFF0000, 100, 100);
    bmp = new h2d.Bitmap(tile, s2d);
    bmp.x = s2d.width * 0.5;
    bmp.y = s2d.height * 0.5;
  }
  
  override function update(dt:Float)
  {
      bmp.rotation += 0.1;
  }
  
  static function main()
  {
     new Main();
  }
}
```

HeapsをHashLinkで使用するには、hldxかhlsdlを併用する必要があります。
今回はhlsdlを使います。

```hxml:build.hxml
-cp src
-dce full
-hl test.hl
-lib heaps
-lib hlsdl
-main Main
```

<br>

よし、コンパイルだ！

```console:
hl test.hl
src\module.c(311) : FATAL ERROR : Failed to load function sdl@gl_uniform_block_binding
```

んん？
なんか怒られてしまいました。

しかもmodule.cが原因とな。
私はHashLink 1.6.0のバイナリを直接ダウンロードして使っているのですが、そのバージョンに不具合があるみたいですね。

<br>

…仕方ねぇ。

**自力でHashLinkビルドすっぞ！！！**

---

## **HashLinkをビルドする**

### **準備**

そんな訳で、HashLinkを自分でビルドします。
そのうちリリースされるであろうHashLink 1.7.0では修正されるでしょうから、それまでのツナギです。

それに、Githubから入手できるバイナリは32ビット版のみ。どうせなら64ビット版が使いたいですし。

> 注: 今回の説明はWindows(x64)を使っている事が前提となっております。Linuxをお使いの方は、[HashLinkリポジトリ](https://github.com/HaxeFoundation/hashlink)のREADMEを参考にしてください。

まず、HashLinkのビルドにはVisual Studioが必要です。Communityでも何でも良いので、インストールしてきてください。

次に、HashLinkの最新のソースコードをダウンロードします。
`git clone https://github.com/HaxeFoundation/hashlink.git`しても良いですし、面倒ならzipで落としてきても良いでしょう。
今回は、`～\Github\hashlink`にファイルがあるものとして進行します。

![01.png](https://qiita-image-store.s3.amazonaws.com/0/177229/0d88a46d-fee6-a13b-a5ac-fa9a03bd49f8.png)

さて、このままではOpenALとSDL2のソースコードが不足しているので補充します。

OpenALの場合は、[こちらのサイト](http://openal-soft.org/)より**openal-soft-1.18.2-bin.zip**を、
SDL2の場合は、[こちらのサイト](https://www.libsdl.org/download-2.0.php)より**SDL2-devel-2.0.8-VC.zip**を、それぞれダウンロードし、解凍します。

`～\Github\hashlink\include`の中に、**openal**フォルダと**sdl**フォルダを作成しましょう。

![02.png](https://qiita-image-store.s3.amazonaws.com/0/177229/63b19293-c9b5-4acb-3aa4-b7181110d6dc.png)

そしてopenalフォルダに`～\openal-soft-1.18.2-bin\include`と`～\openal-soft-1.18.2-bin\libs`を、
sdlフォルダに`～\SDL2-2.0.8\include`と`～\SDL2-2.0.8\lib`を、それぞれぶち込みます。

これで準備は終わりです。

### **ビルドする**

さて、いよいよビルドに入ります。

とは言っても、普通にhl.slnをVisual Studioで開いて、**x64**向けに**Release**ビルドするだけなんですけど。
32ビット版のWindowsを使っているのなら、Win32向けで。

少ししたらビルドが終了、`～\Github\hashlink\x64\Release`に下記のファイルが出力されているはずです。

![03.png](https://qiita-image-store.s3.amazonaws.com/0/177229/6ce15dfb-e0d5-a614-545a-4d12e5c7a39c.png)

ハイライトされているファイル以外は全部要らないので、消しちゃいましょう。
要するに**.dll**、**.exe**、**.hdll**、**.lib**以外は消して構いません。

### **あと少し**

`～\Github\hashlink\x64\Release`に**include**フォルダを作成しましょう。
そして`～\Github\hashlink\src`にある**hl.h**、**hlc.h**、**hlc_main.c**の3つをぶち込みます。

最後に、HashLinkアプリケーションのパッケージ化に必要な幾つかのライブラリファイルを調達します。

まず、**msvcr120.dll**。これは必須です。
**Visual C++ 2013 再頒布可能パッケージ**の中に含まれているdllで、インストール済みなら`C:\Windows\System32`の中にあるはず。64ビット版Windowsだけどwin32向けにビルドしたよって人は、`C:\Windows\SysWOW64`にあるものを使います。。
msvcr120.dllを発見したら、`～\Github\hashlink\x64\Release`に**コピー**しましょう。コピーですよコピー。大事なファイルですからね。
もしもmsvcr120.dllが見つからない場合は、Visual C++ 2013 再頒布可能パッケージをインストールする事で該当のパスに出現します。

以降は使用するライブラリに応じて必要となるファイルです。全部入れておくと安心。
ただし、Heapsを使うには**hldxかhlsdlのどちらか**を併用する必要があるのでご注意を。

* **D3DCompiler_47.dll**
 * hldxを使う場合に必要。**.NET Framework 4.7**に含まれています。
* **msvcp120.dll**
 * hlsteamを使う場合に必要。**Visual C++ 2013 再頒布可能パッケージ**に含まれています。
* **OpenAL32.dll**
 * hlopenalを使う場合に必要。[こちらのサイト](https://www.openal.org/downloads/)からダウンロードできる**OpenAL 1.1 Windows Installer (zip)**に含まれています。

上記3つは、該当のプログラムがインストールされていれば`C:\Windows\System32`（32ビット版の場合は`C:\Windows\SysWOW64`）にあるはずです。

* **bullet.hdll**、**bullet.lib**
 * hlbulletを使う場合に必要。`～\Github\hashlink\libs\bullet\bullet.sln`をビルドすると出力されます。
* **SDL2.dll**
 * hlsdlを使う場合に必要。HashLinkをビルドした後に、`～\Github\hashlink\include\sdl\lib\x64`に残っているはずです。32ビット版なら`～\Github\hashlink\include\sdl\lib\x86`です。
* **steam.hdll**、**steam.lib**
 * hlsteamを使う場合に必要。[hlsteam](https://github.com/HeapsIO/hlsteam)をビルドすると出力されます。
* **steam_api.dll**
 * hlsteamを使う場合に必要。[Steamworks SDK](https://partner.steamgames.com/)の中に入っています。

上記を全て導入すると、↓のようになるはずです。

![04.png](https://qiita-image-store.s3.amazonaws.com/0/177229/f5e11741-b5da-c20f-5b59-7c277c18b603.png)

**終わりです。**

`～\Github\hashlink\x64\Release`を適当にリネームしたりどこかに移動させて、PATHでも通しておきましょう。
残った`～\Github\hashlink`のファイルは要りませんので煮るなり焼くなりしてください。

## 完成！

お疲れ様でした。これで冒頭のサンプルプログラムが動作するはずです。

![05.png](https://qiita-image-store.s3.amazonaws.com/0/177229/9b4c908f-c2f5-ad35-4143-102d48fd90ab.png)

<br>

いやぁ、サンプル動かすだけでこんな大変な事になるとは思いませんでした。
HashLink 1.7.0でこの問題が改善されている事を願います。

ちなみに、普通に使う分には.hdllと.dllだけで事足りるはずなのですが、どこかのページに「HashLinkは動的ライブラリ使うけど、静的ライブラリを使うように設定する事もできるよ。OpenALはライセンス上できないけどね」みたいな事が書いてあった気がするんですよね。
なので、.libも念の為に残してあります。

---

## **追記**

hlbulletとhlsteamを使用するには、それぞれのライブラリを自分でビルドする必要があります。

### **hlbulletを使用する**

[Bullet3のリポジトリ](https://github.com/bulletphysics/bullet3)から、ソースコードをダウンロードします。安定性を考えると、cloneするよりも最新のリリース（現在は2.87）を使う方が良いかもしれません。

`～\bullet3-2.87\src`を`～\Github\hashlink\include\bullet`にコピーします。

後は`～\Github\hashlink\libs\bullet\bullet.sln`をVisual Studioでビルドするだけなのですが、そのままビルドしようとするとエラーを吐きます。
これは、Visual Studioがhllib.hを見つけられないのが原因です。

「プロジェクト」→「プロパティ」を開き、「リンカー」→「全般」→「追加のライブラリディレクトリ」に、ビルド済のHashLinkのパスを追加します。

これでビルドすれば、bullet.hdllとbullet.libが出力されます。

### **hlsteam**を使用する

[hlsteamのリポジトリ](https://github.com/HeapsIO/hlsteam)からソースコードをダウンロードします。

[Steamworks](https://partner.steamgames.com/)にサインインし、あれこれすると**steamworks_sdk_142.zip**をダウンロードできます。

`～\hlsteam\setup.bat`を実行、指示に従って操作します。
`Enter path to Steam SDK root:`にはsteamworks_sdk_142.zipを解凍して出てきたsdkフォルダのパスを、
`Enter path to hashlink root:`にはビルドしたHashLinkのパスを入力すれば良いです。

後は`～\hlsteam\bullet.sln`をVisual Studioでビルドするだけなのですが、そのままビルドしようとするとエラーを吐きます（またか

bulletの時のhllib.hに加え、今度はsteam_api64.dllの場所も教えてあげなければなりません。
さっきと同じく「プロジェクト」→「プロパティ」→「リンカー」→「全般」→「追加のライブラリディレクトリ」に、ビルド済HashLinkのパス、そして`～\steamworks_sdk_142\sdk\redistributable_bin\win64`を追加します。

上手くビルドできれば、steam.hdllとsteam.libが出力されます。