PS2Linuxでプレイステーション2プログラミングをしよう(後編)

 PS2 Linux Kitは家庭用ゲーム機「プレイステーション2」上で、動作するLinuxですが、通常のLinuxディストリビューション同様、ライブラリやコンパイラなど開発環境が用意され、プレイステーション2ならではのプログラミングの世界が待っています。その第一歩のために、ケータイWatchでおなじみの大和 哲氏によるプログラミング入門を前後編で掲載します。(編集部)


■プログラミング作りの環境を作る

 PS2Linuxでのプログラミングは、Users Manualなどを見る限りアセンブラレベルでもできるようだが、サンプルプログラムやライブラリの整備状況を見る限り、gccを使って、cで書くのが普通なのだろう。

 libps2のサンプルを見る限りでは、main.cをメインプログラムとして、Makefileを用意して、makeでmainという実行ファイルを作り、

./main

 でプログラムを実行するスタイルのようだ。この記事でも作るプログラムは基本的にこの形を踏襲する。

なお、gccのオプションの内容などを知りたい場合は、「GNUコンパイラ集(GCC)の使いからと移植について」( http://www.sra.co.jp/wingnut/gcc/gcc-j.html )を参照するといいだろう。

PS2Linuxを使って迷ったら、たとえばGNU CコンパイラやLinux全般の知識ということであれば、PS2Linux関連サイトだけでなくほかの専門サイトを探してみるのも手だ。PS2Linuxは比較的素直なLinuxそのものなので、共通の知識も多い

 さて、プログラミングの環境だ。

 基本的には、PS2Linuxには、プログラミングのための環境は一通りそろっている。

 もし、プレイステーション2を単体で使っているのであれば、テキストエディタにはvim(vi)、コンパイラはgcc、デバッガにはgdbが使える。

 英文のテキストだけでプログラムを書き、サンプルプログラムを改造してコンパイルするだけなら現状の環境だけでも問題はでないはずだ。

 ただ、そのままでは、あまり楽な環境とは言えないだろう。たとえば、libps2の各ディレクトリにはGSやVUを使ったライブラリの関数に関する解説などがあり(日本語で書かれたファイルもある)それを見ることはプログラミングに有用なのだが、PS2Linuxそのままではこの辺の設定を読むのも厳しい。

 たとえば、テキストファイルを見るためにはlinuxには普通、lessというプログラムがあるのだが、PS2Linuxでは環境設定が全然されていないためlessが日本語のテキストを見ようとすると「バイナリファイルですがよろしいですか?」というようなメッセージを出してしまう。「LESSCHARSET=japanese-euc」というような環境変数を1つセットすればいいだけの話なのだが、ほかにもvimの設定もあったりと、この手の設定がいろいろな状況で出てきてしまうのだ。

 もし、Windowsなど慣れている環境があれば、telnet、ftpなどを使えるように設定して編集やサンプルテキストの参照などはWindowsで行ない、ftpでファイルを転送してコンパイルと実際のプログラムの実行だけPS2で行なう、というようにするのも1つの手だろう。

 塩田氏のPS2Linuxレポート(環境整備、デモプログラムのテスト編 http://pc.watch.impress.co.jp/docs/article/20010725/PS2Linux.htm )にtelnetの利用方法が書かれているが、同様に/etc/inetd.conf内で、

#ftp stream tcp nowait root /usr/sbin/tcpd in.ftpd -l -a

という行があるので、この先頭にある#記号を削除するとFTPを利用することができるようになる。

ftpを有効にする方法。telnetと同様に/etc/inetd.confでコメントを外して再起動するだけの話。ただ、環境によってはftpがもたつくこともあるそうなので、余裕があるならWindowsとファイル共有できるsambaなどを設定した方が楽かもしれない

 実は、筆者も今回はマニュアルPDFファイル、ライブラリの説明テキストファイルの参照、プログラムの編集はWindows上で行ない、telnetを使ってコンパイル、実際のプログラムの起動だけをPS2のコンソールで行なった。


■プログラミングリストを見よう

 PS2Linuxには、プレイステーション2の機能を使ったサンプルプログラムがいくつか用意されている。低レベルライブラリlibps2のサンプルで「basic3d」、「vu1/blow」などがそうだ。画面に3Dの物体を表示するデモや、塩田紳二氏のPS2Linuxレポートにもあるようにパーティクルのデモなど、さすがと思わせるようなプレイステーション2の機能を使ったデモだ。

 これを見ると、プレイステーション2らしさといえば、何はともあれGraphics Sythesizerを使わなくては、という気になってくる。

 そこで、まずははじめてのPS2プログラミングとしてGSを使って画面表示をする、第1歩のプログラムを作ってみよう。

 もし、プログラミングに自信がある(特に3Dグラフィックスとプレイステーション2に関するある程度の前提知識があるのならば)ならば「Core3D」のプログラムをざっと眺めてみると、なんとなくプレイステーション2プログラミングの感触がつかめるかもしれない。

 あるいは、GSということであれば、インターネット上にもいくつかごくごく簡単なサンプルプログラムもあるようなのでこちらをダウンロードして眺めてみるとさらに理解が早いかもしれない。

 たとえば筆者の知っているところだと、天野研究所による「PS2プログラミング」に「シンプルに3角形を描いてみる」( http://homepage2.nifty.com/MagicBoxSoft/ps2programing.htm )などがある。

天野研究所。PS2Linux用のかなりシンプルなサンプルプログラムがいくつかある。PS2Linuxに添付のサンプルが複雑で過ぎて読みにくい、という人はまずはこのあたりの簡単なプログラムを読んで見るのもステップとしてはいいだろう


■GSを使うプログラミングの方針

 このサンプルで使われている低レベルライブラリはGraphicsSynthesizerに渡されるコマンドについての理解がないと扱うのは難しい。これらのサンプルプログラムと、「GS User's Manual」を見て、GSにできることと、GSを使ったプログラミングの基本を見てみよう。

 まず、GSはEEからの命令を受けてさまざまな画像をディスプレイ上に表示する。

 このどのような形の物体を画面に描くか、その要素の1つを「プリミティブ」と呼んでいる。プレイステーション2で画面に表示している3D画像はこのプリミティブが集まってできたものだ。

 PS2Linux添付の「GS User's Manual」だと、プリミティブに関する解説は41ページからの「GSプリミティブ」にある。

 それによると、GSでは「点」「線」「連続線」「三角形」「連続三角形」「扇形連続三角形」「長方形」の7種類のプリミティブを描くことができる。

GS User's Manualに掲載されている、GSで描くことのできる7種類のプリミティブ

 また、これらのプリミティブは「シェーディング」、「テクスチャマッピング」、「フォグ」、「アルファブレンディング」、「アンチエイリアシング」、「テクスチャ」などを設定することができる。

 たとえば、シェーディング方法では、フラットシェーディングでは一枚のプリミティブは単色になってしまうが、グーローシェーディングを利用すると頂点の間で滑らかに色を変えることができる。テクスチャマッピングを利用すればプリミティブに、好きなイメージを貼りつけることも可能だ。

 GS User's Manualを読みすすめていこう。

 GSを利用する場合「描画手順」と呼ばれるデータをまず用意しておき、それをGSに転送することで、GSに描画をさせることになる。このデータは一般的な形として

1)PRIMレジスタ・GSプリミティブの種類と描画属性の設定
2)頂点情報レジスタ群・頂点情報の設定
3)頂点キック
4)ZXYF2レジスタ・描画の開始

 などがある。たとえば、三角形を画面に描く場合、「Triangleの描画手順」に書かれているが、最初にPRIMレジスタにプリミティブの種類であるPS2_GS_PRIM_PRIM_TRIANGLE、それから頂点1、2、3をそれぞれ、色情報・頂点座標の順番で並べておく。

 これで画面に三角形を書くために、GSに渡すデータはできたわけだ。

 これをGSに転送し、画面をフリップしながらこのデータを描かせれば画面表示ができることになる。

