たまりば

  パソコン・インターネット パソコン・インターネット  三鷹市 三鷹市

【訂正・加筆】
2019年07月17日 00:00

2019/07/17 ファミコンで9×9ドット文字表示(ほか)に実機動作していただいたツイートを追加、およびコードのミスを修正。
2019/07/17 ファミコンで全画面に任意の画像(ただしモノクロ)を表示のコードのミスを修正。
2017/04/23, 2017/05/22, 2017/07/24, 2017/11/21, 2019/06/08, 2019/06/16, 2019/06/22, 2019/07/15ゼルダの伝説ブレスオブザワイルドプレイ日記(ネタバレ有) 更新。
2016/12/06 漢点字一覧表で、別の元データとの間で不一致があったので追記。
2016/09/10 ネット契約を1Mbpsにしてみたの読み込み時間の記述が間違っていたので訂正。
2016/09/04 ファミコンの縦解像度224px説の考察 左8pxを隠す機能の用途が思っていたのと違ったので追記。
2016/06/06 Windows7でのペイントの劣化具合に新しく気づいたバグ情報を追加。
2015/08/29 ベースラインPICの注意点で、型番の間違いを訂正、OPTION2の書き込み方法の間違いを訂正。
2015/08/28 Windows7でのペイントの劣化具合に新しく気づいたバグ情報を追加。
2013/09/26 5×5 ひらがなフォント5×5フォント改 / JavaScriptフォント表示機から5×5ドットフォント完成版に、思えばリンクを貼っていなかったのでリンク。
2013/05/05 最弱のPICマイコンで電子オルガン_前編の単純ミスを1ヶ所修正。
2013/04/27 文字コード表示機が特定の環境で動かない問題を修正、RTL文字での表示崩れを修正。
2013/03/03 5×5ドットフォント完成版が紹介されていたので少々加筆しました。
2012/11/18 ハロウィー?ンの正規表現に訂正・加筆があります。

