Yuki Nakata's Blog

天才 中ちゃん♪

Raspberry pi3にretropiをインストールしてみました。

retroPiとはラズベリーパイ向けのエミュレーターてんこ盛りOSのことです。

retropiをインストールして、あとはゲームソフトを転送してやればレトロゲームを遊ぶことができるようになります。

retropiを使うとラズベリーパイをゲーム用マシンにすることができます。 ファミコン、スーパーファミコン、アーケード、64などの主要なエミュレーターが含まれています。

プレイステーションもN64も遊べますが動作しないソフトもあるようです。

新たにmicroSDカードを購入。一枚のmicroSDカードを使い回すのではなくOS毎にSDカードを持っておくと便利です。ラズベリーパイに入れ替えるだけですからね。

RetroPie から RetroPi 4.0.2をダウンロードします。現在最新は4.0.2です。
解凍してimgファイルを取り出します。

microSDをSDFormatter を使ってフォーマットします。
sdformatter
オプション設定から上書きフォーマット 論理調整 ONでフォーマットします。

取り出したimgをWin32DiskImagerを使って書き込みます。
win32diskimager
出来たらmicroSDカードを取り出しラズベリーパイに装着します。

ゲームコントローラーを付けてラズパイの電源を入れます。
cf42f25c-3cee-11e5-8f91-c1fc1c57175c
ゲームコントローラーのボタンを割り当てていきます。

Logicool F310を使っています。下の画像と同じように設定。
7f353148-42c0-11e6-9023-dbaf074bc933

割り当てるボタンがなかったり、スキップしたい場合にはAボタン長押しです。

c6bbdb3a-3734-11e6-998f-8cc714a320ce
EmulationStationが現れます。retropiのエミュレーターの統括プログラムをEmulationStationといいます。

ここで1時間ハマりました。何をしていいかわからない。ゲームが遊べないので困りました。

実はRomを適切なフォルダに入れるとNESやSNES, MAMEのメニューが出てきます。

最初にネットワークにつなぎましょう。有線LANでつないでいますが、無線の場合にはメニューからConfigure Wifiで無線設定をします。
7ed23ec0-3cf5-11e5-9944-a8f7870cc6c0
無線の場合
92b08b8c-3735-11e6-8f20-5d1550af0882

ネットに接続されたらIPアドレスを確認します。SHOW IP

この場合は192.168.0.19です。192.168.0.19がラズベリーパイのIPアドレスになります。

これを控えて覚えておきます。

RETROPIE SETUPからBasic Installをしました。
エミュレーターのインストールが始まります。大分時間がかかります。


RETROPI SETUPからエミュレーター単体で追加インストールすることもできます。

ここからはwindowsPCで操作しています。

パソコンに入っているゲームソフトをラズパイに転送します。

Filezillaを使うのが一番簡単だと思います。

retropiがネット接続できていれば、filezillaからファイル転送することができます。

Filezilla clientをダウンロードして実行します。
filezilla
ホストにIPアドレス 192.168.0.19  ラズベリーパイのIPアドレスを指定します
ユーザー名 pi
パスワード raspberry
ポート 22 で接続できます。

放り込むロムのディレクトリが指定されています。

日本語のファイル名は文字化けします。

ファミコンの場合には/home/pi/RetroPie/roms/nes
スーファミ /home/pi/RetroPie/roms/snes
N64  /home/pi/RetroPie/roms/n64
アーケード /home/pi/RetroPie/roms/mame-mame4all

アーケードゲームの場合注意が必要です。
ロムのバージョンが0.37b5でなければ動作しません。
真っ黒の画面でクラッシュする場合にはロムセットが間違っている可能性があります。
zipでmame-mame4allのディレクトリに入れます。
RetroPie Mame

PS1 /home/pi/RetroPie/roms/psx
cueとbinをpsxディレクトリに入れます。
bios SCPH1001.BIN を/home/pi/RetroPie/BIOS
プレイステーションはcueファイルがないと動作しません。
Playstation Cue FIle cueファイルがここで手に入るようです。
RetroPie PlayStation


ロムを放り込むと初期の画面が変わります。 

