PCゲーム「雫」の移植方法1

「雫」(しずく)とは、1996年にLeaf(現アクアプラス)が企画・販売していて、ノベルタイプの18才以上を対象としたゲームです。とある業界(汗)には大変有名な作品で、特に「雫」はリーフ・ビジュアルノベル・シリーズ三部作(雫、痕、To Heart)の1つと言われています。

 

詳しい歴史についてはWikipediaを参照してください。昔のゲームなので今に比べて機能も随分劣っていると思います。今回、移植対象としているものはリメイク前なのでグラフィックは16色、メモリも最大で640KBしかないPCで動いていました。

GBAに移植したくなった理由

インターネット上では一時期、ものすごい勢いでPCゲームを別プラットフォーム(りなざう、Linuxなど)に移植するブームが起きていました。そのときに詳細な解析資料がインターネットに公開され、当時は市販レベルのアドベンチャーゲームの中身が見れると思って大変驚いたものです。

 

ただ残念なことに、そのブームは2001~2004年までを境にぱったり終わってしまい、2007年現在では解析資料の消失が目立ってきています。このまま消えていくのはあまりにもったいない。この資料を元に自分のつたない技術でもいいから移植してみようと思ったわけです。ほかにも以下のような理由がありました。

1.png

GBAの移植例

移植に関しては、いろいろな方がすでに実践していらっしゃっています。どのようなGBAの機能を使っているか調べてみました。既にできあがっているものを見れるというのは、大変心強いです。


調べていて、だいたいですが以下のようなことがわかりました。

移植するに当たって必要なこと

移植というはやったことがない人からみると随分漠然としたものです。自分もそうだったのでよくわかります。そこで肝心なのは、移植するための視点を持ってみることだと後で気がつきました。ある意味でゲームとは「小さな機能がよりあつまり、構成されているものだ」といえます。アドベンチャーゲームを思い浮かべてみると、背景画像がって、キャラクターがいて、メッセージウィンドウなどがあって・・・などと言うことができます。プログラマからみると、アドベンチャーゲームの構成している要素は次のように移るらしいです。

小さな機能の構成がゲームを作っているように、移植するときも小さな単位ごとにしていった方が簡単です。ここでは画像、音、プログラムを単位としてGBAに移植していくことにします。

資料集め