GS User's Manualに記載されている、Triangleの描画手順。PRIMに続いて頂点のデータが並んでいるだけで、こうしてみると割と簡単だ

 それから、プログラム全体をつかさどるEEコアにとって、しなければならないことを考えよう。

 EEコアからみて、まず必要な作業はGSの初期化がある。コンソールをグラフィックモードに設定する(ps2_gs_vc_graphicsmode())、GSの初期化をする(ps2_gs_reset())、などの作業だ。

 ちなみに、ps2_gs_resetの値を変えるとPC用のVESAディスプレイではなく、NTSCの通常の家庭用TVに画像を出力するような設定にすることも可能だ。

 それから、1つしなければならないのは「画面のロック」である。

 LinuxやWindowsでは複数のタスクが同時に動くので、同時に画面を書き換えようとする可能性もある。そのようなことが起きないように画面を描くには

「画面を占有を始める(ロックする)」
		↓
「描画する」
		↓
「占有を解放する(アンロックする)」

という順序をとる必要がある。ロックはps2_gs_vc_lock()、アンロックはps2_gs_vc_unlock()で行なう。

 ps2_gs_vc_lock()、ps2_gs_vc_unlock()の間で画面描画を行なわせるために、先ほど作ったGS描画手順データをGSに転送する。転送はDMA転送を利用する。bufferにデータが入っているとすると