メニューが変わり、ゲームが選べるようになった。 

音はHDMIから出力されるようになっています。
イヤホンに変更する場合にはemulationstationを一旦終了するとコマンドが打てるようになります。
$ amixer cset numid=3 1     イヤホンに音を出力させる

$amixer cset numid=3 2       HDMIに音を出力させる

音量設定 パーセンテージで指定します。 50%~100%で指定します。
$ amixer cset numid=1 70%
70%ぐらいがおすすめです。 50%以下だと何も聞こえなくなります。 

みうみうの愛称で親しまれている三浦九段がスマホカンニング疑惑で年内出場停止処分を受けました。

8月頃から疑惑を持たれていたようです。

三浦九段というと結婚式でも詰め将棋を解いていたエピソードが有名です。

昔はものすごく寡黙でしたが、ニコニコ動画にも登場するようになりイメージがずいぶん変りました。

文春の続報が入ってきました。
渡辺竜王が連盟に疑惑を提起。
羽生2冠、佐藤名人、千田五段含む7人で検討した結果、クロと認定。
三浦9段のPCに入っていたソフトは技巧 (妻がダウンロードしたと弁明)
疑惑の対局は4局
三枚堂4段が遠隔操作ソフトteamViewerの存在を教える (インストールしていないと弁明)

文春を読んだ結果、真っ黒だと思いました。teamViewerはアウトです。モロに遠隔操作ソフトだからです。

しかしteamViewerはインストールしていないしと弁明、PCとスマホを提出しても良いと言っていますし、どうやら調査の方向へ進むようです。
三浦九段の反論文書全文

正直に言ってわかりません。これで白ならどうするんだろう?笑
逆に渡辺竜王と連盟の立場が悪くなりますよ。
このままグレー決着の方が跡を濁さないのでいいと思うのですが。

疑惑の4局
2016年10月3日 順位戦 三浦弘行 九段 vs. 渡辺 明 竜王 
2016年9月8日 竜王戦 三浦弘行九段 vs. 丸山忠久九段
2016年8月26日 竜王戦 三浦弘行 九段 vs. 丸山忠久 九段
2016年7月26日 竜王戦 久保利明 九段 vs. 三浦弘行 九段

ではスマホカンニングしたと言われている疑惑の一局です。この対局が最もソフトっぽい。
 
A級順位戦 三浦九段 対 渡辺竜王

渡辺竜王がボロボロにやられてしまいます。感想戦も20分程度で終わってしまったそうです。

言われてみればソフトっぽい。

▲45桂から▲71角はソフトらしい踏み込み。でも序盤なのでこの辺は事前研究でしょう。
miumiu
後手は飛車を打ち込まれると弱い陣形です。

△85同飛と桂馬を取りたいが、▲74歩と飛車交換を迫られる。

といっても結局飛車交換に持ち込まれ飛車を打ち込まれるのですが。

ソフトを使っていなければ大分棋風を改造した感じです。

ソフトを使ったかどうかはわかりません。


ニコニコのテトリスさんが棋譜解析をされています。
三浦九段はトータルで68%の一致率、後半はなんと90%の一致率!
前半は事前研究、中盤カンニングなし、後半カンニングありだと説明はつきますが。








shogidroid
そんなことよりスマホアプリで最強はshogiDroid。

これは強いよ。

やねうら王がこのshogiDroidで動作している、ということでこのアプリを知りました。

将棋エンジンを追加できるので電脳戦2位のAperyや技巧とも対局することができるようです。

もちろん棋譜解析も付いています。次の一手もわかります。

棋譜を入力し次の一手を探させる、5分~10分あれば出来ます。

スマホカンニングするならshogiDroidが絶対おススメです。

もし三浦9段がスマホを使っていたとしたらこのソフトかもしれません。

このソフトを使えば7冠王になれるかも。






raspberry pi3でSDカードの速度を測ってみました。

_SL1500_
使っているのはTrascend TS32GUSDU1PE
32GB Class10 UHS-I対応 400×
価格は1000円程度。

