M5StickCの画面制御ST7735のソース解析

現時点の情報です。最新情報はM5StickC非公式日本語リファレンスを確認してみてください。

概要

M5StickCの画面制御で使われているST7735関連のソースコードを読んでみました。

ST7735とは?

ST7735とST7735Sがあるようですが、M5Stack社が公開しているデータシートからM5StickCで使われているのはSがついている方だと思います。(違いはわかりません、、、最近はS付きばかり売られている?)

ST7735は132×162ドットのフレームバッファを内蔵しており、フレームバッファに16ビットの色情報を書き込むことで、いい感じに液晶に表示してくれるコントローラーです。

液晶とコントローラーは個別に選択することができますが、個人で買えるモジュールはセットで販売されていると思います。

ST7735_Defines.h

使っている液晶などの設定をするファイルです。

液晶のサイズ指定

// Change the width and height if required (defined in portrait mode)
// or use the constructor to over-ride defaults
#ifndef TFT_WIDTH
  #define TFT_WIDTH  80
#endif
#ifndef TFT_HEIGHT
  #define TFT_HEIGHT 160
#endif

M5StickCの液晶は縦長なので80×160と定義されています。この値が画面用のクラスであるTFT_eSPIのコンストラクタの引数として指定されています。

他のサイズの液晶を使う場合には、宣言を書き換えるかコンストラクタの引数の引数で与えろとコメントがありますね。

class TFT_eSPI : public Print {

 public:

