Blog, The

1 月 22 日生まれ、ブログ座です。

Doom のソースコードを読んでみる - 環境構築編

なんとなく Doom のソースコードを読んでみようと思い、コンパイルする環境を構築してみたのでメモ。
ただソースを読むだけだとダラダラしちゃいそうだけど、こうやって記事を書けば、多少なり義務感みたいなのが生じるんでないかと。

Doom ってのはあれです。FPS の始祖みたいなやつですね。

f:id:tkmsaoi:20130211233051p:plain

DOOM - Wikipedia

ゲームエンジンのソースが GPL で公開されているという、素敵なゲームです。
もう発売から 20 年近く経ちますが、僕は割と最近はじめました。
色褪せないです。面白いです。

題材とする Doom エンジン

Doom はソースの公開以来、無数の改良エンジンが作られています。
今回はその中でもオリジナルの Doom に忠実と言われる、PrBoom というエンジンを読んでみます。

PrBoom - Project Homepage

環境

OS は Mac OS X Mountain Lion (10.8.2)、パッケージ管理には Homebrew を使ってます。
Snow Leopard でもコンパイルしてみたんですが、トラップがありました。(後述)

事前準備

Autotools

SVN の最新版をコンパイルしたいので Autotools をインストール。

$ brew install libtool autoconf automake

最近の Xcode (Command Line Tools) には含まれてないんですね。

SDL

PrBoom では SDLSDL_mixer、SDL_net を使います。
いずれも Homebrew でインストールできます。

$ brew install sdl sdl_mixer sdl_net

OpenGL

Mac の OpenGLフレームワーク形式になってて、PrBoom のやり方では configure の時にライブラリが見つけられずエラーになります。
今回はホームディレクトリにシンボリックリンクを作るというゴリ押しで対応しました。

