令和のSFXVIプログラミング②クロスコンパイル実践
ABIを変更する
かつてX68000で主に使われていたGCC(通称真理子版)およびXCと現在のGCCはABI(Application Binary Interface)が異なるため、それぞれを単独でコンパイル&リンクする場合は問題ありませんが混合してリンクすると正しく動いてくれません。
SFXVI用に開発された各種ライブラリは真理子版相当のABIで動作するように作られているため、elf2x68kでコンパイルする場合もそれに合わせる必要があります。
elf2x68kをビルドするとm68k-xelf/install-xclib.shというシェルスクリプトが作成されます。これを実行すると無償公開されているXCのインクルードファイルやライブラリがローカルに取り込まれると共に、elf2x68kのコンパイル結果が真理子版相当のABIとなるように設定が変更されます。
./install-xclib.sh
または
source install-xclib.sh
このシェルスクリプトはelf2x68kのインストールパスを変更したらその都度実行するようにしてください。
SFXVI開発キットのインストール
SFXVI開発キットを一次配布しているサイトは現状存在しないため二次配布しているサイトからダウンロードしてください。
sfxvi40d.lzhとsfxvi40l.lzhが開発キットになります。これらを任意のディレクトリに展開します。どこでもいいですがパス名が短くなる場所の方が何かと都合がいいでしょう。以降はC:¥SFXVI40Dに展開した前提で解説します。
ファイルのコンバート
開発キット内のインクルードファイル(C:\SFXVID\DEVELOP\INCLUDE)はファイルの末尾にファイル終端を表すコントロールコード(0x1A)が付いており、これが邪魔をしてコンパイルに失敗してしまいます。
なのでこれを削除する必要があります。
ファイル数も少ないので手作業で削除してしまいましょう。
任意のテキストエディタで各ヘッダファイルを読み込み、最終行にある謎の空白を削除して保存します。サクラエディタを持っていればカーソル位置にある文字の文字コードを確認することが可能なのでわかりやすいでしょう。
この作業を以下のファイルに対して行います。コントロールコードを削除してもX68000でのコンパイルには影響がないため上書き保存してしまって問題ありません。
SFXVI.H
SFXVI6BI.H
SFXVIICC.H
SFXVILIB.H
SFXVIMAC.H
SFXVITYP.H
次にライブラリのコンバートを行います。elf2x68kではX68000形式のライブラリを読み込むことができません。コンバートにはm68k-xelf/bin/x68k2elf.pyを使う必要があります。
が、ここでSFXVI特有の問題が発生します。SFXVIのライブラリに含まれる関数は全角文字を使った名前が付けられています。
/__________________________________________________________________________/
/* キャラの登録に関する操作 [LIB] */
void 同期開始_キャラ登録( int argc, char *argv[], char *message );
void 同期完了_キャラ登録();
これがSJISの文字コードであるためにコンバートが失敗してしまうのです。
x68k2elf.pyを書き換えてSJISに対応させましょう。
x68k2elf.pyのコピーをx68k2elf_sjis.pyの名前で作成し、それをエディタで読み込みます。これはUNIX環境でもWindows環境でもどちらでも構いません。
157:self.name = strtab[self.nameidx:strtab.index(b'\0',self.nameidx)].decode('Shift_JIS')
329:return s.decode('Shift_JIS')
332:return s.decode('Shift_JIS')
360:return name[0:name.find(b'\0')].decode('Shift_JIS')
上記の通り、157行、329行、332行、360行のdecodeメソッドの引数にShift_JISを追加します。
修正したx68k2elf_sjis.pyを使ってライブラリを変換します。変換後のライブラリはX68000では使えなくなるため上書きはせず別のディレクトリに保存します。保存先をC:\SFXVI40D\LIB\XELF\だとした場合はMINGWのシェル上で下記のコマンドを実行します。
x68k2elf_sjis.py /c/sfxvi40d/lib/sfxvi6bi.a /c/sfxvi40d/lib/xelf/sfxvi6bi.a
x68k2elf_sjis.py /c/sfxvi40d/lib/sfxviicc.a /c/sfxvi40d/lib/xelf/sfxviicc.a
x68k2elf_sjis.py /c/sfxvi40d/lib/sfxvilc1.a /c/sfxvi40d/lib/xelf/sfxvilc1.a
x68k2elf_sjis.py /c/sfxvi40d/lib/sfxvilib.a /c/sfxvi40d/lib/xelf/sfxvilib.a
x68k2elf_sjis.py /c/sfxvi40d/lib/sfxvirun.a /c/sfxvi40d/lib/xelf/sfxvirun.a
標準のSFXVIライブラリ以外に使用しているものがあれば同様に変換してください。
キャラクターのmakefileを作成する
開発キットに含まれるキャラクターのソースはバッチファイルでビルドするようになっていますがmakefileを作成してmakeコマンドでビルドするようにします。makefileの書き方は色々あるのでここでは簡単なものにします。
TARGET = ../object/action.x
SRCS = action.c command.c func.c mmp_act.c mmp_cpu.c mmp_opt.c mmp_sub.c mmp_vct.c shot.c
OBJS = $(SRCS:.c=.o)
LIBS = ../../../LIB/xelf/sfxvi6bi.a ../../../LIB/xelf/sfxviicc.a ../../../LIB/xelf/sfxvilib.a ../../../LIB/xelf/sfxvirun.a
CROSS = m68k-xelf-
CC = $(CROSS)gcc
AS = $(CROSS)as
LD = $(CROSS)gcc
CFLAGS = -m68000 -O2 -g -I/c/sfxvi40d/DEVELOP/INCLUDE -Wno-builtin-declaration-mismatch -finput-charset=cp932
LDFLAGS =
all: $(TARGET)
$(TARGET): $(OBJS)
$(LD) $(LDFLAGS) -o $@ $^ $(LIBS)
#%.o: %.c
# $(CC) $(CFLAGS) -o $@ $^
action.o: action.c action.h
$(CC) $(CFLAGS) -c $<
command.o: command.c command.h
$(CC) $(CFLAGS) -c $<
func.o: func.c func.h
$(CC) $(CFLAGS) -c $<
mmp_act.o: mmp_act.c mmp_act.h
$(CC) $(CFLAGS) -c $<
mmp_cpu.o: mmp_cpu.c mmp_cpu.h
$(CC) $(CFLAGS) -c $<
mmp_opt.o: mmp_opt.c mmp_opt.h
$(CC) $(CFLAGS) -c $<
mmp_sub.o: mmp_sub.c mmp_sub.h
$(CC) $(CFLAGS) -c $<
mmp_vct.o: mmp_vct.c mmp_vct.h
$(CC) $(CFLAGS) -c $<
shot.o: shot.c shot.h
$(CC) $(CFLAGS) -c $<
clean:
-rm -f *.o $(TARGET).elf $(TARGET)
このファイルをC:\SFXVI40D\DEVELOP\CHAR\D_LUKS\PROGRAMに配置します。
次にSFXVI開発キットのインクルードファイルと同様にファイル終端コードが含まれているファイルからコードを削除します。
D_LUKSの場合は下記の三つが該当します。
command.c
command.h
user.h
あとは何故か最初から用意されているfunc.oを削除します。
これで準備完了。あとはmakeを実行するだけです。なお、make実行時に-jコマンドを指定すると並列コンパイルが可能です。
ビルドに成功すればC:\SFXVI40D\DEVELOP\CHAR\D_LUKS\OBJECTにaction.xとaction.x.elfの二つのファイルが作られます。あとはSFXVIのキャラクターディレクトリに成果物をコピーしてSFXVIを起動し、遊ぶだけです。
action.x.elfは不要なので削除してしまって構いません。
終わりに
SFXVIの全盛期から30年近くたっているというのは中々の衝撃ですが、今だからこそできる楽しみ方もあるんじゃないかなと思います。この記事がそれの役に立てたら幸いです。