ps2_dma_start( g_fd_gs, NULL, (ps2_dmatag *)buffer );

のように行なう。 あるいは、GSへのプリミティブの転送専用の命令もあって、

ps2_gs_put_drawenv( &prim.giftag );

こちらを使ってもOKだ。


■はじめてのGSプログラミング

 ということで、サンプルプログラムを作ってみた。

 プレイステーション2でのポリゴン描画の第1歩ということで、libps2devを利用して三角形を1つだけ表示するプログラムだ。200行弱のショートプログラムである。

 画面上にグーローシェーディングされた三角形を表示し、コントローラの動きに応じて変形させる。x、y座標のみ使っていて、アルファブレンディングなどは使っていない。パッドのSELECTボタンを押すとプログラムを終了する。

 コントローラのチェックは、

paddata = sjoy_get_ps2_button(0);

で行なって、十字キーで頂点を移動。セレクトボタンが押されたことを検知するとメインループを脱出して終了だ。

メインループは以下のような構造になっている。

while(1){
	ps2_gs_vc_lock()で画面をロック

	paddataにsjoy_get_ps2_button()でコントローラの値を入れる
	if ( paddataがSELECTボタンなら ) { break; }

	padadtaによって頂点のx,yを変更

	GS描画手順を設定
	頂点0,1,2をセット

	ps2_gs_put_drawenv()でGSに描画手順を転送;

	ps2_gs_vc_unlock()で画面をアンロック
}

 GSにプリミティブのデータを送って描画させる部分は先に説明したそのままのことをしている。

 実際にこのプログラムを利用するには、ファイル「tritest1.lzh」をダウンロードして、PS2Linuxのコンソール上からコマンドライン上で

>lha x test1.lzh

として展開してほしい(LHAは標準でインストールされている)。ほかのPS2Linuxのサンプルプログラム同様、ここで解説しているプログラム本体はmain.cだ。 既にMakefileが作られているので

>make

とすることでプログラムをコンパイルできる。

 さて、これでまずはGSを使って描画をすることができた。

 しかし、なんといっても、プレイステーション2らしいプログラムといえば3Dらしい描画、それにハードウェアで言えばベクトル演算ユニットなども使ってみたい、ということもあるだろう。

 来月は、この辺も使ってもう少しプレイステーション2らしいプログラムの作り方をご紹介する予定だ。

【追記】
 前編でのPS2のハードウェア構成について、読者の方からご指摘とご教示をいただきました。訂正させていただくとともに、ご指摘に感謝いたします。

□参考サイト
天野研究所
http://homepage2.nifty.com/MagicBoxSoft/
- PS2 Linux Developer -
http://www.mirai.ne.jp/~kagii/ps2/
PSLinux(銀杏座β)
http://www.anakureon.com/pslinux/

(2001年8月22日)

[Reported by 大和 哲]


【PC Watchホームページ】


ウォッチ編集部内PC Watch担当 pc-watch-info@impress.co.jp

Copyright (c) 2001 impress corporation All rights reserved.