$ mkdir -p $HOME/local/lib
$ ln -s /System/Library/Frameworks/OpenGL.framework/Libraries/*.dylib $HOME/local/lib
$ mkdir -p $HOME/local/include/GL
$ ln -s /System/Library/Frameworks/OpenGL.framework/Headers/*.h $HOME/local/include/GL

加えて、コンパイラやらリンカがシンボリックリンクを見つけれるように ~/.bash_profile とかに以下を追記。

export CFLAGS="-I$HOME/local/include"
export LDFLAGS="-L$HOME/local/lib"

SDL を介して OpenGL を使ってるっぽいので、実は OpenGL のチェック自体を削除しても問題無いのかもしれない。

コンパイル

あとはソースをチェックアウトしてコンパイル、インストール。
今回は $HOME/local 以下にインストールしました。

$ svn co http://www.crowproductions.de/repos/prboom/trunk/prboom2 prboom2
$ cd prboom2
$ ./bootstrap
$ ./configure --prefix=$HOME/local
$ make install

エラーが無ければ、$HOME/local 以下に色々できてるはず。

起動してみる

IWAD を ~/.prboom ディレクトリにコピーします。

$ cp path/to/doom.wad ~/.prboom

IWAD ってのは Doom のゲームデータで、Doom はこれとゲームエンジンを組み合わせて遊びます。
僕は製品版の IWAD を持ってるのでそれを使ってますが、Freedoom っていうフリーの IWAD もあります。

あと $HOME/local/games/prboom ってのがゲームエンジン本体なので、~/.bash_profile とかで PATH を追加しときます。

export PATH="$HOME/local/games:$PATH"

そして起動!

$ prboom

f:id:tkmsaoi:20130211233052p:plain

ちゃんと動いとる!音が若干おかしい気もするけど。

ちなみに 16:9 (1366x768) でキャプチャを撮ったら・・・

f:id:tkmsaoi:20130211233102p:plain

何とも前衛的な仕上がりに。バグでしょうか?

まあなんとかコンパイルして動かせる状態になったので、コードを触ったりしながら読んでみようと思います。

番外: Snow Leopard での注意点

現状 (2013/02/11 時点) Homebrew で SDL をインストールすると 1.2.15 ってバージョンがインストールされます。
Snow Leopard でもコンパイルは通るんですが、実行すると・・・

$ ./src/prboom

prboom v2.5.0 (http://prboom.sourceforge.net/)

# 中略...

2013-01-08 01:11:34.257 prboom[57133:9007] *** __NSAutoreleaseNoPool(): Object 0x100348b40 of class NSCFString autoreleased with no pool in place - just leaking
2013-01-08 01:11:34.262 prboom[57133:9007] -[__NSCFType objectForKey:]: unrecognized selector sent to instance 0x10033fa10
2013-01-08 01:11:34.262 prboom[57133:9007] *** __NSAutoreleaseNoPool(): Object 0x10037b8d0 of class NSCFString autoreleased with no pool in place - just leaking
2013-01-08 01:11:34.263 prboom[57133:9007] *** __NSAutoreleaseNoPool(): Object 0x10037cba0 of class NSException autoreleased with no pool in place - just leaking
2013-01-08 01:11:34.263 prboom[57133:9007] *** __NSAutoreleaseNoPool(): Object 0x10037f7f0 of class _NSCallStackArray autoreleased with no pool in place - just leaking
2013-01-08 01:11:34.264 prboom[57133:9007] *** __NSAutoreleaseNoPool(): Object 0x10037f850 of class _NSCallStackArray autoreleased with no pool in place - just leaking
2013-01-08 01:11:34.264 prboom[57133:9007] An uncaught exception was raised
2013-01-08 01:11:34.266 prboom[57133:9007] -[__NSCFType objectForKey:]: unrecognized selector sent to instance 0x10033fa10
2013-01-08 01:11:34.266 prboom[57133:9007] *** __NSAutoreleaseNoPool(): Object 0x10037f9c0 of class NSCFString autoreleased with no pool in place - just leaking
2013-01-08 01:11:34.267 prboom[57133:9007] *** __NSAutoreleaseNoPool(): Object 0x1008b1200 of class NSCFString autoreleased with no pool in place - just leaking
2013-01-08 01:11:34.268 prboom[57133:9007] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFType objectForKey:]: unrecognized selector sent to instance 0x10033fa10'
*** Call stack at first throw:
(
    0   CoreFoundation                      0x00007fff89ccd784 __exceptionPreprocess + 180
    1   libobjc.A.dylib                     0x00007fff87a84f03 objc_exception_throw + 45
    2   CoreFoundation                      0x00007fff89d27110 +[NSObject(NSObject) doesNotRecognizeSelector:] + 0
    3   CoreFoundation                      0x00007fff89c9f8ef ___forwarding___ + 751
    4   CoreFoundation                      0x00007fff89c9ba38 _CF_forwarding_prep_0 + 232
    5   libSDL-1.2.0.dylib                  0x00000001001e5495 QZ_ThreadFlip + 237
    6   libSDL-1.2.0.dylib                  0x00000001001c4507 SDL_RunThread + 71
    7   libSDL-1.2.0.dylib                  0x00000001001e8eaa RunThread + 9
    8   libSystem.B.dylib                   0x00007fff82b39fd6 _pthread_start + 331
    9   libSystem.B.dylib                   0x00007fff82b39e89 thread_start + 13
)
terminate called after throwing an instance of 'NSException'

派手にエラーが出ます。
どうやら SDL 1.2.15 と Snow Leopard の相性が悪いらしく、フルスクリーンモードで上記のようなエラーが出るようです。
(ちなみに 1.2.15 は Lion のフルスクリーンに対応したバージョンみたいです)

Snow Leopard の場合、一つ前の 1.2.14 を使うのがよさそうです。

$ brew versions sdl
1.2.15   git checkout 4562ce4 /usr/local/Library/Formula/sdl.rb
1.2.14   git checkout af59bb9 /usr/local/Library/Formula/sdl.rb
$ cd /usr/local
$ git checkout af59bb9 /usr/local/Library/Formula/sdl.rb
$ brew install sdl