近況報告

本当はすご〜い真面目な記事を途中まで書いてたんですけど、アホらしくなってきたので適当な近況報告に替えさせていただきます。

Twitterについて

本当にうんざりしている。
具体的には去年の夏頃からうんざりしている。

理由は色々あると思うけど、元々他人とうまくやっていくのはそこまで上手な方だとは思えないし、そもそも自分の個人としての実態以上に多くの人にツイートを見られるようになってしまっていたことがストレスだったのだと思う。
もちろん多くの人にツイートを見られるようになったのは自分に責任がある。最初はライフログとして、日々の出来事や個人的な「つぶやき」を中心にツイートしていたが、そのうち他人から反応をもらえることに快感を覚えるようになって、トレンドの話題に挑発的な言及をしたり、さしづめインターネット芸人のように振る舞うようになっていた。その結果がご覧の有り様だから、滑稽なことこの上ないと自分でも思う。
暇だったのだと思う。暇だととにかく自分の哲学みたいなものを考え込んでしまうタイプだし、その哲学を他人に見せびらかしたかったのだと思う。そうやって多くの共感と反感を買ってきた。
多くの人を必要なく傷つけたと思う。そう思えるようになったのも、かつて小市民としてインターネット芸人のことを唾棄していた側から、自分が攻撃をされる側の人間になってしまったことに気がつけたからだと思う。他人を傷つけた分だけ自分に返ってくるというありがたい教えを授かった。
今でも自惚れていると思う。そしてそういう自分を軽蔑しているのも事実だと思う。そうでなければこの記事は書かなかっただろうし、そもそも書く必要もなかった。

今年に入ってからもう一度本来のTwiiterに向き合うために、色々なことを試してみた。色々と周りから言われた日記もその一環だった。でもあまりうまくいかなかった。すでに周りにとっての自分はインターネットの「やぷらす」さんになっていた。何もかも遅かった。
大学の親しい友人からHNで呼ばれるのはあまり嫌悪感を感じなかった。尤も彼らと親しいからということもあるだろうが、彼らはインターネットの「やぷらす」についてあまり言及をしないでくれて、単にニックネームとしての「やぷらす」でいてくれた。
4月から研究室に入ったが、同期が研究室内で「やぷらす氏」と呼んできたとき、思わず苦い顔をしてしまった。彼にとっての僕は同じ研究室の同期である以前に、「やぷらす氏」だったんだと思うし、彼を責める資格はない。ただ、研究室の先輩や先生の前でもそう呼ぶような様子だったので、2人きりの時にそう呼ぶのはやめてほしいと伝えたのだが、その次のゼミでも「やぷらすさん」と呼ばれてしまった。自分勝手なことだと思うけど、悲しかった。
姉と僕は歳が近いこともあって、小さい頃はよく喧嘩したけど、今ではお互い良き理解者であると思っている。僕は姉のTwitterアカウントを知っているし、姉も僕のTwitterアカウントを知っている。これを言ってしまうと本人から抗議されてしまうと思うが、姉は他人への配慮がズレているタイプであると思う。僕は家庭内で自分のインターネットでの活動を完全に秘密にしていたかった(姉はそうではないらしい)し、その旨を何度も姉に言ってたはずだが、姉は(おそらく悪意はなく)僕がTwitterで他人に褒められたことを家族の前で紹介する。今でも本当にやめてほしいのだけど、そういうことも続くと自分も感覚が麻痺してきて、姉が家で「やっぴー」と呼んできても返事してしまうようになっていたし、姉とTwitterで緩やかな交流をするようになっていた。

