ジョン!

2018-12-06

はじめに

これは、WORDIAN Advent Calendar 20186日目の記事です。本当に。
ジョン!
これは何の音でしょうか? そう、これはかつてPlayStation 2用ゲームソフトのCMで冒頭に流れていた音です。 PS2現役時代に小学生だった私は、出力される映像の精細さに感動したものでした。 PS2は今となっては過去のものですが、その特殊なハードウェアには当時の先端技術が詰め込まれています。 スマホでもUnityとかOpenGL ESとかが使える現代よりずっと、当時のプログラマは苦労していたはずです。 というわけで今回は、プログラムを書いてPS2で動かしてみようと思います。

PS2向けのプログラムを書く

やっていきましょう。 PS2で自作のプログラムを動かす方法は2通りあり、1つはSonyが公式にリリースしたPS2 Linux Kitを利用する方法、もう1つはPS2 SDKで作ったバイナリをmod済のPS2で動かす方法です。 PS2 Linux Kitは入手性が極めて低いので、現代では全くおすすめできません。 この記事ではPS2 SDKを使うことにします。

PS2 SDKのセットアップ

PS2 SDKには主に、PS2で動作するバイナリをつくるツールチェインと、PS2のハードウェアを抽象化するライブラリが含まれています。 これらはUnixライクなOSで利用できるように整備されていますが、現代の環境へのセットアップは一筋縄ではいきません。 私は頑張りましたが、ふつうの場合はドカドカするとよいです。 ただ、このDockerfileだとportsで入れる必要のあるlibjpegとかlibpngとかzlibとかが入らないっぽいので困りがあります。 まあ適当にやってください。
セットアップに成功すると、古代のGCCを使うことができるようになります。
% ee-gcc -v      
Reading specs from /home/ntsc_j/.local/ps2dev/ee/lib/gcc-lib/ee/3.2.3/specs
Configured with: ../configure --prefix=/home/ntsc_j/.local/ps2dev/ee --target=ee --enable-languages=c,c++ --with-newlib --with-headers=/home/ntsc_j/.local/ps2dev/ee/ee/include --enable-cxx-flags=-G0
Thread model: single
gcc version 3.2.3
      

とにかく動くコードを書く

PS2にはEE, GS, IOP, VU0, VU1などといったプロセッサがありますが、とりあえずメインのCPUであるところのEE (Emotion Engine)と、GPUであるところのGS (Graphics Synthesizer)を扱えればよいものとします。 GSを直接触るのは面倒なので、抽象化ライブラリのgsKitを使います。 gsKitはPS2 SDKに含まれています。
サンプルコードを見ながらがんばって書きましょう。 スプライト機能を適当に使ってみたコードがこちらになります。

書いたプログラムを動かす

エミュレータを使う

たぶんPCSX2を使うといいです。 が、Linuxでamd64の環境だとセットアップが異常にめんどくさいので私は試してません。

PS2実機で実行する

詳しくは述べませんが、2018年現在ではsoftmodを利用するのが最も良い方法といえるでしょう。 これは最後期型以外のすべてのPS2に存在する脆弱性を利用し、改造されたメモリーカードからブートするものです。 ただし、メモリーカードの改造にはmod済のPS2か、PS3用のメモリーカードアダプタ(これも入手困難)が必要になります。 周囲を見渡して、持ってそうな人を捕まえてみると良いでしょう。 詳しくはPSX Sceneとかを参照してください。

PS2Link

PS2LinkはPS2でネットワーク経由のデバッグを行うためのアプリケーションです。 適当にセットアップすると、
ps2client -h <PS2本体のIPアドレス> execee host:test.elf
とかやると手元のELFを実行できるようになるほか、標準入出力もつながるのでデバッグしやすくなります。

とりあえず動かしてみる

はい。

3Dの描画もしたい、けど……

gsKitを使えば3Dの描画も簡単……と思いきや、ここに難しさがあります。 モデルの座標をディスプレイの座標系に変換するため、ふつうはMVP行列を用意して掛け算すると思います。 が、PS2のCPU(EE)はそんなに速くないので、この計算はベクトルユニット(VU)で行うのが普通です。 VUのプログラムはアセンブリで書く必要がありますが、VUは独自のVLIWなアーキテクチャであり、なんだか難しそうです。 本当は立方体をぐるぐる回すぐらいはしたかったのですが、全然間に合わないので今回は諦めます。すいません。

おわりに

この記事読んでも何もわからんな。ガハハ。
PS2で動くプログラムを書くだけでも結構大変なんですが、PS2向けのゲームには美麗なグラフィックを備えた秀逸なものが数多くあります。 当時のプログラマへの敬意が深まりますね。