遅ればせながらNetBSD Advent Calendar 2016、24日目の記事です。
(もう過ぎちゃったけど)12/24はクリスマス。ふとLinux Advent Calendar 2016を見ると「クリスマスncursesアプリ特集2016」という記事が。
そこでふと"Leaf Rogue"というRogueの実装系で敵キャラのメッセージとかを外部ファイルで切り替えられるようにしたバージョンがあったことを思い出し、さっそくNetBSDでもビルドしてみようと考えてみました。
Leaf Rogueのファイルを入手する
Leaf Rogueは以下のURLから入手できます。別途必要なメッセージ分離型Rogueのソースコードもここから入手できます。
以下のファイルを展開します。
$ tar zxvf rogue_s.tar.gz
$ tar zxvf lfrog072.tar.gz
Lead RogueのメッセージはEUC-JPまたはSJISで提供されているので、おもむろにUTF-8に変換します。
$ cd lf_rogue
$ iconv -f euc-jp -t utf8 leaf.msg > tmp.msg && mv tmp.msg leaf.msg
メッセージの内容は以下のような感じです。(手元での動作は確認できていますが)これちゃんとUTF8対応しないとハマりそうな気がしますね。
特に「文字列の長さは最大79バイトです。」のあたり、UTF8で必要バイト数が3倍くらいになる感じなのでちょっとマズイかも...。
$ cat leaf.msg
リーフ・ローグ メッセージファイル
Ver0.72
by 風の谷のガンダルフ&K
本メッセージファイルは、
「雫」「痕」「さおりんといっしょ」「To Heart」
「初音のないしょ」「White Album」
(C)Leaf
の内容を元にしています。
漢字コードは EUC(UNIX), Shift-JIS(MS-DOS, HUMAN) である必要があります。
エスケープシーケンスなどのコントロールコードを含めることはできません。
文字列の長さは最大 79 バイトです。
メッセージのバージョン(play.c)
1 "Leaf version Ver0.72 (by ohno@tutics.tut.ac.jp, tsumura@kuis.kyoto-u.ac.jp)"
持ちものの種類
2 "ヤックシェーク"
3 "巻きもの"
4 "弁当"
5 "モップ"
Leaf Rogueのビルド
Leaf Rogueのビルド、といっても、実際はメッセージ分離型Rogueをビルドし、実行時にLead Rogueのメッセージファイルを読み込ませる形になります。
メッセージ分離型Rogueのソースコードは古い時代のままなので、2016年の現代のNetBSD環境(たぶん他の環境でも)ではソースコードの修正が必要になります。
とりあえずビルドが通るように修正した差分は以下のようになります。
diff -ur rogue_s/Makefile.nix rogue_s.DEVEL/Makefile.nix
--- rogue_s/Makefile.nix 1992-09-13 23:36:02.000000000 +0900
+++ rogue_s.DEVEL/Makefile.nix 2016-12-26 03:55:29.000000000 +0900
@@ -11,8 +11,8 @@
trap.o use.o zap.o
# for BSD (Japanese, using my own CURSES) by Yasha
-CC = gcc -traditional-cpp
-CFLAGS = -O -g -DUNIX -DUNIX_BSD4_2 -DCURSES -DJAPAN -DEUC -DTOPSCO
+CC = gcc
+CFLAGS = -O -g -DUNIX -DUNIX_BSD4_2 -DCURSES -DJAPAN -DEUC -DTOPSCO -DUNIX_386BSD
LIBS =
# for 386BSD (Japanese, using my own CURSES) by Yasha
@@ -26,8 +26,8 @@
#ADDHEADER = jcurses.h
# for BSD
-#CFLAGS = -O -DUNIX -DUNIX_BSD4_2
-#LIBS = -lcurses -ltermcap
+CFLAGS = -O -DUNIX -DUNIX_BSD4_2
+LIBS = -lcurses -ltermcap
# for BSD (with COLOR, using my own CURSES)
#CFLAGS = -O -DUNIX -DUNIX_BSD4_2 -DCURSES -DCOLOR
Only in rogue_s.DEVEL/: Makefile.nix.ORIG
diff -ur rogue_s/machdep.c rogue_s.DEVEL/machdep.c
--- rogue_s/machdep.c 1992-09-14 14:40:12.000000000 +0900
+++ rogue_s.DEVEL/machdep.c 2016-12-26 03:56:15.000000000 +0900
@@ -278,10 +278,13 @@
#ifdef UNIX_386BSD
fpurge(stdin);
#else
+ fpurge(stdin);
+/*
ln += stdin->_cnt;
for (; ln > 0; ln--) {
(void) getchar();
}
+*/
#endif /*386BSD*/
#endif /* UNIX */
diff -ur rogue_s/message.c rogue_s.DEVEL/message.c
--- rogue_s/message.c 1992-09-14 14:40:12.000000000 +0900
+++ rogue_s.DEVEL/message.c 2016-12-26 03:56:38.000000000 +0900
@@ -283,7 +283,7 @@
case '\032':
/* putstr(CL); */
fflush(stdout);
- tstp();
+ //tstp();
#if defined(NeXT) && !defined(CURSES) /* by Yasha (till "#endif") */
getyx(stdscr, y, x);
move(0, 0);
Only in rogue_s.DEVEL/: rogue.core
diff -ur rogue_s/rogue.h rogue_s.DEVEL/rogue.h
--- rogue_s/rogue.h 1992-09-13 16:36:59.000000000 +0900
+++ rogue_s.DEVEL/rogue.h 2016-12-26 03:54:19.000000000 +0900
@@ -24,6 +24,9 @@
#define fflush(p)
#endif
+#include <string.h>
+#include <signal.h>
+
#if 0
#ifndef ORIGINAL
typedef unsigned char uchar;
make -f Makefile.nix
でビルドします。
$ make -f Makefile.nix
gcc -O -DUNIX -DUNIX_BSD4_2 -c curses.c
gcc -O -DUNIX -DUNIX_BSD4_2 -c hit.c
gcc -O -DUNIX -DUNIX_BSD4_2 -c init.c
gcc -O -DUNIX -DUNIX_BSD4_2 -c invent.c
gcc -O -DUNIX -DUNIX_BSD4_2 -c level.c
gcc -O -DUNIX -DUNIX_BSD4_2 -c machdep.c
machdep.c: In function 'md_heed_signals':
machdep.c:403:2: warning: passing argument 2 of 'signal' from incompatible pointer type [enabled by default]
signal(SIGINT, onintr);
...
gcc -O -DUNIX -DUNIX_BSD4_2 -c zap.c
gcc -o rogue curses.o hit.o init.o invent.o level.o machdep.o main.o message.o monster.o move.o object.o pack.o play.o random.o ring.o room.o save.o score.o spechit.o throw.o trap.o use.o zap.o -lcurses -ltermcap
warningは取り除いてしまいたいのですが、まずは動作するかを先に確認したいので今はこのままで。とりあえず実行バイナリは生成されています。
$ file rogue
rogue: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for NetBSD 7.0.2, not stripped
Leaf Rogueを実行する
メッセージファイルを指定してLeaf Rogueを実行します。
$ ./rogue ../lf_rogue/leaf.msg
無事に葉っぱの洞窟での冒険が始まりました。
が、2階くらいでツッコミに負けてGAME OVER...。あと何やらAAが崩れている感じ。
まとめ
Leaf RogueをNetBSDでビルドしてみました。メッセージ分離型Rogueのコードが古いままということもあってか、ビルドを通すためには若干の修正が必要でした。こういった少し手直しすれば現代の環境で動作するようになるアプリとかは他にもありそうなので、GitHub上でforkする等、フォローアップしておけるようにしたいものです。