文字表示が出来たところで、基本中の基本、ファイル選択を実装してみた。
「ファイル選択」は、NESエミュレーター、オーディオプレイヤーなど、
使用頻度が高いものなので、汎用性を高く実装する必要がある。
C++ の使いどころの一つに「テンプレート」がある。
C++ を始めたばかりの時は、テンプレートは難解で、とっつきにくく、敬遠
していた事や、簡単なシンプルなものに限られていたものの、馴れてくると、
利用範囲が広がり、最近は、テンプレート無しではプログラムが作れなくな
っている。
・便利すぎて、Cでプログラムする気がおきなくなる。
C++ の良いところは「型」に忠実である点がある。
但し、「より厳密な方法で実装」していない場合、細かいエラーが出て、先
に進めない。
この辺りは経験的な部分が大きいものの、反復する事で、考えなくても自然
に厳密な書き方が行えるようになると思う。
※Arduino のスケッチが駄目だと思うのは、C++ なのに、未だに「#define」
を多様していたり、C++11 以降の構文を使っていない部分、そんなスケッチ
が氾濫している。(動けば良いという考え方は良くないと思う)
※及第点を付けられるような、見本になるソースコードが少ないと思う。
※テンプレートプログラムの推薦書籍
使い始め、エラーが出た時に、そのエラーの意味や解消法、どうしてエラー
になるのかなど、意味不明が続くが、エラーが出なくなるまで、より簡単で
シンプルな構造にして、エラーの原因を見極めると、より複雑な構造に対処
できるようになる。
ネットにあるサンプルプログラムは、ある程度参考になるが、コピーペース
トだけでは限界がある、自分で考えて、実装する必要があると思う。
また、boost などの便利なテンプレートや STL を利用したいところでもある
が、メモリーの少ないマイコンでは、それも使える場合と使えない場合があり、
やはり、その場合は自分で何とかするしかない。
独学で勉強するには限界があると思える、勉強会などに参加して、誰かに習う
のが、やはり習得するには必要かと思える。
※この辺り、ある程度Cなどでプログラムが組める人には大きなハードルなの
かと思う。
今回のファイラーは、SDカードの操作クラス(SDC)、グラフィックス描画
クラス(RDR)の型が必要なので、テンプレートとなっている。
template <class SDC, class RDR> class filer { SDC& sdc_; RDR& rdr_; public: filer(SDC& sdc, RDR& rdr) noexcept : sdc_(sdc), rdr_(rdr), ctrl_(0), open_(false), rdr_st_(rdr_) { } ... };
これらクラスは、参照のコピーを内部に置いておくので、コンストラクター
で参照を渡す必要がある。
typedef utils::sdc_man SDC; SDC sdc_; typedef graphics::font8x16 AFONT; typedef graphics::kfont<16, 16, 32> KFONT; KFONT kfont_; typedef graphics::render<uint16_t, 480, 272, AFONT, KFONT> RENDER; RENDER render_(reinterpret_cast(0x00000000), kfont_); typedef graphics::filer<SDC, RENDER> FILER; FILER filer_(sdc_, render_);
上記のように、型の定義が複雑なので、途中に反故があると、コンパイルは全く
機能しない、その場合に出るエラーは「意味不明」な場合が多く、対処にはコツ
が必要となる場合が多い。
「graphics::render」クラスは、ピクセルの型「uint16_t」、横幅、高さ、アス
キーフォント、漢字フォントをテンプレートパラメーターとしている。
又、コンストラクターでは、フレームバッファのアドレス、漢字フォントクラス
の参照を渡す必要がある。
「graphics::kfont」クラスは、フォントサイズと、フォントキャッシュの数を
テンプレートパラメーターとしている。
※ディレクトリーは青で表示される、又、左端に「/」を表示している、通常は
右終端に表示すべきであるが、ディレクトリー名が長い場合に、画面の外に表示
されてしまう為。
上下スクロールはできるが、左右スクロール機能は無いので、画面に表示しきれ
ない場合がある。
また、操作はファミコンパッドで操作するようになっている、今後画面タッチで
も操作出来るようにする予定。
if(chip::on(data, chip::FAMIPAD_ST::UP)) { graphics::set(graphics::filer_ctrl::UP, ctrl); } if(chip::on(data, chip::FAMIPAD_ST::DOWN)) { graphics::set(graphics::filer_ctrl::DOWN, ctrl); } if(chip::on(data, chip::FAMIPAD_ST::LEFT)) { graphics::set(graphics::filer_ctrl::BACK, ctrl); } if(chip::on(data, chip::FAMIPAD_ST::RIGHT)) { graphics::set(graphics::filer_ctrl::SELECT, ctrl); }
ファイラーの制御は、制御ビットで行うので、上記のようにファミコンパッドの
操作をファイラーの制御ビットに変換している。
-----
漢字フォントのビットマップデータは、250K程あるので、現在は、SDカード
上に置いて、キャッシュ機構を設けてあるのだが、RX65Nの場合、2Mバイト
のプログラムフラッシュがあるので、そこに置いても良いと思い、rx-elf-objcopy
を使い、「kfont16.bin」をオブジェクトに変換してアクセスしてみた。
しかしながら、何故か、fread 関数が正常動作しなくなった・・・
原因に思い当たる部分がなく、とりあえず、SDカード上に置くようにしてある。