第1弾:WonderSwan用プログラムツール「WonderWitch」
目覚めよホビープログラマ! [第2回]
●ソフトウエアアーキテクチャ
さて、話はさらに深いところへと続く。WonderSwanのソフトウエアアーキテクチャについてだ。
ソフトウエアアーキテクチャはI/Oを制御するFreyaBIOS、その上にFreyaOS、IL(インダイレクトライブラリ)などのライブラリ群、その上にアプリケーションプログラム、という構造になっている。ILというのは、各プログラムから共通に呼び出すことのできる動的なライブラリで、WindowsのDLLに相当するものと思えばいいだろう。
標準でILライブラリがいくつかCD-ROMに収められているので、もし、この標準ILを使ったプログラムを使用する場合、ユーザーはアプリケーションとILの両方をWonderSwanに転送しておく必要がある(ただし、WonderSwanのファイルシステム上にあれば、アプリケーションは勝手にILを探し出して使用してくれるので、アプリケーション側から特に呼び出しなどが必要になることはない)。
ユーザーが作ることのできるのは、このユーザーアプリケーションの部分と、IL。ユーザーアプリケーションからアクセスできるのはBIOSコールとILの定義するAPIということになる。その下のOS層は、I/Oポートやビデオメモリのアドレスなどが公開されていないのでハードウエアを叩くことはできない(保護しているわけではないので、特権モードなどにならずとも触ることは可能なはずだが……)。
BIOSコールが「ソフトウエア割り込み」という形を取っているため、多少オーバーヘッドが大きくなるが、残念ながらそれをまぬがれることはできない。
ちなみに、このFreyaOSには「Meg」というユーザーインターフェイスが添付されており、ユーザープログラムの転送などWonderSwan側からの操作はこのMegで行なうのだが、このMegもFreyaOSのILのひとつで、ユーザーがこのMegの代わりのシェルを作って使用することも可能となっている。
なお、WonderWitchのマニュアルにはBIOSコールはレジスタ名と関数名が定義されているだけでCからの呼び出し方については書かれていない。Cプログラミングする場合はヘッダファイルを直接見て使用方法を確認することになる(とはいえ、せいぜいx,y座標がBIOSコールだとAXレジスタ=x*$100+yだったのが、int x,int yに変わるくらいで、ほぼパラメータの並びや個数は同じで、慣れれば検索する必要もなくなるのだが)。
CD-ROMに収録されているPC側の転送プログラム「TransMagic」 | WonderWitch専用カートリッジを立ち上げ、通信モードにしたところ。この状態でプログラムの転送を行なう |
●ふた昔前のゲーム機に似た画面周りハードウエア
さて、つづいてはハードウエア周りの解説に移ろう。WonderSwanの画面解像度は224×144ドット、白黒16階調だ。ただし、ハードウエアの都合により画面に実際に表示できる階調は16階調のうちの8階調分のみとなっている。つまり、アーキテクチャ的にはふた昔くらい前のゲーム機によく似た構造となっている。
画面は、バックグラウンド用の2スクリーンとプラススプライトという構成で、これの合成されたものが画面表示出力となる。
スクリーンはいわゆる、X68000などで言う「BG」などと同じで、8×8ドットのキャラクターを敷き詰めることで背景の表現を受け持つ。当然、表示できる座標は8ドット単位ということになる。
これに対して、好きな座標キャラクタを置いて、ゲーム中のキャラクタ表示などに使われるのがスプライトだ。スプライトも大きさは1つで8×8ドット、最大128個まで定義して画面上に表示することができる(ただし、同一水平線上には最大32個までしか表示されない)。もちろん、設定によってどのプレーン(スクリーン、スプライト)を使用するのか、あるいはどのような優先順位にするのかも設定可能だ。
これらをユーザープログラムから利用するにはBIOSコールを使うことになる。Freya BIOSでは、スクリーンへの文字列出力、スクリーン設定や、スプライトの表示などのファンクションが一通り揃っていて、割と簡単に制御することができる。たとえば、単に文字列を表示したいのであれば、 text_put_string(0,0,"Press Any Key to Exit!"); と設定することでスクリーンへの文字列の表示が行なわれる。
あるいは、ゲームのようなキャラクタを表示するには以下の手順で行なう。
キャラクタパターンはWindowsビットマップファイルからのコンバーターがあるので、これを使ってデータを作るのが楽だ。このプログラムは、8×8ドット単位の大きさのWindows 256色ビットマップファイル(ただし、使用色数は4色であること)を白黒灰色透過色、もしくは白黒4階調のキャラクタデータに変換することができる。変換したデータはリソースファイルとして持つか、あるいはソースコード中に直接ハードコートするためのファイルを作ることも可能だ。
とりあえず、ここではソースコード中に直接ハードコートするためのリストを出力させてみよう。すると、以下のようなファイルができる。
/*ボールのパターン*/ #define ball16_width 2 #define ball16_height 2
static unsigned short bmp_ball16[] = { |
ちなみに、これは16×16ドットの大きさのBMPファイルが、カラーキャラクタ2×2個分のデータに変換されたデータなのだが、このリストをアプリケーションの本体プログラムなり、ヘッダファイルなりにコピーし font_set_colordata(128, 1, bmp_checker); (キャラクタ定義)とすればキャラクタが作成できるので、ここで作ったキャラクタは、スクリーンには screen_fill_char(); などで画面に配置できるし、また、 sprite_set_char(0,128); でキャラクタ番号128の定義内容をスプライト0番に定義し、 sprite_set_range(0,1); でそのスプライトの画面への表示を許可して、 sprite_set_location(0,0,0); で座標(0,0)にスプライト0番を表示することもできる。
ちなみに、わずか3.07Mhzという非力なWonderSwanだが、このようなアーキテクチャを採用しているために、画面表示はなかなか快適である。X68000、FM-TOWNSでのプログラミング経験がある方はわかると思うが、BG、スプライト構造のビデオアーキテクチャではキャラクタの移動などをする際に画面の重ねあわせなどを一切考慮する必要がないからだ。このワンダーウイッチでも、たとえば、先に座標(0,0)に表示されていたスプライト0番を他の座標、たとえば(52,40)に表示したいときは、再び sprite_set_location() 関数を使って sprite_set_location(0,52,40); と一命令で済む。
ボールがポンポン飛び交うサンプルプログラム |
先ほどの16×16ドットのサンプルデータを使って一度にいくつものオブジェクトを動かすサンプルプログラムを作ってみたが、ストレスなく複数の物体を移動させることができる。もし、WonderWitchプログラムをダウンロードできる環境にある方は、ダウンロードして実行し、スプライトの威力(の一部)を体験してみてほしい。
●4声サンプリングボイスが使えるサウンド機能
手のひらに乗るような小さなサイズのハードウエアだが、一昔前(PC-98、TOWNS、X68000と言ったあたり)のパソコンのハードウエアを知る人からすると、グラフィック周り以上に感嘆せざるを得ないのが、WonderSwanのサウンド機能だ。
WonderSwanでは、4チャネル構成のPCM音源ユニットが搭載されていて、登録された16レベル×32ステップの波形データと周波数、それにボリュームを掛け合わせて音を発生させることができる。WonderSwanにはスピーカーはひとつしかないのでモノラル音声だが、音源自体はステレオ音源となっていて、別売りのヘッドフォン付きアダプタを接続すればステレオで出力できる。また、チャンネルひとつひとつには基本となる機能の他に、それぞれのチャネルにサンプリングデータをそのまま再生するボイスモードや、スイープ、ノイズなどの付加機能がつけられていて、特殊効果などに使うことも可能だ。わずか4,000円弱の手のひら機械にこれだけの機能搭載されているとは驚かされる。
これらの音源機能もBIOS、SoundIL2つの方法でのアクセスがサポートされていて、簡単な制御プログラムなら数行で書けてしまうのだ。直接サウンド機能のI/Oに近い部分を触ることができるのが、BIOSコールのほうで、たとえば、こちらを使用する場合は、16レベル(4ビット)×32ステップPCM波形データを、16バイトのデータでチャンネルに登録する。これは要するにある時間を32分割した単位で、それぞれの時間でのボリュームを4ビットで表して、2単位ごとに1バイトで表したテーブルだ。ちなみにマニュアルにも記述されているが、サイン波だったら以下のように記述することになる。
/*サイン波パターン*/ static unsigned char wav[]={ 0xa8,0xdc,0xee,0xde,0xbc,0x9a,0x89, 0x67,0x56,0x34,0x12,0x01,0x11,0x32,0x75 }; |
上記のような感じでダダダダダっと音を出すために、ボリュームオンオフを繰り返すのであれば、矩形パターンで以下のように記述すればよい。
/*矩形波パターン*/ static unsigned char wav[]={ 0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; |
あとは、サウンド周りの初期化(サウンドBIOSの初期化、チャネルのモード設定)などを行なった後、このデータを sound_set_wave(0,wav); (チャネル0と波形データを結び付ける)で使いたい音声チャネルを付けてから、以下のように記述する。
sound_set_pitch(0, 430); sound_set_volume(0, ff); |
そして、周波数、ボリュームをチャネルに指定してやれば、WonderSwanから音を出すことができる。
parse_mml(_heap,"CDEFG",0); bgm_play(_heap,PLAY_LOOP); |
これだけでWonderSwanで「ドレミファ」の演奏ができてしまうのだ。
●手探りだけど、その他拡張機器も……
WonderSwanには、RS-232Cと信号互換なEXTコネクタ端子がついている。WonderWitchではPCへの接続ケーブルを接続している部分だ。WonderSwanではEXTコネクタ端子を使い、WonderSwan同士を接続する「通信ケーブル」、プレイステーションなどと赤外線を使って通信する「ワンダーウェーブ」、それにNTT DoCoMoの携帯電話と連携できる「モバイルワンダーゲート」なども接続できるのだが、このEXTポートもWonderSwanからは単なるシリアルポートに見える。WonderSwan接続ケーブルを除いて、通信方法などに関しては仕様が公開されていないので、手探り状態となってしまうが、基本的にデータの読み書き自体はWonderWitchで作ったプログラムでできる。
ちなみに、BIOSコールのcomm_open(),comm_send_char(),comm_receive_char(),comm_close()で1バイトデータの読み書きができる。現在、これを利用して、バンダイ未公認のオプションとしては市販のGPSとの通信に成功した例などがあるようだ。
項目 | 仕様 |
---|---|
プロトコル(データリンク下層) | 調歩同期、全2重通信 |
ボーレート | 9,600bps/38,400bps切り替え |
データビット長 | 8ビット固定パリティー無し |
送信ストップビット長 | 1ビット |
送信バッファ | なし |
受信バッファ | 1段 |
エラー検出 | 受信オーバーラン |
モデム制御信号 | なし |
最後に、このWonderWitchというプログラミングツールは必ずしも万人に向けでないことはこの記事を読まれた方ならわかったかもしれない。今のところWonderWitchには、“BASIC”や“なんとかWizard”のように手軽にプログラムを組むための支援はほとんどない。今のWindowsを中心としたいたれりつくせりのソフトウエア開発環境と違って、基本的に、WonderWitchが提供するのは、WonderSwanというハードをコントロールするための最低限の橋渡し部分のみ。機械をいかに操るかの算段は自分でしなければならないのだ。
だが、だからこそこのツールには自由がある。「WonderSwanにこんなソフトがあればなぁ」と思うことは、このキットと努力と根性さえあれば、ほぼすべてのことができると言ってもいい。必ずしも万人向けの製品ではないが、この強力さをなにより魅力に思うアマチュアプログラマは多いことだろう。
WonderWitchを買うユーザーは、WonderWitchというツールと同時に可能性と夢を買うことができる。最近、売られているソフトウエア開発環境にはないものを与えてくれる、1本だと言っていいだろう。
□バンダイのホームページ
http://www.bandai.co.jp/
□Quteのホームページ
http://www.qute.co.jp/
□WonderSwanのホームページ
http://www.swan.channel.or.jp/
□WonderWitchのホームページ
http://www.swan.channel.or.jp/wonderwitch/index.html
□WonderWitchのサポートページ
(ダウンロードコーナーなどはユーザー登録をしなければ利用できない)
http://wonderwitch.qute.co.jp/
(2000年8月7日)
[Text by 大和哲]