読者です 読者をやめる 読者になる 読者になる

みずぴー日記

陽気なプログラマが世界を廻す

ファミコン エミュレータ

f:id:mzp:20160904225208p:plain

エミュレータを作ってみたいなぁという漠然とした思いがずっとあったので、ファミコンエミュレータを書いている。スクリーンショットにあるような表示はできる。

ファミコンにした理由

エミュレータは作りたいが、よく知らない機械のエミュレータを作ってもつまらないので、多少は親しんだファミコンにした。

一番印象深いゲーム機はスーパーファミコンだが、スーパーがついてないほうが簡単かな、と思ってファミコンにした。

買ったもの

カートリッジからROMイメージを吸い出すために、吸い出し機をAmazonで購入した。

ゲーム自体は大須レトロゲームを取り扱ってる店に行って買った。1200円くらいした。

f:id:mzp:20160904230002p:plain

進捗の様子

Hello world

f:id:mzp:20160904230234p:plain

NES研究所にあるサンプル。

最初はこれを動かすのを目標にしていた。作ろうと思ってから、これを動かすまで2週間ほどかかっている。

ギコ猫

f:id:mzp:20160904230540p:plain

ギコ猫でもわかるファミコンプログラミングにあるサンプルを一個づつ動かしていった。ギコ猫なつかしい。

スーパーマリオブラザーズ

一番最初にスーパーマリオブラザーズを動かしたときの様子。 空の色がおかしい。 f:id:mzp:20160904230658p:plain

だいたいの背景色が正しくなったが、一部おかしい。

f:id:mzp:20160904230732p:plain

空の表示はできるようになった。

f:id:mzp:20160904230834p:plain

Sprite 0の当り判定(ヒットフラグ)を実装したら、タイトルがでるようになった。

f:id:mzp:20160904230859p:plain

VRAMの読み込みがおかしかったので修正した。

f:id:mzp:20160904231000p:plain

スプライトの表示をちゃんとしたらマリオっぽいのが表示された。 が体がバラバラになっている。

f:id:mzp:20160904231053p:plain

スプライトの反転処理を実装したら、体がくっついた。

f:id:mzp:20160904231134p:plain

スプライトの背景処理をちゃんとした。

f:id:mzp:20160904231202p:plain

他の画面もそこそこ動く。

f:id:mzp:20160904232335p:plain

f:id:mzp:20160904231230p:plain

実装してないこと

実装してない部分を列挙すると以下のようになる。ゲームとして遊ぶのは無理だと思う。

  • mapper 0以外のカートリッジの対応
  • タイミング制御。普通に画面がチラつく。
  • サウンド

つらさ

うまく動作しないときの原因の特定が、本当に大変だった。

エミュレータは任意のプログラムを入力とするので、許容する入力が圧倒的に多い。さらに、その内容は機械語で書かれているので意図を理解するのが難しい。 だいたいは、以下のような手順でデバッグしていた。

  1. ディスアセンブルしたコードを読んでなんとなくの動きを把握する。
  2. そして、その通りに動いてるかどうかをメモリを監視しながら確認する。
  3. 変な動きをしてるところがあったら命令のログもとって重点的に動きを追っていく。

Rubyで書かれたNESエミュレータであるoptcarrotと動きを比較してみることも多かった。

現状

さぼっていた部分がだんだんと致命的になってきてウワーとなっている。

  • 上から順に1ラインづつ画面を更新していく、
  • CPUとPPUのタイミング動機

がっつり直さないといけないけど、どうしようかな…。

レポジトリ

https://github.com/mzp/famicom/

そろそろGo言語を勉強するか、という気分だったのでGo言語で書いている。深い意図はない。

参考にしたページ

その他

f:id:mzp:20160904231928p:plain

f:id:mzp:20160904231448j:plain

f:id:mzp:20160904231506j:plain

AquaSKK 4.4.1

f:id:mzp:20160903090237p:plain

AquaSKK 4.4.1で設定画面で辞書を追加する際に file:// がついてしまう問題を修正した。詳細は、Issues #55に書いてある。 あとスクリーンショットの壁紙がかわいい。

ダウンロード

https://github.com/codefirst/aquaskk/releases/tag/4.4.1

経緯