  TFT_eSPI(int16_t _W = TFT_WIDTH, int16_t _H = TFT_HEIGHT);

利用している液晶選択

//#define ST7735_INITB
// #define ST7735_INITB
// #define ST7735_GREENTAB
// #define ST7735_GREENTAB2
//#define ST7735_GREENTAB3
// #define ST7735_GREENTAB128    // For 128 x 128 display
#define ST7735_GREENTAB160x80 // For 160 x 80 display (BGR, inverted, 26 offset)
 //#define ST7735_REDTAB
//#define ST7735_BLACKTAB
 //#define ST7735_REDTAB160x80  
// Enumerate the different configurations

ここではM5StickCで利用しているST7735_GREENTAB160x80だけコメントが外されており、それ以外はコメントアウトされています。

グリーンタブというのが、わかりにくいのですが新品の液晶を購入した場合の液晶保護シートについているタブの色です。上記が緑で80×160なのでM5StickCと同じものだと思います。

いまは緑ばかりですが、上記のようにREDTABもあります。

液晶の列挙

#define INITR_GREENTAB       0x0
#define INITR_REDTAB         0x1
#define INITR_BLACKTAB       0x2 // Display with no offsets
#define INITR_GREENTAB2      0x3 // Use if you get random pixels on two edges of green tab display
#define INITR_GREENTAB3      0x4 // Use if you get random pixels on edge(s) of 128x128 screen
#define INITR_GREENTAB128    0x5 // Use if you only get part of 128x128 screen in rotation 0 & 1
#define INITR_GREENTAB160x80 0x6 // Use if you only get part of 128x128 screen in rotation 0 & 1
#define INITR_REDTAB160x80   0x7 // Added for https://www.aliexpress.com/item/ShengYang-1pcs-IPS-0-96-inch-7P-SPI-HD-65K-Full-Color-OLED-Module-ST7735-Drive/32918394604.html
#define INITB                0xB

上記の選択に近いですが、ここは定義されている液晶が列挙されています。INITR_REDTAB160x80とかのURLを見ると、中身は緑に変わっていたりと商品はどんどん入れ替わるので気をつけましょう!

ここに無いものは自分で定義することになると思います。

液晶の確定

#if defined (ST7735_INITB)
  #define TAB_COLOUR INITB
...(略)
#elif defined (ST7735_GREENTAB160x80)
  #define TAB_COLOUR INITR_GREENTAB160x80
  #define CGRAM_OFFSET

#elif defined (ST7735_REDTAB160x80)
  #define TAB_COLOUR INITR_REDTAB160x80
  #define CGRAM_OFFSET

ST7735_GREENTAB160x80を指定したので、内部で使う設定はINITR_GREENTAB160x80になります。また、CGRAM_OFFSETという宣言が追加されています。

この宣言がある液晶と、ない液晶があるので、ST7735_*で選択したものをここの#IFで切り分けています。

M5StickCの液晶は80×160ですので、フレームバッファには収まっています。

上記はちょっと大げさに書いてありますが、フレームバッファのどこを画面に表示するのかは、液晶によって違います。上記の場合液晶は右上に寄っています。この場合左側には使われない領域があります。(説明用の図なので実際とは違います!)

初期化を間違えてしまうと左上から描画してしまうので、一番端の列は変な色になってしまいます。obnizの初期ライブラリはこの状態なので、全面塗りつぶしても、よく見ると端っこの色が変です。

上記のように、描画する座標を調整する必要があるって宣言がCGRAM_OFFSETみたいです。

色の宣言

// Color definitions for backwards compatibility with old sketches
// use colour definitions like TFT_BLACK to make sketches more portable
#define ST7735_BLACK       0x0000      /*   0,   0,   0 */
#define ST7735_NAVY        0x000F      /*   0,   0, 128 */
#define ST7735_DARKGREEN   0x03E0      /*   0, 128,   0 */
#define ST7735_DARKCYAN    0x03EF      /*   0, 128, 128 */
#define ST7735_MAROON      0x7800      /* 128,   0,   0 */
#define ST7735_PURPLE      0x780F      /* 128,   0, 128 */
#define ST7735_OLIVE       0x7BE0      /* 128, 128,   0 */
#define ST7735_LIGHTGREY   0xC618      /* 192, 192, 192 */
#define ST7735_DARKGREY    0x7BEF      /* 128, 128, 128 */
#define ST7735_BLUE        0x001F      /*   0,   0, 255 */
#define ST7735_GREEN       0x07E0      /*   0, 255,   0 */
#define ST7735_CYAN        0x07FF      /*   0, 255, 255 */
#define ST7735_RED         0xF800      /* 255,   0,   0 */
#define ST7735_MAGENTA     0xF81F      /* 255,   0, 255 */
#define ST7735_YELLOW      0xFFE0      /* 255, 255,   0 */
#define ST7735_WHITE       0xFFFF      /* 255, 255, 255 */
#define ST7735_ORANGE      0xFD20      /* 255, 165,   0 */
#define ST7735_GREENYELLOW 0xAFE5      /* 173, 255,  47 */
#define ST7735_PINK        0xF81F

#define BLACK               0x0000      /*   0,   0,   0 */
#define NAVY                0x000F      /*   0,   0, 128 */
#define DARKGREEN           0x03E0      /*   0, 128,   0 */
#define DARKCYAN            0x03EF      /*   0, 128, 128 */
#define MAROON              0x7800      /* 128,   0,   0 */
#define PURPLE              0x780F      /* 128,   0, 128 */
#define OLIVE               0x7BE0      /* 128, 128,   0 */
#define LIGHTGREY           0xC618      /* 192, 192, 192 */
#define DARKGREY            0x7BEF      /* 128, 128, 128 */
#define BLUE                0x001F      /*   0,   0, 255 */
#define GREEN               0x07E0      /*   0, 255,   0 */
#define CYAN                0x07FF      /*   0, 255, 255 */
#define RED                 0xF800      /* 255,   0,   0 */
#define MAGENTA             0xF81F      /* 255,   0, 255 */
#define YELLOW              0xFFE0      /* 255, 255,   0 */
#define WHITE               0xFFFF      /* 255, 255, 255 */
#define ORANGE              0xFD20      /* 255, 165,   0 */
#define GREENYELLOW         0xAFE5      /* 173, 255,  47 */
#define PINK                0xF81F

色を宣言しています。ST7735は16ビットで色を制御しています。RGB順に並んでいますがRが5ビット、Gが6ビット、Bが5ビットで制御しています。

01234567 01234567
RRRRRGGG GGGBBBBB

16ビットの場合にはこの他に透明色のAを追加してRGB各5ビットの場合もあります。

コマンドと設定値

// Delay between some initialisation commands
#define TFT_INIT_DELAY 0x80

// Generic commands used by TFT_eSPI.cpp
#define TFT_NOP     0x00
#define TFT_SWRST   0x01

#define TFT_CASET   0x2A
#define TFT_PASET   0x2B
#define TFT_RAMWR   0x2C

#define TFT_RAMRD   0x2E
#define TFT_IDXRD   0x00 //0xDD // ILI9341 only, indexed control register read

#define TFT_MADCTL  0x36
#define TFT_MAD_MY  0x80
#define TFT_MAD_MX  0x40
#define TFT_MAD_MV  0x20
#define TFT_MAD_ML  0x10
#define TFT_MAD_BGR 0x08
#define TFT_MAD_MH  0x04
#define TFT_MAD_RGB 0x00

#define TFT_INVOFF  0x20
#define TFT_INVON   0x21

// ST7735 specific commands used in init
#define ST7735_NOP     0x00
#define ST7735_SWRESET 0x01
#define ST7735_RDDID   0x04
#define ST7735_RDDST   0x09

#define ST7735_SLPIN   0x10
#define ST7735_SLPOUT  0x11
#define ST7735_PTLON   0x12
#define ST7735_NORON   0x13

#define ST7735_INVOFF  0x20
#define ST7735_INVON   0x21
#define ST7735_DISPOFF 0x28
#define ST7735_DISPON  0x29
#define ST7735_CASET   0x2A
#define ST7735_RASET   0x2B // PASET
#define ST7735_RAMWR   0x2C
#define ST7735_RAMRD   0x2E

#define ST7735_PTLAR   0x30
//Add
#define ST7735_VSCRDEF 0x33
#define ST7735_COLMOD  0x3A
#define ST7735_MADCTL  0x36
#define ST7735_VSCRSADD 0x37

#define ST7735_FRMCTR1 0xB1
#define ST7735_FRMCTR2 0xB2
#define ST7735_FRMCTR3 0xB3
#define ST7735_INVCTR  0xB4
#define ST7735_DISSET5 0xB6

#define ST7735_PWCTR1  0xC0
#define ST7735_PWCTR2  0xC1
#define ST7735_PWCTR3  0xC2
#define ST7735_PWCTR4  0xC3
#define ST7735_PWCTR5  0xC4
#define ST7735_VMCTR1  0xC5

#define ST7735_RDID1   0xDA
#define ST7735_RDID2   0xDB
#define ST7735_RDID3   0xDC
#define ST7735_RDID4   0xDD

#define ST7735_PWCTR6  0xFC

#define ST7735_GMCTRP1 0xE0
#define ST7735_GMCTRN1 0xE1

いろいろコマンドとかが列挙されていますが、ここだけみてもわからないので実際のコードのところで理解したいと思います。

ST7735_Init.h

液晶の初期化をしているファイルです。

初期化コマンド

