Legacy at Petitcom mkII part.3

PC作れるようにしたり、シート見られるようにしたり、レベルエディタを作りかけていたり。

pmkii_WIP0.jpg

うーん。

pmkii_WIP1.jpg

まだゲームらしい要素は何もなく、下地を作っているにも関わらずコード量が肥大化しているのが懸念事項か。1プログラムあたりの最大行数9999行の既に1/3近くを使ってしまっている。コード以外のデータは極力コード外に追い出すようにしないと間違いなく不足はするだろう。出来るならば、極力スクリプトエンジン化してしまってゲーム進行は全部コード外にしてしまいたいところだが。
あと、マジックナンバーを減らすためにenumのような変数を定義しまくっているのだが、これも結構洒落にならない行数を食っているのでなんとかしたい。その辺のconstantな変数や配列を宣言しまくって初期化したプログラムを分けておいて最初にロード、次に本体プログラムはCLEARせずにロード、とかをやれば比較的まともに解決できそうだが、その辺の切羽詰まったやり方は最大行数に到達したら考えよう。

また、今の段階で既にコードの可読性がやばそうだったので一旦整理。
ラベル分布リストをPC上に作成する(出来れば変数もやりたいのだが、更新が面倒なのでパス)。
検索移動用のラベルを埋め込む。似た処理や続いて呼ばれるサブルーチンの配置をまとめる。更新頻度の低いサブルーチンは下の方に配置する。
変数やラベルの命名規則をガチガチに固めてしまう。グローバルに触られる変数にはprefixをつける。いわゆるローカル変数(呼び出し元や呼び出し先で弄られても影響がない変数)にはアンダースコアをつける。などなど。
プチコンではコピペが1行ずつしかできないので、一旦PC上で作業した方が良いですね。

さて、ぼちぼちと戦闘周りにとりかかっているが、ちょっとエンカウント処理を作ってみて、毎回起動の度にPCを作らんと駄目なのが面倒すぎるなということで、戦闘よりも先にセーブ/ロード周りを作らないと駄目そう。
プチコンのセーブメモリーのMEM$は255文字までなので、PC情報*PC人数+システム情報を詰めなければならないことを考慮すると、ビット単位で詰めていったとしても入りきるかどうかはかなり怪しい。
GRP領域をメモリとして割り当ててしまえば、かなりの量が確保できるが、余計に書き込み読み出しを作る必要があるのと、最終的に利用するセーブデータ量が未だ不明なので、分割して保存することを考える。MEM$なりGRP1個に収まるのならば、後でくっつけてしまえばいいわけで。
LOADは確認ダイアログを省略できるが、SAVEは確認ダイアログが必ず出るので、ダイアログ出まくりでうぜえということになるかどうかは要検証。
やるつもりはないけれど、PCロスト即セーブというのもダイアログが出るので無理なのよね。

Legacy at Petitcom mkII part.2

え、続けるの?
がっつりと時間が確保できるわけではないのでぼちぼちと。進捗報告的な。

Petitcomkii_WIP.jpg

一人称視点の描き換えのちらつきと遅さは結構解消されて、10フレーム前後でちらつきも無しに。なんとかなりそう。
ただやはり、描き換えるタイルを減らそうと、差分のみ描き換えしようとしたりすると、比較が増えてかえって重たくなるのは変わらないようで。
奥から順に上書きしていっているのを、手前から描くように変更してして稼ぐやり方も、同様の理由から厳しい。これがうまくいくと、もっと軽くなる見込みだし、時折遮蔽されている奥のものが微妙にはみ出していたりするのが防げるのだが。これを諦めて、はみ出ないような絵素材にするしかないのかね。

テスト用の小規模なレベルもなんなので、どこかで見たことがあるようなレベルをちくちくと打ち込んだり。専用のレベルエディタが無いとしんどいことが分かったので、これまた作る必要がありそう。
オートマッピングは多分無しな気がする。
レベルの大きさは通行したかどうかを記録するのならば16×16が効率的で良さそう?