ddを使えば簡単に性能テストすることができます。
まずは書き込みから3回。
$dd if=/dev/zero of=test bs=1048576 count=200
200+0 レコード入力
200+0 レコード出力
209715200 バイト (210 MB) コピーされました、 9.51548 秒、 22.0 MB/秒
$ dd if=/dev/zero of=test bs=1048576 count=200
200+0 レコード入力
200+0 レコード出力
209715200 バイト (210 MB) コピーされました、 10.7134 秒、 19.6 MB/秒
$ dd if=/dev/zero of=test bs=1048576 count=200
200+0 レコード入力
200+0 レコード出力
209715200 バイト (210 MB) コピーされました、 10.0956 秒、 20.8 MB/秒
約20MB/秒出ています。
 
次は読み込み3回。
$ dd if=test of=/dev/null bs=1048576
200+0 レコード入力
200+0 レコード出力
209715200 バイト (210 MB) コピーされました、 0.283352 秒、 740 MB/秒
$ dd if=test of=/dev/null bs=1048576
200+0 レコード入力
200+0 レコード出力
209715200 バイト (210 MB) コピーされました、 0.284043 秒、 738 MB/秒
$ dd if=test of=/dev/null bs=1048576
200+0 レコード入力
200+0 レコード出力
209715200 バイト (210 MB) コピーされました、 0.297618 秒、 705 MB/秒

やけに早くねえか。ま、いっか。

結果は上出来だと思います。
価格の高いものを買ってもラズベリーパイの起動が早くなることはありません。ほとんど変わらないようです。

Raspberry PI SDカード 
ここに対応SDカードと性能パフォーマンスが載っています。

書き込み20MB/s 出て入れば最高クラスです。

次回も同じTrascendを購入することにしています。

 

raspberry pi3でmameを動かします。ちゃんとアーケードゲームが遊べてしまいます。

Better AdvanceMAME debs with Sound! から advancemame-raspberrypi_1-1_armhf.debをダウンロードします。

サウンドも出るようになりました。

$sudo dpkg -i advancemame-raspberrypi_1-1_armhf.deb

起動は /usr/local/bin/advmameです。

ロムファイルをデフォルトの/home/pi/.advance/rom に放り込みます。

$advmame  gamename
で起動します。gamenameは.zipなしで。

ゲームパッドも接続するだけ。後は何もしません。

設定ファイルは/home/pi/.advance/advmame.rc ですが、何も変更なし。

知っていると思いますが、デフォルトで数字の5でコイン投入(Coin)、1でゲームスタート(Player Start)。

最後にMAMEを自動起動させてみましょう。キーボードとマウスなしでもいけます。

起動時のOKはゲームパッドの左、右の入力でOKと同じことになります。

ゲーム中 Tab -> input (general) -> other controls
ここから Player StartとCoinボタンをカスタマイズ。好きなボタンに設定。

スクリプトを作成。
$sudo /usr/local/bin/advmame.sh

#!/bin/bash

BASEDIR=/usr/local/bin

# Wait for the PS3 Game pad to be available
while [ ! -e /dev/input/js0 ]; do sleep 2; done

# The DISPLAY=:0 bit is important for the GUI to work
DISPLAY=:0 $BASEDIR/advmame gamename

#gamenameを指定しなければなりません。でスクリプトを実行可能にする。
$sudo chmod +x /usr/local/bin/advmame.sh

自動起動に登録
$vi /home/pi/.config/lxsession/LXDE-pi/autostart

最後の行に追加
@/usr/local/bin/advmame.sh

これでラズベリーパイが起動すると自動的にadvmameが立ち上がります。 

 

とんかつ 松のやへ行きました。

仕事で東園田に行き、園田駅でぶらぶらしていたところ、新しくできたお店を見つけました。


松のや
松のや HP 牛どんの松屋グループ。どうやら出店ラッシュのようです。

メニュー
gm_160609_01
gm_160609_02
gm_160921_03
500円 ロースかつ定食に惹かれて入りました。

ネットで調べてもワンコイン定食はインパクトが大きかったようです。
 
内装もいいかんじ。


揚げたてさくさくのとんかつが出てきます。これで500円。

小食派の私にはご飯の量が少し多い。

ソースとドレッシングそれぞれ2種類ずつ。