	// Initialization commands for ST7735 screens
  static const uint8_t PROGMEM
  Bcmd[] = {                  // Initialization commands for 7735B screens
    18,                       // 18 commands in list:
    ST7735_SWRESET,   TFT_INIT_DELAY,  //  1: Software reset, no args, w/delay
      50,                     //     50 ms delay
    ST7735_SLPOUT ,   TFT_INIT_DELAY,  //  2: Out of sleep mode, no args, w/delay
      255,                    //     255 = 500 ms delay
    ST7735_COLMOD , 1+TFT_INIT_DELAY,  //  3: Set color mode, 1 arg + delay:
      0x05,                   //     16-bit color
      10,                     //     10 ms delay
...(略)

この辺は定形の決り文句みたいなので、無視します。データシートをみると何をやっているかはわかると思いますが、定形なので順番に必要なパラメータをセットしているだけのようです。

液晶初期化

     if (tabcolor == INITB)
     {
       commandList(Bcmd);
     }
     else 
     {
	  commandList(Rcmd1);
       if (tabcolor == INITR_GREENTAB)
       {
         commandList(Rcmd2green);
         colstart = 2;
         rowstart = 1;
       }
       else if (tabcolor == INITR_GREENTAB2)
       {
         commandList(Rcmd2green);
         writecommand(ST7735_MADCTL);
         writedata(0xC0);
         colstart = 2;
         rowstart = 1;
       }
       else if (tabcolor == INITR_GREENTAB3)
       {
         commandList(Rcmd2green);
         colstart = 2;
         rowstart = 3;
       }
       else if (tabcolor == INITR_GREENTAB128)
       {
         commandList(Rcmd2green);
         colstart = 0;
         rowstart = 32;
       }
       else if (tabcolor == INITR_GREENTAB160x80)
       {
         commandList(Rcmd2green);
         writecommand(TFT_INVON);
         colstart = 26;
         rowstart = 1;
       }
       else if (tabcolor == INITR_REDTAB160x80)
       {
         commandList(Rcmd2green);
         colstart = 24;
         rowstart = 0;
       }
       else if (tabcolor == INITR_REDTAB)
       {
         commandList(Rcmd2red);
       }
       else if (tabcolor == INITR_BLACKTAB)
       {
         writecommand(ST7735_MADCTL);
         writedata(0xC0);
       }
       commandList(Rcmd3);
     }

上記で初期化しています。M5StickCはINITR_GREENTAB160x80なので、ハイライトされている場所が実行されます。

commandList(Rcmd1)

ブラックタブ以外の共通初期化処理みたいです。

commandList(Rcmd2green)

グリーンタブの共通初期化処理。

writecommand(TFT_INVON)

他で利用していないコマンドがでてきました!

宣言を調べると、INVのONとOFFがあります。

#define TFT_INVOFF  0x20
#define TFT_INVON   0x21

ここからは20とか21を参考にデータシートを調べます。

INVOFFはデフォルトの状態で、フレームバッファのメモリをそのまま表示させるモードみたいです。

INVONはフレームバッファのメモリの輝度を反転させて転送するモードかな?

液晶画面によって0が一番暗い状態が一般的ですが、たまに反転していて0が一番明るい状態の物があります。

M5Stackだと途中で使っている液晶モジュールが変わって、古いライブラリだと色がおかしくなった事象があったと思います。液晶の色が反転してみる場合には、この設定も疑いましょう。

colstart = 26, rowstart = 1

この設定がフレームバッファと液晶の表示座標のズレを指定しています。横1ドット、縦26ドットずれた場所から描画されているみたいです。

commandList(Rcmd3)

こちらもブラックタブ以外の共通初期化処理みたいです。

ST7735_Rotation.h

画面の回転をした場合の処理です。

入力値チェック

  rotation = m % 4; // Limit the range of values to 0-3

画面の方向は0から3までなので、変な値が来ても大丈夫なように4のあまりで0-3の値に変更しています。

writecommand(TFT_MADCTL)

コマンドを投げていますね。データシートを調べます。

上記が定義です。ちょっとこれだけだと、よくわからないですね。

ビット概要
MYY軸反転
MXX軸反転
MVX軸とY軸を入れ替える
ML横方向の描画方向
MH縦方向の描画方向
RGBRGBかBGR

上記がどのように使われているのかを確認します。

    case 0:
     if (tabcolor == INITR_BLACKTAB) {
       writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_RGB);
     } else if(tabcolor == INITR_GREENTAB2) {
       writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_RGB);
       colstart = 2;
       rowstart = 1;
     } else if(tabcolor == INITR_GREENTAB3) {
       writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_BGR);
       colstart = 2;
       rowstart = 3;
     } else if(tabcolor == INITR_GREENTAB128) {
       writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_MH | TFT_MAD_BGR);
       colstart = 0;
       rowstart = 32;
     } else if(tabcolor == INITR_GREENTAB160x80) {
       writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_MH | TFT_MAD_BGR);
       colstart = 26;
       rowstart = 1;
     } else if(tabcolor == INITR_REDTAB160x80) {
       writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_MH | TFT_MAD_BGR);
       colstart = 24;
       rowstart = 0;
     } else if(tabcolor == INITB) {
       writedata(TFT_MAD_MX | TFT_MAD_RGB);
     } else {
       writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_BGR);
     }
      _width  = _init_width;
      _height = _init_height;
      break;

方向が0なので、M5StickCだと縦においた場合の画面方向です。

M5StickCはINITR_GREENTAB160x80なので、TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_MH | TFT_MAD_BGRが指定されていました。

MXとMYはだいたい入っているので、よくわからないですね。M5StickCのだけ抜粋したコードを見てみます。

  switch (rotation) {
    case 0:
       writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_MH | TFT_MAD_BGR);
       colstart = 26;
       rowstart = 1;
      _width  = _init_width;
      _height = _init_height;
      break;
    case 1:
       writedata(TFT_MAD_MV | TFT_MAD_MY | TFT_MAD_BGR);
       colstart = 1;
       rowstart = 26;
      _width  = _init_height;
      _height = _init_width;
      break;
    case 2:
       writedata(TFT_MAD_BGR);
       colstart = 26;
       rowstart = 1;
      _width  = _init_width;
      _height = _init_height;
      break;
    case 3:
       writedata(TFT_MAD_MX | TFT_MAD_MV | TFT_MAD_BGR);
       colstart = 1;
       rowstart = 26;
      _width  = _init_height;
      _height = _init_width;
      break;
  }

えーっと、画面の回転は以下の図です。

一番シンプルなのが2の逆さですね。TFT_MAD_BGRのみの指定です。おそらくこの向きが液晶の正しい向きな気がします。

