ユーザ用ツール

差分

このページの2つのバージョン間の差分を表示します。

この比較画面へのリンク

両方とも前のリビジョン前のリビジョン
次のリビジョン
前のリビジョン
フルーツフィールド_for_m5stack_m5core2 [2024/12/12 04:32] – [ヘッダを作れ] arakiフルーツフィールド_for_m5stack_m5core2 [2024/12/12 05:05] (現在) – [音] araki
行 45: 行 45:
 ===== 割込 ===== ===== 割込 =====
  
 +キーのリピート処理や、BGMなど、ゲームの負荷に関係なく一定間隔で行いたいものは、割込み処理で行う。
 +
 +ESP32は4本のタイマー割込みを持っているので、キーとBGMと分けてもいいなとか思ったんですが、収拾がつかなくなるだけのような気もしたので、一つの割込みの中かっら、キーボードと、BGM処理をそれぞれ呼び出すことで済ませています。
 +
 +タイマーは0.1秒間隔で割り込むように設定してある。
 ===== 音 ===== ===== 音 =====
  
 +本格的なサウンドドライバーとか作ってMMLを処理するなんていう大それた野望はなく、そもそも、X1版のフルーツフィールドもPSGをひっぱたくための周波数データが置いてあるだけだったので、それを M5.Speker.tone()に食わせられる値に変換して持ってきただけで済ませてある。
 +
 +タイマー割込みでタイミングをとって、APIをひっぱたくだけで済ませている。
 +ちょっと音痴なので、気が向いたら手を入れるかもしれないが、そもそも私自身が音痴なので、かえっておかしくしてしまうかもしれない。
 ===== キーボード回り ===== ===== キーボード回り =====
 +
 +わかっている。
 +本当はゲームなら、オートリピートじゃなくて、今押されているキーを取得できるIFをつけるべきだっていうのは。
 +
 +まあ、正直、それもできなくもない。
 +
 +多分、それをやるために、何か次のゲームをM5に乗せようとするに違いない。
 +あるいは、フルーツフィールドで試すかもしれない。
 +
 +でも、とりあえずは、まずはオートリピートである。
 +
 +==== BLEキーボードとの通信 ====
 +
 +ほとんどすべてのBLEキーボードは、キーを押したときと離したときに通知を送ってくる。
 +それ以外は通信しない。
 +
 +だからこその省電力なので、当然なのだが、なので、キーのリピートなんかの処理はセントラル/クライアント側でやらないといけない。
 +
 +
  
 ===== デモ ===== ===== デモ =====
  
 +デモは、タイトル画面の時に、REM君が動き回って、ブロックを動かし、壊して、フルーツを回収する奴が、PC-8001版で用意されていたので、それをそのまま頂戴します。
 +
 +まあ、疑似的なキー入力を定義しておいて、順にそれを食っていくだけなので、大したことはありません。
 +
 +ただ、よく考えると、キー操作の説明がどこにもないなと思ったので、キー操作の説明画面も作り、上のデモと交互に出るようにしました。
 +
 +PC-6001mkIIでは [SHIFT]でGive upでしたが、M5版では [ESC]をGive upに割り付けてあります。
 +まあ、それが表示されるだけなんですけれどね。
 +
 +タイトルロゴは、Geminiに「作って」っていって作ってもらいました。
 ===== スクリーンショット ===== ===== スクリーンショット =====
  
行 108: 行 146:
  
 なので、構造体を使ってヘッダーを作成するなら、ヘッダーを詰めて配置するようにコンパイラに指示しなければならない。 なので、構造体を使ってヘッダーを作成するなら、ヘッダーを詰めて配置するようにコンパイラに指示しなければならない。
-__attribute__((__packed__)) は詰めて配置しろという指示になる。 
 大体が、組込みプロセッサであるESP32の場合、デフォルトがこっちでいいんじゃないかという気もするんだが。 大体が、組込みプロセッサであるESP32の場合、デフォルトがこっちでいいんじゃないかという気もするんだが。
  
行 166: 行 203:
 </code> </code>
  
 +==== スクリーンショット本体 ====
 +
 +あとはヘッダを整えて、画像データをくっつけるだけである。
 +
 +<code>
 +void
 +ScreenShot::take(const char *filename)
 +{
 +    if (filename == nullptr)
 +    {
 +        filename = get_next_filename();
 +    }
 +   
 +    _bf = {
 +        ('M'<<8)|'B',
 +        (uint32_t)(M5.Displays(0).width() * M5.Displays(0).height() * (M5.Displays(0).getColorDepth() / 8)),
 +        0,
 +        0,
 +        14 + 40,
 +    };
 +    _bi = {
 +        40,
 +        (uint32_t)M5.Displays(0).width(),
 +        (uint32_t)M5.Displays(0).height(),
 +        1,
 +        M5.Displays(0).getColorDepth(),
 +        0,
 +        (uint32_t)(M5.Displays(0).width() * M5.Displays(0).height() * (M5.Displays(0).getColorDepth() / 8)),
 +        7874,
 +        7874,
 +        0,
 +        0,
 +    };
 +    uint16_t lineBuf[M5.Displays(0).width()];
 +    uint8_t b = M5.Displays(0).getBrightness();
 +    M5.Displays(0).setBrightness(20);
 +    File fp = SD.open(filename, FILE_WRITE);
 +    if (fp)
 +    {
 +        fp.write((uint8_t*)&_bf, sizeof(_bf));
 +        fp.write((uint8_t*)&_bi, sizeof(_bi));
 +        for (int y = M5.Displays(0).height() - 1 ; y >= 0 ; y--)
 +        {
 +            for (int x = 0 ; x < M5.Displays(0).width() ; x++)
 +            {
 +                lineBuf[x] = M5.Displays(0).readPixel(x, y);
 +            }
 +            fp.write((uint8_t*)lineBuf, sizeof(lineBuf));
 +        }
 +        fp.close();
 +    }
 +    M5.Displays(0).setBrightness(b);
 +}
 +</code>
  
 +画面を暗くしているのは、SDにアクセスするときに暗くしないとうまく動かないとかいう噂を聞きつけたからだけれど、[[ハイハイスクールアドベンチャー]]で既に平気で動かしていたのだから、関係ないのはわかっている。
 +でも、スクショの処理をしている間暗くなるのはシャッターを切っているみたいでいいので、コードに含めている。
 +なお、スクリーンショット撮るの思ったより時間がかかるなっていうのが印象。
 +SDへの書き込み速度の問題だと思う。
  
  
  

This website uses cookies. By using the website, you agree with storing cookies on your computer. Also, you acknowledge that you have read and understand our Privacy Policy. If you do not agree, please leave the website.

More information