ORANGE pico 標準搭載のキャラクターを確認する

[ORANGE pico](http://www.picosoft.co.jp/orange/) に標準搭載されているキャラクターを確認しておく。
このキャラクターには、以下の3グループが存在する。

* 文字フォント
* システムキャラクター
* スプライトパターン

# 新たに発見した罠

本題に入る前に、新しく発見した罠を紹介する。

## cpeek コマンドの罠

公式のコマンド一覧の `cpeek` 命令の説明には、以下のように書かれている。

> パターン指定が1000～1133の場合は16×16ピクセルのパターンをメモリー配列の8000～8031に読み込みます。

しかし、パターン指定で `1133` を指定していみると、Illegal function call になってしまった。
さらに試してみると、`1128` 以降のパターンを指定すると Illegal function call が出るようである。

![cpeekコマンドで正しいはずのパターン指定が動かない](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/7e37e2be-ad62-081e-df59-86ffb0fd37f7.png)

表示上の問題だけではなく、実際にパターンの読み込みができていないようである。
以下の例では、左側に描画しようとした1128番のパターンは描画できていない (読み込めていない) が、右側に描画した1127番のパターンは描画できている。

![cpeekコマンドで有効なはずのパターンが読み込めない](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/059feff4-b57e-427d-79b2-68a6489b3086.png)

`sprite` コマンドでは、1128～1133番のパターンも普通に参照できるようである。
そのため、この罠の回避策としては、取得したいパターンを一旦 `sprite` コマンドで画面に出力し、`point` 関数で1ピクセルずつ取得していく方法がある。
公式のコマンド一覧の `point` 関数の説明には「TFT液晶では使用できません」と書かれているが、以下のプログラムで試したところ `sprite` コマンドによる画面出力はTFT液晶モードであっても `point` 関数の返り値に反映されていた。(`line` コマンドによる描画は反映されなくなった)

```
10 cls
20 sprite 1,0,0,1000,0
30 line 0,0,100,100,rgb(255,255,255)
40 for y=0 to 20
50 for x=0 to 20
60 print point(x,y);
70 next
80 print ""
90 next
```

## cpoke コマンドの罠

公式のコマンド一覧の `cpoke` 命令の書式と説明には、以下のように書かれている。

> ```
> cpoke キャラクターコード , パターン指定
> ```
>
> 指定したキャラクターコード（0～255）のパターンを設定します。パターンは、数値(0～128)で指定します。
> (中略)
> パターン指定を省略すると、デフォルトのパターンにリセットされます。

「数値(0～128)」と書かれているにもかかわらず、128を指定すると、Illegal function call になってしまった。

![範囲内のはずの数値128でIllegal function call](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/6be2f1d9-642f-aff3-467f-11c706cb43b3.png)

さらに、パターン指定を省略し、キャラクターコードのみを指定してみると、Syntax error になってしまった。
キャラクターコードに続けて `,` のみを指定した場合、Syntax error は出なかったが、パターンのリセットも行われなかった。

![cpokeによるパターンのリセットが期待通り動作しない](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/91f9b936-ec60-cfdf-915f-d873c07a085b.png)

キャラクターコードも省略した

```
cpoke
```

により、全キャラクターのパターンのリセットを行うことはできるようである。

# キャラクターを確認する

## 文字フォント

普通に文字を描画する際に用いられるフォントを、ここでは「文字フォント」と呼ぶ。
すなわち、テキストVRAMに文字を書き込んだ際、それに応じて表示されるパターンである。

以下のプログラムにより、パターンをリセット後、テキストVRAMに0～255の文字コードを書き込み、文字フォントを描画させる。
最後に、何かキーが押されるまで描画したまま待機する。

```
10 cpoke
20 mset 0, 0, 1000
30 lx=12:ly=4
40 for i=0 to 15
50 c=asc(format$("%X", i))
60 mpoke 40*(ly-2)+lx+i, c
70 mpoke 40*(ly+i)+lx-2, c
80 next
90 for y=0 to 15
100 for x=0 to 15
110 mpoke 40*(ly+y)+lx+x,16*y+x
120 next
130 next
140 vmove 0, 1
150 locate 0, ly+16
160 if inkey()==0 then goto 160
```

実行結果は以下のようになった。

![0～255のコードに対応する文字フォント](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/e6310d44-f0ff-d080-7d53-c19098a3378a.png)

[IchigoJam キャラクターコード一覧 - イチゴジャム レシピ](https://15jamrecipe.jimdofree.com/%E3%83%84%E3%83%BC%E3%83%AB/%E3%82%AD%E3%83%A3%E3%83%A9%E3%82%AF%E3%82%BF%E3%83%BC%E3%82%B3%E3%83%BC%E3%83%89%E4%B8%80%E8%A6%A7/)
と比較すると、以下のことがいえる。

* IchigoJam では &H00～&H1F の範囲もパターンが定義されているが、ORANGE pico では空白である。
* &H80～&H8F の範囲では、ORANGE pico でも IchigoJam と同様のグラフィック文字になっている。
* &H90～&H9F の範囲は、罫線という点では似ているが、まっすぐな線と枝分かれがある線の順番が異なるなど、互換性は無い。
* &HE0～&HFF の範囲は、IchigoJam では様々なキャラクターが定義されているが、ORANGE pico ではシンプルなパターンがメインである。
* 円マーク(￥)は、IchigoJam では &HA0 であるが、ORANGE pico では &HFC である。

なお、IchigoJam では &HE0～&HFF の範囲のパターンのみを変更可能であるが、ORANGE pico では &H00～&HFF 全てのパターンが変更可能であることにも注目したい。

※IchigoJamはjig.jpの登録商標です。

さらに、ORANGE pico には[美咲フォント](https://littlelimit.net/misaki.htm)が搭載されており、`cpeek` コマンドでフォントを読み出して使用することができる。
これにはひらがなや漢字などが含まれ、量が多いため、ここでは紹介しない。

## システムキャラクター

文字フォントとは別に `cpeek` 命令や `cpoke` 命令で0～127の数値を用いて参照できる8×8ピクセルのパターンを、ここでは「システムキャラクター」と呼ぶ。
このシステムキャラクターは公式で一覧が出ているが、プログラムでも描画して確認してみる。

以下のプログラムにより、`cpeek` 命令でシステムキャラクターを読み出し、`gput` 命令でグラフィック画面に描画を行う。
最後に、何かキーが押されるまで待機する。

```
10 lx=3:ly=4:wx=40:wy=12:ox=26
20 cls:color=rgb(255,255,255)
30 for y=0 to 15
40 for x=0 to 7
50 c=16*x+y
60 gprint lx+wx*x,ly+wy*y,format$("%3d",c),color
70 cpeek -1,c
80 gput lx+wx*x+ox,ly+wy*y,8,8000,color
90 next
100 next
110 if inkey()==0 then goto 110
```

実行結果は以下のようになった。

![システムキャラクター一覧](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/1e6c7d84-df5d-dd5d-9991-d26cb3e2fc89.png)

公式のシステムキャラクター一覧の通りになっていることが確認できた。
(ピクセル単位で一致しているかどうか確かめてはいないが、少なくとも絵と数値の対応はドキュメント通りのようである)

## スプライトパターン

`cpeek` 命令や `sprite` 命令で1000～1133の数値を用いて参照できる16×16ピクセルのパターンを、ここでは「スプライトパターン」と呼ぶ。
システムキャラクターとは異なり、現時点でドキュメントを発見できていない。

以下のプログラムにより、`cpeek` 命令でスプライトパターンを読み出し、`gput` 命令でグラフィック画面に描画を行う。
ただし、前述の通りなぜか `cpeek` 命令で取得できない1128番以降のパターンについては、かわりに `sprite` 命令で描画を行う。
パターン番号の千の位は全て1なので、画面配置の関係で省略した。
何かキーが押されるまで待機し、2ページにわけて表示する。

```
10 lx1=4:lx2=8:wx=32:ly1=2:ly2=12:wy=28:safe=1127:color=rgb(255,255,255)
20 for p=0 to 1
30 cls
40 for y=0 to 6
50 for x=0 to 9
60 puttern=p*70+x*7+y
70 gprint lx1+wx*x,ly1+wy*y,format$("%03d",puttern),color
80 if 1000+puttern>safe then goto 120
90 cpeek -1,1000+puttern
100 gput lx2+wx*x,ly2+wy*y,16,8000,color
110 goto 130
120 sprite 1000+puttern-safe,lx2+wx*x,ly2+wy*y,1000+puttern,0
130 next
140 next
150 if inkey()==0 then goto 150
160 next
```

実行結果は以下のようになった。

![スプライトパターン一覧 1](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/3793df17-53e4-e034-9bda-198c8941bce7.png)
![スプライトパターン一覧 2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/1365c778-1d4d-50a1-9ce4-0cb66fc911fa.png)

風船、人、果物、スロットの絵柄、飛行機、球などのパターンがあるようである。
1134番以降のパターンは8×8ピクセルのパターンがずれて表示されているような乱れた表示になっており、無効そうなことがわかる。

# ライセンス

今回のプログラムは、[CC0 1.0](https://creativecommons.org/publicdomain/zero/1.0/deed.ja) でライセンスする。

ORANGE pico のファームウェア、およびそこに搭載されているフォント (美咲フォントを除く) のライセンスは現時点では不明である。

# 結論

公式で一覧が出ているシステムキャラクターに加え、一覧がこれまで発見されていなかった文字フォントおよびスプライトパターンをプログラムで出力させ、一覧を作成した。
その過程で、1128～1133番のパターンが有効であるにもかかわらずなぜか取得できないという `cpeek` コマンドの罠を発見した。