Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # ** Input
- #------------------------------------------------------------------------------
- # Created By Cidiomar R. Dias Júnior
- # Originally posted at http://rgss3help.cidiomar.com/?p=145
- #
- # Terms of Use: http://rgss3help.cidiomar.com/?page_id=159
- #------------------------------------------------------------------------------
- # A module that handles input data from a gamepad or keyboard.
- # Managed by symbols rather than button numbers in RGSS3.
- #==============================================================================
- module Input
- #--------------------------------------------------------------------------
- # * Keymap in symbols
- # To get a key from the keymap, you can use Input.key(sym) or Input:KEYMAP[sym]
- # Or if you want to use a symbol in a input function, just pass the symbol
- # as argument.
- #--------------------------------------------------------------------------
- KEYMAP = {
- LBUTTON: 0x01, RBUTTON: 0x02,
- CANCEL: 0x03, MBUTTON: 0x04,
- XBUTTON1: 0x05, XBUTTON2: 0x06,
- BACK: 0x08, TAB: 0x09,
- CLEAR: 0x0c, RETURN: 0x0d,
- SHIFT: 0x10, CONTROL: 0x11,
- MENU: 0x12, PAUSE: 0x13,
- CAPITAL: 0x14, KANA: 0x15,
- KANA: 0x15, KANA: 0x15,
- JUNJA: 0x17, FINAL: 0x18,
- HANJA: 0x19, HANJA: 0x19,
- ESCAPE: 0x1b, CONVERT: 0x1c,
- NONCONVERT: 0x1d, ACCEPT: 0x1e,
- MODECHANGE: 0x1f, SPACE: 0x20,
- PRIOR: 0x21, NEXT: 0x22,
- END: 0x23, HOME: 0x24,
- LEFT: 0x25, UP: 0x26,
- RIGHT: 0x27, DOWN: 0x28,
- SELECT: 0x29, PRINT: 0x2a,
- EXECUTE: 0x2b, SNAPSHOT: 0x2c,
- INSERT: 0x2d, DELETE: 0x2e,
- HELP: 0x2f, N0: 0x30,
- KEY_1: 0x31, KEY_2: 0x32,
- KEY_3: 0x33, KEY_4: 0x34,
- KEY_5: 0x35, KEY_6: 0x36,
- KEY_7: 0x37, KEY_8: 0x38,
- KEY_9: 0x39, colon: 0x3a,
- semicolon: 0x3b, less: 0x3c,
- equal: 0x3d, greater: 0x3e,
- question: 0x3f, at: 0x40,
- LETTER_A: 0x41, LETTER_B: 0x42,
- LETTER_C: 0x43, LETTER_D: 0x44,
- LETTER_E: 0x45, LETTER_F: 0x46,
- LETTER_G: 0x47, LETTER_H: 0x48,
- LETTER_I: 0x49, LETTER_J: 0x4a,
- LETTER_K: 0x4b, LETTER_L: 0x4c,
- LETTER_M: 0x4d, LETTER_N: 0x4e,
- LETTER_O: 0x4f, LETTER_P: 0x50,
- LETTER_Q: 0x51, LETTER_R: 0x52,
- LETTER_S: 0x53, LETTER_T: 0x54,
- LETTER_U: 0x55, LETTER_V: 0x56,
- LETTER_W: 0x57, LETTER_X: 0x58,
- LETTER_Y: 0x59, LETTER_Z: 0x5a,
- LWIN: 0x5b, RWIN: 0x5c,
- APPS: 0x5d, asciicircum: 0x5e,
- SLEEP: 0x5f, NUMPAD0: 0x60,
- NUMPAD1: 0x61, NUMPAD2: 0x62,
- NUMPAD3: 0x63, NUMPAD4: 0x64,
- NUMPAD5: 0x65, NUMPAD6: 0x66,
- NUMPAD7: 0x67, NUMPAD8: 0x68,
- NUMPAD9: 0x69, MULTIPLY: 0x6a,
- ADD: 0x6b, SEPARATOR: 0x6c,
- SUBTRACT: 0x6d, DECIMAL: 0x6e,
- DIVIDE: 0x6f, F1: 0x70,
- F2: 0x71, F3: 0x72,
- F4: 0x73, F5: 0x74,
- F6: 0x75, F7: 0x76,
- F8: 0x77, F9: 0x78,
- F10: 0x79, F11: 0x7a,
- F12: 0x7b, F13: 0x7c,
- F14: 0x7d, F15: 0x7e,
- F16: 0x7f, F17: 0x80,
- F18: 0x81, F19: 0x82,
- F20: 0x83, F21: 0x84,
- F22: 0x85, F23: 0x86,
- F24: 0x87, NUMLOCK: 0x90,
- SCROLL: 0x91, LSHIFT: 0xa0,
- RSHIFT: 0xa1, LCONTROL: 0xa2,
- RCONTROL: 0xa3, LMENU: 0xa4,
- RMENU: 0xa5, BROWSER_BACK: 0xa6,
- BROWSER_FORWARD: 0xa7, BROWSER_REFRESH: 0xa8,
- BROWSER_STOP: 0xa9, BROWSER_SEARCH: 0xaa,
- BROWSER_FAVORITES: 0xab, BROWSER_HOME: 0xac,
- VOLUME_MUTE: 0xad, VOLUME_DOWN: 0xae,
- VOLUME_UP: 0xaf, MEDIA_NEXT_TRACK: 0xb0,
- MEDIA_PREV_TRACK: 0xb1, MEDIA_STOP: 0xb2,
- MEDIA_PLAY_PAUSE: 0xb3, LAUNCH_MAIL: 0xb4,
- LAUNCH_MEDIA_SELECT: 0xb5, LAUNCH_APP1: 0xb6,
- LAUNCH_APP2: 0xb7, cedilla: 0xb8,
- onesuperior: 0xb9, masculine: 0xba,
- guillemotright: 0xbb, onequarter: 0xbc,
- onehalf: 0xbd, threequarters: 0xbe,
- questiondown: 0xbf, Agrave: 0xc0,
- Aacute: 0xc1, Acircumflex: 0xc2,
- Atilde: 0xc3, Adiaeresis: 0xc4,
- Aring: 0xc5, AE: 0xc6,
- Ccedilla: 0xc7, Egrave: 0xc8,
- Eacute: 0xc9, Ecircumflex: 0xca,
- Ediaeresis: 0xcb, Igrave: 0xcc,
- Iacute: 0xcd, Icircumflex: 0xce,
- Idiaeresis: 0xcf, ETH: 0xd0,
- Ntilde: 0xd1, Ograve: 0xd2,
- Oacute: 0xd3, Ocircumflex: 0xd4,
- Otilde: 0xd5, Odiaeresis: 0xd6,
- multiply: 0xd7, Oslash: 0xd8,
- Ugrave: 0xd9, Uacute: 0xda,
- Ucircumflex: 0xdb, Udiaeresis: 0xdc,
- Yacute: 0xdd, THORN: 0xde,
- ssharp: 0xdf, agrave: 0xe0,
- aacute: 0xe1, acircumflex: 0xe2,
- atilde: 0xe3, adiaeresis: 0xe4,
- PROCESSKEY: 0xe5, ae: 0xe6,
- PACKET: 0xe7, egrave: 0xe8,
- eacute: 0xe9, ecircumflex: 0xea,
- ediaeresis: 0xeb, igrave: 0xec,
- iacute: 0xed, icircumflex: 0xee,
- idiaeresis: 0xef, eth: 0xf0,
- ntilde: 0xf1, ograve: 0xf2,
- oacute: 0xf3, ocircumflex: 0xf4,
- otilde: 0xf5, ATTN: 0xf6,
- CRSEL: 0xf7, EXSEL: 0xf8,
- EREOF: 0xf9, PLAY: 0xfa,
- ZOOM: 0xfb, NONAME: 0xfc,
- PA1: 0xfd, thorn: 0xfe,
- ydiaeresis: 0xff
- }
- KEYMAP[:WIN] = [KEYMAP[:LWIN], KEYMAP[:RWIN]]
- #--------------------------------------------------------------------------
- # * Default Keys, you can configure here instead of by pressing F1.
- #--------------------------------------------------------------------------
- UP = [KEYMAP[:UP]]
- DOWN = [KEYMAP[:DOWN]]
- LEFT = [KEYMAP[:LEFT]]
- RIGHT = [KEYMAP[:RIGHT]]
- A = [KEYMAP[:SHIFT]]
- B = [KEYMAP[:LETTER_X]]
- C = [KEYMAP[:LETTER_Z]]
- X = []
- Y = []
- Z = []
- L = [KEYMAP[:PRIOR]]
- R = [KEYMAP[:NEXT]]
- F5 = [KEYMAP[:F5]]
- F6 = [KEYMAP[:F6]]
- F7 = [KEYMAP[:F7]]
- F8 = [KEYMAP[:F8]]
- F9 = [KEYMAP[:F9]]
- SHIFT = [KEYMAP[:SHIFT]]
- CTRL = [KEYMAP[:CONTROL]]
- ALT = [KEYMAP[:MENU]]
- I = [KEYMAP[:LETTER_I]]
- E = [KEYMAP[:LETTER_E]]
- S = [KEYMAP[:LETTER_S]]
- T = [KEYMAP[:LETTER_T]]
- #--------------------------------------------------------------------------
- # * Symbol version of default keys.
- #--------------------------------------------------------------------------
- SYM_KEYS = {
- :UP => UP,
- :LEFT => LEFT,
- :DOWN => DOWN,
- :RIGHT => RIGHT,
- :A => A,
- :B => B,
- :C => C,
- :X => X,
- :Y => Y,
- :Z => Z,
- :L => L,
- :R => R,
- :F5 => F5,
- :F6 => F6,
- :F7 => F7,
- :F8 => F8,
- :F9 => F9,
- :SHIFT => SHIFT,
- :CTRL => CTRL,
- :ALT => ALT,
- :I => I,
- :E => E,
- :S => S,
- :T => T
- }
- #--------------------------------------------------------------------------
- # * Key Codes Used in Events Conditional Branchs
- #--------------------------------------------------------------------------
- EventsKeyCodes = {
- 2 => :DOWN,
- 4 => :LEFT,
- 6 => :RIGHT,
- 8 => :UP,
- 11 => :A,
- 12 => :B,
- 13 => :C,
- 14 => :X,
- 15 => :Y,
- 16 => :Z,
- 17 => :L,
- 18 => :R
- }
- #--------------------------------------------------------------------------
- # * Internal APIs to handle keyboard functions
- #--------------------------------------------------------------------------
- GetKeyboardState = Win32API.new('user32.dll', 'GetKeyboardState', 'I', 'I')
- MapVirtualKeyEx = Win32API.new('user32.dll', 'MapVirtualKeyEx', 'IIL', 'I')
- ToUnicodeEx = Win32API.new('user32.dll', 'ToUnicodeEx', 'LLPPILL', 'L')
- #----------
- @language_layout = Win32API.new('user32.dll', 'GetKeyboardLayout', 'L', 'L').call(0)
- DOWN_STATE_MASK = (0x8 << 0x04)
- DEAD_KEY_MASK = (0x8 << 0x1C)
- #-----
- UNICODE_TO_UTF8 = Encoding::Converter.new(Encoding.list[2], Encoding.list[1])
- #--------------------------------------------------------------------------
- # * States of keys
- #--------------------------------------------------------------------------
- @state = DL::CPtr.new(DL.malloc(256), 256)
- @triggered = Array.new(256, false)
- @pressed = Array.new(256, false)
- @released = Array.new(256, false)
- @repeated = Array.new(256, 0)
- #--------------------------------------------------------------------------
- # * Singleton attrs of states
- #--------------------------------------------------------------------------
- class << self
- attr_reader :triggered, :pressed, :released, :repeated, :state
- end
- #--------------------------------------------------------------------------
- # * Get a key code by simbol
- #--------------------------------------------------------------------------
- def self.key(sym)
- KEYMAP[sym] || 0
- end
- #--------------------------------------------------------------------------
- # * Updates input data.
- # As a general rule, this method is called once per frame.
- #--------------------------------------------------------------------------
- def self.update
- GetKeyboardState.call(@state.to_i)
- #-----
- 0.upto(255) do |key|
- if @state[key] & DOWN_STATE_MASK == DOWN_STATE_MASK
- @released[key] = false
- @pressed[key] = true if (@triggered[key] = !@pressed[key])
- @repeated[key] < 17 ? @repeated[key] += 1 : @repeated[key] = 15
- elsif !@released[key] and @pressed[key]
- @triggered[key] = false
- @pressed[key] = false
- @repeated[key] = 0
- @released[key] = true
- else
- @released[key] = false
- end
- end
- end
- #--------------------------------------------------------------------------
- # * Checks the status of the directional buttons, translates the data into
- # a specialized 4-direction input format, and returns the number pad
- # equivalent (2, 4, 6, 8).
- #
- # If no directional buttons are being pressed (or the equivalent), returns 0.
- #--------------------------------------------------------------------------
- def self.dir4
- return 2 if self.press?(DOWN)
- return 4 if self.press?(LEFT)
- return 6 if self.press?(RIGHT)
- return 8 if self.press?(UP)
- return 0
- end
- #--------------------------------------------------------------------------
- # * Checks the status of the directional buttons, translates the data into
- # a specialized 8-direction input format, and returns the number pad
- # equivalent (1, 2, 3, 4, 6, 7, 8, 9).
- #
- #If no directional buttons are being pressed (or the equivalent), returns 0.
- #--------------------------------------------------------------------------
- def self.dir8
- down = self.press?(DOWN)
- left = self.press?(LEFT)
- return 1 if down and left
- right = self.press?(RIGHT)
- return 3 if down and right
- up = self.press?(UP)
- return 7 if up and left
- return 9 if up and right
- return 2 if down
- return 4 if left
- return 6 if right
- return 8 if up
- return 0
- end
- #--------------------------------------------------------------------------
- # * Determines whether the button corresponding to the symbol sym is
- # currently being pressed.
- #
- # If the button is being pressed, returns TRUE. If not, returns FALSE.
- #
- # if Input.press?(:C)
- # do_something
- # end
- #--------------------------------------------------------------------------
- def self.press?(keys)
- if keys.is_a?(Numeric)
- k = keys.to_i
- return (@pressed[k] and !@triggered[k])
- elsif keys.is_a?(Array)
- return keys.any? {|key| self.press?(key) }
- elsif keys.is_a?(Symbol)
- if SYM_KEYS.key?(keys)
- return SYM_KEYS[keys].any? {|key| (@pressed[key] and !@triggered[key]) }
- elsif (KEYMAP.key?(keys))
- k = KEYMAP[keys]
- return (@pressed[k] and !@triggered[k])
- else
- return false
- end
- end
- end
- #--------------------------------------------------------------------------
- # * Determines whether the button corresponding to the symbol sym is
- # currently being pressed again.
- # "Pressed again" is seen as time having passed between the button being
- # not pressed and being pressed.
- #
- # If the button is being pressed, returns TRUE. If not, returns FALSE.
- #--------------------------------------------------------------------------
- def self.trigger?(keys)
- if keys.is_a?(Numeric)
- return @triggered[keys.to_i]
- elsif keys.is_a?(Array)
- return keys.any? {|key| @triggered[key]}
- elsif keys.is_a?(Symbol)
- if SYM_KEYS.key?(keys)
- return SYM_KEYS[keys].any? {|key| @triggered[key]}
- elsif KEYMAP.key?(keys)
- return @triggered[KEYMAP[keys]]
- else
- return false
- end
- end
- end
- #--------------------------------------------------------------------------
- # * Determines whether the button corresponding to the symbol sym is
- # currently being pressed again.
- # Unlike trigger?, takes into account the repeated input of a button being
- # held down continuously.
- #
- # If the button is being pressed, returns TRUE. If not, returns FALSE.
- #--------------------------------------------------------------------------
- def self.repeat?(keys)
- if keys.is_a?(Numeric)
- key = keys.to_i
- return @repeated[key] == 1 || @repeated[key] == 16
- elsif keys.is_a?(Array)
- return keys.any? {|key| @repeated[key] == 1 || @repeated[key] == 16}
- elsif keys.is_a?(Symbol)
- if SYM_KEYS.key?(keys)
- return SYM_KEYS[keys].any? {|key| @repeated[key] == 1 || @repeated[key] == 16}
- elsif KEYMAP.key?(keys)
- return @repeated[KEYMAP[keys]] == 1 || @repeated[KEYMAP[keys]] == 16
- else
- return false
- end
- end
- end
- #--------------------------------------------------------------------------
- # * Determines whether the button corresponding to the symbol sym
- # was released.
- #
- # If the button was released, returns TRUE. If not, returns FALSE.
- #--------------------------------------------------------------------------
- def self.release?(keys)
- if keys.is_a?(Numeric)
- return @released[keys.to_i]
- elsif keys.is_a?(Array)
- return keys.any? {|key| @released[key]}
- elsif keys.is_a?(Symbol)
- if SYM_KEYS.key?(keys)
- return SYM_KEYS[keys].any? {|key| @released[key]}
- elsif KEYMAP.key?(keys)
- return @released[KEYMAP[keys]]
- else
- return false
- end
- end
- end
- #--------------------------------------------------------------------------
- # * Gets the character that correspond to vk using the keyboard layout
- #--------------------------------------------------------------------------
- def self.get_character(vk)
- c = MapVirtualKeyEx.call(vk, 2, @language_layout)
- return '' if c < 32 && (c & DEAD_KEY_MASK != DEAD_KEY_MASK)
- #-----
- result = "\0" * 2
- length = ToUnicodeEx.call(vk, MapVirtualKeyEx.call(vk, 0, @language_layout),
- @state, result, 2, 0, @language_layout)
- #-----
- return (length == 0 ? '' : result)
- end
- #--------------------------------------------------------------------------
- # * Accents Table, to bo used in conversion from ASCII to UTF8
- #--------------------------------------------------------------------------
- AccentsCharsConv = {
- 'A' => ['À', 'Á', 'Â', 'Ã', 'Ä'],
- 'E' => ['È', 'É', 'Ê', 0, 'Ë'],
- 'I' => ['Ì', 'Í', 'Î', 0, 'Ï'],
- 'O' => ['Ò', 'Ó', 'Ô', 'Õ', 'Ö'],
- 'U' => ['Ù', 'Ú', 'Û', 0, 'Ü'],
- 'C' => [ 0 , 'Ç', 0 , 0, 0 ],
- 'N' => [ 0 , 0, 0 , 'Ñ', 0 ],
- 'Y' => [ 0 , 'Ý', 0 , 0, 'Ÿ'],
- 'a' => ['à', 'á', 'â', 'ã', 'ä'],
- 'e' => ['è', 'é', 'ê', 0 , 'ë'],
- 'i' => ['ì', 'í', 'î', 0 , 'ï'],
- 'o' => ['ò', 'ó', 'ô', 'õ', 'ö'],
- 'u' => ['ù', 'ú', 'û', 0 , 'ü'],
- 'c' => [ 0 , 'ç', 0 , 0 , 0 ],
- 'n' => [ 0 , 0 , 0 , 'ñ', 0 ],
- 'y' => [ 0 , 'ý', 0 , 0 , 'ÿ'],
- }
- # Letters that can have accent
- PssbLetters = 'AEIOUCNYaeioucny'
- # Accents, in ASCII, configured at runtime to avoid encoding troubles
- Accents = [96.chr, 180.chr, 94.chr, 126.chr, 168.chr].join
- NonCompatChars = [180, 168]
- @last_accent = nil
- #--------------------------------------------------------------------------
- # * Get inputed string transcoded to UTF8
- #--------------------------------------------------------------------------
- def self.UTF8String
- result = ''
- 31.upto(255) {|key|
- if self.repeat?(key)
- c = self.get_character(key)
- if (cc = c.unpack('C')[0]) and NonCompatChars.include?(cc)
- result += cc.chr
- else
- result += UNICODE_TO_UTF8.convert(c) if c != ''
- end
- end
- }
- return '' if result == ''
- #-----
- if @last_accent
- result = @last_accent + result
- @last_accent = nil
- end
- f_result = ''
- jump = false
- for i in 0 ... result.length
- c = result[i]
- if jump
- jump = false
- next
- end
- #-----
- if Accents.include?(c)
- if (nc = result[i+1]) != nil
- if PssbLetters.include?(nc)
- if (ac = AccentsCharsConv[nc][Accents.index(c)]) != 0
- f_result << ac
- jump = true
- else
- f_result << c
- f_result << nc
- jump = true
- end
- elsif Accents.include?(nc)
- f_result << c
- f_result << nc
- jump = true
- else
- f_result << c
- f_result << nc
- jump = true
- end
- else
- @last_accent = c
- end
- else
- f_result << c
- end
- end
- #-----
- return f_result
- end
- #----------
- end
- #
- # Game_Interpreter
- # def command_111 modification to work properly with my Input System
- #
- class Game_Interpreter
- #--------------------------------------------------------------------------
- # * Conditional Branch
- #--------------------------------------------------------------------------
- def command_111
- result = false
- case @params[0]
- when 0 # Switch
- result = ($game_switches[@params[1]] == (@params[2] == 0))
- when 1 # Variable
- value1 = $game_variables[@params[1]]
- if @params[2] == 0
- value2 = @params[3]
- else
- value2 = $game_variables[@params[3]]
- end
- case @params[4]
- when 0 # value1 is equal to value2
- result = (value1 == value2)
- when 1 # value1 is greater than or equal to value2
- result = (value1 >= value2)
- when 2 # value1 is less than or equal to value2
- result = (value1 <= value2)
- when 3 # value1 is greater than value2
- result = (value1 > value2)
- when 4 # value1 is less than value2
- result = (value1 < value2)
- when 5 # value1 is not equal to value2
- result = (value1 != value2)
- end
- when 2 # Self switch
- if @event_id > 0
- key = [@map_id, @event_id, @params[1]]
- result = ($game_self_switches[key] == (@params[2] == 0))
- end
- when 3 # Timer
- if $game_timer.working?
- if @params[2] == 0
- result = ($game_timer.sec >= @params[1])
- else
- result = ($game_timer.sec <= @params[1])
- end
- end
- when 4 # Actor
- actor = $game_actors[@params[1]]
- if actor
- case @params[2]
- when 0 # in party
- result = ($game_party.members.include?(actor))
- when 1 # name
- result = (actor.name == @params[3])
- when 2 # Class
- result = (actor.class_id == @params[3])
- when 3 # Skills
- result = (actor.skill_learn?($data_skills[@params[3]]))
- when 4 # Weapons
- result = (actor.weapons.include?($data_weapons[@params[3]]))
- when 5 # Armors
- result = (actor.armors.include?($data_armors[@params[3]]))
- when 6 # States
- result = (actor.state?(@params[3]))
- end
- end
- when 5 # Enemy
- enemy = $game_troop.members[@params[1]]
- if enemy
- case @params[2]
- when 0 # appear
- result = (enemy.alive?)
- when 1 # state
- result = (enemy.state?(@params[3]))
- end
- end
- when 6 # Character
- character = get_character(@params[1])
- if character
- result = (character.direction == @params[2])
- end
- when 7 # Gold
- case @params[2]
- when 0 # Greater than or equal to
- result = ($game_party.gold >= @params[1])
- when 1 # Less than or equal to
- result = ($game_party.gold <= @params[1])
- when 2 # Less than
- result = ($game_party.gold < @params[1])
- end
- when 8 # Item
- result = $game_party.has_item?($data_items[@params[1]])
- when 9 # Weapon
- result = $game_party.has_item?($data_weapons[@params[1]], @params[2])
- when 10 # Armor
- result = $game_party.has_item?($data_armors[@params[1]], @params[2])
- when 11 # Button
- key = Input::EventsKeyCodes[@params[1]]
- result = Input.press?(key) if key
- when 12 # Script
- result = eval(@params[1])
- when 13 # Vehicle
- result = ($game_player.vehicle == $game_map.vehicles[@params[1]])
- end
- @branch[@indent] = result
- command_skip if !@branch[@indent]
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment