Emscriptenでcursesなコードを動かすには

## はじめに

cursesを使ったプログラムもEmscriptenで
[PDCurses-emscripten](https://github.com/coolwanglu/PDCurses-emscripten)を使えば、白黒表示ながら動く。

slコマンドをEmscriptenで動かそうとして、悪戦苦闘した際のメモです。


## [PDCurses-emscripten](https://github.com/coolwanglu/PDCurses-emscripten)をビルド

### まずbuild.shを編集して実行

emscriptenのインストール場所を自分の環境に合わせて書き直して、ビルド実行

```
./build.sh
```

### 自分のコードを動かすのに必要となるファイル

以下の2ファイルが以降の作業で必要となる。

- pdcfont.bmp
- libpdcurses.a

## 自分が動かしたいコードをPDCurses-emscriptenを使てビルドするには

### メインループ相当の処理を関数にして切り出す

```
#ifdef EMSCRIPTEN
void my_end()
{
    mvcur(0, COLS - 1, LINES - 1, 0);
    endwin();
}

void my_main(void);

void my_main()
{
	if (LOGO == 1) {
	  if (add_sl(x) == ERR) {my_end();return;}
	}
	else if (C51 == 1) {
	  if (add_C51(x) == ERR) {my_end();return;}
	}
	else {
	  if (add_D51(x) == ERR) {my_end();return;}
	}
	refresh();
  x--;
}
#endif
```


### emscripten_set_main_loopに登録

切出した関数ポインタをemscripten_set_main_loopに登録する。

この作業により、Canvasに描画するタイミングをウェブブラウザに与えることが可能になる。
これをやらないと、ビルドできて、いざ表示しても真っ黒い画面という残念な結果になる。

```
#ifndef EMSCRIPTEN
    for (x = COLS - 1; ; --x) {
	if (LOGO == 1) {
	    if (add_sl(x) == ERR) break;
	}
	else if (C51 == 1) {
	    if (add_C51(x) == ERR) break;
	}
	else {
	    if (add_D51(x) == ERR) break;
	}
    getch();
	refresh();
	usleep(40000);
    }
    mvcur(0, COLS - 1, LINES - 1, 0);
    endwin();
#else
  x=COLS - 1;
  emscripten_set_main_loop(my_main,50,1);
#endif
```

#### 本体のビルド

pdcfont.bmpとlibpdcurses.aをコピーするなりして、持ってくる

```
~/local/emscripten/emcc -O2 -Wall -fPIC -I.  -o sl.bc sl.c libpdcurses.a `sdl-config --libs`
```

#### ブラウザで動かすのに必要なHTMLファイルを生成

```
~/local/emscripten/emcc -o sl.html sl.bc --preload-file pdcfont.bmp
```

# まとめ

それほど手間なくcurses.hなコードをjs化することが出来ました。

[slコマンドをJsdo.itで](http://jsdo.it/kjunichi/kFLq)動かしてみました。

# 追記

どうも手元のMavericks環境ではビルドは出来ても
js実行時に参照しているシンボルが未解決なエラーがでて
動きませんでした。

Ubuntu12.04な環境で動いてます。

という状況でしたが、
Mavericks環境のEmscriptenは古かったようで、
EmscriptenSDKを導入したら、無事動かすことが出来ました。


# 関連記事

- [libiconvをemscriptenでjs化し、node.jsで使った](https://abrakatabura.hatenablog.com/entry/2015/04/18/115323)
- [jsdo.itでEmscriptenを動かすときのメモ](https://abrakatabura.hatenablog.com/entry/2014/04/17/072514)
- [slコマンドのWebGL版を作ろうとしたら](https://abrakatabura.hatenablog.com/entry/2014/04/09/071724)
- [Emscriptenでファイルを読み込む](https://abrakatabura.hatenablog.com/entry/2013/10/03/120831)
- [emscriptenでOpenGL](https://abrakatabura.hatenablog.com/entry/2013/07/20/081301)

# Link

- [Bringing back the eighties with Emscripten - let the fun begin](http://blog.cfiet.net/posts/2014/bringing-back-eighties-with-emscripten-part3.html)
- [Implementing an asynchronous main loop in C/C++](https://github.com/kripken/emscripten/wiki/Emscripten-browser-environment#implementing-an-asynchronous-main-loop-in-cc)

- [SL.jsでSLを走らせてみるテスト - jsdo.it](http://jsdo.it/cx20/pwMB)
- [JavaScriptでSLを走らせる「SL.JS」を作りました [C!]](http://creazy.net/2008/02/sl_js.html)

# 関連ツイート

<blockquote class="twitter-tweet" lang="ja"><p>slコマンドのリポジトリをクローンして、emscripten対応版作るの今朝の時間だけでは終わらなかった。jsdo.itの作品に使ったソースは、流石のこの俺を持ってしても晒せないと言うか、オリジナルをリスペクトしたコードになっていないので清書したかった。</p>&mdash; kjunichi (@kjunichi) <a href="https://twitter.com/kjunichi/statuses/456938597296271360">2014, 4月 17</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>