Saturday, February 25, 2012

プチコンでMSXのタイトル画面 その2


プチコンでMSXのタイトル画面 その1のつづき。
絵は描けたので、次は表示のしかた。
MSX2は縦スクロール、2+は横スクロールし、いずれも1ドット単位。 GRAPHIC画面にはスクロール機能はないので、スクロール機能があるBGを使う。
(キャラクタを画面に敷きつめておき、パターンを書き換えする力技もあるにはある)

なのでGRPからBGを作成。
8x8ドット分GSPOITで読み取り、CHRSETの画像文字列にする。 これでいけるはずだったが、作ってみるとエラーになった。
BGU0のキャラ数256個では足りなかったのが原因。
黒い部分は(23,43)-(234,123)。
同じ位置に表示させるため、8ドット区切りにすると(16,40)-(240,128)。
つまり28x11=308キャラ必要だった。

意外と大きいタイトルロゴ

対策は2つ。
  1. BGU0に収まらない分はBGU1にいれる。プチコンは1024個BGキャラが作れるので余裕。
  2. なんとかして256キャラ以内に(BGU0)におさめる。
じゃあどうやっておさめるか、と画面を眺めると、黒や白だけのマス目が多い。
黒や白だけのマスを2つ定義しておけば、必要なキャラ数が減るのでは! (BGキャラを並べるのがめんどくさくなるけど)

  • あらかじめ、真っ黒と真っ白BGキャラは定義しておく
  • 左上から右下に向けてGRAPHIC画面からちまちま画像文字列を作成
  • 真っ黒か真っ白のBGキャラなら、BGキャラ定義しない
  • 真っ黒でも真っ白でもなかったら、BGキャラ定義
  • BGキャラ定義した場合、そのBGキャラコードをキャラ表示用配列に記録
  • BGキャラ定義しない場合、真っ黒/真っ白コードをキャラ表示用配列に記録
みたいなかんじでやってみると、210キャラぐらいに納まった。

ここまでできると、BGに"MSX"と表示し、BGOFSで好きにスクロールできる。

MSX2タイトル画面は、画面中央くらいから、MSXのロゴがせり上がってくるので、BGCLIPで表示範囲を制限して、縦スクロールさせれば完成。

MSX2+タイトル画面は、1ラインおきの画面が左右から横スクロールし、合成される。 (動画後半参照)

どうしたかというと、
  • GRAPHIC画面からの読取結果を偶数ラインならBGU0に、奇数ラインならBGU1に、BGキャラ定義 
  • BGキャラ表示用配列に従ってBGPAGE0にBGU0のBGキャラ、BGPAGE1にBGU1のBGキャラを配置 0,1ページとも256ドット左右にスクロールさせておく
  • 適当なスピードで0,1ページともBGOFSでスクロール表示

Saturday, January 14, 2012

プチコンでMSXのタイトル画面 その1

プチコンでMSX(2,2+)のタイトル画面を再現してみようとおもいました。

実機やエミュレータで動きをみてると走査線割り込みを使っていそうなのですが、プチコンでそれはできません。
しかしプチコンには
  • 豊富なBG定義(上画面で1024個)
  • 2ページのスクロールレイヤー(BG)
  • ウィンドウ機能(BGCLIP)
があるので、それなりに再現できそうです。

MSXのロゴをBG画面に作るにあたり、
  1. グラフィック画面に描画
  2. グラフィック画面を読み取り
  3. キャラクタパターンへ変換
  4. BGキャラ定義
という流れで作ることにしました。

今回は1.の部分です。

方針が決まったところで、次はデータ作成です。
MSX2,2+のタイトルロゴはこんな感じです。
MSX2のタイトル画面。2+だとVRAMではなくRAMとなる
"MSX"の部分はSCREEN6らしいので、ピクセル数は512x212になります。
("VRAM:128KBytes"の部分はSCREEN5っぽいですが)
プチコンの画面は256x192なので、横方向を1/2にし、さらに縦192ドット以降は無視。