デレステ辞書を作るのを手伝っている途中で指摘されたので、「すみません、すみません」と思いながら修正した。

この挙動はかなり前から認識していて、実際たまに困っていた。 ただ、たまになので手動で直して回避してしまっていた。

ちょうどいい機会なので、勢いで直した。

要約

GithubとTrelloの連動

f:id:mzp:20160705212448p:plain

GithubのラベルとTrelloのリストを移動を連動させるprprプラグインとして作成した。

https://github.com/mzp/prpr-trello

解決したい問題

Misocaの開発チームではタスクをTrelloで管理している。 そのため、タスクに対応するPull requestをレビュー待ちにしたら、Trelloのカードを「レビュー待ち」リストに移動するという運用をしている。

しかし、この移動を忘れがちでレビューに支障がでていた。

prpr-trello

この問題を解決するために、prpr-trelloを作成した。

これは、Pull requestのdescriptionの一行目にTrelloカードのURLが書いている場合、以下のようにカードを移動する。

  • WIP用のラベルをつける: 作業中リストに移動する
  • REVIEWラベルをつける: レビュー待ちリストに移動し、カードの説明にPull requestへのリンクを追記する
  • Pull requestを閉じる: 完了リストに移動する

余談: 開発前夜

ぼく「....みたいなbotほしくないですか?」

@ 「あれ? 今でもそういう機能ありませんか? ほら、例えばこれとか」

ぼく「それはボクが毎朝、手動でやってるんです...」

論文紹介: The Evolution of C Programming Practices: A Study of the Unix Operating System 1973–2015

ICSE 2016勉強会に参加するために論文リストを確認していたら、40年間のC言語のプラクティスの変遷を追った論文がおもしろかったので紹介する。

対象の論文

要約

過去40年間のUnixソースコードを分析し、コーディングスタイルの変化を調査した。その結果、以下のことが分かった。

  • 新しい言語機能は価値のあるものならば採用される
  • レジスタ割り当てをコンパイラに任せるようになる
  • スペースをどこにいれるかなどのコードの書き方が統一されていく

分析対象

1972年以降にリリースされた計66個のUnixを対象とする。 これには以下のものが含まれる。

分析したリリースをタイムラインにまとめると以下のようになる。

f:id:mzp:20160607082146p:plain

