みんなでアドベンチャーゲームを作ってみませんか?

これは何?

「みんなでアドベンチャーゲームを作ったらどうなるのだろうか?」

f:id:inajob:20200208133330p:plain

ふと浮かんだ、この試みを実際に始めてみました。

 

↓↓↓早速プロジェクト自体を見たい方はこちら↓↓↓

github.com

 

アドベンチャーゲームとは?

ここで言うアドベンチャーゲームというのは、テキストと選択肢によって構成される物語で、選択肢に応じて物語が分岐し、プレイヤー毎に異なるストーリーを楽しむことができるゲームのことです。

 

単なる小説とは違い、選択肢による分岐ごとに異なるストーリを展開することができるため「みんなで作る」のに向いているのでは?と考えました。

みんなで作るために工夫していること

 Git/GitHubを使う

みんなでアドベンチャーゲームを作るためには、差分を取り込む仕組みが必要です。今回はこれを簡単に解決するためにGit/GitHubを使うことにしました。

差分はGitで管理し、GitHub上で取り込みのためのコミュニケーションができます。

ブラウザですぐに遊べる

みんなで作るためには、「みんなで遊べる」ことが重要です。特定の環境に依存していたり、インストールが必要であったりすると、遊ぶためのハードルが高くなります。

またストーリを作る際も、さっと動作を試せることが重要です。

そのため、今回はブラウザで動作するようにゲームエンジンを作成しました。これによりGitHub Pagesで簡単にホスティングすることもできました。

またgit cloneしてきたhtmlをブラウザで開くだけで遊ぶことができるので、開発時も簡単に動作確認できます。

 

↓ちょっと味気ないですが、Webブラウザで誰でも遊べます。

f:id:inajob:20200208133519p:plain

https://inajob.github.io/cyoa-experiment/

アドベンチャーゲームの仕様を最小限にする

昨今のアドベンチャーゲームエンジンは多機能です。背景画像、音声、BGM、書式設定などなど、アドベンチャーゲームを盛り上げるための様々な機能を搭載しています。

しかし、「みんなで作る」という観点では、これらの機能が利用できることで、アドベンチャーゲームにクォリティが求められるようになり、参入の障壁が高くなってしまうことが予想されました。

そこで、今回はシンプルなゲームエンジンを自作し、本当にストーリーだけに注力してアドベンチャーゲームを開発できるようにしました。

ゲームエンジンから揉めそうな要素を排除

それでもゲームエンジンには、いくつかの機能があります。選択肢でジャンプする先を表す「ラベル」や、状態を表す「フラグ」、フラグによる「条件分岐」などです。

ここで「ラベル」と「フラグ」に関してはそれぞれ固有の名前が必要です。

一般的なゲームエンジンでは「場面1」「学校のシーン」「ライフルを持っているか」など、「ラベル」「フラグ」にはわかりやすい名前を付けます。

しかし、みんなでアドベンチャーゲームを作る場合、これらの名前が衝突したり、一定のルールを強制するなど、わかりやすい名前にしたいがためにもめごとが起きることが予想されました。

そこで、今回はUUIDをベースとした名前を採用することで、わかりやすい名前という利点とは引き換えに、命名が衝突するという問題を回避しました。

ライセンスを明記

アドベンチャーゲームをみんなで作るということは、そのシナリオのライセンスで揉めることが予想されました。そこでリポジトリにあらかじめCC BY-SAのライセンスを明記しています。

このライセンスにより、誰でもこのストーリーを利用することができ、またこのストーリーから派生したストーリについても同様のライセンスを強制することを実現しています。

ゲームエンジン紹介

 このゲームエンジンの雰囲気を知ってもらうためにストーリの例を紹介します。

下に示したように、基本的にはストーリを書いていくだけです。選択肢は「:」で始め、選択肢の文字列と、飛び先ラベルIDを記載します。

ラベルIDは暗号のようですが、これは自動生成したものです。このようにラベルIDを自動生成することで、命名で揉めないようにしています。ラベルは「*」で始め、ラベルIDとそれに続けて人間がわかるラベルの名前を記載します。このラベルの名前は他と被っても大丈夫です。

「%」で始まるのはその他の命令で、ここでは「%end」というゲーム終了の命令を利用しています。今のところ他には「%set」と「%eqif」があります。(詳しく知りたい方はリポジトリの説明を読んでください。)

*l972e5150755648f9abe435c10df2d231,初めのシーン
みんなで作るゲームエンジンのサンプルです。

このプロジェクトに興味がありますか?

:はい, l1b8a48cf456f43c69241cdf40b7a1417
:いいえ, ld21c8d7d9a2e42828c6f8fed022bb593

*l1b8a48cf456f43c69241cdf40b7a1417,はいの場合

やったー!
今すぐ https://github.com/inajob/cyoa-experiment をForkして物語を作ってみてください!

%end

*ld21c8d7d9a2e42828c6f8fed022bb593,いいえの場合
そんなぁ~

周りにこういうのが好きそうな人がいたら紹介してほしいです!

%end

 

少し運用してみて感じたこと

1週間ほど運用してみて、ストーリー周りに関して4つのPull Requestをいただきました。

自分でもいくつかのストーリーのPull Requestを作成したのですが、変更の仕方によってずいぶん印象が違うように思いました。

既に存在しているストーリーを少しだけ変更することは、様々な整合性を考慮する必要があり、普通に0からストーリーを作るのとはまた違った難しさを感じました。しかし、選択肢を増やすだけで、またすぐ元の流れに合流するような変更は変更差分が少ないためストーリーそのものを考えるほどの想像力や労力はかからないように思いました。

f:id:inajob:20200208161459p:plain

一方、既に存在しているストーリーから分岐するものの、その後の展開は完全にオリジナルというようなストーリーを作るのは、整合性に関する難しさはほとんどない代わりに、新たなストーリを考えるという想像力と比較的長い文章を書くための労力が必要だと感じました。

f:id:inajob:20200208161514p:plain

このように、このみんなでアドベンチャーゲームを作るという試みでは、従来の1人でストーリを作るのとはまた違ったスタイルで開発が行えることがわかりました。

まとめ

とりあえずはじめてみたこのプロジェクトですが、既にいくつかの方からPull Requestをいただき、一応コラボレーションできているという状態まで持ってこれました。

 

今後ものんびりと進めていければと考えていますので、この記事を読んでみて「面白そうだな」と思った方は、ぜひプロジェクトをforkして物語を追加してみてください。

f:id:inajob:20200208161727p:plain

 

FusionPCBを使って(ほぼ)はんだ付けせずに自作ゲーム機を作った(PCBA)

f:id:inajob:20200126160107p:plain

↑この状態で中国から届く!というのがPCBAです。

どういうこと?

PCBAというのをご存知でしょうか?

Printed Circuit Board Assemblyの省略なのですが、要は電子基板の作成(PCB)」「電子パーツのはんだ付け(A)」をやってくれるサービスです。

 