このBGRは液晶の色の並び方を示しています。他の液晶はRGBの指定もありましたが、この液晶はBGRの順に色が並んでいます。デフォルトはRGBなのでBGRを指定しないと色が変になってしまいます。

obnizの初期ライブラリは未指定だったみたいで、デフォルトのRGBモードで動いていたので、色がおかしかったです。

rotation方向MXMYMVMHBGR
0
2
1
3

各指定をまとめたのが上の図です。画面を横にしているときには、XとY軸が逆になるのでMVを指定する必要があります。

MXとMYで反転させて、回転方向を決めます。0は逆さに回転するので、MXとMYの両方をしていします。

MHは画面の転送順番を指定するのですが、実際のところ指定しなくても見た目はほとんど変わりません。画面の上から描画されていくか、下から描画されていくかの違いです。同じくMLで右からか左からかも指定できますが、転送が非常に遅い場合か、スローカメラで撮影しないと差はわからないと思います。

1と3はどっちの方向に回転するのかでMXとMYを選択しています。

左右反転の鏡面表示や、上下反転表示をしたい場合には、上記のデフォルト値から反転したい方向のフラグを逆に設定します。

    // 縦向きのデフォルト値
    M5.Lcd.setRotation(2);
    M5.Lcd.writecommand(TFT_MADCTL);
    M5.Lcd.writedata(TFT_MAD_BGR);

    // 縦向きの左右反転(TFT_MAD_MXを追加)
    M5.Lcd.setRotation(2);
    M5.Lcd.writecommand(TFT_MADCTL);
    M5.Lcd.writedata(TFT_MAD_MX | TFT_MAD_BGR);

    // 縦向きの上限反転(TFT_MAD_MYを追加)
    M5.Lcd.setRotation(2);
    M5.Lcd.writecommand(TFT_MADCTL);
    M5.Lcd.writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_MV | TFT_MAD_BGR);

    // 横向きのデフォルト値
    M5.Lcd.setRotation(3);
    M5.Lcd.writecommand(TFT_MADCTL);
    M5.Lcd.writedata(TFT_MAD_MX | TFT_MAD_MV | TFT_MAD_BGR);

    // 横向きの左右反転(TFT_MAD_MYを追加)
    M5.Lcd.setRotation(3);
    M5.Lcd.writecommand(TFT_MADCTL);
    M5.Lcd.writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_MV | TFT_MAD_BGR);

    // 横向きの上限反転(TFT_MAD_MXを取る)
    M5.Lcd.setRotation(3);
    M5.Lcd.writecommand(TFT_MADCTL);
    M5.Lcd.writedata(TFT_MAD_MV | TFT_MAD_BGR);

上記の関係になります。横になった場合はMVによってXとYが逆になっているので、反転方向も逆になります。

#include <M5StickC.h>

int mode = -1;

void setup() {
  M5.begin();
}

