wiiリモコンをruby/sdlで

wiiボードを使いたくて、ネットを探してみた。
なかなか、欲しい情報に出会えない。
とりあえず、ステップアップの為にwiiリモコンを使ってみた。
参考ページは
http://www.covia.jp/net/bbs/viewtopic.php?f=9&t=419
まず、
sudo apt-get install wminput lswm
たぶん、これでいいと思う。
いろいろ、試したから自信はないが、そんなに遠くないと思う。
参考ページの中で、
sudo modprobe uinput
を、すると書いてあったが、VirtualBoxのUbuntu10.10では必要ないみたい。
VirtualBoxを使っている場合は、VirtualBoxのメニューのデバイス => USBデバイスで、
Bluetoothデバイスのチェックをしておいてください。
ちなみに、これをチェックすると、Bluetoothマウスが不安定になるので、
USBマウスの方がいいかな。
wminputをマウス代りに使うとマウスポインターが動かない。
だけど、ジョイパットの代りなら十分だ。
今回のプログラムは、起動したら、rootのパスワードを入れて、
wiiリモコンの1と2のボタンを同時押し。
その後は、wiiリモコンの十字キーで移動。
homeキーで終了。

#!usr/bin/env ruby

require 'rubygems'
require 'sdl'

class EventHandle
def initialize(hash)
struct = Struct.new(:event,:const,:method)
@handle = {}
hash.each do |key,value|
event,const = key
if const
if event == SDL::Event::KeyDown || event == SDL::Event::KeyUp
@handle[struct.new(event,const,:sym)] = value
elsif event == SDL::Event::MouseButtonDown || event == SDL::Event::MouseButtonUp
@handle[struct.new(event,const,:button)] = value
end
else
@handle[struct.new(event)] = value
end
end
end

def match?(key,event)
if key.const
event.kind_of?(key.event) && key.const == event.method(key.method).call
else
event.kind_of?(key.event)
end
end

def handling(event)
@handle.each do |key,value|
return value.call(event) if match?(key,event)
end
nil
end
end

class Phase
def initialize(screen)
@screen = screen
@item = SDL::Surface.new(SDL::SWSURFACE,30,30,@screen)
@item.draw_rect(0,0,@item.w,@item.h,[0,200,0],true)
@x,@y,@dx,@dy = 150,150,0,0
@scale = 5
@handle = EventHandle.new(
[SDL::Event::KeyDown,SDL::Key::LEFT] => proc{@dx -= 1},
[SDL::Event::KeyDown,SDL::Key::RIGHT] => proc{@dx += 1},
[SDL::Event::KeyUp,SDL::Key::LEFT] => proc{@dx += 1},
[SDL::Event::KeyUp,SDL::Key::RIGHT] => proc{@dx -= 1},
[SDL::Event::KeyDown,SDL::Key::UP] => proc{@dy -= 1},
[SDL::Event::KeyDown,SDL::Key::DOWN] => proc{@dy += 1},
[SDL::Event::KeyUp,SDL::Key::UP] => proc{@dy += 1},
[SDL::Event::KeyUp,SDL::Key::DOWN] => proc{@dy -= 1},
SDL::Event::Quit => proc{quit},
[SDL::Event::KeyDown,SDL::Key::ESCAPE] => proc{quit}
)
end

def update
@x += @dx * @scale
@y += @dy * @scale
if @x < 0
@x = @screen.w
elsif @x >= @screen.w
@x = 0
end
if @y < 0
@y = @screen.h
elsif @y >= @screen.h
@y = 0
end
@screen.draw_rect(0,0,@screen.w,@screen.h,[50,50,50],true)
@screen.put(@item,@x,@y)
end

def quit
system("sudo pkill wminput")
exit
end

def run
loop do
update
@screen.flip
while event=SDL::Event.poll
@handle.handling(event)
end
SDL.delay(10)
end
end
end

wmconf = <<EOF
Wiimote.Up = KEY_UP
Wiimote.Down = KEY_DOWN
Wiimote.Left = KEY_LEFT
Wiimote.Right = KEY_RIGHT
Wiimote.Home = KEY_ESC
EOF
system("echo '#{wmconf}' > /tmp/wmconf")
#system("sudo modprobe uinput")
system("sudo wminput -c /tmp/wmconf -d &")
puts "Put Wiimote in discoverable mode now (press 1+2)..."
SDL.init(SDL::INIT_EVERYTHING)
screen = SDL::Screen.open(350,350,16,SDL::SWSURFACE)
Phase.new(screen).run
[PR]
by gaziya | 2011-03-03 23:09