#==============================================================================
# ** Modules.Keyboard Input (6.1) By Near Fantastica
# Additions By Wachunaga & SephirothSpawn
#------------------------------------------------------------------------------
# * Description :
#
# The Keyboard Input Module is designed to function as the default Input
# module does. It is better then other methods keyboard input because as a
# key is tested it is not removed form the list. so you can test the same
# key multiple times the same loop. This script automatically updates itself
# with the input module.
#------------------------------------------------------------------------------
# * Syntax :
#
# Test if Key is Triggered :
# - if Keyboard.trigger?(Keyboard::<Keyboard_constant>)
#
# Test if Key is Pressed :
# - if Keyboard.pressed?(Keyboard::<Keyboard_constant>)
#==============================================================================
#==============================================================================
# ** Keyboard
#==============================================================================
module Keyboard
#--------------------------------------------------------------------------
# * Constants (These Are Your Keyboard Keys)
#--------------------------------------------------------------------------
Mouse_Left = 1 ; Mouse_Right = 2
Back = 8 ; Tab = 9
Enter = 13 ; Shift = 16
Ctrl = 17 ; Alt = 18
Capslock = 20 ; Esc = 27
Space = 32 ; End = 35
Home = 36 ; Left = 37
Right = 39
Del = 46 ; Collon = 186
Equal = 187 ; Comma = 188
Underscore = 189 ; Dot = 190
Backslash = 191 ; Tilde = 192
Lb = 219 ; Rb = 221
Forwardslash = 220 ; Quote = 222
Numberkeys = {} ; Numberkeys[0] = 48
Numberkeys[1] = 49 ; Numberkeys[2] = 50
Numberkeys[3] = 51 ; Numberkeys[4] = 52
Numberkeys[5] = 53 ; Numberkeys[6] = 54
Numberkeys[7] = 55 ; Numberkeys[8] = 56
Numberkeys[9] = 57
Numberpad = {} ; Numberpad[0] = 45
Numberpad[1] = 35 ; Numberpad[2] = 40
Numberpad[3] = 34 ; Numberpad[4] = 37
Numberpad[5] = 12 ; Numberpad[6] = 39
Numberpad[7] = 36 ; Numberpad[8] = 38
Numberpad[9] = 33
Numpad = {} ; Numpad[0] = 96
Numpad[1] = 97 ; Numpad[2] = 98
Numpad[3] = 99 ; Numpad[4] = 100
Numpad[5] = 101 ; Numpad[6] = 102
Numpad[7] = 103 ; Numpad[8] = 104
Numpad[9] = 105
Letters = {} ; Letters['A'] = 65
Letters['B'] = 66 ; Letters['C'] = 67
Letters['D'] = 68 ; Letters['E'] = 69
Letters['F'] = 70 ; Letters['G'] = 71
Letters['H'] = 72 ; Letters['I'] = 73
Letters['J'] = 74 ; Letters['K'] = 75
Letters['L'] = 76 ; Letters['M'] = 77
Letters['N'] = 78 ; Letters['O'] = 79
Letters['P'] = 80 ; Letters['Q'] = 81
Letters['R'] = 82 ; Letters['S'] = 83
Letters['T'] = 84 ; Letters['U'] = 85
Letters['V'] = 86 ; Letters['W'] = 87
Letters['X'] = 88 ; Letters['Y'] = 89
Letters['Z'] = 90
Fkeys = {} ; Fkeys[1] = 112
Fkeys[2] = 113 ; Fkeys[3] = 114
Fkeys[4] = 115 ; Fkeys[5] = 116
Fkeys[6] = 117 ; Fkeys[7] = 118
Fkeys[8] = 119 ; Fkeys[9] = 120
Fkeys[10] = 121 ; Fkeys[11] = 122
Fkeys[12] = 123
#--------------------------------------------------------------------------
# * Text Representation
#--------------------------------------------------------------------------
TR = {}
TR[Tab] = [' ', ' ']
TR[Enter] = ['/n', '/n']
TR[Collon] = [';', ':']
TR[Equal] = ['=', '+']
TR[Comma] = [',', '<']
TR[Underscore] = ['-', '_']
TR[Dot] = ['.', '>']
TR[Backslash] = ['/', '?']
TR[Tilde] = ['`', '~']
TR[Forwardslash] = ["\\", "|"]
TR[Quote] = ["'", '"']
TR[Numberkeys[0]] = ['0', ')']
TR[Numberkeys[1]] = ['1', '!']
TR[Numberkeys[2]] = ['2', '@']
TR[Numberkeys[3]] = ['3', '#']
TR[Numberkeys[4]] = ['4', '$']
TR[Numberkeys[5]] = ['5', '^%']
TR[Numberkeys[6]] = ['6', '^']
TR[Numberkeys[7]] = ['7', '&']
TR[Numberkeys[8]] = ['8', '*']
TR[Numberkeys[9]] = ['9', '(']
Letters.values.each do |key|
TR[key] = [key.chr.downcase, key.chr.upcase]
end
#--------------------------------------------------------------------------
# * API Declaration
#--------------------------------------------------------------------------
State = Win32API.new('user32','GetKeyState', ['i'],'i')
Key = Win32API.new('user32','GetAsyncKeyState', ['i'],'i')
#--------------------------------------------------------------------------
# * Clear Key & Pressed
#--------------------------------------------------------------------------
@keys = [] ; @pressed = [] ; @lock = []
@disabled_keys = [] ; @disabled_timer = {}
@delay = {} ; @disabled_tr = [] ; @text_window = nil ; @text_max = 10
#--------------------------------------------------------------------------
# * Get Key State (Test Pressed)
#--------------------------------------------------------------------------
def self.getstate(key)
return !State.call(key).between?(0, 1)
end
#--------------------------------------------------------------------------
# * Test Key (Test Trigger)
#--------------------------------------------------------------------------
def self.testkey(key)
return Key.call(key) & 0x01 == 1
end
#--------------------------------------------------------------------------
# * Test Lock (Test Trigger)
#--------------------------------------------------------------------------
def self.testlock(key)
return State.call(key) & 0x01 == 1
end
#--------------------------------------------------------------------------
# * Trigger? Test
#--------------------------------------------------------------------------
def self.trigger?(key)
return @keys.include?(key)
end
#--------------------------------------------------------------------------
# * Pressed? Test
#--------------------------------------------------------------------------
def self.pressed?(key)
return @pressed.include?(key)
end
#--------------------------------------------------------------------------
def self.lock?(key)
return @lock.include?(key)
end
#--------------------------------------------------------------------------
# * Update
#--------------------------------------------------------------------------
def self.update
# Clears Keys & Pressed
@keys, @pressed, @lock = [], [], []
# Pass Through Timer List
@disabled_timer.each do |key, timer|
# Next if nil timer or key not-disabled
next if timer.nil? || !@disabled_keys.include?(key)
# If Greater than 0 Timer
if timer > 0
timer -= 1
next
end
# Enable Key
@disabled_keys.delete(key) if @disabled_keys.include?(key)
# Set Timer to Nil
@disabled_timer[key] = nil
end
# Test All Keys
for key in [Mouse_Left, Mouse_Right, Back, Tab, Enter, Shift, Ctrl, Alt,
Capslock, Esc, Space, End, Home, Left, Right, Del, Collon,
Equal, Comma, Underscore, Dot, Backslash, Tilde, Lb, Rb,
Forwardslash, Quote] + Numberkeys.values + Numberpad.values +
Numpad.values + Letters.values + Fkeys.values
# Skip If Key Disabled
next if @disabled_keys.include?(key)
# Add Key to Triggered Array if Triggered
@keys.push(key) if self.testkey(key)
# Add Key to Pressed Array if Pressed
@pressed.push(key) if self.getstate(key)
end
# Add Lock Key If Capslock
@lock.push(Keyboard::Capslock) if Keyboard.testlock(Keyboard::Capslock)
# Update Text Window Text If Text Window Present
self.update_text if @text_window != nil && @text_window.active
end
#--------------------------------------------------------------------------
# * Update Text
#--------------------------------------------------------------------------
def self.update_text
# Return if Nil Text Window
return if @text_window.nil?
# Gets Text Window Text
text = @text_window.text.dup
# Backspace Pressed
text.pop if self.trigger?(Back)
# If Text Size is Less Than Text Max
if text.size < @text_max
# Pass Through Triggered Array
(@keys + @pressed).each do |key|
# If TR has Key
if TR.has_key?(key)
# If Delay Has Key
if @delay.has_key?(key)
# Subtract Delay Count and Return (if greater than 0)
if @delay[key] > 0
@delay[key] -= 1
next
end
end
# Skip if TR Key Disabled
next if @disabled_tr.include?(key)
# If Shiftcase
if ( self.lock?(Capslock) && !self.pressed?(Shift)) ||
(!self.lock?(Capslock) && self.pressed?(Shift))
text += TR[key][1]
# If Regular Case
else
text += TR[key][0]
end
# Start Delay Count
@delay[key] = 6
end
end
end
# Sets Text Window Text
@text_window.text = text
end
#--------------------------------------------------------------------------
# * Read Disabled TR
#--------------------------------------------------------------------------
def self.disabled_tr
return disabled_tr
end
#--------------------------------------------------------------------------
# * Set Disabled TR
#--------------------------------------------------------------------------
def self.disabled_tr=(disabled_tr)
@disabled_tr = disabled_tr
end
#--------------------------------------------------------------------------
# * Read Text Window
#--------------------------------------------------------------------------
def self.text_window
return text_window
end
#--------------------------------------------------------------------------
# * Set Text Window
#--------------------------------------------------------------------------
def self.text_window=(text_window)
@text_window = text_window
end
#--------------------------------------------------------------------------
# * Read Text Max
#--------------------------------------------------------------------------
def self.text_max
return text_max
end
#--------------------------------------------------------------------------
# * Set Text Max
#--------------------------------------------------------------------------
def self.text_max=(text_max)
@text_max = text_max
end
#------------------------------------------------------------------------
# * Disable Key
#------------------------------------------------------------------------
def self.disable_key(constant, frames = nil)
# Add Key to Disabled List
@disabled_keys << constant unless @disabled_keys.include?(constant)
# Set Disabled Counter if non-nil
@disabled_timer[constant] = frames unless frames.nil?
end
#------------------------------------------------------------------------
# * Enable Key
#------------------------------------------------------------------------
def self.enable_key(constant)
# Remove Constant From List
@disabled_keys.delete(constant)
# Set Nil Timer
@disabled_timer[constant] = nil
end
end
#==============================================================================
# ** Input
#==============================================================================
module Input
class << self
#------------------------------------------------------------------------
# * Alias Listings
#------------------------------------------------------------------------
unless self.method_defined?(:seph_keyboard_input_update)
alias_method :seph_keyboard_input_update, :update
end
#------------------------------------------------------------------------
# * Frame Update
#------------------------------------------------------------------------
def update
# Original Update
seph_keyboard_input_update
# Update Keyboard
Keyboard.update
end
end
end