スーパーカセットビジョンでカセットを入れずに電源を入れた時に
表示される風船デモを MSX-BASIC で再現したものです。
……とはいっても、スプライト 32 個を同時に動かしているので、
実機では MSX turbo R の高速モード(R800 モード)でないと遅いです。
MSXPen での WebMSX 動作も MSX turbo R での動作にしてあります。
100 COLOR ,1,1:SCREEN 1,1
110 KEY OFF:WIDTH 30
120 T=RND(-TIME):DEFINT A-Z:B=0
130 DIM X(31),Y(31),C(31),M(31)
140 LOCATE 1,2:PRINT "MSX-BASIC DEMO"
150 H$=CHR$(14)+CHR$(29)
160 H$=H$+CHR$(31)+CHR$(31)
170 H$=H$+CHR$(14)+CHR$(8)
180 H$=H$+CHR$(16)+CHR$(224)
190 SPRITE$(0)=H$
200 FOR I=0 TO 31
210 X(I)=RND(1)*256
220 Y(I)=RND(1)*192
230 C(I)=RND(1)*15+1
240 M(I)=RND(1)*8+1
250 NEXT I
260 FOR I=0 TO 31
270 FOR J=0 TO 31
280 PUT SPRITE J,(X(J),Y(J)),C(J),0
290 ON M(J) GOSUB 370,370,410,380,380,380,410,370
300 ON M(J) GOSUB 410,390,390,390,410,400,400,400
310 NEXT J
320 M(I)=RND(1)*8+1
330 IF I MOD 15<>14 GOTO 350
340 B=(B+1)MOD 15:COLOR ,B+1
350 NEXT I
360 GOTO 260
370 Y(J)=(Y(J)+4)MOD 192:RETURN
380 Y(J)=(Y(J)+188)MOD 192:RETURN
390 X(J)=(X(J)+252)MOD 256:RETURN
400 X(J)=(X(J)+4)MOD 256:RETURN
410 RETURN
WebMSX では起動してから乱数を発生するタイミング(TIME の値)が
毎回同じになってしまうので、現在時刻の秒から乱数を生成しています。
(MSX1 では CLOCK-ID がないので除外しています)
125 IF PEEK(&H2D)=0 GOTO 130
126 GET TIME T$
127 R=VAL(RIGHT$(T$,2))
128 R=RND(-R)
BASIC ではさすがに遅いので、
z88dk を用いて C 言語で作成し、マシン語プログラムにしてみました。
スペースキーでプログラム実行を停止し、BASIC へ戻ります。
WebMSX の実行では停止しないようにしてあります。
2024年12月に改良し、スプライト情報(座標・スプライト番号・色)を
一旦メモリに入れ、LDIRVM でメモリから VRAM へ ブロック転送する事で
32 個の風船を一斉に動かしていて、より高速に風船が動くようにしました。
あまりに速くなったので、背景色を変えるタイミングは
32 個の風船を 3 回動かした後にしてあります。
BASIC は 15~17 個毎なので、およそ 6 倍になります。
2025年1月更に改良し。乱数生成アルゴリズムに xorshift を用いて、
風船の数を BASIC 同様 32 個にしてあります。
(以前は乱数の精度により 31 個にしていました)
zcc +msx -lndos -create-app -subtype=disk -bn balldemo balldemo.c
BALLDEMO.MSX が生成したマシン語の実行ファイルです。
BASIC より BLOAD"BALLDEMO.MSX",R で実行します。
MSX1 でも動作可能な事を確認できています。
MSX1 ではカセットテープでの保存が主でしたが、
(WebMSX は MSX1 でも Disk BASIC が使えます)
「-subtype=disk」を外してコンパイルするとカセットイメージ BALLDEMO.CAS、
「-subtype=wav」に変えると実機で読める音声データ BALLDEMO.WAV
になります。 BLOAD"CAS:",R で実行します。
WebMSX は Alt+S でスプライトを Unlimited にしても良いです。
C-BIOS では文字の フォント・キャラクタ が異なります。
上の画像も C-BIOS での動作です。