【このエントリについて】
(2012/11/18)
今まで、記事の内容にミスを見つけた場合はその記事だけ修正していたのですが、最新の記事はともかく古い記事にミスを見つけた場合は直しても気づかれないだろうと思って直すのが億劫になっていました。
これではいけないと、どうするべきか考えた結果、訂正を知らせるエントリを1つ作ることにしました。
記事を訂正した際にはこのエントリを更新して最上位に持ってくるように運用しようと思います。
(2013/03/03)
訂正だけに限らなかったので、エントリ名を【訂正】から【訂正・加筆】に変更しました。  
タグ :お知らせ

  • Twitterの画像の扱いがやっとまともになって嬉しい
    2019年06月23日 00:23

    大昔、TwitterにJPEG画像を上げればJPEGのまま、PNG画像を上げればPNGのままだった。まあこれはこれで最高ではあった。

    それが2016年1月、基本的にPNGはJPEGに変換されるようになった。
    ただし、1pxでも透過部分のあるPNGはPNGを維持する。(容量の上限もあり。3MB?)

    この仕様の問題点は
    ・PNGの方が容量が少ないようなファイルは、容量が増える。
    ・PNGの方が望ましいような画像をPNGで上げたい場合、目立たないよう隅などを透過する面倒な作業が発生する。
    ・PNGをPNGで上げる操作は本来意図していないであろう裏技であり、知っている者と知らない者に不公平がある。
    ・JPEGの方が望ましい画像(JPEGの劣化はさほど目立たない一方、PNGでは容量が非常に大きくなるもの)もPNGで上げられる。ダウンロードに時間が掛かったり、ギガが減る。


    それが先日、2019年2月11日の新しい仕様で、透過PNGの裏技が使えなくなったとともに、一定の条件でPNGを維持するようになった。
    具体的には、「900×900以下」または「256色」または「JPEGに変換した場合よりPNGのままの方がデータ量が少ない」場合にPNGを保つようになった。
    (なおJPEGも、TwitterのJPEGよりデータ量が少ない場合に上げたままのJPEGを保つようになったようだ)

    これは上記の問題点の解決を意図したものだろう。
    ・PNGの方が容量が少ないようなファイルは、PNGのまま容量は増えない。
    ・PNGの方が望ましいような画像をPNGで上げたい場合、PNGで上げるだけで済む。
    ・裏技は無く、公平に処理される。
    ・PNGでは容量がかさむ画像はJPEGでしか上げられないので、適切な容量で閲覧できる。900×900制限は、小サイズなら容量も少ないので許容ということだろう。

    新仕様に問題が無いわけではない。

    イラストなど劣化の無い最高の画質で見せたい/見たいような画像については、新仕様では無劣化は不可能になった。
    これ自体はサーバーのコストとの兼ね合いであり、仕方ないことだ。
    だが、それにしてもPNGとJPEGで落差が激しすぎるのは問題だと思う。
    Twitterで使われるJPEGは85%・サンプリング4:1:1という画質のだいぶ低めな設定なので、色がくすむなどものによって劣化がかなり目立つ。
    そしてPNGを保つ条件はこの低画質のJPEGより容量が少ないことなので、かなり厳しい条件となってしまっている。

    一方、900×900の上限はかなり緩すぎると感じる。このサイズの無駄PNGはかなりの大容量だ。
    風景写真などJPEGの方が望ましい画像も、このサイズ以内ならPNGで上げられてしまう。
    わざわざ写真をPNGで上げる人もそういないと思うだろうが、フォトリアルなゲームのスクリーンショットはよくPNGで上げられる。
    また実写写真でもたまに見かける。MSペイントのデフォルト保存形式がPNGなことや、ファイルでなく画像データをそのまま投稿画面にペーストすることができることを考えると、意図せずPNGで上げられることもあるのだろう。


    総合して、問題はあるものの、基本的には今回の仕様変更は改善だと思っている。
    以前あった無駄や不公平は無くなり、新たな制限もコストとのトレードオフで納得のできるものだ。

    一応改善案も示しておこう。
    PNGとJPEGの落差が激しい問題に対して、現状のPNG・低画質JPEGの間に例えば90%・4:4:4程度の「それなりに高画質のJPEG」を挟めば大分印象は変わる。
    単純に判定するなら、「PNGは高画質JPEGより容量が少ない場合PNGを保ち、そうでなければ高画質JPEGにする。JPEGは低画質JPEGにする。」という判定が考えられる。
    JPEGをPNGとして上げると高画質で上げられてしまう欠点はある。
    もっと適切な判定をするなら、何らかの指標(単純なPSNRで十分だろう)でJPEG化した時の劣化度合いを測り、劣化が激しいようなら高画質にするという判断が考えられる。
    サーバーコストとのトレードオフだが、まず900×900の小サイズ許容は無くしても問題ないだろう。
    また、現状PNGを保つ場合はタイムラインに表示される縮小版もクリックして表示される拡大版もPNGとなっているが、縮小版はサイズがかさむ場合JPEGでも構わない(むしろ望ましい)だろう。
    拡大して見る画像は少ないから、これだけでかなり通信量は抑えられるのではないだろうか。それでも足りなければ縮小版を更に低画質にするのもよいだろう。  

  • ファミコンで9×9ドット文字表示(ほか)
    2019年04月08日 02:02

    ファミコンあたりのゲーム機は画面を8×8ドットのタイルを並べて構成している。よって文字表示は8×8ドット(空白含む)にするとプログラムが簡単だ。
    このサイズだとひらがなカタカナ(濁点・半濁点なし)にちょうどいいサイズである。英数字にはやや大きいがさほど不自然でもない。

    問題は漢字表示である。
    8×8ドットに漢字を描くのはかなりの無理がある。16×16ドットにすれば何不自由なく描けるが、このサイズの文字は大きすぎて画面内に書ける文章量が減る。
    そこでその中間あたりのサイズの文字表示をやってみようと思い立った。

    まず考えたのが12×12ドット(空白含む)だ。1.5マスで比較的扱いが楽そうだ。
    ゲームボーイでプログラムを組んでみて、まあうまくいった。
    12×12ドット文字_ゲームボーイ

    なお後に知ったのだがゲームボーイで12×12ドットのフォントはいくつか例がある。その1つの「合格ボーイ」シリーズの「常識の書」がこちらだ。
    常識の書_横書き常識の書_縦書き

    さて、12ドット文字プログラムだが、意外と面倒な面が多かった。
    1文字を18バイトで持っていたのだが、18は切りが悪い。縦横に空白をとると11×11ドットであり、11×11=121ビットというのは16バイトに収まる。せっかくだから収めたくなるがなかなか上手くいかない。
    半角文字も用意したくなるが、横6ドットとなるとせっかくの1.5マスの切りの良さが無くなってしまう。
    12×12ドットはわりと面積が広く、書き込みに意外と時間がかかる。
    (なお先述の「常識の書」だが、英数字は全角の半分ではなく横8ドットにして切りの良さを保ち、フォントデータは中央4ドットを重複して持つことで表示を楽にしている。勉強になる)

    12ドットでも面倒なら別のサイズでも似たようなものではないかという思いにいたり、別のサイズを模索してみることにした。
    すると9×9ドット(空白含まず)がかなり楽そうだと分かった。
    一見中途半端だが、9×9ドットはどのように配置しても8×8ドットのマス目の4マスにかかるという重要な性質がある。場合分けが不要というのは楽だ。
    8bitCPUのレジスタは8bitだが、キャリーフラグをうまく使えば9bitを保持しておくことができる。
    文字を9×9ドットとして1ドットの空白を設ければ10ドット。偶数なので奇数より多少楽だ。

    そんなわけでゲームボーイで組んだ。
    9×9ドット文字_ゲームボーイ
    見ての通り表示できる文字数が増えるのも利点だ。漢字の読みやすさは12ドットには劣るものの、十分だろう。

    その後ファミコンに移植してみた。
    ファミコンでもカートリッジにメモリを積めばゲームボーイと同様にキャラクタを書き換えることができる。(CHR-RAMと呼ばれる)
    (以前はあまりカートリッジ側に複雑なものを載せるのはレトロゲームプログラミングとして反則な気がして敬遠していたのだが、CHR-RAMを使っているソフトは普通にある感じなのでいいかと思い直した)
    9×9ドット文字_ファミコン
    ゲームボーイでは1文字出力のコードしか書いていなかったのだが(上の画像は1文字出力関数を文字数分呼んでいるのだ)、ファミコン版でやっとテキストデータを呼んで文字列を表示するコードを書いた。
    (もっとも現状文字コードが1バイトで文字を256種しか使えないのだが)

    これの製作中に1つ思いついて実装したのが、フォントデータの一部をテキストデータに持たせる手法だ。
    フォントデータは普通には9×9で81bit、10バイトと余り1bitになる。これを11バイトで持つのは無駄が多く気に食わない。
    そこで、例えば文字コードの最上位bitを文字の右上のドットに対応するようにする。するとフォントデータとして持つのは残りの10バイトのみでよくなる。
    文字コードの並びは不規則になってしまうが、文字列を表示するだけなら問題は無い。
    問題が起こるのは、まず外部とのやり取りで既存の文字コードを使う場合。これはゲームではあまり考えなくてよいだろう。
    それと、文字列をソートしたい場合。これはやや問題になるかもしれない。漢字はソートできなくてよいと考えて、仮名のみならテーブルを作るか、文字コードを上手く作れば仮名の順は取れるようにできるかもしれない。

    あと文字の送り幅を変えるコードもやっつけで書いた。やっつけなので1文字あたり1バイトを余計に使う無駄なコードだが。文字データも10バイト使って無駄だ。

    NESファイルは[こちら]
    コードは汚いので(まだ)公開しない。そのうち整えてCC-BY-NCあたりで公開するつもり。ゲームボーイからファミコンへの移植で変わったとことかも文章にまとめたい。

    (2019/07/17追記)
    実機動作していただいた!

    …そして初期化忘れに気付かされる。
    エミュレータはふつう初期状態のメモリは全ゼロになっているので初期化しなくても動いてしまい、実機で動作させて初めて気づくことが多い。PICマイコンでもしょっちゅうやらかした。
    これをエミュレータでテストするのはなかなか面倒である。今回はテスト用に乱数生成(Xorshift)のコードを書いてまず最初にRAMをランダム値で埋めることにした。
    それでできたのがこちらである。見事に再現できた。
    初期化忘れ再現
    さらに調べているとスタックが3バイト単位の繰り返しで全部埋まっていることにも気づいた。スタックオーバーフローだ。
    コードを確認すると、初期化からVBlank割り込みルーチンに流れ込むわ、VBlank割り込みルーチンは最後リターンせずにVBlank待ちに入るわのめちゃくちゃなコードだった。よく動いていたな。

    そんなわけで割り込みルーチンを直しメモリのゼロクリア処理を追加して、
    確認してみると目的のノイズは消えたのだが、起動時に一瞬別のノイズが見えるようになったのが治らない。
    起動時一瞬のノイズ
    どうやらランダム値をVRAMに書き込む際に出ているようで、表示は切ってあるはずなのに不思議である。
    ランダム化を消せば消えると思われたが、理由が分からないのは不安なので調べることにした。
    結果、案の定仕様を勘違いしていたことが分かった。PPUADDRレジスタがパレットのあるアドレスを「表示中に」指しているとそのパレットの色が出るという仕様があるのだが、これを非表示中に起こるものと思っていた。
    https://wiki.nesdev.com/w/index.php/PPU_palettes#The_background_palette_hack
    更に、この仕様に関連して、ファミコンは起動時の一瞬、PPUが操作可能になる前に(条件によって異なる)とある1色を表示するということも知った。そういえばそんなだった気がするな。PPUが操作可能になる前なのでどうしようもないらしい。

    理由が分かったので安心してゼロクリア処理を消す。今まで確認に使っていてNintendulatorではノイズが見えなくなったが、再現度の高いらしいMesenでは本来のパレットへの書き込みの分まだわずかに残っている。VBlank中へ持っていけば消せるのかもしれないが面倒なのでひとまずこれでよしとする。
    画像を載せようかと思ったが上のと全く同じなのでやめる。
    上のNESファイルは更新した…はず。エミュレータで見ても表示は同一なので確認が難しい。

    あと全画面任意画像の方にも同じバグがあったので合わせて修正した。  

  • 【お知らせ】プロフィールつけました
    2019年01月20日 22:42

    思えばTwitterへのリンクが無かったなと。  

  • 【お知らせ】サイト復活しました
    2019年01月16日 07:47

    ブログでない方のWentWayUp(Annex)のサイトをGitHub Pagesにて再開しました。
    新しいURLはこちら。https://ikadzuchi.github.io/wwu/
    このブログからリンクしていたファイルも全てアップロードしてリンクを修正したつもりです。
    (面倒なので個別の記事に更新は明記していません)