さっさとPCまわりを作ってみたいのだが、それにはまずテキストボックスを作らないと、ということで、チマチマと作る。
文字は横に32文字(枠で2文字分減るので実際は30文字)しかないので、定番のPC一覧表示も情報を切り詰めないと厳しそうだ。
重ねても破綻しないようにしたり、自動改行とか自動サイズ調整など。禁則処理は後回し。選択決定したりする部分も、なるべく汎用的に使い回せるように書いてみる。出来ればタッチ操作でやってしまいたいところだが、面倒なのはもとより、文字サイズが8×8しかないので押しにくかろうということで見送り気味。
ううむ、先は長い。

それはそうと、文字数取得でL=LEN(LINE$(IDX))とかやっていると、時々syntax errorとなるのは何でだろう。全く同じコードで全く同じ文字列を渡しているのに。プチコンmkII本体の未初期化なニオイがする。

Legacy at Petitcom mkII

グラフィック機能に関しては先のあれで大体触ったので、スプライトとBGも触る。

スプライトは、スプライトという言葉が形骸化して、ただの2Dを示すようになって以降の方が馴染みがあるので使い勝手に関してはなんともかんとも。メモリにゴリゴリと色を書き込んでいる感覚のある、グラフィック機能の方が好きかな。
サンプルなどでは固定値でN個確保してやっているのですが、これをフレキシブルに管理してみたいので、生成・破棄関数作って空きスプライトの番号を探してとるとかいうマネージメントをやってみたりするも、100個の使用状況を舐めて比較したあたりで処理落ちしだしたのであえなく終了。必要最小限に小分けするべし。
スプライト100個全部出し切って、無茶できるようになってほしいものです。

 

PetitcommkII_FPValpha.jpg

BGは、BGだけでFPVが表現できるのかなと試す。
これは全部プリセットを使っていますが、自分でキャラとパレットの定義をしないと駄目ですね。洋ゲー臭いドットと色遣いにしたいところです。ドット打てませんが。
BGは8×8単位なので、場所によっては斜めの壁と正面の壁の繋ぎ目がどうしてもずれたりするので、ちゃんと不自然に見えないようにLODを作らないと駄目なようです。
あとBGは変に工夫するよりも、そのまま出してしまう方がかえって高速なのが曲者な気がします。高速とはいっても、流石にこれだけの書き換えはすぐには終わらず、書き換えるタイミングで見えてはいけない部分が見えてしまうので、レベルの構造がばれて台無しに。かといって、一旦バッファに番号を書きだして差分だけを書き換えるとかもやってみたのですが、比較処理が増えてかなり重たくなってしまうという。
画面全部を使ったこの手のゲームがあの時代になかったように、描画サイズをこれ以上に小さくしていまえば楽ですが、それは最終手段ということで高速化の研究が必要なようです。画面サイズの倍以上BGの描画領域があるので、この余白を使わない手は無いといったところでしょうか。

しかしながら、この手の古い表現は失われていってるので、新規でアルゴリズムを考えるのに等しいのでなかなか大変ですね。今ならポリゴン置くだけで正確に描画できるし。サンプルでもラインで描画しているものがありますが、なかなか力業でやってるんだなあと。

ちなみに私はこの手の超古典的なRPGはかじった程度で碌にやったことはないので、このまま投げ出さずに出来上がっていくとどんなものができるのか、色んな意味でちょっと楽しみです(妄想しながら)。

A Cube in Petitcom mkII

以前プチコンで作ったやつですが、プチコンmkIIでQRコードが扱える使えるようになったので公開してしまいましょう。1枚ならともかく、複数枚の場合はどういう形式で公開するのがいいんでしょうかね。

 