(Figure 1: Timeline of indicative analyzed revisions and milestones. in Proc. of ICSE '16, p.754)

立てた仮説と結果

事前に立てた仮説と、分析によりその仮説が支持されたかどうかについて述べる。

なお以下に示すグラフは Figure 2: Long term evolution of programming practices. (Metrics appear in alphabetical order; the number following the metric name is adjusted R2). in Proc. of ICSE '16, p.755からの引用である。

H1: 技術の進歩によって、プログラミングプラクティスは変化する

画面解像度や通信速度などの向上にともない、識別子や行が長くなっていくと考えた。

分析の結果、以下の平均値が増加していることが分かった。

  • ファイル行数 (FILINE)
  • ファイル内のステートメント数 (FISTMT)
  • 行の長さ(文字数) (LICHAR)
  • 識別子の長さ (IDCHAR)

f:id:mzp:20160607210715p:plainf:id:mzp:20160607210726p:plainf:id:mzp:20160607210737p:plainf:id:mzp:20160607210742p:plain

一方、関数の平均行数(FULINE)はこの仮説と関連しているが、途中から減少している。これは複雑になりすぎたことへの反応であると考えられる。これに関してはH6で議論する。

f:id:mzp:20160607211059p:plain

これらにより仮説は支持された。

H2: コードの規模とともにモジュール性が増す

コード規模が増えるにつれて、開発者はモジュール化を進めるのではないかと考えた。

分析の結果、可視性を制御するためのstatic(DSTATIC)が増加していき上限値に達していたことが分かった。最近、若干減少しているのは、カーネルモジュールや共有ライブラリといった言語外の仕組みが導入されたためと考えられる。

f:id:mzp:20160607213856p:plain

これらにより仮説は支持された。

H3: 新しい言語機能は一定数に達するまで使用が増加していく

unsignedキーワードといった新しい言語機能は、使用箇所が増えていき飽和点に達すると考えた。

分析した結果、以下のキーワードの使用は増加していることが分かった。

  • const(DCONST)
  • enum(DENUM)
  • inline(DINL)
  • unsigned(DUNS)
  • void(DVOID)
  • volatile(DVOL)

f:id:mzp:20160607214804p:plainf:id:mzp:20160607214808p:plainf:id:mzp:20160607214811p:plainf:id:mzp:20160607214816p:plainf:id:mzp:20160607214820p:plainf:id:mzp:20160607214823p:plain

基本的に上昇傾向だが、 enumとinline は部分的に下降している。開発者が態度が変化した時期があると考えられる。

unsigned はここ数年で減少している。 これは以下の2つの要因が考えられる。

  • size_t が導入され、それが使われる箇所が増えた。
  • 64ビットアーキテクチャが導入され、扱える数値の幅を広げるために unsigned が使われることが減った

signed(DSIGN)はあまり使われていない。signedキーワードはchar型に符号付きの値を格納する際に利用できるが、現在では必要になることはない。

f:id:mzp:20160607215906p:plain

これらにより「その言語機能が便利ならば」という限定付きで仮説は支持された。

H4: 開発者はコンパイラレジスタ割り当てを信頼している

コンパイラ技術が発展しレジスタ割り当てが改善するにつれて、開発者はコンパイラレジスタ割り当てを信頼するようになっていったと考えた。

分析の結果、registerキーワードの使用(DREG)は1990年ごろから減少していることが分かった。

f:id:mzp:20160607220707p:plain

H5: コードの書き方は収束していく

Unixという一つのプロジェクトで作業してるため、共通のコーディングスタイルが採用され、コードベースは均一になっていくと考えた。

分析した結果、コードフォーマットのばらつき(FMINC)やインデントのばらつき(INDEV)は減少していったことが分かった。

f:id:mzp:20160607222806p:plain f:id:mzp:20160607223230p:plain

これにより仮説は強く支持された。

H6: ソフトウェアの複雑性には自己修正機構が働く

ソフトウェアが進歩に複雑性は増し、人間の限界を越えてしまう。 そのため、成功したプロジェクトでは複雑性を減少させる自己修正機構が働くと考えた。

分析した結果、以下の項目が、いったん複雑性を増したのち減少に転じるというパターンを示した。

f:id:mzp:20160607224130p:plainf:id:mzp:20160607224142p:plainf:id:mzp:20160607224210p:plainf:id:mzp:20160607224214p:plain

goto(DGOTO)についても同様のことが言える。 gotoは長期間減少しつづけていたが最近は増加している。 gotoの有用性に気付いたのかもしれない。

f:id:mzp:20160607225638p:plain

H7: コードの可読性は増す

開発者コミュニティで管理しやすくするために、可読性は増していくと考えた。

これを調べるために、以下の項目を分析した。

  • インデントのためのスペースの平均値(INSPC)
  • ステートメントの密度(DSTMT)
  • コメントの文字数の密度(DCMCHAR)
  • コメントの文字数の平均値(CMCHAR)
  • コメントの密度(DCM)
  • TODOコメントの密度(DKLUDGE)

f:id:mzp:20160607231046p:plainf:id:mzp:20160607231056p:plainf:id:mzp:20160607231108p:plainf:id:mzp:20160607231113p:plainf:id:mzp:20160607231117p:plainf:id:mzp:20160607231123p:plain

コメントの密度とコメントの文字数の密度が増加したのち減少しているのは、より長い識別子が使えるようになって、自己文書化が進んだためと考えられる。

ステートメントの密度は減少傾向にあるが、2000年ごろから増加している。これはコメントのついていないステートメントが増えていることを示す。インデントのためのスペースの平均値も減少していたものの、最近は増加している。 そのため、Unixソースコードの可読性が今も増加していることの確証は得られなかった。

まとめ

長年にわたるUnixの発展を追跡することで、Unixの開発者が以下のことを行なってきたことが分かった。

  • ハードウェアの進歩にあわせてコーディングスタイルを変化させる
  • 複雑度が増すにしたがいモジュール化を促進させる
  • 価値のある新しい言語機能を採用する
  • コンパイラレジスタ割り当てをまかせる
  • コードの書き方に関して合意に達する

また、ソフトウェアの複雑性と自己修復機構が関連していることと、文書によるコード構成の改善が頭打ちになっていることも発見した。

🍓 橘ありす分類器

GWに日光に開発合宿に行ってきた。

機械学習で遊ぼう」をテーマにしたので、橘ありす分類器を@と作成した。

成果物

m@gic-with-arisu from MIZUNO Hiroki on Vimeo.

ありすには青枠を、それ以外には赤枠を表示している。

宿

日光東照宮至近の炭火焼きの宿・ペンションはじめのいっぽに宿泊した。開発合宿に理解のある宿でよかった。ただ、理解があるあまり「昨日は成果でましたか?」と聞かれてつらい思いもした。 進捗を聞かれるより、成果を聞かれるほうが厳しい。

また旧型のiMacがあってよかった。起動したらバージョン1のSafariや、Mac版のIEが入ってて楽しかった。

f:id:mzp:20160525221012j:plain

ありすの調達

@デレステのガシャを引きまくって、SSRありすを調達した。

学習データの作成

学習データとしてAngelBreezeTulipのMVを撮影したのち、顔画像を切り出して学習データを作成した。

顔画像の切り出しはOpenCVによるアニメ顔検出ならlbpcascade_animeface.xml - デーを用いた。また毎フレームを切り出すと多くなりすぎるため、ある程度間引いている。

切り出した顔画像がありすかそうでないかを入力するために、専用のiPhoneアプリを作成した。データの更新や反映を容易にするようDropboxと連携できるようになっている。

このタイミングで大量の顔画像が手に入って楽しかった。

f:id:mzp:20160525222111p:plain

学習

ありす画像が117枚、非ありす画像が107枚得られたので、機械学習によって分類器を作成した。このとき用いたモデルは4コマ漫画の画像管理✨ - みずぴー日記と同様のものである。

分類

学習に用いたMVとは別にM@GICのMVを撮影し、各フレームの各顔画像に対してありす・非ありすの分類を行なった。 そして得られた結果を元に、動画を合成した。

その他

see_no_evil

せっかくの日光なので🙈(:see_no_evil:)の実物を見て、闇のようなコードと戦う気持ちを新たにした。

いちご

www.instagram.com

ありすといえばいちご、ということで完成したあとにいちごを食べに行った。

より正確には、インターネットでいちごパフェを出している店を調べて向ったがすでに潰れたあとで、どうしようかなぁとふらふらしてたら、たまたまいちごを路上販売してたので買って食べた。

レポジトリ名の由来

レポジトリ名である arisu-in-fact は、ありすの曲であるin factに由来している。

iTerm2 + AquaSKK

要約

f:id:mzp:20160515142324j:plain

経緯

iTerm2 + AquaSKKには、l/L/q/Qで入力モードを切り替えるとその文字も入力されてしまう問題がある。(参考: iTerm2/Apple TerminalでAquaSKKを使う - みずぴー日記)

これを修正するPull requestを @__tai2__が作ってくれたので、取り込むための各種議論に参加していた。

そのPull requestが本日(2016/5/15)masterに取り込まれたので、次回のNightly BuildsやTest Releasesとともにリリースされるはず。

🇯🇵 SJIS/EUC-JPのテキストファイルをQuick Lookする

SJIS/EUC-JPのテキストファイルをQuick Lookできないのが不便なので、プラグインを書いた。

ダウンロード

https://github.com/mzp/qltext-jp

実装

Quick Lookされたときにエンコードの自動判定を行ない、その後の表示はシステムにまかせている。

実装は以下のプラグインを参考にした。

また文字コードの判定は以下のコードを用いている。

他の方法

xattr

xattr で拡張属性を設定すれば特にプラグインをいれなくても、Quick Lookできる。(参考: Mac の Quick Look をちょっとだけ快適に – xattr 編 – (フェンリル | デベロッパーズブログ))

xattr -w com.apple.TextEncoding "SHIFT_JIS;2561" README.txt

が、毎回これをやるのは大変なので、Quick Lookプラグインを作成した。

quicklook-jptxt

GitHub - ento/quicklook-jptxt: Quick Look plugin for public.plain-text with better encoding handling. を使えば同等のことができる。文字コード判定が微妙に違うくらい。

これでダメな理由は特にないが、まあ作りかけてしまったので完成させてしまった。

その他

最近はSJISのファイルってあまりないよね。