映画やゲームなどで最後に制作者名や権利表示が出てくるのがエンドロールです。これは主に制作関係者に対する感謝の気持ちとして、その作品の末尾に名前を載せていたりします。何気なく見てると気が付きませんが、結構作るのに手間がかかります。また、これをレトロPCで実現しようとすると、機種によってはとても大変だったりします。今回はエンドロールを実現するための高速化テクニックをまとめて記載してみようと思います。データの表記は Z80 アセンブラを基準としています。
- メッセージデータの仕様
特に高速な機種の場合は、単純なメッセージデータをリストとして持っているだけで事足ります。ところがレトロPCで単なるリストだけでデータを用意すると、処理が間に合わなくなります。どうしてでしょうか。以下は XeGrader で現在作成中のエンドロールの一部です。
まず気がつく事として、テキストに色が付いています。次に文字がセンタリングされています。最後に名前がアカウント名を表す@マークで揃って表示されています。色を付けるには COLOR コマンドを用意する必要があります。まあ、これはデータを増やすだけで良いのですが、センタリングはどうしましょうか。センタリングを実現するには、画面の横幅から文字列の長さを引いてから半分にした値を、文字列の左側座標として使用する事で実現します。
文字列を表示する前に、文字連れの最後まで走査して、文字の長さをカウントする?また、半角文字は 1、全角文字は 2 としてカウントする?その後また文字列を最初から描き直す?…いやー、ただでさえ遅いマシンに一つの文字列で何度もデータを走査させるのはなかなか厳しいです。色を付けるのだって、論理演算が必要なのに…。
そこで、文字列の先頭に文字の表示開始座標をヘッダ情報として事前に用意します。この値を、適切に設定すれば、@マークのアカウント名の頭出しも同時に出来てしまいます。ここまでは、まあそれなりにプログラム経験者であれば、すぐに仕様策定できると思いますが、私はここにさらに1つの改良と2つの仕様追加をしています。
1つの改良とは文字の色です。テキストに COLOR n とか書くのは視認性が悪くなりますので、文字列の先頭に > があれば、それはタイトル名とみなして赤色にします。また、文字列の先頭に >> であれば、項目名と判断して緑色にします。これの何が良いかと言えば、秀丸エディタで編集中に自動的に色が変わるのです。> って引用として見なされますからねぇ。勝手に色が変わるので、文字編集中にタイトル行が一発で分かるので便利なのです。
※ マグネットがあるとちょっとしたメモをあちこちに挟んで置けるので便利です。強力な磁石は傷をつける可能性もありますので、このようにコーティングされているのが使い勝手が良いです。
- 仕様の改良とデータ編集
まず改行等の制御コードの追加をします。あと、メッセージデータをよく見ると、名前とアカウント名の間に全角サイズの空白があります。半角スペース2つで1つの制御コードとしてしまえば、少なくとも全角サイズのテキストデータは1バイトで済みます。これが省メモリに効いたりします。
次に重要なのが、使用している文字の列挙です。テキストで文字が表示されるわけではないので、どの文字が使われているかを全て抜きださなければいけません、そして、抜き出した文字を元に、画像を用意します。抜き出した文字データを辞書と呼びます。この辞書を元に文字画像を作ります。今回は 8x12 dot Japanese font "k8x12s"という文字フォントを使用しました。
これがフォントから作った文字画像です。作成には私は Photoshop を用いています。メッセージデータは、UTF-8 等の冗長な文字コードから出来ていますので、それを辞書の連番に変換する必要があります。このようにメッセージデータから辞書を抜き出したり、メッセージを連番に置き換えたり、制御コードを発行したりは手動で行うと途方もなく大変なので、何かしらのツールを作ることになります。私は C# でサクッと変換ツールを作りました。自分用かつ今回のプロジェクト用ですから、エラー処理とか体裁とかは二の次で、変換できることが最優先のプログラムとなっています。
※接点復活剤です。レトロPCとかファミコンのような昔のゲーム機のコネクタ部が汚れなどで接触不良になることも多々ありますが、こちらで綺麗にすると余程の状態であれば復活します。
- 変換後のデータ
専用ツールを用いてデータ変換した後の、組み込み用テキストが以下のようになります。
まず、私の名前の行で説明します。最初に $1E とあるのが文字の書き出しを行う左の座標です。10進数で 30 です。内藤時浩で8文字、間の空白で2文字、@NAITOTokihiro で 14文字で、文字列は全部で 24 の長さです。画面の横幅は 80 なので、(80-24)/2 = 28 です。…あれ?28 は16進数で $1C なので位置が合わないですよね。
実は私の名前の中に@マークがあるので、そこが固定位置になるように補正されているのです。@マークの位置は 40 ときめてあるので、先の文字列の先頭から@マークまで 10文字ですから、40-10 = 30 で $1E になったというわけなのです。
続いて $99, $86, $84F,... とあるのが文字連番です。全角と半角を区別するために、全角文字は最上位ビットを 1(+$80)としてあります。文字の表示の仕方が半角と全角では異なりますので、その判定のためです。途中で $E1、最後に $E7 とあるのが制御コードです。制御コードは NEG した値を使っています。これで、数値のかなり大きい値に制御コードが固まりますので、そこから判定するようにしています。$E1 が全角スペース、$E7 が改行コードです。
左端の大きさは最大でも画面幅いっぱいの 79 ですので、改行コード $E7 はその中に混じっても判定できます。そのため、改行だけの場所は $E7 の 1バイトで済ませています。
>GRAPHICS の表示ですが、ここはタイトル行になります。最初にセンタリング位置となる左側の座標値 $24(36)が配置されます。続いて制御コード $E3 となります。これはタイトル行を表しています。以降は $E7 まで半角連番が続きます。
>>Using... の表示は項目名です。同じく最初に左側の座標値 $1A(26)が入ります。続いての $E4 が項目名を表す制御コードとなっています。
※耐水性のある印刷用ラベルです。プリンタ側もインクが耐水である必要はありますが、こちらを使えばかなり長持ちします。その商品名の通りラベルとしては最適なのではないでしょうか。様々なサイズがありますので用途に応じて選択が必要です。
データが揃ったら次はプログラム全体の把握となります。
コメント