lib/dxruby_sdl/input.rb
# -*- coding: utf-8 -*-
require 'set'
module DXRubySDL
module Input
module_function
def set_repeat(wait, interval)
SDL::Key.enable_key_repeat(wait, interval)
end
def x(pad_number = 0)
res = 0
if sdl_key_press?(SDL::Key::LEFT)
res -= 1
end
if sdl_key_press?(SDL::Key::RIGHT)
res += 1
end
return res
end
def y(pad_number = 0)
res = 0
if sdl_key_press?(SDL::Key::UP)
res -= 1
end
if sdl_key_press?(SDL::Key::DOWN)
res += 1
end
return res
end
def pad_down?(button_code, pad_number = 0)
if button_code == P_BUTTON0 && sdl_key_press?(SDL::Key::Z) ||
button_code == P_BUTTON1 && sdl_key_press?(SDL::Key::X) ||
button_code == P_BUTTON2 && sdl_key_press?(SDL::Key::C) ||
button_code == P_LEFT && sdl_key_press?(SDL::Key::LEFT) ||
button_code == P_RIGHT && sdl_key_press?(SDL::Key::RIGHT) ||
button_code == P_UP && sdl_key_press?(SDL::Key::UP) ||
button_code == P_DOWN && sdl_key_press?(SDL::Key::DOWN) ||
((j = joystick(pad_number)) && j.button(button_code))
return true
end
return false
end
def pad_push?(button_code, pad_number = 0)
if button_code == P_BUTTON0 && sdl_key_push?(SDL::Key::Z) ||
button_code == P_BUTTON1 && sdl_key_push?(SDL::Key::X) ||
button_code == P_BUTTON2 && sdl_key_push?(SDL::Key::C) ||
button_code == P_LEFT && sdl_key_push?(SDL::Key::LEFT) ||
button_code == P_RIGHT && sdl_key_push?(SDL::Key::RIGHT) ||
button_code == P_UP && sdl_key_push?(SDL::Key::UP) ||
button_code == P_DOWN && sdl_key_push?(SDL::Key::DOWN) ||
((j = joystick(pad_number)) && j.button(button_code))
return true
end
return false
end
def mouse_pos_x
return SDL::Mouse.state[0]
end
def mouse_pos_y
return SDL::Mouse.state[1]
end
def key_down?(key_code)
return sdl_key_press?(to_sdl_key(key_code))
end
def key_push?(key_code)
return sdl_key_push?(to_sdl_key(key_code))
end
def mouse_down?(button)
case button
when M_LBUTTON
index = 2
when M_MBUTTON
index = 3
when M_RBUTTON
index = 4
end
return SDL::Mouse.state[index]
end
def mouse_push?(button)
case button
when M_LBUTTON
index = 2
when M_MBUTTON
index = 3
when M_RBUTTON
index = 4
end
return SDL::Mouse.state[index] && !@last_mouse_state[index]
end
def keys
return @keys
end
class << self
alias_method :setRepeat, :set_repeat
alias_method :padDown?, :pad_down?
alias_method :padPush?, :pad_push?
alias_method :mousePosX, :mouse_pos_x
alias_method :mousePosY, :mouse_pos_y
alias_method :keyDown?, :key_down?
alias_method :keyPush?, :key_push?
alias_method :mouseDown?, :mouse_down?
alias_method :mousePush?, :mouse_push?
end
private
@keys = Set.new
@checked_keys = Set.new
@down_keys = Set.new
@last_mouse_state = [false, false, false]
@joysticks = []
class << self
private
SDL_KEY_TABLE = {}
replace_table = {
'BACK' => 'BACKSPACE',
'ADD' => 'PLUS',
'DIVIDE' => 'SLASH',
'LCONTROL' => 'LCTRL',
'RCONTROL' => 'RCTRL',
'SCROLL' => 'SCROLLOCK',
'GRAVE' => 'BACKQUOTE',
'LBRACKET' => 'LEFTBRACKET',
'RBRACKET' => 'RIGHTBRACKET',
'LWIN' => 'LSUPER',
'RWIN' => 'RSUPER',
'YEN' => 'BACKSLASH',
}
::DXRubySDL.constants.grep(/^K_/).each do |k|
name = k.to_s.sub(/^K_/, '')
name.gsub!('COMMA', 'PERIOD')
if replace_table.key?(name)
name = replace_table[name]
end
case name
when /^\d$/
name = "K#{name}"
when /^NUMPAD(.+)$/
md = Regexp.last_match
if md[1].length > 1
name = "KP_#{md[1]}"
else
name = "KP#{md[1]}"
end
end
begin
SDL_KEY_TABLE[DXRubySDL.const_get(k)] =
SDL::Key.const_get(name.to_sym)
rescue NameError
end
end
private_constant :SDL_KEY_TABLE
DXRUBY_KEY_TABLE = SDL_KEY_TABLE.invert
private_constant :DXRUBY_KEY_TABLE
def store_last_state
@down_keys.merge(@checked_keys)
@checked_keys.clear
@last_mouse_state = SDL::Mouse.state
end
def sdl_key_press?(key)
dkey = to_dxruby_key(key)
if @keys.include?(dkey)
@checked_keys.add(dkey)
return true
else
return false
end
end
def sdl_key_push?(key)
dkey = to_dxruby_key(key)
return sdl_key_press?(key) && !@down_keys.include?(dkey)
end
def joystick(pad_number)
if pad_number >= SDL::Joystick.num
return nil
end
if !@joysticks[pad_number]
@joysticks[pad_number] = SDL::Joystick.open(pad_number)
end
return @joysticks[pad_number]
end
def to_sdl_key(key_code)
return SDL_KEY_TABLE[key_code]
end
def to_dxruby_key(key_code)
return DXRUBY_KEY_TABLE[key_code]
end
def handle_key_event(event)
dkey = to_dxruby_key(event.sym)
case event
when SDL::Event::KeyDown
@keys.add(dkey)
when SDL::Event::KeyUp
@keys.delete(dkey)
@checked_keys.delete(dkey)
@down_keys.delete(dkey)
end
end
end
end
end