そこまでして自分が世間に物申すようなことってあまり無いのではないか。そう思えるようになったので、ためしに5日ほど一切のSNSをやめてみたが、実際そうだった。Twitterをしないストレスよりも、Twitterで受けるストレスの方が多くなっていたし、他人にストレスを与えることもなかった。本当に素晴らしいことだと思う。
そういう試みをしているのと同じ時期にUserStream廃止という出来事があった。UserStream廃止については、すでに多くの(あまりに多くの)賢人たちが言及していると思うから、僕から説明する必要もないと思うし、それらの言及に対して肯定も否定もしたくない。ただ、少しだけみんな感傷的という範疇を超えて集団ヒステリーになってしまっているのかなと思う(この表現を不愉快に感じた方には申し訳ないと思う)。
自分もTweetbotが使えなくなって軽いパニック障害になってしまった。自分がここまで適応障害気質なのかと自覚できた一方で、UserStreamによる対話性が失われたことでTwitterの用途について冷静になるきっかけになれたと思う。自分はTwitterというチャットルームに入り浸りのネトゲ廃人だったのかもしれない。よくTwitterの代替としてMastodonが挙げられているけど、そこで得られる「かつてTwitterにあったもの」は小さなコミュニティ内での対話性くらいで、そこには発言の場を担保することによる損得勘定のジレンマがある以上、Twitterとは別の問題を孕んでいると思う。しかも、僕がいくらTwitterの変心を訴えたところでTwitterはチャットルームではないし、元々チャットルーム的なTwitterの利用にうんざりしていたわけだから、僕の問題に関していえばどこかに移って解決するものでもない。新しい喫煙所を見つけたところで、禁煙が成功するわけではないのは当然である。

これからTwitterとどう向き合うかはよく分からない。多分今まで通りTwitterを続けると思うけど、もう少しミニブログとして付き合っていくことになるんじゃないかなと思っている。そうやって少しずつ自分の人生に向き合えるようになって、ゆくゆくはSNSをやめられればベストじゃないかなと思う。
適当に済ませるつもりが思いの外長文になってしまった。本当はもっと書きたいことがあったと思うけど、心の整理をするにはこれくらいで十分だったのだと思う。

絵とか卒論とかその他の生産的なこととか

夏だからバリバリやっていきたい。相変わらずスランプ気味だし、他のやらなきゃいけないことが頭の中に残っていて、あまり筆が進まないけど、とにかくやるしかない。暇だから考えすぎてしまうだけだから、とにかく何も考えないことにする。ノイローゼになる前に色々な人に相談できてよかったと思う。

ゲームボーイで画像を表示した話

昨日の続きでゲームボーイ(以下GB)のお話。

画像を表示したい(BG編)

GBにも任天堂ハードの例によってBGとOBJ(加えてGBにはウインドウ)があります。ざっくり言えばOBJはスプライト(プレイヤーや敵キャラみたいな動き回るやつ)でBGは背景(タイル状に敷き詰められてオフセットスクロールのみ)です。ウインドウはまだ詳しく調べてないけど、BGとは別に(=オフセットスクロールに依存しない)サブ画面を持たせるためのやつらしい。ファミコンよりゲーム用の機能を充実させた感じ。
今回は任意の画像をGBのBG画面に表示させたいと思います。ところで「GBのBG画面」ってややこしいな。

まずGBDKのコンパイラのインクルードファイルを眺めます。/opt/gbdk/include 以下がそれですね。
gb/hardware.h とか gb/gb.h あたりにいい感じの定義とか関数がたくさんまとめられてるっぽい。gb/gb.hを見てみましょう。

(略)
/** Turns on the background layer.
    Sets bit 0 of the LCDC register to 1.
*/
#define SHOW_BKG \
  LCDC_REG|=0x01U
(略)

LCDC_REG はBGコントロールレジスタへのポインタっぽいです。SHOW_BKG;でBGを有効化できるみたいですね。

続けて下の方も見てみましょう。

(略)
/** Sets the tile patterns in the Background Tile Pattern table.
    Starting with the tile pattern x and carrying on for n number of
    tile patterns.Taking the values starting from the pointer
    data. Note that patterns 128-255 overlap with patterns 128-255
    of the sprite Tile Pattern table.  

    GBC: Depending on the VBK_REG this determines which bank of
    Background tile patterns are written to. VBK_REG=0 indicates the
    first bank, and VBK_REG=1 indicates the second.

    @param first_tile   Range 0 - 255
    @param nb_tiles Range 0 - 255
*/
void
set_bkg_data(UINT8 first_tile,
         UINT8 nb_tiles,
         unsigned char *data) NONBANKED;
(略)

void set_bkg_data() はタイルの画像データを配列 *data で受け取ってVRAMに設定してくれそうな感じがします。