期待以上に美味しかったです。

武庫之荘駅前にも出店するので行ってみたいです。 

牛どんなんていらんかったんやー。 


アマゾンで本を買った結果


アマゾンで加治将一さんのアルトリ岬を買いました。
  




サイン本でした。

普通に新書を買ったんですがねー。こんなことってあるんですね。

この本素晴らしかったです。一気に読めました。

 相川文弥は、何事にも自信のない中年男だ。平凡な暮らしを望んでいたが、息子はひきこもり、娘は放浪癖、妻からは離婚を突きつけられる。

家庭崩壊寸前です。

こういう家庭は結構ありがちです。

かつてナニワ金融道の青木雄二は経済が問題だと見抜いたのです。 だから彼はずっとお金の漫画を描き、資本主義批判をしたのです。
50億円の約束手形を掲載してみます。

貧乏サラリーマン今井一郎さんの場合
tegata1
tegata2


ところが大金が手に入ると分かると一変する。


 tegata3

tegata4
tegata5
tegata6
青木雄二は資本主義批判をしましたが一体何か変わりましたでしょうか?

貧乏なのは経済に原因があるわけですが、それだとドツボにハマる可能性があります。

宝くじでも当たらなければ、給料が上がらなければ、資本主義が終わらなければ永久に解決不可能です。

今は問題解決の仕方が違うのですよ。

このアルトリ岬のように心の問題だというのです。

心の扱い方に問題がある。最近でいうマインドフルネスです。

幸せに生きるにはどうすれば良いのかを考える科学的なメソッドです。

心の問題ですから各人意識の仕方で一瞬で変わり得るのです。

物事のとらえ方次第なんですね。

先ほどの漫画を思いだしましょう。大金が手に入るかもしれない、と皆が思っただけで家庭円満になり解決してしまいます。

その時点では大金は手にしていません。思っただけで解決してしまったのです。

だったら大金がなくても解決する方法があるのではないでしょうか。

それが心の使い方です。

心の使い方というのは面白く、奥が深いです。

私も常日頃未熟だと痛感しています。

人間というのは一度徹底的に挫折したり、絶望するのも悪くないと思っています。

久しぶりに良い小説を読みました。読んでもらいたい小説です。

コンビニ人間とかいうヘンテコなの読んでたからな。w

上の漫画はGoogle Playで無料で読めてしまいます。

50億円の約束手形

淀川河川敷

ラテン喫茶の頃

屋台などが収録されています。どれも名作ですよ。

青木雄二漫画短編集 完全版1 ゼニの掟編


 

マウスをカスタマイズしよう linux編の続きです。

実はゲームパッド Elecom F310についてずっと考えていました。笑

マウス同様ジョイパッドをカスタマイズしましょう。なんとかプログラムもできました。

ゲームパッドをマウスみたいにします。

前回同様にUSB接続を調べます。
$ cat /proc/bus/input/devices
I: Bus=0003 Vendor=1bcf Product=0005 Version=0110
N: Name="USB Optical Mouse"
P: Phys=usb-3f980000.usb-1.2/input0
S: Sysfs=/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.2/1-1.2:1.0/0003:1BCF:0005.0001/input/input0
U: Uniq=
H: Handlers=mouse0 event0 
B: PROP=0
B: EV=17
B: KEY=1f0000 0 0 0 0 0 0 0 0
B: REL=143
B: MSC=10

I: Bus=0003 Vendor=0d62 Product=8070 Version=0111
N: Name="ELECOM Wired Keyboard"
P: Phys=usb-3f980000.usb-1.4/input0
S: Sysfs=/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/0003:0D62:8070.0002/input/input1
U: Uniq=
H: Handlers=sysrq kbd leds event1 
B: PROP=0
B: EV=120013
B: KEY=10000 7 ff9f207a c14057ff febeffdf ffefffff ffffffff fffffffe
B: MSC=10
B: LED=1f