void loop() {
  M5.update();
  if ( M5.BtnA.wasPressed() ) {
    mode++;
    mode = mode % 10;
    if ( mode == 0 ) {
      M5.Lcd.setRotation(0);
      M5.Lcd.writecommand(TFT_MADCTL);
      M5.Lcd.writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_MH | TFT_MAD_BGR);
    } else if ( mode == 1 ) {
      M5.Lcd.setRotation(0);
      M5.Lcd.writecommand(TFT_MADCTL);
      M5.Lcd.writedata(TFT_MAD_MY | TFT_MAD_MH | TFT_MAD_BGR);
    } else if ( mode == 2 ) {
      M5.Lcd.setRotation(0);
      M5.Lcd.writecommand(TFT_MADCTL);
      M5.Lcd.writedata(TFT_MAD_MX | TFT_MAD_MH | TFT_MAD_BGR);
    } else if ( mode == 3 ) {
      M5.Lcd.setRotation(0);
      M5.Lcd.writecommand(TFT_MADCTL);
      M5.Lcd.writedata(TFT_MAD_MH | TFT_MAD_BGR);
    } else if ( mode == 4 ) {
      M5.Lcd.setRotation(0);
      M5.Lcd.writecommand(TFT_MADCTL);
      M5.Lcd.writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_BGR);
    } else if ( mode == 5 ) {
      M5.Lcd.setRotation(0);
      M5.Lcd.writecommand(TFT_MADCTL);
      M5.Lcd.writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_ML | TFT_MAD_BGR);
    } else if ( mode == 6 ) {
      M5.Lcd.setRotation(3);
      M5.Lcd.writecommand(TFT_MADCTL);
      M5.Lcd.writedata(TFT_MAD_MX | TFT_MAD_MV | TFT_MAD_BGR);
    } else if ( mode == 7 ) {
      M5.Lcd.setRotation(3);
      M5.Lcd.writecommand(TFT_MADCTL);
      M5.Lcd.writedata(TFT_MAD_MV | TFT_MAD_BGR);
    } else if ( mode == 8 ) {
      M5.Lcd.setRotation(3);
      M5.Lcd.writecommand(TFT_MADCTL);
      M5.Lcd.writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_MV | TFT_MAD_BGR);
    } else if ( mode == 9 ) {
      M5.Lcd.setRotation(3);
      M5.Lcd.writecommand(TFT_MADCTL);
      M5.Lcd.writedata(TFT_MAD_MY | TFT_MAD_MV | TFT_MAD_BGR);
    }
    M5.Lcd.fillScreen(BLACK);
    M5.Lcd.setCursor(5, 10);
    M5.Lcd.print("mode:");
    M5.Lcd.print(mode);
  }
}

上記サンプルスケッチを動かして関係性を調べてみてください。

その他のコマンド

Sleepなど

M5StickCだとAXP192で制御するので、あまり使わないはずですが液晶のON、OFFやスリープ設定があります。

GAMSET (26h): Gamma Set

画像などで、ガンマ値を変更して表示したい場合に使えそうです。

VSCSAD: Vertical Scroll Start Address of RAM (37h)

特定エリアの画像などを縦スクロールする機能。かなり難易度が高そうなので普通は使わないと思います。

その他

フレームバッファへのアクセス方法がいろいろありますが、通常はTFT_eSPIクラスやTFT_eSpriteクラス経由でアクセスしたほうがよいと思います。

まとめ

結構長くなってしまいましたが、ST7735を使う上でのアウトラインは理解できたきがします。TFT_eSPIクラスが実際の描画まわりのラッパークラスになります。ただTFT_eSPIクラスは操作単位でST7735につど転送しているので、処理がかなり重いです。

画面のチラツキも出てくるので、高速描画ではダブルバッファリングという処理を行います。これは描画途中のフレームバッファを用意して、その画面にすべての描画が終了してから、実際のフレームバッファに転送する方法です。

おそらくTFT_eSpriteがダブルバッファリングをおこなっている描画クラスな気がするのですが、らびやんさんが最新版のTFT_eSpriteに入れ替えるプルリクエストを出しているので、取り込まれたバージョンがでたら、もう少し検証を進めたいと思います。

コメントする

メールアドレスが公開されることはありません。

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)