別にこれをやろうと思ってたわけではないんだけど、そういえばやってなかったな、というのと
DAMの機械でDOOM、DAAMじゃん、とかくだらないことを思いついたのでやってみることにしました。
ここまでのリバエンの成果で、一応画面に何かしら出せることはわかっていました。
しかし、動作している時に割り込んだりしているのでいまいち思い通りにはかけていませんでした。
内部歌詞バックバッファにアクセスできる証拠として歌詞を二重書きして見せようとしたら、内部歌詞行カウンタが自動インクリメントだったため異世界カラオケになってしまった pic.twitter.com/wDsgQgl45K
— ひろみつ (@bakueikozo) 2024年3月8日
そこで、DAMの機械の中の描画関数について調べていきました。
どうやら、CScreenというクラスがあり、そいつが描画関数を持っているらしい、ということはわかったのですが、いまいち挙動がよくわかりません。
あちらこちらにprintfやメモリダンプを埋め込み、調べていた結果、ある程度のまとめを得ました。
うーんなるほど、Create(LayerID,position,size)を呼ぶと、既設のLayerに対してsizeのWindowという名のScreenが作られるのか。GetBufferでアクセスするときはLayerIDに対してのBufferが出てくるので、positionのオフセットでsizeの塗りをしないといけないんだな。ようやく階層がわかった。 pic.twitter.com/fnIvOEl2S1
— ひろみつ (@bakueikozo) 2024年3月23日
システムは以下の描画レイヤを持ち、バッファサイズとカラーフォーマットは以下の通り
0 LAYER_OSD 1280x720 INXDEXED SP8
1 LAYER_LYRIC 1280x2880 RGB32
2 LAYER_SCORE 704x1920 RGB32
3 LAYER_VIDEO 1280x720 RGB32
4 LAYER_TFT_LYRIC 512x2048 TFT_RGB16
5 LAYER_TFT_BACK 512x2048 TFT_RGB16
6 LAYER_SUB_VIDEO 704x480 RGB32
・CScreenインスタンスを作成後、CreateメソッドでLayer IDとposition,sizeを指定すると、その大きさを持つサブウィンドウとして実体化される
・CScreenインスタンスは以下の描画メソッドを持ち、それぞれが作成したサブウィンドウ左上を0とする座標で描画可能。実際には親レイヤを参照し、ウィンドウ内に描画している。
PutCharの中身
・CSpriteというオブジェクトがあって、スプライト描画機能を持っている。
AddしてPutしておくと、スプライトとして保持される
これらを元に、とりあえずLAYER_LYRICレイヤを実体化し、
このバックバッファにDOOMのfb用のバックバッファを転送することで、
↑LyricLayerにバッファ作成し
↓DOOMのバッファからコピーする
このようにDOOMの画面を表示することができました。
やっとDAAM動いた pic.twitter.com/RPCQaoRMNu
— ひろみつ (@bakueikozo) 2024年3月23日
しかし、ピクセル単位での転送なので結構重いね...
LAYER_VIDEOはどうやらデコーダからのDMAで受け取るっぽいのでその辺で何かできないかな?
さてしかし、ここまでやったおかげで描画周りを明確に把握することができましたので、
カラオケ再生中に追加情報を表示するのも割とできたりするような気もしてきましたぞ。