[ ICE-MAN(アイスマン) その2 ]

※途中で戻りたい場合は、ブラウザの「戻る」機能を使ってください。



ICE-MANの解析



雑誌「MSXFAN」の1991年2月号に掲載された、アドレスさん作「ICE-MAN」です。


今回からは、このゲームプログラムを解析していきたいと思います。


プログラムリストを解析する



これからプログラムリストを1行ずつ取り上げて、解析をしていきます。


文法などは前回でほぼ学習した為、新しい文法と何を行っているのかの把握を紹介していきます。


10行目




コロンで区切られて、幾つかの命令が書かれています。


順番に読んでいきます。


SCREEN文とCOLOR文で、画面環境を設定し、KEYOFFでファンクションキーを非表示します。


DEFINTで変数を整数扱いにして、横32文字に設定します。


PLAY文では、設定のみで音を鳴らしません。
また、ダブルクォーテーションで囲まれたMMLがコンマで区切られ二つ並んでいます(内容は同じ)。
これは2チャンネル使用し、どちらとも同じ設定を行っている事になります。


次はFOR文で1〜5までを繰り返します。
内容は、MID$でダブルクォーテーションで囲まれた文字列から、任意の文字列を取り出してA$に足して連結しています。そのあとCHR$でA$の連結が3つ続いて、再びMID$で任意の文字列を取り出してA$に足しています。


MID$の内容をプログラムを実行してから見てみると、



緑の囲み部分がMID$のダブルクォーテーション中のキャラクタとなります。
なんだか見えて来ましたね。


MID$(文字列,I*2,2)で、Iは1〜5というわけですから、2文字目から2つずつ拾ってくる事になります。


最初のブロックから、背景、ブロック、ハシゴ、ゴールドフィガー、アイスブロックの順番で並んでいます。
また、前のMID$の文字列が上半分で、後のMID$が下半分のキャラクタだとわかります。


雑誌にも変数リストが載っており、A$(n)でnの意味は、

0:空間(背景)

1:壁(ブロック)

2:ハシゴ

3:金塊(ゴールドフィガー)

4:氷(アイスブロック)

と表記されており、A$(I)のI=0〜4に当てはまります。


では、その間に入るCHR$(31)+CHR$(29)+CHR$(29)とは何なのでしょうか?


調べてみるとコントロールキャラクタとして、

CHR$(31)は1キャラクタ分下へ移動する

CHR$(29)は1キャラクタ分左へ移動する

ことがわかりました。


キャラクタの上半分を2キャラクタ分描いて、下、左、左、と移動し、また下半分の2キャラクタを書く事で、4キャラクタを描く事になります。


20行目

次に10行最後のFOR文が2回続き、次の行に続いている為、20行も表示します。




M$は「2行分の壁(ステージ表示の準備処理で使用)」と雑誌に書いてあり、先程の実行後のリストを見る限り、ブロックのパターンを定義しています。

FOR文の0〜15を2回行うことで、ブロックのパターンの前半1行分(32キャラクタ)とパターンの後半1行分(32キャラクタ)の計2行分ををM$に格納する事になります。


次の命令のFOR I=384 TO 703 〜ですが、後のVPEEKやVPOKEのアドレスとして変数Iが使われています。

384〜703のアドレス(&H0180〜&H02BF)は何の場所かというと、&H0000〜&H07FFの「キャラクタパターンジェネレータテーブル」ということで、文字キャラクタの形の情報が格納されています。

またデータは、コード順に並んでおり、1文字に8バイトずつ全部で2048バイトの大きさがある(2048÷8=256文字)。

という事はこの場合、384÷8=48、703−384+1=320、320÷8=40となり、&H030(48)から40キャラクタ文VPEEKで読み込んだものを、V OR V/2と加工し、再び同じアドレスの中へ入れることをしています。

では、どの文字を加工(?)しているのか、実際に見てみましょう。