ゲーム本体の.exeファイルを逆アセンブルしていって、全体像を把握する方法もありますがそれはあまりに無謀です。「雫」に関しては、既にその手にかけてエキスパートな職人さんが解析を終えていて、さらにwindowsユーザには馴染みのデータフォーマットに変換するプログラムも用意されていました。ちなみに当方は解析についてはサッパリなので、資料がそろわなかった場合移植することを断念していたと思います(^^;。


このような情報から、作業の流れが自然と浮かび上がってくると思います。

データフォーマット

以下にデータフォーマットを表します。すでに変換プログラムが用意されているので知る必要はないのですが、ここでは簡単に概要のみを説明します。*1

アーカイブファイル

8Bマジックナンバー("LEAFPACK")
1Wファイルの数
?ファイルのデータ
?ファイルの一覧情報
ファイルの先頭 + ファイルサイズ - 24 * ファイルのデータ数

画像ファイル(.lfg)

画像は16色で、24バイトのパレットを使用します。基本はリングバッファのLZ法です。バッファサイズを4096バイト、初期状態は全て0、バッファへの書き込み開始位置は0xfeeです。読み取る前にアーカイブのkeyで復号する必要があります。

8Bマジックナンバー("LEAFCODE")
24Bパレット
2W開始位置(x0,y0)
2W終了位置(x1,y1)
1B方向
1B透明色の指定
2B???
1L展開後の長さ
?B圧縮データ

スクリプトファイル

スクリプトファイルには大きく分けて、イベントと、メッセージという2つ構造に分かれています。データの最初の部分(イベントデータ、メッセージデータの位置)以外はリングバッファのLZ圧縮がされており、さらにbit反転されています。

1Wイベントデータの位置
1Wメッセージデータの位置
6W?
?イベントデータ
?メッセージデータ
コマンドサイズ説明
0x001ブロック終了
0x013特殊効果(画面)
0x032不明
0x044別スクリプトへジャンプ
0x05?選択肢
0x061不明
0x071前選択肢に戻る位置保存
0x0a2背景のみロード
0x142画面クリア
0x162Hシーンロード
0x223キャラクタロード
0x0a2背景のみロード
0x142画面クリア?
0x162Hシーンロード
0x223キャラクタロード
0x243キャラクタロード2?
0x281選択肢に存在するデータ
0x382表示処理(画面に反映)
0x3d4if文
0x3e4if文(否定)
0x473フラグの値設定
0x483フラグの加算
0x542テキストメッセージ
0x5a1不明
0x5c2不明
0x601不明
0x613不明
0x622不明
0x631不明
0x641不明
0x651不明
0x661不明
0x6e2BGM再生
0x6f1不明
0x731不明
0x7c2エンディング関係(不明)
0x7e2エンディング番号設定
0x7d2エンディングBGM&起動
0xff1本来アクセス不可
コマンドサイズ説明
& 0x80?連続したメッセージ
'$'1メッセージ終了
'r'1改行
'p'1ページ更新
'K' 'k'1キー入力待ち
'O'1不明
'C'4キャラクタ位置交換
'B'7背景ロード
'S'10背景付きキャラ表示
'D'4キャラ全消去後表示
'A' 'a'10キャラ3人表示
'Q'1画面を揺らす
'E'7背景ロード(2)?
'F'1フラッシュ
'V'7ビジュアル?
'H'7Hシーン
'M'2BGM再生
'P'2-4PCM関連(効果音)
'X'2不明
's'2表示速度指定?

移植手順

移植の流れは以下のようになります。実際の作業はこんなに綺麗に分かれているわけではなく、色々作業を同時進行していました。

スクリプトエンジン部分のプロトタイプを作る

途中で挫折しないようにする為、一番難しいことを最初にやってしまうことにしました。このプログラムは「DOSプロンプト上でスクリプトメッセージを表示する」使い捨てでしたが、アドベンチャーゲームの本質と思える部分で、一番の難関になると思います。

 

プロトタイプのソースコードを以下に表します。見せるために用意したものではないので、ワーニング出しまくりのヒドイものですが必要ならダウンロードしてみてください(^^;。アーカイブファイル(MAX_DATA.PAK)からスクリプトファイル(SCN002.DAT)をデコードして、メッセージを表示しています。コンパイラはBorland C++ 5.5.1 for Win32(ダウンロード版)を使用しました。

file(SCN002  DAT)
event size   = 40
message size = 2225

...(中略)

 unknown!![cmd:31 1]
 [22] 
 42 
 僕は黙々とシャープペンシルの先を走らせ、青い罫
 [59] 
 72 
線が刻まれた真新しい大学ノートに、ひとつの円を描

...(以下略)

.gbaファイルのサイズを確定させる

次の問題は.gbaファイルの最大サイズ32MBに収まるように考慮することになります。この問題については(雫とゲームシステムがほぼ同じ)痕が移植を成功していることもあり、あまり大きな問題にはなりませんでした。ただし、痕を移植しました大賀 きゆき 様の日記から伺いできるように、様々なトレードが絡んでいることが窺い知れます。たとえば、データのサイズを抑える為に圧縮してしまうと解凍に時間がかかり、無圧縮にした場合はデータのサイズが大きくなってしまいます。理想はPCゲームと同じ品質であることが望まれます。

画像ファイルを表示するプログラムの作成

ここでのポイントは画像ファイルを表示するという目的以外にも、データ容量について調べてみることです。作業の流れはだいたい次のようなものです。

2.png

以下にその結果を表します。

データの形式サイズ備考
lfg8bpp3.94MB
bmp8bpp15.1MB
bmp(resize)24bpp13.5MB倍率約37%
img(GBA用)15bpp3.98MBLZ圧縮あり。240x160サイズ固定

lfgファイルの数は195。サイズはLZ圧縮が掛っているとはいえ、無圧縮のbmpに比べて約5倍ほどの違いがあります。リサイズ時には縦横比(アスペクト)を無視して240x160のサイズに変更をしている為、若干横に太めに見えてしまうかもしれません。ここでわかったことは、オープニングアニメーション用の画像ファイルはスピードが気になるので無圧縮にして、他の画像は圧縮することで約4.5MBぐらいになると想像できます。詳細が知りたい場合、旧サイトのNo.76を参照してください。ちなみに最終版では容量に問題がならなかった為、無圧縮にしています。

音楽ファイルを再生するプログラムの作成

「雫」はCD-DA形式の為、ターゲットはWAVファイルということになります。全25ファイル(曲)で無圧縮の場合、517MB(16bit 44khz stereo)です。当初はsoxというツールを使って変換をかける予定でしたが、容量がかなりきびしいことがわかりました。そもそも圧縮していない点で場違いみたいです(^^;。

soxのオプションサイズ
-r 11025 -c 1 -b29.8MB
-r 8192 -c 1 -b22.2MB

次にGBAで定評のあるライブラリを使用してみます。今回はGSM player for GBAと、8ad codecを調べてみることにしました。ビットレートの変更はGSMはできなかったのですが、8adはちょうど容量に収まりそうなパラメータに変更しています。

名前容量
GSM10.1MB
8ad18MB

GSMはビットレートの低い特有のシャワシャワ感(?)が出てしまうので少し気になっていたのですが、8adはあまり気になりません。決定打となったは、8adの広告に「6 percent of the GBA's CPU time.」という記載があることと移植しやすいソースコードであったことです。詳細が知りたい場合、それぞれの公式サイトを見てみることをオススメします。サンプルプログラムは旧サイトのNo.77を参照してください。

履歴


*1 yatsushiさんの痕解析結果(閉鎖)http://member.nifty.ne.jp/yatsushi/を参考にさせていただきましたm(__)m。

トップ   一覧 検索 最終更新   ヘルプ   最終更新のRSS