(略)
/** Sets the tiles in the background tile table.
    Starting at position x,y in tiles and writing across for w tiles
    and down for h tiles. Taking the values starting from the pointer
    data.

    For the GBC, also see the pan/k00Pa section on VBK_REG.

    @param x        Range 0 - 31
    @param y        Range 0 - 31
    @param w        Range 0 - 31
    @param h        Range 0 - 31
    @param data     Pointer to an unsigned char. Usually the 
                first element in an array.
*/
void
set_bkg_tiles(UINT8 x,
          UINT8 y,
          UINT8 w,
          UINT8 h,
          unsigned char *tiles) NONBANKED;
(略)

こっちの void set_bkg_tiles() はタイルのパターン(配置)を配列 *tiles で受け取ってVRAMに設定してくれそうな感じがします。

ここで昨日紹介したGBTDG(GAMEBOY Tile Data Generator) を見ると、ちょうど画像から画像データとそのタイルパターンの配列を出力してくれる(しかも同じタイルを最適化してくれる、神)じゃないですか!
ゲームボーイの解像度は160x144、色数はモノクロ4階調なので、それに合わせて画像を作成して、GBTDGに投げて出力を保存します(ここではshumatsu.cとしましょう)。

上のgb/gb.hを参考に、昨日のHello Worldのmygame.cを以下の内容に書き換えます。

#include <gb/gb.h>
#include "shumatsu.c"

void main() {
    set_bkg_data(0, 255, shumatsu_tile_data);
    set_bkg_tiles(0, 0, shumatsu_tile_map_width, shumatsu_tile_map_height, shumatsu_map_data);

    SHOW_BKG;
}

コンパイルされたmygame.gbをエミュレータで開いて、あらかじめ作成した画像が表示されれば成功です。やったぜ。

f:id:yaplus:20180603180412p:plain
終わるまでは終わらないよ

set_bkg_tilesし忘れるとこうなります。(追記:この形状的に起動直後のNintendoロゴの残骸っぽいと思うんだけどよくわからん。VRAM見れるエミュレータが必要だな…。)

f:id:yaplus:20180603180445p:plain
石でも食ってろ

こんなんサルでもできるやろがい

f:id:yaplus:20180603180556p:plain
エーケイザー・エケリ

GBAの時は参考書籍を参考にドライバを自作したので、インクルードひとつでこれだけの機能が扱えるあたり、先哲の知恵は偉大ですね。
まあ実際には貧弱なリファレンスとインターネットの怪情報を片手にGBDKにどういう機能が用意されているのか調べる必要があるし、コンパクトなソースにしたいのであれば自分で実装した方が早いというのもあるかもれないですけども、今回は車輪の再発明をしないという方向でやっていきたいと思います。英語を読む勉強にもなるし。

色々と気になったことがあったので以下は備忘録です。

ROMの拡張(バンク切り替え)ってどのくらいの規模になると必要になるの?

こんなもの見つけました。GBのソフトとその容量およびカセット内部の構成をまとめたものです。
とりあえず思いつくゲームタイトルで検索してみると、なんとGBのローンチタイトルであるスーパーマリオランドですらいきなりMBC1によるバンク切り替え(64KB)を行なっているようです(!)。ファミコンでのノウハウから最初からバンク切り替えを前提に設計されたと思っていいでしょう。実際MBC1にはMMCに似たところがあるようです(未確認)。
一方でテトリス(無印)やドクターマリオヨッシーのたまごあたりの初期のパズルゲームタイトルはバンク切り替えなし(32KB)です。ハードは異なりますが、以前自作したガヴドロアドバンスの容量は90KBくらいで、しかもGBAは複数BG分タイルデータが大きいにも関わらずこの程度で済んでるので、自作ソフトでどれだけ作り込むかにもよりますが、案外ミニゲーム程度であれば32KBでもなんとかなるんじゃないかと思えてきました。

万一容量がオーバーするような場合にはGBDKは手動でのバンク切り替えをライブラリでサポートしてくれるみたいですGBDKのドキュメントは色々お役立ち情報があるみたいですがたまに書きかけで雑に放置されてたりするので過信は禁物。

OBJ(スプライト)のパレットってどうなってるの?透明色の設定は?

GBはファミコンと同じく1つのOBJに対して3色+透明色1色を設定できます。扱える色は4色なので、4色のうち1色が透明色という扱いになるみたい。
具体的には