もととなる画像から位置を割り出し、GLINEで書いていきます。
黒い部分は(23,43)-(234,123)てな感じで。※この大きさが後で問題に。。

データを打ち込み、描画結果を見ながら適当に補正し、思いつきで短くしてみた結果が以下のプログラムです。
MSXタイトルロゴ作成プログラム。謎の文字列がいい感じ
期せずして1画面に収まりました。(1行目GOSUB @SETUPはとび先でRETURNしているだけです。消し忘れ)
とはいえ、いきなりこんなリストになったわけではありません。最初はDATA文で数字で座標を打ち込み、見栄えを確認してからデータを圧縮・プログラムを変更しています。

プチコンでの実行結果は次の画像です。
MSXタイトルロゴ作成プログラム実行結果。一瞬で表示される
なかなかそっくりにできたのではないでしょうか。
Sの曲線がそれっぽくできました。
ただ斜め線ががたがたに見えるのがやや残念なところです。
本物の画面をよく見るとわかりますが、斜め線では灰色も使用しており、アンチエイリアシングされています。
でもめんどくさい現状のできばえに満足してしまったので、灰色ピクセルの再現はしませんでした。

「MSX」はMSXライセンシングコーポレーションの登録商標です。

Monday, November 28, 2011

そんなんAR..とは

ニコニコにあげた動画(プチコンでテトリス2)が監視されてたみたいです。少なくとも存在を察知されていた模様。似て非なるものにしてたつもりが。。
そういえば一時期「この動画は三原によって監視されています」ってタグがついてました(今は消えてます)。


変なことにならないようにしないと。

Tuesday, November 1, 2011

プチコンでテトリス2

テトリスを再び作りました。

どこかにありそうなゲーム画面
作成中だったものをyoutubeにアップロード


前に作ったのは今おもえばプロトタイプ?。無駄なつくりがそこかしこにあって、細かいところがいまいちだったので、新たに作り直し。

  • 見た目をよくした
  • ブロックのデータが16個の配列だったのを4つに
  • ブロックの表示ループを展開
  • 移動中のブロックをBGからスプライトに変更
  • プログラムでキャラ定義していたのをCHRED2で作成
  • タイトルつけた
  • ランキング(自動読み込み、保存)つけた
  • スコアをつけた
  • レベル、グレードをそれっぼくした
  • プログラムの構造を見直してGOSUB〜RETURNを減らした
  • ブロックが消えるときに飛び散らせてみた
  • ブロックがNEXT直下まで積みあがっている時のIRSの挙動をちゃんとした
  • 40ラインモードをつけた(ワンダースワン版テトリスに似た感じで)
  • 20Gモードをつけた
などなど、山ほど変更。
TGMでいうT.L.S(ゴーストブロック)の処理が意外と重く、姑息な高速化をふんだんに使い、ブロックを消す処理以外は1フレーム以内で動くように。

ひたすらテストプレイを繰り返すうちにちょっとだけ本家TGMでのグレードがあがり、上達したかも(といってももともとがたいしてうまくないのですが)

Saturday, October 1, 2011

プチコンで数式計算

プチコンでPB-100 挫折放棄中をみて、面白いなあとおもったので作ってみた。ほんとはBASICがつくれたらすごいんだけど、そんな能力が無いので数式計算。変数も関数も無く、整数のみ、数字は5桁までという制約つき。プチコンのダイレクトモード使えばいいじゃんという話ですが。
ひとつだけいいところがあって、ベキ乗(累乗)が計算できます。2^16=65536とか。
上がプチコン、下の">"以降がプログラム実行結果

使い方:実行すると">"が表示されるので、数式を入力。1+1や1*2+3や3*(2+1)など。でEnterを押すと、答えを表示。かっこ、演算子は^、%、*、/、+、-が入力可能。
演算はプチコン頼り。数式の解釈がメイン。デバッグはプチコンで計算し、プログラムの計算と一致すればOKとしてます。


