下一页 上一页 目录

12. 第四个例子:红心大战

这是一个古老的红心大战游戏,由 Bob Ankeney 在 80 年代为 UNIX 系统编写,1992 年由 Mike Yang 修订,目前由 Jonathan Badger 维护。它的前身是 Oregon Software 的 Don Backus 编写的更早的 Pascal 程序,后来由 Jeff Hemmerling 更新。最初 intended 作为多人客户端,它在单人模式下对抗电脑对手时也运行良好。图形效果不错,尽管游戏缺乏复杂的功能,电脑玩家也不是特别强大。尽管如此,即使在今天,它似乎仍然是唯一可用于 UNIX 和 Linux 机器的像样的红心大战游戏。

由于其年代久远和传承,这个软件包在 Linux 系统上构建尤其困难。它需要解决一系列漫长而令人困惑的难题。这是一项考验耐心和决心的练习。

在开始之前,请确保您已安装 motiflesstif 库。

xmkmf

make

client.c: In function `read_card':
client.c:430: `_tty' undeclared (first use in this function)
client.c:430: (Each undeclared identifier is reported only once
client.c:430: for each function it appears in.)
client.c: In function `scan':
client.c:685: `_tty' undeclared (first use in this function)
make: *** [client.o] Error 1

这些是文件 client.c 中的罪魁祸首

#ifndef SYSV
        (buf[2] != _tty.sg_erase) && (buf[2] != _tty.sg_kill)) {
 #else
        (buf[2] != CERASE) && (buf[2] != CKILL)) {
#endif

client.c 中,添加

#define SYSV
在第 39 行。这将绕过对 _tty 的引用。

make

client.c:41: sys/termio.h: No such file or directory
make: *** [client.o] Error 1

include 文件 termio.h 在 Linux 系统上的 /usr/include 目录中,而不是像旧的 UNIX 机器那样在 /usr/include/sys 目录中。因此,将 client.c 的第 41 行从

#include <sys/termio.h>
改为
#include <termio.h>

make

gcc -o hearts -g      -L/usr/X11R6/lib client.o hearts.o select.o connect.o
sockio.o start_dist.o  -lcurses -ltermlib       
/usr/bin/ld: cannot open -ltermlib: No such file or directory
collect2: ld returned 1 exit status
make: *** [hearts] Error 1

现代 Linux 发行版使用 terminfo 和/或 termcap 数据库,而不是过时的 termlib 数据库。

编辑 Makefile

第 655 行

CURSES_LIBRARIES = -lcurses -ltermlib

更改为

CURSES_LIBRARIES = -lcurses -ltermcap

make

gcc -o xmhearts -g      -L/usr/X11R6/lib xmclient.o hearts.o select.o
connect.o sockio.o start_dist.o gfx.o  -lXm_s -lXt -lSM -lICE -lXext -lX11
-lPW       
/usr/bin/ld: cannot open -lXm_s: No such file or directory
collect2: ld returned 1 exit status

主要的 lesstif 库是 libXm,而不是 libXm_s。因此,编辑 Makefile

在第 653 行

XMLIB = -lXm_s $(XTOOLLIB) $(XLIB) -lPW

更改为

XMLIB = -lXm $(XTOOLLIB) $(XLIB) -lPW

make

gcc -o xmhearts -g      -L/usr/X11R6/lib xmclient.o hearts.o select.o
connect.o sockio.o start_dist.o gfx.o  -lXm -lXt -lSM -lICE -lXext -lX11 -lPW       
/usr/bin/ld: cannot open -lPW: No such file or directory
collect2: ld returned 1 exit status
make: *** [xmhearts] Error 1

找出通常的嫌疑对象。

没有 PW 库。编辑 Makefile

第 653 行

XMLIB = -lXm $(XTOOLLIB) $(XLIB) -lPW

更改为

XMLIB = -lXm $(XTOOLLIB) $(XLIB) -lPEX5
PEX5 库最接近 PW。)

make

rm -f xmhearts
gcc -o xmhearts -g      -L/usr/X11R6/lib xmclient.o hearts.o select.o
connect.o sockio.o start_dist.o gfx.o  -lXm -lXt -lSM -lICE -lXext -lX11 -lPEX5       

make 终于可以工作了(万岁!)。

安装

以 root 用户身份,

[root@localhost hearts]# make install
install -c -s  hearts /usr/X11R6/bin/hearts
install -c -s  xmhearts /usr/X11R6/bin/xmhearts
install -c -s  xawhearts /usr/X11R6/bin/xawhearts
install in . done

测试运行

rehash

(我们正在运行 tcsh shell。)

xmhearts

localhost:~/% xmhearts
Can't invoke distributor!

来自 hearts 包中的 README 文件

     Put heartsd, hearts_dist, and hearts.instr in the HEARTSLIB
     directory defined in local.h and make them world-accessible.

来自文件 local.h

/* where the distributor, dealer and instructions live */

#define HEARTSLIB "/usr/local/lib/hearts"

这是一个典型的 RTFM 案例。

root 用户身份,

cd /usr/local/lib

mkdir hearts

cd !$

distributor 文件复制到此目录。

cp /home/username/hearts/heartsd .

cp /home/username/hearts/hearts_dist .

cp /home/username/hearts/hearts.instr .

尝试另一次测试运行。

xmhearts

它有时可以工作,但更多时候会崩溃并显示 dealer died! 消息。

“distributor” 和 “dealer” 扫描硬件端口。因此我们应该怀疑这些程序需要 root 用户权限。

尝试以 root 用户身份,

chmod u+s /usr/local/lib/heartsd

chmod u+s /usr/local/lib/hearts_dist

(请注意,如前所述,suid 二进制文件可能会创建安全漏洞。)

xmhearts

它终于可以工作了!

Hearts 可从 Sunsite 获取。


下一页 上一页 目录