OBP0_REG = 0xE1;

みたいに設定します。
GBでは2ビット(4色)が11が黒、10が濃いグレー、01が薄いグレー、00が白と設定されています。
0xE1 = 0b11100001であり、OBP0_REGの2ビットずつがパレットであり、最下位2ビットが透明色に設定されるということらしいです。この場合は01(薄いグレー)が透明色になります。

当面の目標

OBJ(スプライト)の表示

キー入力の受け付け

これがないとゲームにならないでしょ。
やることとしては当面GBA開発のときと同じ手順でやっていくつもり。

感想

うるせ〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜!!!!!!!
しらね〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜!!!!!!!!

魔界塔士Sa・
Ga

ゲームボーイの開発環境を整えた話

某ポルノアニメ氏を見てたら何かしらレトロゲームぽいやつを作りたい熱が再燃してきたので、ゲームボーイの開発環境を整えた。
前にゲームボーイアドバンスの開発環境を整えたことがあったが、GBとGBAアーキテクチャが全く異なるように開発環境も違うっぽい(ちなみにDSの開発はdevkitProで済む)。以下メモ。

環境は以下の通りです(2018年6月2日現在最新)。

GBDKのインストール

ゆとり世代だからアセンブリなんか書きたくない!
GB用のCコンパイラや色々便利なライブラリがセットになったGBDKをインストールします。
さくさんさんの記事を参考にしました。

macOS用パッチ付きのGBDKをcloneしてきてビルドします。

$ git clone https://github.com/CH3COOH/gbdk.git
$ cd gbdk
$ patch -p0 < macosx.patch
$ mkdir -p sdcc/bin
$ make

次からが重要で、ビルドが終わったら (作業ディレクトリ)/gbdk/build/ppc-unknown-linux2.2/ 以下の gbdk/ ディレクトリを /opt 以下にコピーしてあげましょう(シンボリックリンクにしようとしたけどうまく動かんかった)。
/opt がなければ作ってください。

$ sudo mkdir /opt
$ cp -r ./build/ppc-unknown-linux2.2/gbdk/ /opt

終わったらサンプルをビルドしてみましょう。

$ cd /opt/gbdk/examples/gb 
$ make
../../bin/lcc -Wa-l -Wl-m -Wl-j -c -o galaxy.o galaxy.c
../../bin/lcc -Wa-l -Wl-m -Wl-j -o galaxy.gb galaxy.o
../../bin/lcc -Wa-l -Wl-m -Wl-j -c -o space.o space.s
../../bin/lcc -Wa-l -Wl-m -Wl-j -o space.gb space.o
../../bin/lcc -Wa-l -Wl-m -Wl-j -c -o paint.o paint.c
../../bin/lcc -Wa-l -Wl-m -Wl-j -o paint.gb paint.o
../../bin/lcc -Wa-l -Wl-m -Wl-j -c -o rpn.o rpn.c
../../bin/lcc -Wa-l -Wl-m -Wl-j -o rpn.gb rpn.o
../../bin/lcc -Wa-l -Wl-m -Wl-j -c -o rand.o rand.c
../../bin/lcc -Wa-l -Wl-m -Wl-j -o rand.gb rand.o
../../bin/lcc -Wa-l -Wl-m -Wl-j -c -o comm.o comm.c
../../bin/lcc -Wa-l -Wl-m -Wl-j -o comm.gb comm.o
../../bin/lcc -Wa-l -Wl-m -Wl-j -c -o irq.o irq.c
../../bin/lcc -Wa-l -Wl-m -Wl-j -o irq.gb irq.o
../../bin/lcc -Wa-l -Wl-m -Wl-j -c -o filltest.o filltest.c
../../bin/lcc -Wa-l -Wl-m -Wl-j -o filltest.gb filltest.o
../../bin/lcc -Wa-l -Wl-m -Wl-j -c -o ram_fn.o ram_fn.c
../../bin/lcc -Wa-l -Wl-m -Wl-j -Wl-g_inc_ram=0xD000 -Wl-g_inc_hiram=0xFFA0 -o ram_fn.gb ram_fn.o
../../bin/lcc -Wa-l -Wl-m -Wl-j -c -o fonts.o fonts.c
../../bin/lcc -Wa-l -Wl-m -Wl-j -o fonts.gb fonts.o
../../bin/lcc -Wa-l -Wl-m -Wl-j -c -o samptest.o samptest.c
../../bin/lcc -Wa-l -Wl-m -Wl-j -o samptest.gb samptest.o
../../bin/lcc -Wa-l -Wl-m -Wl-j -c -o banks.o banks.c
../../bin/lcc -Wa-l -Wl-m -Wl-j -Wf-ba0 -c -o bank_0.o bank_0.c
../../bin/lcc -Wa-l -Wl-m -Wl-j -Wf-bo1 -Wf-ba1 -c -o bank_1.o bank_1.c
../../bin/lcc -Wa-l -Wl-m -Wl-j -Wf-bo2 -Wf-ba2 -c -o bank_2.o bank_2.c
../../bin/lcc -Wa-l -Wl-m -Wl-j -Wf-bo3 -Wf-ba3 -c -o bank_3.o bank_3.c
../../bin/lcc -Wa-l -Wl-m -Wl-j -Wl-yt2 -Wl-yo4 -Wl-ya4 -o banks.gb banks.o bank_0.o bank_1.o bank_2.o bank_3.o
rm filltest.o comm.o rand.o rpn.o samptest.o paint.o space.o fonts.o irq.o galaxy.o

