マイコン工作実験日記

Microcontroller を用いての工作、実験記録

A2DP sink機能の追加

2024-06-25 20:02:32 | DoomPlayer

Nucleo-U575ZIのDoomPlayerは、随分前にフラッシュの使用量が1MBを超え、内蔵SRAMの使用量もすでに90%を超えているのですが、なんとかA2DP sink機能を追加したいと思い作業中です。この機能によりスマホで再生した楽曲ファイルやストリームをDoomPlayerで再生することができます。基本的にBTStackのa2dp_sink_demoを使用しているのですが、昨年試したAVRCP Cover Art 機能は盛り込まない方向です。理由はSTM32U575にはハードウェアでのJPEGデコード機能が無いのと、SRAMの容量やMCUの処理速度的にもキツそうなため。

A2DP sinkとして動かす場合には、上の写真に示したようにSDカードを抜いた状態で起動することで、動作モードを切り替えることとしました。

楽曲のタイトルやアーティスト名を普通に表示しているぶんには問題ないのですが、この文字列が長くなり水平スクロールしながら表示する必要が生じた場合に、表示処理の負荷が高くなりスペクトラム効果表示の更新が遅くなったり、タッチパネル操作の反応が悪くなったりという現象が発生してしまいます。使用するフォントとサイズを小さくすることで少しは改善できたのですが、それにも限りが。。。


チート・コード

2024-06-06 12:33:24 | DoomPlayer

DOOMにはチートコード(Cheat Codes)という機能があります。キーボードからidで始まるおまじない文字列を入力することで、体力を回復したりするズルが行える機能です。DoomPlayerでは、キーボードをつなげなくても上記の画像に示したようにLCDのタッチパネルに表示されたメニューや仮想キーボードから入力することが可能です。

この表示は、DOOMの画面表示の上にlvglで作成したGUI画面を重ね合わせて表示することで実現されています。STM32H7B3I-DKのようLTDCをサポートするデバイスであり十分なDRAMを搭載するボードの場合には、それぞれの画面を独立した2つのレイヤに割り当て、それらをLTDCの機能で重ね合わせ表示することで実現することができました。しかしながら、Nucleo-U575ZI-QのようにLTDCをサーボーとしておらず、メモリ容量にも制約がある環境では実現方法を考えなければなりません。今回は、次のような手段で重ね合わせ表示を実現しています。

  1. DOOMの実行時にもLVGLのGUI処理タスクは並行して走らせておく。
  2. GUI処理タスクが画面をタッチされたことを検出したならば、DOOMタスクの実行を休止し、メニュー画面を表示する。LVGLタスクは、DOOMの画面表示には関与していないので、画面に変更があったのは、メニュー表示の部分だけだと思い込んでいる。そのため、メニューに相当する矩形部分だけの表示が更新され、残りの部分にはDOOMのゲーム画面画像が残ってくれる。
  3. メニューの選択が終了したならば、DOOMタスクの実行を再開する。DOOMの画面更新処理は毎回全画面の書き直しを行うので、LVGLが表示したメニュー部分もすぐに書き直される。

本来であれば、DOOMの画面更新処理部分をLVGLの描画機能を使って処理するのが全体の構造としてはキレイになるのですが、DOOM画面表示処理では、320x240から480x320への拡大処理とL8からRGB565へのカラーフォーマット変換をDMA2Dを用いて行っています。LVGLで処理させるようにすると、LVGL v9ではDMA2Dがサポートされていないこともあり、画面の更新が遅くなってしまいます。

LTDCを使う場合には、メニュー画面を表示している間も、ゲーム進行は継続されますが、上記の方式ではゲーム進行が休止されるので、慌てずにチートコードの入力が行えます。上記の画面でiddqdを選択すれば、体力が100%になり無敵モードになります。

このようにチートコードの入力機能も用意してあるのですが、わたしが興味あるのはこのような機能の実現であり、ゲームのクリアにはさほど関心がないので、いまだにひとつのエピソードも最後まで到達したことがありません。。