これは何?

  • 立方体をリアルタイムで3Dレンダリングします。レイトレースではないです。
  • 特に高速化の工夫をしているわけでもなく、馬鹿正直に透視変換からラスタライズまでをやっているだけです。
  • 基本的にプチコンのコードですが、ところどころmkIIのコードに置き換えたり、拡張したりしています。
  • 重いです。GPUの偉大さを身に染みましょう。

 

操作方法
※処理が重すぎる所為かボタンの押された瞬間がBUTTON関数で殆ど取れないので、押下で取得しています。そのため、連続して切り替わる可能性があります。

  • 十字キーとL,R:XYZ各軸の回転
  • A:ソリッド/ワイヤーフレーム描画切り替え
  • B:ダブルバッファリングのON/OFF
  • X:カリングのON/OFF
  • Y:シェーディングのON/OFF
  • START:終了

 

cube_qr0.png

1/6

cube_qr1.png

2/6

cube_qr2.png

3/6

cube_qr3.png

4/6

cube_qr4.png

5/6

cube_qr5.png

6/6

 

Petitcom in 3DS

ランバートでシェーディングしたキューブ1個で4FPS程度か。ワイヤーフレームなら20から30FPS程度は出るが、ダブルバッファリングなんぞは無理なので、容赦なくちらつく。ワイヤーフレームは線引き関数で一発だが、ポリゴン面のラスタライズは自前でチマチマやるしか。

petitrenderer.jpg

“あわよくば”、これでdemoでも作ってみるかなと、ここ数日書いてみて、プチコンでリアルタイムレンダリングさせてみたが、重すぎる。当初の目標ではper pixelシェーディングで色々やってみたかったが、これ以上重くなるとリアルタイムとは呼べなくなりそうだ。
DSiよりもパワーのある3DSだとより高速になっているのかと思ったが、そうでもなかったようで。多分同じ速さで動作しているのかね。リミッタ外せないのかな。

ハードウェアの支援など何一つ無い、低速なグラフィックへの読み書きなので、oldschoolな2Dのdemoも結構厳しいのではないだろうか。スプライトもサターン並みに変形出来れば、利用出来たのだろうけれど、このソフトはそういうコンセプトではない。

重い以外にも相当制約が厳しい。
数は固定小数点のみで、精度も余裕が無くカリングがうまくいかないケースがあるし、内積などで最大最小値を超えるとオーバーフローで止まる。
グラフィックは色が256色しか扱えないので、使う色を限定してさらに間引かないと多色を扱うことすら困難。
試しに深度マップ用意しようと愚直に256*192で配列を取ったら配列の限界数を超えるし、メモリも不足する。深度マップに関しては256色ながらも下画面のバッファを活用すれば裏技的に実現できそうだが、色の読み出しが大変重そうである。Zソートしか現実的ではないかな。

さらにBASICがクセモノというか、私はベーマガ世代でもなんでもないが、昔の人はよくこんな言語使って組んでたなと関心するほどに扱いにくい。非効率的すぎる言語だ。
スコープという概念というかローカル変数なんぞ無く、漢らしく全部がグローバル変数。サブルーチン先で値(特にFOR文のカウンタ)を上書きしてぶっ壊してえらいこっちゃ。
サブルーチンに渡せる引数も無いので、仕方がなく引数用の汎用的な変数を用意してそこに値をぶち込むのだが(これも変に値を上書きして壊さないように注意しながら)、行列1個で16回のコピーが発生するのがなかなか馬鹿にならないコストだと思うし、コピーする処理を毎回書くのが面倒である。

アドレスも扱えないし、個人的にはアセンブラの方がまだマシかね。

まあ、こんな馬鹿みたいなことをやろうとしなければ、良い言語だとは思わないけれど、良いソフトだと思う。タッチパネルの仕様の所為か、結構な頻度で押した場所と違う場所が押されてしまい、変な文字が入力されて嫌なことになるのが気になるけれど。

(追記)mkIIが出たので、QRコード公開してます