I: Bus=0003 Vendor=046d Product=c21d Version=4014
N: Name="Logitech Gamepad F310"
P: Phys=usb-3f980000.usb-1.3/input0
S: Sysfs=/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.3/1-1.3:1.0/input/input3
U: Uniq=
H: Handlers=event3 js0 
B: PROP=0
B: EV=20000b
B: KEY=7cdb0000 0 0 0 0 0 0 0 0 0
B: ABS=3003f
B: FF=1 7030000 0 0

私の環境ではマウスがevent0 キーボードがevent1, ゲームパッドがevent3です。
マウスが/dev/input/event0,
キーボードが /dev/input/event1
ゲームパッドが/dev/input/event3 となります。

次にゲームパッドのボタンの割り当てを調べます。

//input2.c
//ゲームパッド入力を調べるプログラム
#include <stdio.h>
#include <stdlib.h>
#include <linux/input.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define GAMEPAD_EVENT "/dev/input/event3"
#define MOUSE_EVENT "/dev/input/event0"

int gamepadfd;
int mousefd;

int main(void)
{
gamepadfd = open(GAMEPAD_EVENT, O_RDWR);
mousefd = open(MOUSE_EVENT, O_RDWR);
  for (;;) {
    struct input_event event;

    if (read(gamepadfd, &event, sizeof(event)) != sizeof(event)) {
      exit(EXIT_FAILURE);
    }
    switch(event.type) {
      case EV_KEY:
printf("type:%x  code:%x value:%x\n", event.type, event.code, event.value);
        break;
      case EV_REL:
printf("type:%x  code:%x value:%x\n", event.type, event.code, event.value);
break;
case EV_ABS:
printf("type:%x  code:%x value:%x\n", event.type, event.code, event.value);
break;
      default:
 
        break;
    }
    fflush(stdout);
  }
  
  close(gamepadfd);
  close(mousefd);
}
ゲームパッドを適当に押すと数字が表示されますので、/usr/include/linux/input.hとにらめっこして調べます。

chrome用にゲームパッドを次のようにカスタマイズします。


プログラムの説明
前回のプログラムと同じような仕組みです。
十字キーと十字スティックはシグナルを使ってポーリングしています。つまり毎回入力されていないかデータを取得しにいっています。ぶさいくですがそれしかできませんでした。

要するにゲームパッドからマウスやキーボードにデータ変換しているだけです。変換する箇所が多いのでごちゃごちゃしています。だいぶ試行錯誤しました。

//gamepad.c
//ゲームパッドをchromeブラウザ用にカスタマイズするプログラム
#include <stdio.h>
#include <stdlib.h>
#include <linux/input.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/uinput.h>
#include <string.h>
#include <signal.h>

//ここでマウスとキーボードとゲームパッドのイベントを設定してください。
#define MOUSE_EVENT "/dev/input/event0"
#define KEYBOARD_EVENT "/dev/input/event1"
#define GAMEPAD_EVENT "/dev/input/event3"

#define die(str, args...) do { perror(str); exit(EXIT_FAILURE); } while(0)

typedef struct _GamepadMouseState GamepadMouseState;
struct _GamepadMouseState 
{
  __s32 vx, vy;
  int wheelvalue;
  int wheeldirection;
};

static GamepadMouseState state;
static struct itimerval itimerval;
static struct itimerval old_itimerval;
static struct itimerval htimerval;
static struct itimerval old_htimerval;

int keyboardfd;
int gamepadfd;
int virtualfd;
int mousefd;
int i;



//イベントを発生させる関数
void send_event(int output, int type, int code, int value)
{
  struct input_event event;
  if (mousefd < 0) {
    return;
  }

  event.type = type;
  event.code = code;
  event.value = value;
  gettimeofday(&event.time, NULL);
write(output, &event, sizeof(event));
}

//ゲームパッドのホイール移動
void wheel_handler()
{
//printf("wheel :%x  \n", state.wheelvalue);
if(state.wheeldirection == 0)
return;
send_event(mousefd, EV_REL, ABS_WHEEL, state.wheeldirection);
send_event(mousefd, EV_SYN, SYN_REPORT, 0);
}

