『XANADU』(ザナドゥ)とは、80年代の名作PCゲームだ。アクションRPGに分類されるゲームだが、それではゲームの本質的な特徴を網羅しきれない。その詳細は、Wikipediaをはじめ、様々なネット・メディアで語られているし*1、YouTubeでも多数の攻略動画が配信されている。
端的には、トレードオフを伴う、限られたリソース(モンスターの数、得られる経験値、アイテム、資金…)を按配して、キングドラゴンを倒すゲームだ。目的を果たす以外に、ストーリーや謎解きの要素は一切なく、前述の制約に基づいてプレイヤーなりの「攻略」を楽しむ。
『Rogue』のクローンがオープンソース、フリーウェアとして流通している様に、『XANADU』にもクローンが存在していることに気付いた。しかし、それはオープンソースでも、フリーウェアでもなかったのだが、実行ファイルとともに、ソースコードとMakefileまで収録されていたのには、驚かされた。
web.archive.org
そのC言語で記述されたコードは、役割、機能ごとに明瞭に区別、整理されており、コメントも適切に挿入されていることから、とても読みやすいものだった。
リソース(画像、音声、マップ、モンスターなど)はソースとは独立しており、設定やファイル名を書き換えることで差し替えることができる。レベルごとのフロア構成、モンスター配置はバイナリ・ファイルだった。
一方、ゲーム上の仕掛け、仕組みだけでなく、武器や魔法、ユーザーのデータはソース中に記述されており、それらの改変にはソースコードのリビルドを伴うのだった。つまり「強くてニューゲーム」的な遊び方をするには、プログラムを書き換え、それらをビルドする必要がある。
まずは、ソースコード全体がエラーなく、コンパイルできる状態であるのかを確認しておく必要がある。エラーなくコンパイルを完了し、実行ファイルが出力されることを目的として、ザナクロをビルドし、独自の実行ファイルを出力する手順を紹介する。
念のため、次の2点を申し添えておく。
前提
Xanadu Clone
prosbiboroku.blogspot.com
この参照先によると、ザナクロには複数のバージョンが存在しているようだ。そして、それらは単純にバージョン・アップを積み重ねたものではなく、異なる開発者が、それぞれにフォーク版をリリースした結果であることが読み取れる。
私が参照しているソースコードは、「Ver.08-392」に該当しているようだ。実行中の画面から”REVISION 1.1.4”の記載を確認できた。
ツール
この投稿で紹介する作業では、次のツールを用いる。必要なものをダウンロード、インストールする。
DCS | ファイルの文字コードをUTF8へ変換する。 |
Make for Windows | Makefileを実行する。 |
C++Builder Community Edition | ソースコードをコンパイル、ビルドする。 |
RAD Studio - C++Builder Community Edition
RAD Studio (C++ Builder Community Edition)のインストールに際し、オプション選択を求められる。この投稿で紹介するコードの読解、コンパイル、ビルドの範囲であれば、最低限のオプションで構わない。コンパイル、ビルドの範囲であれば、実際のところGUIすら必要ない。
端的には、「オプション選択」で示すように”C++ Builder Windows 32-bit Community”さえインストールできていればよい。
🔎オプション選択
紹介する作業手順では、コマンドを実行するに際し、適切に環境変数が設定されていることを前提としている。各ツールのインストール先は、各自の環境によって異なるだろう。各自の適切なパスを設定すること。
この投稿が前提としている環境では、次のパスが環境変数”Path”に登録されていることを前提としている。
DCS | dcsw.exe | C:\myapp\dcs1_10\windows |
Make for Windows | make.exe | C:\Program Files (x86)\GnuWin32\bin |
C++Builder Community Edition | bcc32.exe ilink32.exe brcc32.exe |
C:\Program Files (x86)\Embarcadero\Studio\20.0\bin |
環境変数が適切に登録されていることを確認するため、PowerShellで次のコマンドを実行する。適切な環境であれば、それぞれのヘルプが出力される。
dcsw -h make -h bcc32 -h
フォルダ
この投稿では、ザナクロのソース・ファイルは、次のフォルダに収録されている。以後、このフォルダを「ソース・フォルダ」と呼ぶ。適宜、各々の環境に合わせたパスへ読みかえること。
D:\user temp\work\xanadu\src
文字コードの変換
ザナクロに収録されているファイルは、異なる文字コードで記述されたものが混在している。txtファイルはShift JISだが、ソースとヘッダー・ファイルはJISで記述されていた。そのため、ソースコードをエディタで参照する際、適切なエンコードが指定できなければ、特にコメントが文字化けしてしまう。例えばVSCodeでは、Shift JISを指定することはできるが、JISを指定することはできない。
次の3種類のファイルについて、文字コードをUTF8へ変換する。
- txt
- c
- h
PowerShellで、次のスクリプト(dcs.ps1)を実行する。このスクリプトでは、次のことを実行している。
- ”xanadu”フォルダ配下の全ファイルを精査し、対象ファイルの一覧を取得する。
- 対象ファイルの一覧から一ファイルずつ、DCSを用いてUTF8へ変換する。
🔎dcs.ps1
$src = "D:\user temp\work\xanadu" $ext = @("*.txt", "*.c", "*.h") function dcs($files){ foreach ($i in $files){ $from = '"' + $i.fullname + '"' $to = '"' + $i.fullname + '"' dcsw -d u8 -o $to $from } } foreach ($i in $ext){ $files = get-childitem -path $src -recurse -include $i dcs($files) }
”$from”が変換前のファイル、”$to”が変換後のファイルだ。このスクリプトでは、どちらも同一に設定している。つまり変換前のファイルが上書きされる。変換後のファイルを別に保存したければ、$toの値を書き換えればよい。
Makefileの編集
ソース・フォルダに”Makefile”が格納されている。ザナクロをビルドするには、このファイルを実行する必要がある。実行前に、その内容に目を通すと、いくつかのポイントを修正しておく必要があることに気付く。具体的には、
- bcc実行オプションを変更する。
- ”-wTE”→”-wT”
- UNIXファイル・パスを、Windowsのものへ変更する。
- ”/”→”\”
- UNIXコマンドを、Windowsコマンドプロンプトのものへ変更する。
- ”rm”→"del"
- ※コマンド”make”から実行される都合上、PowerShellコマンドレットは指定できない。
- アーカイブ用のターゲットを削除する
- ”ARCHIVE_DIR = d:/home/archive”以下の行を削除する。
- 再配布する意図はないので、アーカイブ、圧縮ファイルは不要。
Makefileの全文は、次のようになる。
🔎Makefile
.autodepend .cacheautodepend CC = bcc32 LINK = ilink32 RCC = brcc32 CFLAGS = -5 -O2 -OS -c -tW -I..\include LFLAGS = -x -aa -Tpe .c.obj: $(CC) $(CFLAGS) $< .rc.res: $(RCC) -fo$@ $< OBJS1 = main.obj graphics.obj image8.obj image16.obj image24.obj image32.obj OBJS2 = audio.obj dungeon.obj goods.obj user.obj message.obj status.obj OBJS3 = context.obj field.obj tower.obj battle.obj boss.obj cave.obj OBJS4 = equip.obj inventory.obj shop.obj user_dead.obj use_item.obj OBJS5 = animation.obj menu.obj pause.obj opening.obj ending.obj OBJS6 = numinous.obj user_io.obj fade.obj OBJS = $(OBJS1) $(OBJS2) $(OBJS3) $(OBJS4) $(OBJS5) $(OBJS6) STARTUP = c0w32.obj LIBS = cw32mt.lib import32.lib RES = xanadu.res TARGET = xanadu.exe midiplay.exe waveplay.exe all: $(TARGET) xanadu.exe: $(OBJS) $(RES) xanadu.rsp $(LINK) @xanadu.rsp xanadu.rsp: Makefile echo $(LFLAGS)+ > $@ echo $(STARTUP) $(OBJS1)+ >> $@ echo $(OBJS2)+ >> $@ echo $(OBJS3)+ >> $@ echo $(OBJS4)+ >> $@ echo $(OBJS5)+ >> $@ echo $(OBJS6)+ >> $@ echo ,xanadu.exe,, $(LIBS),,$(RES) >> $@ midiplay.exe: midiplay.obj $(CC) -O2 -OS -WC -e$@ midiplay.obj cw32.lib import32.lib waveplay.exe: waveplay.obj $(CC) -O2 -OS -WC -e$@ waveplay.obj cw32.lib import32.lib clean: del *~ *.obj *.ilc *.ild *.ilf *.ils *.tds *.csm *."#"* *.res *.TR2 del ..\include\*~ rebuild: del $(TARGET) make clean make all
リビルド
まだソースコードには何も変更を加えておらず、既にコンパイル済みのバイナリ・ファイルも存在しているため、まずリビルドを試す。PowerShellにて、ソース・フォルダをカレント・フォルダとし、次のコマンドのいずれかを実行する。
- リビルド中の出力をログに記録する場合。
コマンド終了後、フォルダ””src中にlog.txtが出力される。
make rebuild > log.txt
- リビルド中の出力を記録しない場合。
make rebuild
リビルド中に出力されるのは、多数の”Warning”だ。それらはすべて、次のいずれかに該当している。
- 未参照の変数が定義されている。
- sigined、unsigned(符号付き、符号なし)の比較
Comparing signed and unsigned values in function
開発者の意図が分からないため、このWarningを放置してもよいのか、訂正しなければならないのかは、Warningで指摘された行と、関連処理を精査する必要がある。
特に後者は、プログラム実行中に予期せぬエラーや、期待に添わない動作、結果を生じるリスクがある。気になる人はリビルド中の出力を手掛かりに、該当ファイルの該当行を参照し、ロジックを追跡して、必要ならばプログラムを手直しすることになるだろう。
この投稿では、まずコンパイルを通して実行ファイルを得ることを第一義としているため、その詳細には触れない。”Error”が出力されていないため、とりあえずの目的は果たせた。
実行
リビルドが終了すると、フォルダ”src”に”xanadu.exe”が出力される。これはWin32形式の実行ファイルなので、実行前にプロパティの設定を変更する。具体的には、Windows 98の互換モードで実行するよう、設定する。
"Windows XP (Service Pack 3)"までの動作を確認した。それ以降のバージョンでは、起動画面でのキー操作に反応しなかった。プログラムが記述された年代を考慮して、ここでは”Windows 98/Windows ME”を選択している。
記念撮影
🔎XANADU
🔎XANADU scenario II
読みやすく、改変しやすい環境へ
ソースコードは問題なくビルド、実行できることが分かった。より効率的に読みやすく、設定やパラメータを改変しやすい環境を用意したい。次回の投稿では、この環境をVisual Studioへ取り込むことにする。
その次に、ソースコードの全体像を把握しやすいよう、可視化ツールであるSourcetrailも導入する。
impsbl.hatenablog.jp
impsbl.hatenablog.jp