CLEAR
DIM RP$(127),RPA(127),RPW$(127)

LMAX=5
_PAR0=1
_PARC=2
_OPE=3
_NUM=4

@IN
LINPUT ">";I$
IX=0:IE=LEN(I$)-1:B$="":ER=0
RPSP=0:RPWSP=0

@LOOP
C$=MID$(I$,IX,1)
IF C$==" " THEN GOTO @LSKP
ATR=_NUM
IF IX==0 AND C$=="-" THEN GOSUB @NUM
IF (PRE==_PARC OR PRE==_OPE) AND C$=="-" THEN GOSUB @NUM
IF C$>="0" AND C$<="9" THEN GOSUB @NUM
ATR=_PARO
IF C$=")" THEN GOSUB @PARCLOSE
ATR=_PARC
IF C$="(" THEN GOSUB @PAROPEN
ATR=_OPE
IF C$="*" THEN GOSUB @OPE
IF C$="/" THEN GOSUB @OPE
IF C$="^" THEN GOSUB @OPE
IF C$="%" THEN GOSUB @OPE
IF C$="+" THEN GOSUB @OPE
IF C$="-" THEN GOSUB @OPE
@LSKP
IX=IX+1:IF IX<=IE GOTO @LOOP
GOSUB @OPEEND
GOSUB @CALC
?"=";A$
GOTO @IN

@NUM
A$=C$
@NUMLP
C$=MID$(I$,IX+1,1)
IF C$>="0" AND C$<="9" THEN A$=A$+C$:IX=IX+1:GOTO @NUMLP
IF LEN(A$)>LMAX THEN ER=1:?"OVERFLOW ERROR":STOP
IF ER=0 THEN GOSUB @RPPUSH
C$="":PRE=ATR:RETURN

@PAROPEN
A$=C$:GOSUB @RPWPUSH
C$="":PRE=ATR:RETURN

@PARCLOSE
IF RPWSP=0 THEN RETURN
PRE=ATR
GOSUB @RPWPOP
IF A$=="(" THEN RETURN
GOSUB @RPPUSH
IF RPWSP>0 GOTO @PARCLOSE
RETURN

@OPE
IF RPWSP<1 GOTO @OPEPUSH
@OPEPUSHW
A$=C$:GOSUB @RPWPUSH
C$="":PRE=ATR:RETURN

@OPEEND
IF RPWSP==0 THEN RETURN
GOSUB @RPWPOP
GOSUB @RPPUSH
IF RPWSP>0 GOTO @OPEEND
RETURN

@OPEPR
PR=255
IF A$=="^" THEN PR=1
IF A$=="%" THEN PR=2
IF A$=="*" THEN PR=2
IF A$=="/" THEN PR=2
IF A$=="+" THEN PR=3
IF A$=="-" THEN PR=3
RETURN

@CALC
SP=0:RPWSP=0
@CALCLP
A$=RP$(AP):ATR=RPA(SP)
IF ATR==_NUM THEN GOSUB @RPWPUSH:GOTO @CALCSKP
B$=A$
GOSUB @RPWPOP:A2=VAL(A$)
GOSUB @RPWPOP:A1=VAL(A$)
IF B$=="*" THEN A0=A1*A2
IF B$=="/" THEN GOSUB @CALCDIV
IF B$=="^" THEN GOSUB @CALCPOW
IF B$=="%" THEN A0=A1%A2
IF B$=="+" THEN A0=A1+A2
IF B$=="-" THEN A0=A1-A2
A$=STR$(A0):GOSUB @RPWPUSH
@CALCSKP
SP=SP+1
IF SP0 THEN FOR I=1 TO A2:A0=A0*A1:NEXT
RETURN

@RPPUSH
IF RPSP>127 THEN ER=1:?"RP STACK OVERFLOW":STOP
IF ER==0 THEN RP$(RPSP)=A$:RPA(RPSP)=ATR:RPSP=RPSP+1
RETURN

