[i.MXRT1060]emWINでテトリスを作ってみた〜第1回〜

[i.MXRT1060] emWinでテトリスを作ってみた〜第1回〜

今回は、以前作成したマイコンのコンソールで動くテトリスを、GUIライブラリであるSegger社のemWinを使ってLCD画面でテトリスをしたいな〜と思い作ってみました。

emWinのGUIライブラリの使い方なども勉強になるし、実際にGUIを作ってみたいと思いまして。

emWinのライブラリは、NXPのSDKに組み込んで無料で使用出来ます。ただ、GUI画面を作成する際にGUIのシミュレーション画面を見ながら作成する場合には、GUIビルダーを使用することが出来ます。このGUIビルダーはSegger社から有償で提供されています。さらに、JPEGなどのバイナリコードのコンバーターなどのツールも提供されています。

開発効率をあげるツールは、やっぱり有償ってことですね。

是非、皆さんもemWinを使ってGUIを作成してみてください。

ただ、ここで紹介している内容は私が試したことを紹介していて、当然失敗もあります今回は、そのまま失敗も紹介しています。

是非、その失敗も参考にしてください。

あ〜〜〜こうやったら失敗するんだって感じで。。。

では、早速始めてみたいと思います。

やりたいこと

  • LCD画面でGUIというかゲームを作成したい
  • ゲーム画面はSegger社のemWin GUIライブラリを使用する
  • ゲームはテトリス(以前LPC54104で作成したコードを使う)
  • テトリスのブロックであるテトリミノを回転、移動、消去させたい
  • テトリミノは、自分で画像(BMPファイル)を作成したい
  • 最終的にはテトリミノの色をオリジナル通りにしたい
  • ゲーム開始・終了は実装しない(面倒臭い)

テトリスは以前作成したコードを使いi.MXRT用に修正して、主にemWinのGUIライブラリの使い方を確かめていくって感じです。

準備するもの

ハードウェア

EVK-MIMXRT1060
LCD: RK043FN02H-CT: 4.3″ LCD Panel

ソフトウェア

MCUXPresso IDE
SDK i.MXRT1060(middlewareとして、emWinをチェックしてビルドする)

これら統合開発環境やSDK Builderでのダウンロードについての説明は今回は省きます。インストールやSDKダウンロードについて詳しく知りたい方は、以前の記事を参考にしてください。

今回(第1回で)やること

第一回は、とりあえず、emWinで”Hello World”という文字をLCD画面に出力できることを確かめます。そして、テトリスのテトリミノ(ブロック)を作成していきます。

ブロック作成は、第2回以降で失敗に終わっていますので、参考程度に読んでください。

要点

  1. GUIを作る時は、SDKに入っているサンプルプロジェクトを使うと開発が早い
  2. 文字の色の設定は、GUI_SetColor()でできる。
  3. 文字の出力は、GUI_DispString()で出力できる。
  4. WM_Exec()は、画面の再描画を行う。
  5. 画像は、BMPフォーマットで作成する。

サンプルプロジェクトの準備

emWinを使用するためには、MCUXPresso SDK Builderを使ってmiddlewareにemWinを選択してビルドし、ダウンロードしておく必要があります。

MCUXpresso SDK Builderは、こちらから→  MCUXpresso SDK Builder page

emwin_serial_terminalをインポート

今回は、i.MXRT1060のemWinの最も簡単なサンプルプロジェクトをベースにテトリスを実装していきたいと思います。

今回使うサンプルプロジェクトは、LCD制御に関わる設定、初期化(クロックやLCDバス、I2Cなどのピン配設定)など全てが既に設定されているので、このまま使うことにします。

こういう設定や初期化ってスクラッチからやると結構時間が掛かってしまうんです。

できるだけ、サンプルプロジェクトを活用することで、早くPoC(Proof Of Concept)を開発することができるのでおすすめです。

今回は、emwin_serial_terminalをインポートして使うことにします。

「Hello World」をLCD画面に出力させる

WM_Exec()以下が全部いらない!

とりあえず、main()内にある今回のテトリス実装に関係ない部分は全部削除です。

クロック設定やピン設定、GUI初期化部分は残しておきましょう。

具体的には、main()関数内の下記部分をごっそりmain()の最終行まで削除します。

GUI_SetColor(GUI_BLACK);

termWidth = WM_GetWindowSizeX(0);
termHeight = WM_GetWindowSizeY(0);

GUI_SetFont(GUI_FONT_8X16);
lineHeight = GUI_GetFontDistY();
:
:
:

文字出力

LCD画面に文字を出力するAPIは、GUI_DispString()です。そして、文字の色をセットする必要があります。

今回は黒に設定します。

 void GUI_SetColor(GUI_COLOR color);