実行前のキャラクタ一覧です(緑で囲まれた部分が、該当の箇所となります)。




次は、実行後のキャラクター一覧です(緑で囲まれた部分が、該当の箇所となります)。




こうしてみてみると、文字自体は一緒なのですが、太くなっているのがわかります。

V OR V/2 の意味もなんとなくわかってきました。

Vはキャラクタの8×8ドットの1行分をあらわしているので(例、&B00110010)、それを割るという事は右に1ビットシフトしている事で、キャラクタパターンを右に1ドットずらす事と同じです。

それに、もとのずらす前のキャラクタとORをとることで、どちらのパターンも反映される事となり、右に1ドット太くなったパターンとなるのです。

これで、元あった文字パターンが太く変換されている事がわかりました。


E$=CHR$(27)+”Y”:PRINTE$”*+PLEASE WAIT”

画面の中央に「PLEASE WAIT」と表示します。

まず、CHR$(27)はコントロールキャラクターを表しており、調べてみるとエスケープシーケンスです。

+”Y”で

<ESP>Y<Y 座標 +20H><X 座標 +20H> カーソルを (X,Y) の位置に移動

とあり、この場合だと、

<Y 座標 +20H> = ”*”(2AH)

だから、<Y 座標 +32> = ”*”(42) で Y 座標は10

<X 座標 +20H> = ”+”(2BH)

だから、<X 座標 +32> = ”+”(43) で X 座標は11

という事になります。

画面の(11,10)に「PLEASE WAIT」と表示する事になります。


次のIとJの二重のFOR文ですが、見難いのでわかりやすいように並べてみました。



外のループのIは0〜13の14回、内のループは0〜7の8回となっています。

まず、READ文で変数V$にDATA文から一回読み込みます(200行のDATA文からコンマまでを一回で17文字ずつ)。

そしてASC関数でV$の内容をキャラクターコードの数字に変換しています。

V$の内容は17文字で、それを数字に変換するとどうなるだろうと疑問に思ったため、ある実験をして確かめてみました。



こんなプログラムを組んでみました。

10行のDATA文は200行のDATA文のデータをそのまま2回分入れてみました。

そして変数V$とVの内容を、実際に表示してみる事にしました。



結果はこの通りです。

Vの内容は、V$の最初の文字列のみを変換している事がわかりました。

次は内側のループに入り、VPOKEでアドレス(V*8+J)に値(VAL(”&H”+MID$(V$,J*2+2,2)))を入れています。

これは先程も出てきたMID$で取り出した文字列の先頭に”&H”を付けて、VAL関数で数字に直して値にしています。

Jの値から、2文字目から2文字ずつ取り出すことを8回行うので、丁度17文字で合います。


そして20行最後は、FOR文で1〜12の12回、VPOKEであるアドレスに書き込みを行っています。

アドレスは8195(&H2003)+I(I=1〜12)でこの領域は、「AMIDER(アミダー) その10」で紹介したように、「カラーテーブル」という領域です。

アドレスは&H2000〜&H201Fで、8文字ごとにキャラクタの色と背景の色を1バイトで指定し(上位4ビットがキャラクタの色で、下位4ビットが背景の色)、256キャラクタあるため32バイトとなります。

始めに書き込むアドレスは、8195(&H2003)+1なので、33キャラクタ目より8キャラクタずつ色を指定しています。

実際に先程紹介した、キャラクタ一覧を見てみましょう。



2段目(33キャラクタ目)より8キャラクタ分ずつ色が変わっているのがわかるでしょうか(始めが空白になっていますが)?

色の内容は、MID$のダブルクォーテーションで囲まれた文字をASC関数で数値化して指定します。

丁度12文字あり、12回の色指定ができます。


20行でこの章を区切りたいと思います。

次章からは30行からの解析になります。

 

Copyright(C) 2006. ピコピコテクノロジー All Right Reserved.