galaxy.gbが /opt/gbdk/examples/gb にできていればオッケーです。

動作確認用エミュレータのインストール

以前インストールしたmGBAゲームボーイ(カラー)も動作するって書いてあったのに動作しなかった。よくわからん。
色々探してたら上記の記事でも紹介されているGambatteのCocoaアプリ版であるGambattyeがあったのでとりあえずこれを導入。Macネイティブでアプリのアイコンもかっこいい(重要)し。

しかしGambattyeにはRAM/VRAMビューワが付いてないっぽい。うーん…デバッグの時困りそう。いい感じの動作確認用エミュレータがあればコメントやTwitterとかで教えてください。助かります。

Hello Worldをビルドする

まだGBDKについてよくわかってないんですが、この辺を参考に以下の感じでHello Worldできたんでまあいいかってなってます。

適当なディレクトリにmygame.cとMakefileを作る。

mygame.c

#include <stdio.h>

void main() {
    printf("Hello World.\nYappy Dayo.");
}

Makefile

GBDK = /opt/gbdk
CC   = ${GBDK}/bin/lcc -Wa-l -Wl-m -Wl-j
BIN  = mygame.gb

all:    $(BIN)

%.o:    %.c
    $(CC) -c -o $@ $<

%.s:   %.c
    $(CC) -S -o $@ $<

%.o:    %.s
    $(CC) -c -o $@ $<

%.gb:    %.o
    $(CC) -o $@ $<

clean:
    rm -f *.o *.lst *.map *.gb *~ *.rel *.cdb *.ihx *.lnk *.sym *.asm

makeすればmygame.gbっていうファイルができてると思います。やったね!

f:id:yaplus:20180602202551p:plain
こんにちわ〜

ハードウェアの仕様とか調べつついい感じにやっていきたい。ゆうてGBAと似たことすればなんとかなるっしょくらいに思ってる。ゆとり世代だし。

便利そうなやつ見つけた

GAMEBOY Tile Data Generator

GBA開発で言うところのgrit的なやつ(と思われる)。
画像をGB用にモノクロ4色に減色してC(またはZ80アセンブリ)コードに落とし込んでくれるだけなんだけど、GBAでの経験的にこれがあるだけでだいぶ助かると思う。タイルデータさえできればあとは汎用マップエディタでマップデータ作ればいいしね。

感想

2018になって29年前のゲームボーイソフト開発?って思うかもしれないけど、逆にせいぜい17年くらいのGBAよりも風情があってよくない?

精神的に向上心のない者はばかだ。 - K (夏目漱石「こころ」)

精神的に向上心のない太郎なので今日はここまで。

ゲームボーイアドバンス開発メモ その1

大学の主専攻実験の1つでゲームボーイアドバンス(以下GBA)上で動作するプログラムの作成を行うことになったため、以下の環境で開発環境を構築した際の(雑な)備忘録です。