@RPPOP
RPSP=RPSP-1:IF RPSP<0 THEN ER=1:?"RP STACK OVERFLOW":STOP
IF ER==0 THEN RPW$(RPSP)=A$:RPSP=RPSP+1
RETURN

@RPWPUSH
IF PRWSP==127 THEN ER=3:?"ERR:RPW STACK OVERFLOW":STOP
IF ER==0 THEN RPW$(RPWSP)=A$:RPWSP=RPWSP+1
RETURN

@RPWPOP
RPWSP=RPWSP-1:IF RPWSP<0 THEN ER=4:?"ERR:RPWSP -":STOP
IF ER==0 THEN A$=RPW$(RPWSP):
RETURN
ちなみにプログラム名はRPCALC1。その名の通り、逆ポーランド記法(Reverse Polish Notation)を使ってます。おかしいところがあったらすいません。 以下ページを見ながら作りました。非常に分かりやすい説明なので作りやすいのでは。 ところでLINPUTを初めて使いましたが、入力は32桁まででした。これ以上を実現しようとすると、INKEY$/BUTTON/タッチスクリーンとかで自作?

2012/12/1 リストがおかしくなっていたので修正しました

Monday, September 19, 2011

プチコンでカレンダー

3DSはいろいろなソフトが添付されていて、本体だけでいろいろ遊べますが、なぜかカレンダーを見る機能が見あたりません。 なので、プチコンでカレンダーを作ってみます。とりあえず簡単なもので、今月のカレンダーを表示するもの。

リスト
-----
CLEAR:CLS
FOR I=0 TO 6:READ C(I):NEXT
DATA 13,15,15,15,15,15,11
W$="SUMOTUWETHFRSA"
DTREAD(DATE$),Y,M,DT:D=1
IF M<2 THEN Y=Y-1:M=M+12
W=(Y+FLOOR(Y/4)-FLOOR(Y/100)+FLOOR(Y/400)+FLOOR((13*M+8)/5)+7*(4*M+5)+D)%7
A=30+(M-(M>7))%2-2*(M==2)
IF M!=2 GOTO @A
IF Y%4==0 THEN A=29
IF Y%100==0 THEN A=28
IF Y%400==0 THEN A=29
@A
COLOR 15:?Y;"/";M
FOR I=0 TO 6:LOCATE 1+I*3,2
COLOR C(I):?MID$(W$,I*2,2)
NEXT
D=1:FOR I=W TO 42:D$=""
IF D>A GOTO @B
X=1+FLOOR(I%7)*3+(D<=9)
Y=FLOOR(I/7)*2+4:C=C(I%7)
LOCATE X,Y:COLOR C:?D:D=D+1
@B
NEXT
-----
※「W= ... %7」の長い計算式は折り返しなしです。

プログラムの流れ
・システム変数から年月を取得
・月頭の曜日を計算(ツェラーの公式)
・月の末日を計算
・カレンダーをprint

ちゃんとしたプログラムであれば、曜日や月の末日は配列をつかうとおもいます。

Friday, August 5, 2011

プチコンでレインボーシャワーの移植

その昔マイコンベーシックマガジンにMSX用ゲームとして掲載されていた「レインボーシャワー」をプチコンへ移植してみました。

ベーマガの掲載内容を集めているページがありましたので紹介:MSX用 レインボーシャワー ベーマガ投稿プログラム。9801やX68000へも移植されていたようです。

左右キーで画面上の自機を操作。左上の7色の順番でショットを打ちます。下からせりあがってくるブロックに同じ色をぶつけると、周囲3x3マスが消えます。その時同じ色が周囲にあれば、連鎖します。ブロックが自機にぶつかるとゲームオーバー。上キーかSTARTでリプレイ。
連鎖は左から判定しているので、左へ連鎖しやすいです。

MSX版を移植しています。拡大スプライトを含め見た目ソックリになりました。