//ゲームパッドの十字キーの状態を取得し、マウス移動させる
void alarm_handler(int signum)
{
if((i % 25) == 0) {
wheel_handler();
}
i++;
if(i > 5000)
i = 0;
  if (state.vx == 0 && state.vy == 0 ) {
    return;
  }
  if (state.vx!= 0) {
    send_event(mousefd, EV_REL, REL_X, state.vx);
  }

  if (state.vy!= 0) {
    send_event(mousefd, EV_REL, REL_Y, state.vy);
  }
}



//シグナルを設定する 2000マイクロ秒毎にalarm_handlerを実行する
void init_event_handler()
{
  itimerval.it_value.tv_sec = 0;
  itimerval.it_value.tv_usec = 2000;
  itimerval.it_interval.tv_sec = 0;
  itimerval.it_interval.tv_usec = 2000;
  signal(SIGALRM, alarm_handler);
  setitimer(ITIMER_REAL, &itimerval, &old_itimerval);
}


int main(void)
{
mousefd = open(MOUSE_EVENT, O_RDWR);
gamepadfd = open(GAMEPAD_EVENT, O_RDWR);
keyboardfd = open(KEYBOARD_EVENT, O_RDWR);
init_event_handler();
//ゲームパッドを無効化
ioctl(gamepadfd, EVIOCGRAB, 1);
  for (;;) {
    struct input_event event;

    if (read(gamepadfd, &event, sizeof(event)) != sizeof(event)) {
      exit(EXIT_FAILURE);
    }
    //printf("type:%x  code:%x value:%x\n", event.type, event.code, event.value);
    switch(event.type) {
case EV_KEY:
if(event.code == BTN_X) {
send_event(mousefd, EV_KEY, BTN_MOUSE, event.value);
send_event(mousefd, EV_SYN, SYN_REPORT, 0);
}else if(event.code == BTN_Y) {
send_event(mousefd, EV_KEY, BTN_MIDDLE, event.value);
send_event(mousefd, EV_SYN, SYN_REPORT, 0);
}else if(event.code == BTN_A) {
send_event(keyboardfd, EV_KEY, KEY_LEFTCTRL, event.value);
send_event(keyboardfd, EV_KEY, KEY_W, event.value);
send_event(keyboardfd, EV_SYN, SYN_REPORT, 0);
}else if(event.code == BTN_B) {
send_event(mousefd, EV_KEY, BTN_RIGHT, event.value);
send_event(mousefd, EV_SYN, SYN_REPORT, 0);
}else if(event.code == BTN_TL) {
send_event(keyboardfd, event.type, KEY_LEFTCTRL, event.value);
send_event(keyboardfd, event.type, KEY_T, event.value);
send_event(keyboardfd, EV_SYN, SYN_REPORT, 0);
}else if(event.code == BTN_TR) {
send_event(keyboardfd, event.type, KEY_LEFTCTRL, event.value);
send_event(keyboardfd, event.type, KEY_TAB, event.value);
send_event(keyboardfd, EV_SYN, SYN_REPORT, 0);
}
break;
      case EV_ABS:
//printf("type:%x  code:%x value:%x\n", event.type, event.code, event.value);
if(event.code == ABS_HAT0Y) {//上下ボタンを押したとき
state.vy = event.value;
}else if(event.code == ABS_HAT0X) {//左右ボタンを離したとき
state.vx = event.value;
}else if(event.code == ABS_RY) {//ホイール上下
//printf("type:%x  code:%x value:%d\n", event.type, event.code, event.value);
if(event.value > 10000) {
state.wheeldirection = 0xffffffff;
} else if(-8000 < event.value && event.value < 8000){
state.wheeldirection = 0;
}else {
state.wheeldirection = 1;
}
state.wheelvalue = event.value;
//send_event(mousefd, EV_SYN, SYN_REPORT, 0);
}else if(event.code == ABS_RX) {
}else {
}
        break;
      case EV_REL:
break;
 
      default:
        break;
    }
    fflush(stdout);
  }
  
  //ゲームパッドを有効に戻す
  ioctl(gamepadfd, EVIOCGRAB, 0);
  
  close(keyboardfd);
  close(gamepadfd);
  close(virtualfd);
}


$ gcc -o gamepad gamepad.c
$ sudo ./gamepad

 

↑このページのトップヘ