void GUI_DispString(const char * s); 

おなじみの「Hello World」を出力してみます。

int main(void)
{
    //int termWidth;
    //int termHeight;

    //int charWidth;
    //int lineHeight;

    //int c      = 0;
    //int c_prev = 0;

    /* Board pin, clock, debug console init */
    BOARD_ConfigMPU();
    BOARD_InitPins();
    BOARD_InitI2C1Pins();
    BOARD_InitSemcPins();
    BOARD_BootClockRUN();
    BOARD_InitLcdifPixelClock();
    BOARD_InitDebugConsole();
    BOARD_InitLcd();

    /* emWin start */
    GUI_Init();

    WM_SetSize(WM_HBKWIN, LCD_WIDTH, LCD_HEIGHT);

    /* Solid color display */
    GUI_SetBkColor(GUI_WHITE);
    GUI_Clear();

    WM_Exec();
  /* ここから下の部分をごっそり削除した後、下記のコードを記述します*/
    GUI_SetBkColor(GUI_BLACK);
    GUI_DispString("Hello world!");

どうでしょうか?

表示されましたか?

多分これで表示されているはずです。

表示されない時は、画面をリフレッシュして再描画させる必要があります。

画面の再描画

GUI_DispString()の後に、WM_Exec();を実行して再描画してみます。

今度は、無事、表示されたのではないでしょうか?

参考情報
GUI_DispString()だと、左上に表示されるだけです。でも自由に場所を指定したいですよね。

そんな時には、下記のAPIが用意されています。
 void GUI_DispStringAt(const char * s, int x, int y);  At付きのAPIで、後ろ2つの引数で位置を指定します。
試しに、GUI_DispString(“Hello World”, 210, 136);にしてみると、ちょうど画面の真ん中に「Hello World」が表示されると思います。

これで、とりあえず、LCD画面に何がしかを出力させることが出来ました。

次に、画像を表示できるようにしていきます。

テトリミノのブロックを作る

その前に、テトリミノのブロック画像を作っていきます。

これは、WindowsでもMacOSでもどちらでも画像を作成できるアプリで作っていきます。

WIndows10の場合は、「ペイント」や「PowerPoint(パワーポイント)」を使って画像を作成することが可能です。

私の場合は、MacOSなのですが、パワーポイントを持っていないので、今回は「プレビュー」の簡易な画像作成ツール(マークアップツール)を使って作成しました。

プレビューで画像作成
プレビューで画像作成

画像サイズは、ツールバーから「Tool-サイズ調整」で変更が出来ます。ただ、これだと、任意のサイズ調整が画像自体のサイズを設定してくれず、画像のキャンバスというか下地部分のサイズの設定になってしまいます。

そこで、私はお絵かきソフトの「Mediban Paint Pro」を使って、任意の画像サイズに調整し直して作成しました。

画像サイズ 20×20 pixel

画像サイズは、LCD画面サイズ(480×272)にテトリスのフィールド縦(20)x 横(10)を考慮して、20×20 pixel辺りが良さそうです。

Mediban Paint Proを使ってサイズ調整
Mediban Paint Proを使ってサイズ調整している様子

画像フォーマットはBitmap(ビットマップ)

出来たら、あとは画像を保存します。保存する画像フォーマットは、 「BMP(ビットマップ)」 で保存しておきます。

あとは、全8色のブロックを同様の手順で作成しておきます。

画像ソースは、どんな作成方法でも問題ありません。

重要なのは、BMPフォーマットです。サイズは20×20くらいがベストだと思います(多分。。。)

バイナリファイルを変換する

今回作成した画像は、BMPフォーマットのファイルですが、このままだとARMコアで読みこむことが出来ませんので、ARMコア用にBMPフォーマットのバイナリファイルを変換してあげます。

変換方法は、以前の記事を参考にしてください。

macOSの場合には、「ターミナル 」を開いて、MCUXpresso IDE付属の「objcopy」ツールを使うことで、簡単にARM用オブジェクトコードを作成することが出来ます。

作成したテトリミノの画像ファイル(BMP)をMCUXPresso IDEのツールフォルダにコピーして、実行します。

$./objcopy -I binary -B arm -O elf32-littlearm gray_20.bmp gray_20.o --rename-section .data=.rodata,alloc,load,readonly,data,contents
参考情報
MacOSの場合ですが、MCUXpresso IDEのツールフォルダは、以下の場所になります。 Applications/MCUXpressoIDE_11.1.0_3209/ide/tools/arm-none-eabi/bin/

 

今回は、ここまでにします。

次回は、以前作成したテトリスのコードをi.MXRT1060で動作を確認して行きます。

お楽しみに。