2017年にもなって自分からGBA開発する人がどれだけいるかわからないですが、来年の後輩とか興味を持った人の参考程度になるといいです。

devkitProのインストール

GBA用のプログラムのコンパイルにはARM7に対応したコンパイラが必要なので、コンパイラ一式とモジュールやツール類がセットになったdevkitProをインストールします。

ここのdevkitARMupdate.plをダウンロードし、

> perl ~/Downloads/devkitARMupdate.pl

でインストール後、パスを通しておきます。fish(すごいシェル)では以下のように。

# devkitPro (for GBA development)
set -x DEVKITPRO $HOME/.devkitPro
set -x DEVKITARM $DEVKITPRO/devkitARM
set -x fish_user_paths $DEVKITARM/bin $fish_user_paths

以上でdevkitProのインストールは完了です。これで環境構築のほとんどの作業は終わったと思っていいです。

動作確認用エミュレータのインストール

Mac用のGBAエミュレータはいくつかあるみたいですが、比較的最近も更新が行われておりOpenEmuにもコアが内蔵されているmGBAをインストールしました。
デバッグ用のメモリビューアやタイルビューアなども一通り入っておりこれで十分かと思います。
一時期メジャーだったVBA(Visual Boy Advance)のMac移植版のMac Boy Advanceは自分の環境ではなぜかROMの読み込み時に必ずクラッシュしたので確認してません。

実機で動かすためのブートケーブルとソフトウェアの準備

大学の実験ではGBA SPとLinuxから目覚めるぼくらのゲームボーイ!と付属のUSBブートケーブルが貸与され実機で確認できるようになっているので、実機への転送用ソフトウェアもインストールします。
この書籍の著者である西田氏のホームページでoptusbという転送用プログラムが用意されています。

まずoptusbに必要なlibusbをインストールしますが、バージョンが古いために当時のバージョンと互換性のあるlibusb-compatをbrewからインストールします。

> brew install libusb-compat

次に、ここ からダウンロードしてきたソースコードMakefileを以下のよう書き換えます。

optusb: optusb.c usb.h libusb.a
    gcc -I `brew --prefix libusb-compat`/include/usb.h -L `brew --prefix libusb-compat`/lib -lusb -Wall -o optusb optusb.c

clean:
    rm -rf optusb *.o

これをmakeすればoptusbのビルドの完了です。
ここら辺はほとんど大学のOBであるshiftky氏のGistを参考にしました(Makefileはそのままです)。この場を借りて感謝します。問題があれば消します。

サンプルをビルドしてみる

devkitProを通常通りにインストールすると~/.devkitPro以下にサンプルプログラムがたくさん入ってるexamples/gba/があると思うので、この中からtemplate/を適当なディレクトリにコピーしてきます。

> cp -r ~/.devkitPro/examples/gba/template ~/Documents/GBA/
> cd ~/Documents/GBA/template

そのままmakeするとtemplate.gbaというファイルができているはずです。

> make
template.c
arm-none-eabi-gcc -MMD -MP -MF /Users/yaplus/Documents/GBA/template/build/template.d -g -Wall -O3 -mcpu=arm7tdmi -mtune=arm7tdmi -fomit-frame-pointer -ffast-math -mthumb -mthumb-interwork -iquote /Users/yaplus/Documents/GBA/template/include -I/Users/yaplus/.devkitPro/libgba/include -I/Users/yaplus/Documents/GBA/template/build -c /Users/yaplus/Documents/GBA/template/source/template.c -o template.o 
linking cartridge
built ... template.gba
ROM fixed!
> ls
Makefile        source          template.gba    template.sav
build           template.elf    template.pnproj

.gbaファイルがROMファイル(バイナリ)なので先ほどインストールしたエミュレータで動作確認してみてください。

とは言うものの

devkitPro付属のサンプルプログラムはビルドできたものの、これだけではソースコードすら読んでいないし、実際ソースファイルであるtemplate.cではdevkitPro付属であろう未知のライブラリを使っているので、何が何だから全然わからんです。
せっかく組み込みシステムで開発をするのにハードウェアへの理解もないままプログラミングするのは向上心がないので、次のエントリあたりで実際のプログラムについてのメモ書きをしようと思います。