電子工作をある程度取り組んでいると、「自分の作ったものを人に配りたい/売りたい」という欲求がわいてきます。

 

最近は中国のサービスを使うと比較的安くでプリント基板(PCB)の製造をお願いすることができます。(10cmx10cm以内なら10枚で$4.9+送料 1枚あたり500円いかない)

これを使うことで、人に配る・売ることがかなり現実味を帯びてきます。

 

そこで、まず思いつくのは「自分で作って売る」です。しかし、これはなかなか大変。5個くらいなら何とかなりそうですが、10個を超えたあたりからつらくなってきそうです。

次に思いつくのは「キットとして売る」です。実際私も自作電子楽器RakuChordをキットとして何度か販売しました。しかし、これも思ったほど楽ではない、、何なら「自分で作って売る」より神経を使います。

 

そして究極は「誰かに作ってもらって売る」です。そんなことやってくれる人はいるのでしょうか・・・?

そう、それがPCBAです。

作ってもらう流れ

PCBAは名前の通りPCB+Aです。なので、手順はほとんどプリント基板(PCB)を発注するときと同じです。

PCBの手順については以前ブログ記事に書いたので(RakuChordの回路を発注してみた。 - inajob's blog)、基本的にはそれと同じです。

気になるAの部分について少し紹介します。

 

A=Assembleを依頼するために必要なのは、PCBの依頼に加えて、わずか3種類のファイルを用意するだけです。

実装図

これは基板のどこにどの番号の部品を置くかを記載したPDFファイルです。

KICADを使って回路を設計していれば、本当に簡単な手順で出力することができます。

f:id:inajob:20200126142621p:plain

ピック&プレースファイル

こちらもKICADでポチポチするだけで出力できます。

f:id:inajob:20200126142726p:plain

BOM(部品表)

最後が一番用意するのが大変な部品表です。

これは要は、基板上のどの番号に、どの部品を配置するかという対応表です。

以前私はここを用意するのが大変で、PCBAをためらってしまっていました。しかし今回の私には強い味方がいます。それがFusionPCBが提供する「OPL」です。

 

OPLはOpen Parts Libraryの略で、FusionPCBが在庫として抱えているパーツの一覧です。(https://www.fusionpcb.jp/opl.html)ここにあるパーツであればFusionPCB内で在庫が存在するため、比較的早く見積もり・製造をしてくれるというものです。

私にとってうれしかったのは、星の数ほどある部品の中から良さげなものを選んでくれているという点です。もちろん高周波なものやアナログ回路などを設計する人にとっては部品選定こそがメインの戦場なのでしょうが、私が作るような16MHz程度のデジタル回路においては、部品の違いなんていうのはほとんどありません。

ということで、今回はほぼ「OPLにあるパーツ縛り」で基板を設計しました。

 

OPLは一部の部品に対してはフットプリントも公開しているので、これを使うと本当に簡単にPCBAに挑戦することができます。

残念ながらすべての部品に対してフットプリントがあるわけではないので、無い部分はそれっぽいものを自作するなり、KICADの標準ライブラリのものを使いました。 

 

この「それっぽいフットプリント」も発注前は心配でしたが、ちゃんと部品が実装できるように作ってあれば、それっぽいフットプリントで問題なく実装してくれました。

 

 一部の部品はOPLには存在しなかったので、BOM表にはURLを書く形でみんな大好きLCSCのパーツのURLを貼り付けて発注してみました。

f:id:inajob:20200126142923p:plain

 

そうすると、「カートに入っているのですが、決済できない」、という状態になり(どうやらOPL以外の部品を入れると部品の見積もりを行っているようです。)数日後に見積もりが終わり決済ができるようになりました。

おそらくOPLだけで設計してあればすぐに決済できたのだと思います。

 

その後決済を行うと、基板の製造と部品の調達が並行して行われます。ここでもOPLの場合はすぐに調達できるのですが、今回のように別のところから調達しようとすると数日待たされます。(おそらく調達先は少ないほうが良いだろうと思い今回はLCSCだけにしました。)

そして、部品が調達できると実装(Assemble)が行われて、製品が発送されます。

とても簡単です。

時間

前述したように、カートに入れてから決済できるようになるまで2日間ほどかかりました。その後は下の図に書かれたようなスケジュールで製造が進みました。

f:id:inajob:20200126143402p:plain

2020/01/02に入稿されたデータは、01/10に実装が完了しました。

その後DHLで配送され、1/14に我が家に届きました。

f:id:inajob:20200126143612p:plain

f:id:inajob:20200126160107p:plain

お値段

現在FusionPCBではPCBA5枚限定の「実装無料」というセールをやっています。

このセールにより段取り費用、実装費用、運営費用、送料がなんと0円になります!(通常これらは$150ほどかかります。そのためPCBAは大量に発注しないと割に合いません)

で、実際にお金がかかるのは、基板製造費、消耗品費、部品代だけです。

そしてなんと送料も無料です。すごい!

 https://www.fusionpcb.jp/free-assembly-for-5-pcbs.html

f:id:inajob:20200126143644p:plain

今回の基板の場合は5枚で大体$40くらいでした。1枚$10しない!すごい!

 

あくまでセール価格なので、この値段を基にして原価を計算すべきではありませんが、PCBAを試したい人にとってはまたとないチャンスです。 

品質

 実装については個人的には大満足です。自分でやるのに比べて明らかにきれいです。
しかし今回は5枚中1枚、どうも不良の部品が実装されているようで、正しく動作しないものがありました。

f:id:inajob:20200126160229p:plain

クレームをつけても良いのでしょうが、OPLではない部品だったこともあり、今回は何も言わずに受け取っていますが、たくさん作ってこの割合で不良品が入っていたら大変つらそうです。部品選定は大事だなと感じています。

この辺をしっかりするためには、怪しいパーツの動作テストをしてもらうなどが必要そうです(FusionPCBでできるのかな?)

バグ

どんなものにもバグはあります。今回私が設計した自作ゲーム機のハードウェアにもバグがありました。このスイッチです(右上)。

私の計画ではこの部品はUSB端子と同じ側に実装されるつもりでした(左下)。しかし私の送ったデータはそうなっておらず、(当然)指示通りの間違った側に実装されてしまいました。

f:id:inajob:20200126144105p:plain

この部品はフットプリントが大きめだったので、5つすべてのスイッチをつけなおしました。当然つけなおすためには、はんだを加熱して部品をはがす必要があり、これは部品を実装する以上に手間です。やりたくないです・・

 PCBAのコツ

表面実装部品を積極的に使う

PCBAの醍醐味は表面実装部品です。リード部品は手でも簡単に実装できますが、面積を取ります。またICなどは表面実装パッケージしかないものもあります。実装費に関しては、リフローで実装できる表面実装部品のほうが安い(はず)です。

せっかくPCBAするからには表面実装部品を使いたいところです。

初めからOPLにある部品で設計する

OPLにある部品を使うと、製造がスムーズにできます。そのため、PCBAで製造する基板で使用する部品はOPLにある部品を指定するのが良いです。
後から部品を変更するのは大変です。OPLにある部品はAliExpressでも簡単に買える部品が多いので、事前にそれらの部品で動作確認をしておくのが良いでしょう。

今回は抵抗・コンデンサ1206サイズを使って設計したのですが、OPLで安く手に入るのはもう少し小さなサイズ(0805とか0603、0402など)でした。次回作るときは先にサイズを確認しようと思っています。

手はんだできる部品で設計する

表面実装部品もある程度の大きさであれば手ではんだ付けできます。後述する手実装のフェーズのためになるべく手実装しやすい大きさの部品を使いましょう。

一度PCBで発注して手実装して様子を見る

PCBAは結構お金がかかります。そのため失敗したときのダメージが大きいので、一度PCBを作ってもらい自分で実装して動作確認をするのが良いです。今回の自作ゲーム機は3回PCBを作り部品の種類や配置の変更を繰り返し4回目にPCBAに挑戦しました。

f:id:inajob:20200126160033p:plain

4回の変更で実装部品が大幅に減り、実装ミスの少ない基板が設計できました。

まずは5枚PCBAする

せっかくセールで安く少ないロットで注文できるので、これを利用しない手はありません。数百個作りたい場合はまずは5枚のPCBAで様子を見るのはどうでしょう?

私のケースのように品質の悪い部品や、実装面のまちがいなど意外な凡ミスに早期に気づくこととができるでしょう。(大量ロットを注文した時も事前に数枚作って確認する、などができると聞いたことがありますが、私はまだ試していません。)

OPLでおススメ部品

部品についてはそれぞれ皆さんこだわりがあると思いますが、今回偶然にも発見したおススメ部品は「タクトスイッチ DTSM-62K-S-V-T/R(SN431) 」です。

f:id:inajob:20200126144404p:plain

個人的な印象ですが、中国で買うタクトスイッチは、安いのですが、なぜか異常にボタンが固いものが多いです。そんな中今回利用した6mmの表面実装タクトスイッチは100gFという軽いタッチが特徴です。

データシートを見て、「この値段で100gF?!まさか~?」と思って発注したところ、本当に軽く押しやすいスイッチが実装されて届きました。

スイッチの軸の高さが低いのがちょっと気になりますが、100gFのスイッチが欲しい人にはかなりおススメの逸品です。

まとめ

前々からやりたかったPCBAに挑戦し、そこそこ気に入った基板を作ることができたため、PCBは発注したことはあるが、PCBAはまだ・・ という人のためにちょっと紹介を書いてみました。

ここまでそれっぽいことを書いてきましたがまだたった5枚発注しただけのぴよぴよMakerですので、おかしなことを書いているぞ!とか、ほかにも面白いTipsがあるぞ!とう方は、ぜひぜひ教えてください。

 

 

Arduinoだけで和音を鳴らす方法

f:id:inajob:20200103112556p:plain

はじめに

私はRakuChordというArduinoを基にした電子楽器を作っています。

RakuChordはArduinoたった1つでキーの押下の読み取り、ディスプレイの制御、音の生成を制御しています。

inajob.github.io

この記事では、RakuChordでどのように和音を生成しているか?ということを解説していきます。

 

実はこのRakuChord。初期バージョンは10年前くらいで、和音のロジックもそのころから少しずつ改良を加えてきています。

しかし、どこにもドキュメントを残さずにここまで来たため、自分でもなぜこのソースコードで和音が鳴っているのかよくわからなくなることがありまして・・・自分の備忘録的な意味も込めてこの記事を書く事にしました。

Arduinoで「単音」 

【永久保証付き】Arduino Uno

【永久保証付き】Arduino Uno

  • メディア: Personal Computers
 

Arduinoで「単音」を出すのはとても簡単です。最も簡単なのは無限ループを作り、そこでdigitalWriteであるピンの出力を上げたり下げたりする方法です。そのピンにスピーカをつなげることで、単音を再生することができます。

適切に待ち時間を入れることで、これだけで単音を鳴らすことができます。

例えば440Hz(ラの音)を鳴らす時は 1/440秒の半分の待ち時間を入れてdigitalWriteでHIGH/LOWを繰り返せばよいのです。

f:id:inajob:20200104181608p:plain

void setup() {
  pinMode(9, OUTPUT);
}

bool flip = false;
void loop() {
  flip = !flip;
  digitalWrite(9, flip);
  delayMicroseconds(2272/2); // 1/440 = 0.0022727... = 2272uS
}

この方法では、音を鳴らしている間はほかの処理を行うことができません。

しかしArduinoの関数であるtoneを使うとこの問題も解決します。toneは周波数を指定すると即座に処理が終わり、次の命令を実行することができますが、音は鳴り続ける。という動作をします。

void setup() {
  pinMode(9, OUTPUT);
  tone(9,440);
}

void loop() {
// ここで処理中も音は鳴り続けている }

https://www.arduino.cc/reference/jp/language/functions/advanced-io/tone/

例えばゲーム機などを作る際、簡単なBGMであればtoneで十分です。

Arduinoで「和音」

Arduinoで「和音」というのは「単音」の時ほど簡単ではありません。

和音を鳴らすためにはいくつかの方法が考えられます。

1. 複数のピンを使う

和音の数だけピンを使い、オペアンプなどで合成したのちにスピーカーとつなげることで和音を鳴らすことができます。この方法は「単音」を複数並べるという点で単純でわかりやすいですが、ピンをたくさん使うことや、音の合成のためにオペアンプなどの部品が必要なことがデメリットです。

2. ソフトウェアで合成する

今回紹介するのはこちらの方法です。この方法では1つのピンの出力で和音を演奏する方法です。ソフトウェアの処理が複雑になりますが、単純な回路で和音を再生することができます。(音量が小さくて良いなら、それこそArduinoに直接スピーカをつなげるだけでもOKです)

2.1 既存のライブラリ

ソフトウェアで和音を合成するためには、これから紹介する「1から処理を書く」方法とは別に、既存のライブラリを利用することもできます。


2.1.1 Mozzi

MozziはArduinoで利用できるシンセサイザーライブラリとして非常に有名なものです。下記ページで大量のサンプルを聞くことができます。

おそらく音関係でやりたいことの大半は、このライブラリを使うことで実現できます。

このライブラリは音を扱う様々な処理の詰め合わせセットのようなものです。そのため単に「和音を鳴らしたい」という場合でもそこそこのプログラミングが必要となります。単純に和音を鳴らしたい場合はこの後紹介する別のライブラリのほうが簡単に実現できると思います。

一方、単純な和音ではなく、「音作り」にこだわりたい人にとってはMozziの豊富な音関係の関数群は非常に強い武器となるでしょう。

sensorium.github.io

2.1.2 PWMDAC_Synth

PWMDAC_Synthはまさに「Arduinoで和音を鳴らす」ことに特化したライブラリです。6重和音を扱うことができ、さらにエンベロープも設定できます。

ja.osdn.net

2.1.3 VRA8-Pシリーズ

VRA8-Pで利用できる3音を扱えるシンセサイザーのライブラリです。ArduinoのCPUをフルに使うことで、ほかのライブラリを圧倒する高音質を実現しています。

ただし、この音源はArduinoのメモリ・CPUをかなり占有してしまうため、何かのロジックと組み合わせる場合は注意が必要です。場合によってはArduinoを2つ並べるなどして、片方は制御、片方はVRA8-Pを用いた音源、というような使い方のほうが良いかもしれません。

github.com

2.2 自分で和音を鳴らす処理を書く

既存のライブラリでは「痒い所」に手が届かない場合や、メモリ・CPU使用量を細かく調整したい場合、和音の合成処理自体に興味があるような場合は、自分で和音を鳴らす処理を書く事のがおすすめです。

ということで、以降RakuChordの音源での和音の処理について解説していきます。

RakuChordの音源のソースコード

RakuChordのファームウェアオープンソースで公開しています。

音源周りの処理は https://github.com/inajob/rakuchord/blob/cc088ecfc711f7f432e1a3cc55a3f5a8bb0b9c37/firmware/src/MultiTunes.cpp にまとめています。

ここからは、このソースコードを眺めながらArduinoで和音を鳴らす方法を紹介します。

soundSetup

 この関数が音を鳴らすための準備をするものです。起動時に1度だけ呼び出すことを想定しています。

内部では和音合成に必要なタイマーのセットアップを行っています。

RakuChordで使うのはArduinoのピンのうちDigitalの9番ピンです。まずは9番ピンをOUTPUTに設定しています。

 

次にタイマーの設定を行います。このタイマーは9番ピンのPWMの制御と、和音の波形の計算のタイミング制御のために利用しています。

Arduinoが使用しているマイコンATMega328には複数のタイマーが存在しますが、ここではTimer1を使用します。

Timer1の設定のためにはTCCR1AとTCCR1Bという2つのレジスタを用います。このレジスタの特定のビットを上げたり、下げたりすることでTimer1の挙動を設定します。

ここでは下記のような設定をしています。

  • WGM13~10 = 0001
    • 8bit位相基準PWM
  • COM1A1~0 = 10
    • カウントアップ比較一致でLOW、カウントダウン比較一致でHIGH
  • CS12~10 = 001
    • 分周なし

 ちょっとこれだけでは何を言っているかわかりませんね・・もう少し解説します。

分周比

 Timer1はTCNT1の値を適当な間隔でインクリメントしたりデクリメントしたりする仕組みです。具体的にどのようにTCNT1を動かすのかは後ほど説明しますが、その間隔について指定するときに用いるのが分周比です。

ATMega328が動作している周波数に対しての比率でこの間隔を指定します。

今回は「分周なし」の指定なので、Arduinoに搭載されている水晶発振子である16MHzの間隔でTCNT1を動かすことになります。

8bit位相基準PWM と 比較一致

WGM13~10によりTCNT1をどのように動作させるかを指定しています。

今回は8bit位相基準PWMという指定です。このモードではTCNT1は0から1ずつカウントアップしていき0xff(8bitの上限)までカウントアップしたら次は1ずつカウントダウンしていきます。そして0まで下がったらあとは繰り返しです。

オーバーフロー割込みは0xffに達したタイミングで実行されます。

つまり図にするとこのような感じです。

f:id:inajob:20200103105132p:plain

 

COM1A1~0,はTCNT1の動作と連動してデジタル9番ピンにどのような信号を出力するかを設定しています。今回は「カウントアップ比較一致でLOW、カウントダウン比較一致でHIGH」を指定しています。

比較に用いる値はOCR1Aレジスタの値です。

つまり図にするとこのような感じです。

f:id:inajob:20200103105625p:plain

このようにタイマーと連動してデジタル9番ピンを制御することで、非常に高速にピンをHIGH/LOWに切り替えることができます。またOCR1Aの値を変更することで、ON/OFF時間の比率を変更することができます。

これがPWM(Pulse Width Modulation)というテクニックです。このように短い間隔でHIGH/LOWを切り替えることで、HIGH(5V)とLOW(0V)という2種類の値しか出力できないデジタル回路においてアナログっぽい値を作ることができます。(厳密にはアナログとは違いますが・・)

 このPWMを使うことで、単なる矩形波よりも複雑な様々な波形を生成することができます。もちろん「和音」も「波形」であらわすことができるため、そのような信号をPWM作ることで和音を鳴らすことができます。

タイマー割込みの設定

最後にこれらのタイマーを有効にするためにTIMASK1にTOIE1のビットを設定します。これでTCNT1が上限に達したときに割込みが発生します。 

TIMER1_OVF_vect

今回利用するTimer1のオーバーフロー割込みはこの名前で呼び出されます。

ここまでの話を総合すると16MHzでTCNT1が0 → 0xFF → 0と繰り返し変化していきます。 これを1周期とするとこの1周期にかかる時間は

f:id:inajob:20200103110223p:plain

となります。

ソースコード上ここでTCNT2に値を代入しているが、これは何の意味もなさそう・・・)

基本的にはこの割込みルーチンの中でdn[x]にd[x]を足していきます。xは0~4の5通りあり、これがオシレータを表しています。つまり独立した5つの音を制御しているということです。

最終的にはこのdn[x]から波形テーブルを引いて、5つあるそれぞれの結果をすべて足し合わせてOCR1Aレジスタの値として設定しています。

dn,dと音程

dn[x]とd[x]はunsigned intです。つまり16ビットの値です。

先ほど見たように割込みルーチンの中でdn[x]にd[x]をどんどん足していきます。

このd[x]はRakuChordの鍵盤の押下により「音程に対応した値」が代入されています。

「音程に対応した値」というのはhttps://github.com/inajob/rakuchord/blob/cc088ecfc711f7f432e1a3cc55a3f5a8bb0b9c37/firmware/src/tones.hに定義しています。

このソースコードによると「音程に対応した値」というのは周波数そのものとなっています。(NOTE_A4が440、NOTE_A5が880となっていることからも、これが良く知っている周波数と同じであることがわかります。)

一方、d[n]の値は割込みルーチンの中で、上位6ビットを使ってテーブルを引いています。

波形テーブルは64サンプルで1波形を表しています。dn[x]は16ビットですが、その上位6ビット(0~63)を取り出すことでこのサンプルを読みだしています。

d[x]の値を変数としてdn[x]が何回の割込みで1周するかを計算します。

f:id:inajob:20200103110252p:plain

割込みの発生間隔は上で求めたので、これを掛け合わせることで波形1周期にかかる時間が計算できます。

f:id:inajob:20200103110338p:plain
式を変形します

f:id:inajob:20200103110357p:plain

波形1周期にかかる周波数を求めます(↑の逆数)

f:id:inajob:20200103110420p:plain

これによりd[n]の値は周波数をだいたい2で割ったものとなります。

つまり実際にはd[n]の値の表す周波数より1オクターブ低く、かつ少し誤差のある音が鳴っていることがわかります。

オーディオアンプ

どの方法をとったとしても、Arduinoのピンから出てくる信号のレベルは低いものです。イアホンや小さなスピーカであれば何とか音が鳴りますが、大きな音を鳴らしたい場合は、Arduinoとは別にオーディオアンプが必要です。

RakuChordではLM386というICを利用してこれを実現しています。

調べるとLM386を採用したオーディオアンプのモジュールも販売されているため、回路を作るのが面倒な人は、これらを使うのが良いでしょう。

まとめ

Arduinoで和音を生成する方法を紹介しました。

この方法は私が様々なライブラリや、タイマーの仕様を読んで試行錯誤して作成したもので、この方法が唯一の方法ではありませんが、Arduinoで1から和音を生成したい人にとっては試行錯誤の足掛かりとなるのでは、と考えています。

(もっと良い方法や、間違いなどがあれば教えてください。→https://twitter.com/ina_ani) 

 

Arduinoでちょっとリッチな音が鳴るようなガジェットを作りたい人の助けになれば幸いです。

 

2019年まとめ

f:id:inajob:20191226114018p:plain
ピックアップニュース

今年はいくつかのトピックに分けて個人的なニュースを紹介します。バズった1年、通販の1年、表面実装の1年、継続の1年、健康の1年、出版の1年と、様々な点で楽しく充実した2019年でした。

バズった1年

今年はとにかくバズりました。特に家事スプレッドシートの件はねとらぼでも記事にしていただいたり、その結果Yahoo!ニュースに載ったりと、普段できない体験ができました。

 

家事スプレッドシートがバズる

パンツのゴムを通すやつがバズる

アドベントカレンダーの記事「Kubernetesの中にLinuxデスクトップ環境を作る」がややバズる

qiita.com

通販の1年

昨年はイベントで販売したRakuChordですが、今年は通販に挑戦しました。3月と9月に販売しましたがいずれも即完売ということで幸先の良いスタートとなりました。

初めての通販ということで、多くの知見を得ることができました。

inajob.hatenablog.jp

inajob.hatenablog.jp

note.com

inajob.hatenablog.jp

表面実装の1年

昨年まではスルーホール部品のみを使った電子工作をしていましたが、今年は表面実装に挑戦しました。4月に単4電池1本で動くArduino基板を作り、その後は電子ゲーム機HACHIBARを3回、設計を変えつつ基板発注しました。もう少しで表面実装作品の販売ができそう?というところまで経験を積むことができました。

inajob.hatenablog.jp

www.shumi-tech.online

継続の1年

昨年に引き続きKubeWeekly読書メモをほぼ毎週更新することができました。(これは業務だったりもしますが・・)加えて今年は海外の電子工作事例を紹介するブログを開設し、こちらはほぼ平日毎日更新することができました。

ここ最近の自分の関心である「Kubernetes」「電子工作」についてインターネット上で一定の発信力を示せたのでは?と考えています。

qiita.com

inajob.netlify.com

健康の1年

ここ数年続けている「朝のラジオ体操」、「ダンスダンスレボリューション」を実施し、「ダンスダンスレボリューション」については途中で「Wii Fit」に切り替え、さらなる健康を獲得しました。(週末30minジョギングはなかなか継続できません・・)

inajob.hatenablog.jp

出版の1年

これは今年というよりは去年頑張ったのですが、私が共同執筆として名を連ねる本が2冊発売されました。書籍の執筆という非常に面白い経験を得ることができました。(興味がある人は買ってくださいね!)

みんなのDocker/Kubernetes

みんなのDocker/Kubernetes

 

ステータス

  • 引っ越してから3年目
  • 会社に入ってから10年目(来年で11年目)
  • 結婚してから3年ちょっと

今年学んだスキル

  • 電子工作キットの通販
  • 表面実装基板の作成、発注

月別振り返り

1月

2月

3月

4月

5月

6月

7月

8月

9月

10月

  • HACHIBAR 試作3回目

  • inline-editor改良

    inajob.github.io

  • スピーカーボックスを自作

  • 同人ハードウェアミートアップ参加
  • RakuChord爆音化改造

11月

12月

参考

 

Nu:Tekt NTS-1 digital kitでサウンドプログラミング入門 #KORG #NTS1

Nu:Tekt NTS-1 digital kit

Korgが発売している1ボイスのハードウェアシンセサイザーです。

組み立て式のキットとして販売され、1ボイスのオシレータ、それにつながるフィルタとエンベロープ、さらにモジュレーション、ディレイ、リバーブといったエフェクトをかけることができます。

 外部からのオーディオ入力もサポートしており、外部音源に対するエフェクタとしても利用することができます。さらに、テンポシンクのための入出力、MIDI入力、USB(MIDI)とインターフェースも豊富です。

極めつけはカスタムのオシレータ、モジュレーションが作成・利用できるという機能まであります。

RakuChordなどで音を生成するプログラムをちょっと書いたことがある私にとっては、「プロ」の作ったシンセサイザーのハードウェアからソフトウェアまでを触ることができるこの製品は非常に魅力的でした。

組み立て

f:id:inajob:20191128231310p:plain

まずは組み立てです。といってもはんだ付けなどは必要ありません。

まずは基板兼ケースとなっているパネルを折り曲げて分離します。(辺に折り曲げてしまうと取り返しがつかないのでここが一番緊張しました。)

f:id:inajob:20191128231345p:plain

それからそれらをねじで止めて、鍵盤となるリボン抵抗をコネクタで接続し完成です。

USBコネクタに電源をつなげると起動し、鍵盤をタッチすることで音が鳴ることが確認できました。

f:id:inajob:20191128231413p:plain

音を出して遊ぶ

鍵盤を押すと、当然それに対応した音が鳴ります。しかしこのリボン抵抗は細かい操作ができず、音出しのテストくらいしか使用に耐えません。USB/MIDI接続を使いMIDIホストと接続することで、この問題は解消できそうです(まだ試していない)

しかしアルペジエータの機能を使うことで、それっぽいメロディをNTS-1だけでも演奏することができます。

プリセットのオシレータを使い、フィルタ、エンベロープをぐりぐり動かすだけでもかなり面白いです。

エフェクタとして遊ぶ

オーディオ入力端子に自作電子楽器のRakuChordをつなげて、エフェクタとして利用してみました。

モジュレーションのコーラスエフェクトやリバーブは音に深みが出て非常に面白いです。

ディレイはテンポと同期する機能がないため、うまく速度を調整するといい感じに動きますが、合わせるのが非常に難しいです。ぜひテンポと同期できるディレイを実装してほしいと思いました。

オシレータを自作して遊ぶ

プログラマとして見逃せないのがカスタムオシレータの自作です。調べるとNTS-1で利用できるSDKが公開されており、これを使うことでC/C++でオシレータやモジュレータが作れるようです。

github.com

しかし、このSDK、ドキュメントが非常に少なく、また海外・国内ともにあまりチュートリアルのようなものがありません。これは、結構苦労しそうです・・

↓に用意されているスクリプトを使うことでLinux,Windows,macOSそれぞれの環境でNTS-1で利用されているSTM32用のgccをセットアップすることができます。

logue-sdk/tools/gcc at master · korginc/logue-sdk · GitHub

しかし、これらをちゃんとセットアップするのは依存関係も含めて結構手間です。

ということで、まずはこのlogue-sdkの環境をまるっと閉じ込めたコンテナイメージを作成しました。

GitHub - inajob/logue-sdk-docker

このコンテナイメージを使うことで、Dockerをインストールするだけでlogue-sdkの開発を始めることができます。

さて、セットアップは簡単にできるようになったので、いよいよプログラミングです。

オシレータの作成例があるので、これを参考にします↓

logue-sdk/platform/nutekt-digital/demos/waves at master · korginc/logue-sdk · GitHub

このプログラムはよくできていてwaves.hppというファイルにC++のオブジェクトとして、オシレータが実装されており、waves.cppでlogue-sdkから呼び出されるフックの関数を実装しています。

よくできているのですが、SDKの利用方法を学ぶ際にはもう少し簡単な例が欲しいところです。

そこで、とりあえず簡単に「ラ」を鳴らすだけのオシレータを実装してみることにしました。

 

変更したファイルはこれだけ

  • waves.cpp, waves.hpp:これは削除
  • simple.cpp:新しく作成。後ほど説明
  • manifest.json:オシレータの名前やパラメータの設定
  • project.mk:書き換えてsimple.cppを指すように変更

実際にはsimple.cppを作るところ以外はほとんど機械的な変更だけです。

>> code
#include "userosc.h"

uint16_t param1; // オシレータのパラメータ記録用
uint32_t tot; // オシレータの位相の記録用

// このオシレータが起動したときに呼ばれる?
void OSC_INIT(uint32_t platform, uint32_t api)
{
  param1 = 0;
  tot = 0;
}
// オシレータが次の波形を計算するために呼ばれる?
// ynのアドレスからframes分までのメモリに波形を書き込む
// paramsに押された鍵盤の音階や周波数が入っている
void OSC_CYCLE(const user_osc_param_t * const params,
               int32_t *yn,
               const uint32_t frames)
{

  q31_t * __restrict y = (q31_t *)yn;
  // 終了メモリアドレス
  const q31_t * y_e = y + frames;

  // メモリへの書き込みループ
  for (; y != y_e; ) {
    // サンプリングレートは48KHzのようなので、以下の式で440Hzの矩形波が作れる
    // 別途param1を設定することで周波数を変更できるようにしてみる(本当は鍵盤で指定された周波数にすべき)
    float sig = (tot/(48000 / (440 + param1))%2 == 0)?0:1;
   // floatからq31に型変換しメモリに書き込む 
    *(y++) = f32_to_q31(sig);
    tot ++; // 位相を進める(オーバーフローするときに波形が乱れるのであまりよくないような気がする)
  }
}

void OSC_NOTEON(const user_osc_param_t * const params)
{
  // note onの時に呼ばれる
}

void OSC_NOTEOFF(const user_osc_param_t * const params)
{
  // note offの時に呼ばれる
}

// オシレータのパラメータが変更されたときに呼ばれる
void OSC_PARAM(uint16_t index, uint16_t value)
{
  switch (index) { // どのパラメータが変更されたかが入っている
  case k_user_osc_param_id1: //今回はこの変更のみで処理する
    {
      param1 = value; // 0..15 // OSC_CYCLEで使うので変数に入れておく
    }
    break;
  default:
    break;
  }
}
 
<<

 

これが今回の”「ラ」が鳴るだけオシレータ”です。

よく見るととても簡単です。要はOSC_CYCLEでどんどんメモリに次の波形を書き込んでいけばよいわけです。

ビルドは先ほど紹介したlogue-sdk-dockerを使えば簡単にできます。ビルドができると拡張子ntkdigunitのファイルができるので、Librarianという専用ツールでNTS-1に書き込みます。

これでOSCに新しいオシレータが追加されます。

ついでに、このプログラムを改造して押された音階に対応する音が鳴るようにしてみます。

>> code

void OSC_CYCLE(const user_osc_param_t * const params,
               int32_t *yn,
               const uint32_t frames)
{
  q31_t * __restrict y = (q31_t *)yn;
  const q31_t * y_e = y + frames;

  // メモリへの書き込みループ
  for (; y != y_e; ) {
    // osc_w0f_for_note(音階番号, 音階からのずれ周波数?) でオシレータの変分を返す
    // これらは引数のparams->pitchに入っている
    // 参考: https://github.com/korginc/logue-sdk/blob/master/platform/nutekt-digital/inc/userosc.h#L56
    // > high byte: note number, low byte: mod (0-255)

    float w = osc_w0f_for_note((params->pitch)>>8, params->pitch & 0xFF);
    // nowに今の位相が記録されている、これをフレームごとにずらしていく
    now += w;
    // プリセットのウェーブテーブルのnowの位相の値を取り出す
    float sig = osc_wave_scanf(wavesB[param1], now);
    // floatをq32に変更しメモリに書き込む
    *(y++) = f32_to_q31(sig);
  }
}

<<

こんな感じです。osc_w0f_for_noteとかosc_wave_scanfとか、wavesBとかはほかのソースコードを見ながらで書いています。この辺もう少しドキュメントが欲しいところです。(そもそもプリセットのwaves[A-D][0-15]にはどんな波形が入っているか書いてあるドキュメントが見当たらない・・)

 

と、こんな具合でC言語と勘があれば自分でオシレータを作ることができることがわかりました。

 

(ここまでのソースコードhttps://github.com/inajob/simple-oscで公開しています。)

追記: 日本語のドキュメントが公開されました! https://korginc.github.io/logue-sdk/ja/

感想

このガジェットはDTMをたしなむ人はもちろんですが、サウンドプログラミングを学びたい人」にとっても非常に便利なものであると感じました。

音をソースコードで記述する「サウンドプログラミング」ですが、リアルタイムに鳴らそうとすると、たくさんのタスクが並列に処理されるOSの上では案外書きにくいものです。

そこで役に立つのがマイコン上でのサウンドプログラミングです。これまではArduinoやmbedでも似たようなことができましたが、これらはオーディオに特化していないため、パソコンからのMIDI信号受信や、外部音源の取り込み、ディレイを扱うための大きなメモリなど、かなりの周辺機器を自作しないとまともなオーディオプログラミング環境になりません。これにはかなり高度な電子工作、マイコンプログラミングの知識が必要です。

しかしこのNTS-1はこれらの面倒な部分をすべて受け持ってくれて「サウンドプログラミング」の「おいしいところ」だけを扱うことができます。

 

といった感じで、本当にこれはサウンドプログラミング界のArduinoというべき開発環境であると感じました。

また、単純にハードウェアMIDI音源、オーディオエフェクタとしても非常に使いやすいし、品質も良いためプログラミングとは無縁のDTMユーザにもおすすめできます。(まぁ私はDTMユーザではないのでこの部分の評価はほかの人の記事を見ていただくほうが良いです)

 

私は自作電子楽器RakuChordの後段のエフェクタとして、また自作電子楽器の音源の研究という2つの目的でこれからもこのNTS-1を活用していきたいと考えています。

 

記事の中にも書いた通りプログラミング周りはドキュメントなどが少なく、これからの盛り上がりが非常に大事であると考えています。

ぜひぜひ、NTS-1を買った人は得られた知見を公開してもらえると助かります!

 

またTwitterで情報を記載する際にはハッシュタグ#NTS1を使うことをお勧めします(製品名であるNTS-1はハイフンが含まれておりハッシュタグにできないため。)

 

私も自分が発見したことをブログや下記Scrapboxのページにまとめていこうと思うので、NTS-1ユーザの方は見てみてください。

scrapbox.io

 

Amazonで買えます↓ 

 

1年継続!自宅ダンスダンスレボリューションからの1000円追加でWii Fitへの挑戦

1年間継続できました!

去年の11月ごろに購入したWiiダンスダンスレボリューションですが、ここまでの約1年間、なんだかんだと継続することができました!

inajob.hatenablog.jp

(といっても「毎日欠かさず」、とまではいきませんでしたが、「ほぼ毎日」といった感じですが・・)

 

普段からあまり運動をしない私ですが、ダンスダンスレボリューションのおかげでまぁ少しは運動習慣をつけることができたのかなと思います。

 

実施方法は「毎朝3曲踊る」というものです。

f:id:inajob:20191104093700p:plain

上図が典型的な平日の脈拍です。朝8時ごろにガッと上昇しているところがありますが、ここがダンスレボリューションです。その後通勤のためにしばらく高い状態が続き、続いてお昼、そして夕方の帰宅時に上昇しています。

 

(ちなみに上記グラフはFitbit Versaが記録したものです。こうやって運動習慣が可視化されるのは結構面白いのでおススメです。)

Fitbit Versa スマートウォッチ Black L/Sサイズ  [日本正規品] FB505GMBK-CJK

Fitbit Versa スマートウォッチ Black L/Sサイズ [日本正規品] FB505GMBK-CJK

 

遊んだソフト

もともと去年購入時は

こちらのダンスダンスレボリューションフルフルパーティーで遊んでいました。

最近になって、別のソフトも遊んでみようかなと思い

Dance Dance Revolution with MARIO (マットコントローラ同梱)

Dance Dance Revolution with MARIO (マットコントローラ同梱)

 

 こちらのゲームキューブ版のDance Dance Revolution with MARIO(以下 マリオDDR)も購入しました。(中古ですごく安かったので・・)

良く知らなかったのですがWiiではゲームキューブのソフトも遊ぶことができるためソフトとメモリーカードを購入するだけで、遊ぶことができました。

(できればメモリーカードWiiのものが使えると良かったのですが・・)

 

Wii版のダンスレボリューションマットで遊べるかどうかは心配だったのですが、全く問題なく動作しました。

f:id:inajob:20191104095629p:plain

こちらのマリオDDRはマリオにまつわる楽曲や、クラッシック曲をベースにした音楽によるダンスレボリューションです。前述のフルフルパーティーに比べると比較的難易度は易しく、ちょっと物足りない感じがしましたが、よく知っている曲でダンスダンスレボリューションを遊べるという点では楽しかったです。

トラブルはあった?

Wiiやマットが中古ということで、いろいろ 心配事があったのですが、問題が起きたのはこれです。

これはWiiの映像出力をHDMIに変換してくれる非常に役に立つアダプタなのですが、頻繁に抜き差しをしていたこともあり、これのオーディオジャックが内部でもげてしまいました。

f:id:inajob:20191104095304p:plain

幸いにも電子工作の心得があったため、難なくはんだ付けしなおして事なきを得ました。 

Wii本体やマットに関しては1年間遊び続けていますが、特に問題は起きていません。さすが任天堂です。

ダンスは上達した?

ダンスダンスレボリューションが良いのは「自分が進化する」というところです。

購入時は全く歯が立たなかった曲も何度もこなすうちにだんだん踊ることができてくるという体験が楽しく、ここまで継続することができました。

特にダンスレボリューションは1つの曲でも複数の難易度が用意されているため、次から次へとハードルが用意されている感じで、継続していても楽しかったです。

 

フルフルパーティーで「Difficult」の曲は大体A以上は記録できるようになりました「Expert」はなかなか難しく曲によってまちまち・・というところです。

もともと「Basic」の曲が楽しい!くらいのところからスタートしたのでかなりの上達です。

フルフルパーティに関しては難易度がちょうど僕に合っているらしく、まだ楽しめそうです。一方マリオDDRについては、一番難しいモードでも比較的簡単にAがとれてしまい、ちょっと簡単すぎかな、という感じでした。

効果のほどは・・?

こういう健康施策はいまいちわかりやすい効果が出ないものですし、ダンスダンスレボリューション以外の要因も絡んでくるので、効果が出たといっても一概にこれが良かった!ということも難しそうです。なので以下は参考までに・・

足の裏の感覚が変わった

これはダンスレボリューションを始めて1週間ほどで実感があったのですが、歩いているときの足の裏の感覚が少し変わった気がします。今やもうそれが普通になって特に何も感じませんが、何か足の使い方が変わったのかもしれません。

風邪が減った

ここ2-3年本当によく風邪をひきました。まぁそういうこともあって運動習慣をつけようと頑張っていたわけですが、、

今年は例年に比べて風邪をひく回数が減ったように思います。

風邪をが長引くことが減った

上記に加えて体調不良の期間が短くなったように感じます。

朝シャキッとするようになった

ダンスダンスレボリューションは朝行っていたのですが、花粉症のシーズンなどは花粉によるだるさや鼻水が少し楽になるように感じました。

まぁ調べてみると朝に急に運動をすることは健康上あまりよくない、というような話もあるようですが、僕の場合は特に悪いことは今のところ起きていません。

他にも行っている運動習慣

ダンスダンスレボリューションのほかに、毎朝のラジオ体操週末の30minジョギング(これは結構サボりがちですが、、)などを行っています。これら2つはダンスレボリューションより以前から行っていたものなので、上記の気づいた変化はダンスレボリューションによるところが大きいのでは?と考えています。(とはいえ、運動習慣が遅延して影響を及ぼすこともあると思うのでなんともわかりません)

体重は変化なし

僕は体系で言えば「やせすぎ」なので、ダイエット効果は全く期待していませんでしたが、この程度の運動では特に体重が大きく増減することはありませんでした。

ネクストチャレンジ!

そろそろダンスダンスレボリューションはやりつくした感があるので、次は・・・・

Wiiフィット プラス (バランスWiiボードセット) (シロ)

Wiiフィット プラス (バランスWiiボードセット) (シロ)

 

 Wii Fitに挑戦します!(これまた中古ですごく安かったので!)

中古だと1000円くらいでバランスボードと一緒に購入できました!どうせ買うならWii Fit Plusがおすすめです。

f:id:inajob:20191104100527p:plain

購入して数日ですが、早くも背中の筋が痛いです。

1年後、さらに健康になれているといいなぁ。

 

 

Androidを変愚蛮怒専用機にする

これは?

以前Raspberry Pi Zeroを使った携帯型の変愚蛮怒専用機を作成しました。

inajob.hatenablog.jp

しかし、よく考えてみると、ここまで頑張って作ることなく変愚蛮怒を遊ぶ方法がありそうです・・・ そうです スマートフォン を利用するのです。

といっても、遊びたいゲームのiPhone/Android版が存在しないときはどうすればよいでしょうか?

ちょっと調べるとAndroidDebian Linuxを動作させる方法があるようです。

これを利用してAndroid変愚蛮怒を遊ぶ方法を考えてみました。 

f:id:inajob:20191010221624p:plain

AndroidLinux 「GNU Root」

まずはRoot権限なしでAndroid上でLinuxユーザランドを動かす方法を探します。

play.google.com

これを使いました。

注意としては、GNU Rootはもうメンテナンスされていません。そのため新しいAndroid端末ではインストールできません。

代わりにUserLAndというソフトが使えそうです。(ただし僕は古いAndroid端末しかもっていなかったのでGNURootしか使えませんでした。)

play.google.com

 

おそらくこれから紹介する方法はUserLAndでも動作するのでは?と思いますが、確証はないです。

 

GNURootはもう古いアプリなので説明は手身近に・・

 (ここからGNURoot特有の記載です)

Rootfsとして DeibanのWheezyを選択し「Create New Rootfs」をタップ。

するとGNURoot Wheezyというソフトをインストールする画面になるので、そのままインストールします。

その後再びGNURootを起動し「Launch Rootfs」をタップすることでコンソールが起動します。

Root権限が必要な場合は「Launch as Fake Root」にチェックを入れて「Launch Rootfs」をタップするとRoot権限のコンソールが起動します。

必要に応じて2つのコンソールを使い分ける必要があります。 

Debian Wheezyはすでにパッケージリポジトリがarchiveのものしか存在しないのでまずは/etc/apt/source.listを下記のように編集する必要があります。(本当はアップグレードしたいのですが、GNURootがすでにメンテされていないので・・)

dev http://archive.debian.org/debian/ wheezy main contrib non-free
dev-src http://archive.debian.org/debian/ wheezy main contrib non-free

 編集したらapt-get updateしておきます。

さて、ここまででAndroid上にDebianユーザランドを用意することができました。 

 (ここまでがGNURoot特有の記載です)

変愚蛮怒のビルド

変愚蛮怒Linux版はソースコードで提供されています。そのためビルドする必要があるので、必要なライブラリをインストールします。(後で使うのでmake, unzip, curlも入れておきます) 

# apt-get install libncurses5-dev make unzip curl

依存関係でgccやらいろいろ入ります。

 

ここからは一般ユーザで操作します。

変愚蛮怒をダウンロードしてビルドします。

$ cd /home
$ curl -L https://ja.osdn.net/projects/hengband/downloads/10331/hengband-1.6.2.tar.gz/ > hengband-1.6.2.tar.gz
$ tar xzf hengband-1.6.2.tar.gz
$ cd hengband-1.6.2
$ ./configure --without-x
(時間がかかります)
$ make
(すごく時間がかかります)

これで./src/hengbandにバイナリが生成されます。

ここで、./src/hengbandを実行すると、確かに起動するのですが、全体的に文字化けてしまいます。(SHIFT+Qなどで終了できます。)

これは変愚蛮怒EUC-JPにしか対応していないからです。加えてAndroidのTerminalはUTF-8の日本語は表示できますがEUC-JPには対応していません。

 

ここで、役に立つのがcocotです。

cocotのビルド

vmi.jp

cocotは、端末とプロセスの間に割り込んで文字コード変換を行うツールです。これはまさに今欲しい機能です。EUC-JPで動作する変愚蛮怒の出力を受け取り、端末にはUTF-8を返すことで、文字化けを解消できそうです。

こちらもAndroid用のバイナリは存在していないので、自分でビルドします。

$ cd /home
$ curl -L https://github.com/vmi/cocot/archive/master.zip >cocot.zip
$ unzip cocot.zip
$ cd cocot-master
$ ./configure
$ make

特に問題なくcocotもビルドできました。

あとはcocotを通して変愚蛮怒を起動すればよいだけなのですが、なぜか一般ユーザで実行すると「Error: openpty()」などと表示されて実行できないので、rootの端末で作業が必要でした。

 さて、ドキドキしながら起動します。

# cd /home
# cd hengband-1.6.2
# ../cocot-master/cocot -t UTF-8 -p EUC-JP -- src/hengband

 日本語も表示された!

ということでこれでAndroidでも簡単に変愚蛮怒で遊べるようになりました。

ただ、この方法をもってしても、まれに表示の一部が文字化けする起きるようです。まぁゲームの進行に支障がないレベルのものなので、この点は妥協するとしましょう・・

別解: Xで変愚蛮怒を使う

前回Raspberry Piで試したときはX11環境をセットアップしました。Androidでもこの方法で変愚蛮怒を利用することができますが、Androidの容量を非常にたくさん消費するので、あまりお勧めしません。

しかし、もし上記の方法でうまくいかない場合はX環境での実行を試してみるのもよいでしょう。

(といいつつ、詳しい方法はここでは書きません だいたい前回記事のRaspberry Piと同じ方法になると思います。)

f:id:inajob:20191012174818p:plain

おまけ: 3Dプリンタでケースを作る

前回の変愚蛮怒専用機と同様、3Dプリンタでケースを作りました。

f:id:inajob:20191012174138p:plain

f:id:inajob:20191012174201p:plain

スマートフォンの中にバッテリーもディスプレイもCPUも内蔵されているため、非常に簡単な作りで、しかもコンパクトに設計できました。

ちなみにここで使ったキーボードはこちら↓

 まぁ作ってみたのですが、、 意外と使いづらい。キーボードと本体は分離してたほうが遊びやすいですね・・また今後改良していきたいと思います。

まとめ

ということで、物理キーボード付きの変愚蛮怒専用Androidが完成しました。

これで、気軽にどこでも変愚蛮怒が楽しめます!