RPG Maker VX Ace
InpEx

Sometimes you need extra ways to control the game, and sometimes the amount of available buttons and keys isn't enough for the game. Or, you don't want people, especially non-RPG Maker users, to rely on F1 to change the gamepad and / or keyboard settings.

This script adds a way to bind new keys both during development as well as in-game.

Download (87.58 kB, 1888 times downloaded)

Demo (1.63 MB, 491 times downloaded)

Before I'll start, this guide assumes you have set INCLUDE_CORE to true. If that isn't the case, the modules are included in CXJ::INPEX. For example the Mouse module can be found as CXJ::INPEX::Mouse.

In essence, the script is plug-and-play, it already works once installed. However, if you want to add more keybindings, you can always do that. You can later call that bound key in your own script using the same symbol.

In order to bind keys and buttons in-game, you can use the following methods:

Keyboard.bind_keyboard(sym, key)
Gamepad.bind_gamepad(sym, key)

You can also unbind keys:

Keyboard.unbind_keyboard(sym, key) Gamepad.unbind_gamepad(sym, key)

Most other methods in these modules correspond to the Input equivalent, so those don't need explaining.

To check whether a key or button is pressed for keybinding, you can iterate over each key. However, as gamepads have a variable amount of buttons, a method has been defined to determine the amount of buttons.

Gamepad.get_button_range

You can also use mouse control, although this script does not add most functionality, like actual interaction with the menu or the game itself. You can however implement these features yourself.

Mouse.x
Mouse.y
Mouse.left_press?
Mouse.left_trigger?
Mouse.right_press?
Mouse.right_trigger?
Mouse.middle_press?
Mouse.middle_trigger?

There is functionality for custom mouse pointers set. You first need to specify a bitmap image that serves as a pointer, the origin of the pointer and the width and height, and you're set. You can even do it in script.

Mouse.bitmap = bitmap
Mouse.ox = origin_x
Mouse.oy = origin_y
Mouse.width = width
Mouse.height = height

You can also specify the pattern, as in, which mouse pointer to use in the same image file.

Mouse.pattern = pattern

You can easily animate the mouse by putting multiple frames of the mouse pointer next to each other, each frame having the same size as specified on the mouse. Do note that blank frames will still be used in the animation, so be sure to pad single-frame pointers, or use separate images for animated mouse pointers.

This script adds aliases for several methods. If you are sure no method that is used by other scripts get overridden, you can place it anywhere, otherwise, make sure this script is loaded after any other script overriding these methods, otherwise this script stops working.

  • module Input (if keyboard or gamepad hooks are enabled)
    • self.update
    • self.press?(key)
    • self.repeat?(key)
    • self.trigger?(key)
    • self.dir4
    • self.dir8
  • class Scene_Base
    • main
    • update_basic

Download InpEx v1.03 (87.17 kB, 1300 times downloaded)

Download InpEx v1.02 (86.05 kB, 1782 times downloaded)

Download InpEx Demo v1.02 (1.63 MB, 409 times downloaded)

Download InpEx v1.01 (81.36 kB, 1797 times downloaded)

Download InpEx Demo v1.01 (1.63 MB, 408 times downloaded)

Download InpEx v1.00 (62.46 kB, 1818 times downloaded)

Download InpEx Demo v1.00 (1.62 MB, 432 times downloaded)

#==============================================================================
# 
# GaryCXJk - InpEx v1.04
# * Last Updated: 2019.07.17
# * Level: Medium
# * Requires: N/A
# 
#==============================================================================

$imported = {} if $imported.nil?
$imported["CXJ-InpEx"] = true

#==============================================================================
#
# Changelog:
#
#------------------------------------------------------------------------------
# 2019.07.17 - v1.04
#
# * Fixed: Eight directional input didn't work for gamepad
#
#------------------------------------------------------------------------------
# 2014.04.07 - v1.03
#
# * Fixed: Conditional branches now work as should
#
#------------------------------------------------------------------------------
# 2014.04.04 - v1.02
#
# * Added: Ability to disable keys temporarily when InputEx is bound to Input
# * Added: Ability to disable directions temporarily when InputEx is bound to
#          Input
#
#------------------------------------------------------------------------------
# 2013.08.19 - v1.01
#
# * Added: Basic mouse control on menus
# * Added: Message commands to display key presses
#
#------------------------------------------------------------------------------
# 2013.07.31 - v1.00
#
# * Initial release
#
#==============================================================================
#
# Sometimes you need extra ways to control the game, and sometimes the amount
# of available buttons and keys isn't enough for the game. Or, you don't want
# people, especially non-RPG Maker users, to rely on F1 to change the gamepad
# and / or keyboard settings.
#
# This script adds a way to bind new keys both during development as well as
# in-game.
#
#==============================================================================
#
# Installation:
#
# Make sure to put this below Materials, but above Main Process.
#
# This script adds aliases for several methods. If you are sure no method that
# is used by other scripts get overridden, you can place it anywhere,
# otherwise, make sure this script is loaded after any other script overriding
# these methods, otherwise this script stops working.
#
#------------------------------------------------------------------------------
# Aliased methods:
#
# * module Input (if keyboard or gamepad hooks are enabled)
#   - update
#   - press?(key)
#   - repeat?(key)
#   - trigger?(key)
#   - dir4
#   - dir8
# * module SceneManager
#   - snapshot_for_background
# * class Window_Base
#   - convert_escape_characters(text)
#   - process_escape_character(code, text, pos)
# * class Window_Selectable (if mouse hooks are enabled)
#   - update
#
#==============================================================================
#
# Usage:
#
# Before I'll start, this guide assumes you have set INCLUDE_CORE to true.
# If that isn't the case, the modules are included in CXJ::INPEX. For example
# the Mouse module can be found as CXJ::INPEX::Mouse.
#
# In essence, the script is plug-and-play, it already works once installed.
# However, if you want to add more keybindings, you can always do that. You
# can later call that bound key in your own script using the same symbol.
#
# In order to bind keys and buttons in-game, you can use the following methods:
#
# Keyboard.bind_keyboard(sym, key)
# Gamepad.bind_gamepad(sym, key)
#
# You can also unbind keys:
#
# Keyboard.unbind_keyboard(sym, key)
# Gamepad.unbind_gamepad(sym, key)
#
# Most other methods in these modules correspond to the Input equivalent, so
# those don't need explaining.
#
# To check whether a key or button is pressed for keybinding, you can iterate
# over each key. However, as gamepads have a variable amount of buttons, a
# method has been defined to determine the amount of buttons.
#
# Gamepad.get_button_range
#
# If you want certain key binds or directions to temporarily be disabled, you
# can use the following method:
#
# Input.set_key_enabled(sym, status)
# Input.set_dir_enabled(dir, status)
#
# The symbol refers to the kind of button you want to disable, and correspond
# to the keys defined in DEFAULT_BIND in the script settings. With directions,
# it always assumes eight directions, meaning, if you want to disable all left
# movements, even diagonal, you should disable the diagonal directions as
# well.
#
# You can also use mouse control. It covers most of the basic menu control,
# but if you need additional functionality, you can always use the following
# methods:
#
# Mouse.x
# Mouse.y
# Mouse.left_press?
# Mouse.left_trigger?
# Mouse.right_press?
# Mouse.right_trigger?
# Mouse.middle_press?
# Mouse.middle_trigger?
#
# There is functionality for custom mouse pointers set. You first need to
# specify a bitmap image that serves as a pointer, the origin of the pointer
# and the width and height, and you're set. You can even do it in script.
#
# Mouse.bitmap = bitmap
# Mouse.ox = origin_x
# Mouse.oy = origin_y
# Mouse.width = width
# Mouse.height = height
#
# You can also specify the pattern, as in, which mouse pointer to use in the
# same image file.
#
# Mouse.pattern = pattern
#
# You can easily animate the mouse by putting multiple frames of the mouse
# pointer next to each other, each frame having the same size as specified
# on the mouse. Do note that blank frames will still be used in the animation,
# so be sure to pad single-frame pointers, or use separate images for animated
# mouse pointers.
#
# To display keyboard buttons during messages, for example, to show certain
# keybinds, use the following tags:
#
# \key[code]    - Textual representation of one key 
# \keyi[code]   - Picture representation of one key
# \bkey[code]   - Textual representation of bound keys
# \bkeyi[code]  - Picture representation of bound keys
#
# There's a simple window that serves as an example for key presses, and can
# actually be used to poll for keyboard presses. To use it, you'll need to
# make a Window_SimpleKeyTest instance.
#
# Window_SimpleKeyTest.new(array_variable, option1, option2...)
#
# array_variable is an array, preferably empty. When the window closes after
# a button has pressed, it will store the key code inside this array.
#
# You can also pass on symbols that determine what gets ignored.
#
# :no_lr      - Ignores the left and right variants of shift, ctrl and alt.
# :only_lr    - Ignores the directionless shift, ctrl and alt.
# :no_mouse   - Ignores mouse presses.
#
# An example code:
#
# varr = []
# wnd = Window_SimpleKeyTest.new(varr, :only_lr)
# unless wnd.close?
#   wnd.update
#   Fiber.yield
# end
# p varr
#
#==============================================================================
#
# License:
#
#            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
#                    Version 2, December 2004
#
# Copyright (C) 2013 Sam Hocevar <sam@hocevar.net>
#
# Everyone is permitted to copy and distribute verbatim or modified
# copies of this license document, and changing it is allowed as long
# as the name is changed.
#
#            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
#   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
#
#  0. You just DO WHAT THE FUCK YOU WANT TO.
#
# See http://www.wtfpl.net/ for more details.
#
#------------------------------------------------------------------------------
# Extra notes:
#
# This license was picked due to the fact that in my opinion this script
# shouldn't be restricted by the creative commons license, which mostly still
# requires you to attribute the content to the original creator. I also feel
# like this script could help others understand certain mechanics and can
# learn from it without the fear of violating a license due to similar coding.
#
# You can still give credits if you want though, and are free to pick the
# following names when you give credit:
#
# * GaryCXJk
# * Gary A.M. Kertopermono
# * G.A.M. Kertopermono
# * GARYCXJK
#
# To make it clear, this license allows you to DO WHAT THE FUCK YOU WANT TO,
# which means you can use it in commercial as well as non-commercial products,
# you can modify it, redistribute it, make toilet paper out of it, sell it on
# eBay and win a presidential election with it. But it's mostly for making
# games. There are no restrictions, no need to attribute regardless of the
# amount of modifications made, you are allowed to remove all references to me,
# you are allowed to change the license, although that's pretty much a dick
# move (actually, I'm not sure if you can change the license or not, but let's
# just not be dicks here, mmm'kay?), you are allowed to directly sell this
# script or monetize on it on your own site.
#
# This script was originally hosted on:
# http://area91.multiverseworks.com
#
#==============================================================================
#
# The code below defines the settings of this script, and are there to be
# modified.
#
#==============================================================================
module CXJ
  module INPEX
    #------------------------------------------------------------------------
    # General settings
    #------------------------------------------------------------------------
    INCLUDE_CORE = true               # Include core to root
    
    #------------------------------------------------------------------------
    # Hook settings
    #------------------------------------------------------------------------
    ENABLE_COMPATIBILITY = false      # Enable to fall back to vanilla controls
    HOOK_KEYBOARD_TO_INPUT = true
    HOOK_GAMEPAD_TO_INPUT = true
    
    #------------------------------------------------------------------------
    # Keyboard settings
    #------------------------------------------------------------------------
    DISABLE_F12_RESET = true          # Might not be entirely reliable
    KEYBOARD_ICONS = "Graphics/System/KeyboardIcon"
    DEFAULT_ICON_HEIGHT = 24
    
    CUSTOM_KEY_ICON = {}
    CUSTOM_KEY_ICON[:K_BACKSPACE] = [  0, 384,  40,  24]
    CUSTOM_KEY_ICON[:K_TAB]       = [ 40, 384,  40,  24]
    CUSTOM_KEY_ICON[:K_ENTER]     = [ 80, 384,  40,  24]
    CUSTOM_KEY_ICON[:K_SHIFT]     = [120, 384,  40,  24]
    CUSTOM_KEY_ICON[:K_CTRL]      = [160, 384,  40,  24]
    CUSTOM_KEY_ICON[:K_CAPSLOCK]  = [200, 384,  40,  24]
    CUSTOM_KEY_ICON[:K_SPACE]     = [240, 384,  48,  24]
    CUSTOM_KEY_ICON["/"]          = [  0, 408,  24,  24]
    CUSTOM_KEY_ICON["\\"]         = [ 24, 408,  24,  24]
    CUSTOM_KEY_ICON["["]          = [ 48, 408,  24,  24]
    CUSTOM_KEY_ICON["]"]          = [ 72, 408,  24,  24]
    CUSTOM_KEY_ICON[";"]          = [ 96, 408,  24,  24]
    CUSTOM_KEY_ICON["'"]          = [120, 408,  24,  24]
    CUSTOM_KEY_ICON["`"]          = [144, 408,  24,  24]
    #CUSTOM_KEY_ICON["+"]          = [168, 408,  24,  24]
    #CUSTOM_KEY_ICON["-"]          = [192, 408,  24,  24]
    #CUSTOM_KEY_ICON["*"]          = [216, 408,  24,  24]
    CUSTOM_KEY_ICON["="]          = [240, 408,  24,  24]
    
    #------------------------------------------------------------------------
    # Gamepad settings
    #------------------------------------------------------------------------
    DEFAULT_GAMEPAD_TYPE = :xinput
    DEFAULT_GAMEPAD_NUM = 0
    
    #------------------------------------------------------------------------
    # Mouse settings
    #------------------------------------------------------------------------
    ENABLE_CUSTOM_POINTER = true
    HIDE_MOUSE_POINTER = true
    HOOK_MOUSE_TO_WINDOWS = true
    DEFAULT_MOUSE_BITMAP = "Graphics/System/Pointer"
    DEFAULT_MOUSE_ORIGIN = [16, 16]
    DEFAULT_MOUSE_SIZE = [32, 32]
    DEFAULT_MOUSE_PATTERN = 0
    DEFAULT_MOUSE_TICKS_PER_FRAME = 5
    
    #------------------------------------------------------------------------
    # Game message vocabulary
    #------------------------------------------------------------------------
    VOCAB_UNDEFINED = "UNDEFINED"
    VOCAB_KEY_UNKNOWN = "KEY"
    VOCAB_AND = "and"
    VOCAB_OR = "or"
    
    #------------------------------------------------------------------------
    # The default bind settings for keyboard.
    #------------------------------------------------------------------------
    DEFAULT_BIND = {
    :UP => [:K_UP, :K_NUMPAD8],
    :DOWN => [:K_DOWN, :K_NUMPAD2],
    :LEFT => [:K_LEFT, :K_NUMPAD4],
    :RIGHT => [:K_RIGHT, :K_NUMPAD6],
    
    :A => [:K_SHIFT],
    :B => [:K_ESC, :K_NUMPAD0, :K_X],
    :C => [:K_SPACE, :K_ENTER, :K_Z],
    :X => [:K_A],
    :Y => [:K_S],
    :Z => [:K_D],
    :L => [:K_Q],
    :R => [:K_W],
    
    :SHIFT => [:K_SHIFT, :K_LSHIFT, :K_RSHIFT],
    :CTRL => [:K_CTRL, :K_LCTRL, :K_RCTRL],
    :ALT => [:K_ALT, :K_LALT, :K_RALT],
    
    :F5 => [:K_F5],
    :F6 => [:K_F6],
    :F7 => [:K_F7],
    :F8 => [:K_F8],
    :F9 => [:K_F9],
    
    :TAB => [:K_TAB],
    
    :SLOT1 => [:K_1],
    :SLOT2 => [:K_2],
    :SLOT3 => [:K_3],
    :SLOT4 => [:K_4],
    :SLOT5 => [:K_5],
    }
    
    #------------------------------------------------------------------------
    # The default bind settings for gamepad.
    #------------------------------------------------------------------------
    DEFAULT_BIND_GAMEPAD = {
    :UP => [:X_STHUMBL_UP],
    :DOWN => [:X_STHUMBL_DOWN],
    :LEFT => [:X_STHUMBL_LEFT],
    :RIGHT => [:X_STHUMBL_RIGHT],
    
    :A => [:X_A],
    :B => [:X_B],
    :C => [:X_X],
    :X => [:X_Y],
    :Y => [:X_LSHOULDER],
    :Z => [:X_RSHOULDER],
    :L => [:X_BACK],
    :R => [:X_START],
    }
  end
end

#==============================================================================
#
# The code below should not be altered unless you know what you're doing.
#
#==============================================================================

#----------------------------------------------------------------------------
# *  Detects The OS Running
#  So far only Windows is supported, but it's being prepared for the
#  possibility of other operating systems.
#----------------------------------------------------------------------------
def get_os
  case RUBY_PLATFORM
  when /win32/i
    :win32
  else
    :unknown
  end
end

module CXJ
  module INPEX
    #------------------------------------------------------------------------
    # This block defines the functions to use.
    #------------------------------------------------------------------------
    if get_os == :win32
      module WIN32
        GETACTIVEWINDOW = Win32API.new("user32", "GetActiveWindow", '', 'L')
        GETASYNCKEYSTATE = Win32API.new("user32", "GetAsyncKeyState", 'L', 'L')
        GETCURSORPOS = Win32API.new("user32", "GetCursorPos", 'P', 'V')
        SCREENTOCLIENT = Win32API.new("user32", "ScreenToClient", 'LP', 'V')
        SHOWCURSOR = Win32API.new("user32", "ShowCursor", 'L', 'L')
        MAPVIRTUALKEY = Win32API.new("user32", "MapVirtualKey", 'II', 'I')
        GETKEYBOARDSTATE = Win32API.new("user32", "GetKeyboardState", 'P', 'V')
        TOUNICODE = Win32API.new("user32", "ToUnicode", 'LLPPIL', 'I')
      end
    end
    
    module UNKNOWN
      GETACIVEWINDOW = Proc.new {}
      GETASYNCKEYSTATE = Proc.new {}
      GETCURSORPOS = Proc.new {}
      SCREENTOCLIENT = Proc.new {}
      SHOWCURSOR = Proc.new {}
      MAPVIRTUALKEY = Proc.new {}
      GETKEYBOARDSTATE = Proc.new {}
      TOUNICODE = Proc.new {}
    end
    
    module CORE
      
      #========================================================================
      # ** Keys
      #------------------------------------------------------------------------
      #  The key codes that correspond to keys.
      #========================================================================
      module Keys
        M_LEFT = 0x01
        M_RIGHT = 0x02
        M_MIDDLE = 0x04
        
        K_BACKSPACE = 0x08
        K_TAB = 0x09
        K_ENTER = 0x0D
        K_RETURN = 0x0D
        K_SHIFT = 0x10
        K_CTRL = 0x11
        K_ALT = 0x12
        K_MENU = 0x12
        K_PAUSE = 0x13
        K_CAPSLOCK = 0x14
        K_ESCAPE = 0x1B
        K_ESC = 0x1B
        K_SPACE = 0x20
        K_PGUP = 0x21
        K_PGDOWN = 0x22
        K_END = 0x23
        K_HOME = 0x24
        K_LEFT = 0x25
        K_UP = 0x26
        K_RIGHT = 0x27
        K_DOWN = 0x28
        K_PRINTSCREEN = 0x2C
        K_INSERT = 0x2D
        K_DELETE = 0x2E
        K_0 = 0x30
        K_1 = 0x31
        K_2 = 0x32
        K_3 = 0x33
        K_4 = 0x34
        K_5 = 0x35
        K_6 = 0x36
        K_7 = 0x37
        K_8 = 0x38
        K_9 = 0x39
        K_A = 0x41
        K_B = 0x42
        K_C = 0x43
        K_D = 0x44
        K_E = 0x45
        K_F = 0x46
        K_G = 0x47
        K_H = 0x48
        K_I = 0x49
        K_J = 0x4A
        K_K = 0x4B
        K_L = 0x4C
        K_M = 0x4D
        K_N = 0x4E
        K_O = 0x4F
        K_P = 0x50
        K_Q = 0x51
        K_R = 0x52
        K_S = 0x53
        K_T = 0x54
        K_U = 0x55
        K_V = 0x56
        K_W = 0x57
        K_X = 0x58
        K_Y = 0x59
        K_Z = 0x5A
        K_LWIN = 0x5B
        K_RWIN = 0x5C
        K_NUMPAD0 = 0x60
        K_NUMPAD1 = 0x61
        K_NUMPAD2 = 0x62
        K_NUMPAD3 = 0x63
        K_NUMPAD4 = 0x64
        K_NUMPAD5 = 0x65
        K_NUMPAD6 = 0x66
        K_NUMPAD7 = 0x67
        K_NUMPAD8 = 0x68
        K_NUMPAD9 = 0x69
        K_MULTIPLY = 0x6A
        K_ADD = 0x6B
        K_SEPARATOR = 0x6C
        K_SUBTRACT = 0x6D
        K_DECIMAL = 0x6E
        K_DIVIDE = 0x6F
        K_F1 = 0x70
        K_F2 = 0x71
        K_F3 = 0x72
        K_F4 = 0x73
        K_F5 = 0x74
        K_F6 = 0x75
        K_F7 = 0x76
        K_F8 = 0x77
        K_F9 = 0x78
        K_F10 = 0x79
        K_F11 = 0x7A
        K_F12 = 0x7B
        K_NUMLOCK = 0x90
        K_SCROLLOCK = 0x91
        K_LSHIFT = 0xA0
        K_RSHIFT = 0xA1
        K_LCTRL = 0xA2
        K_RCTRL = 0xA3
        K_LALT = 0xA4
        K_LMENU = 0xA4
        K_RALT = 0xA5
        K_RMENU = 0xA5
        
        K_OEM_1 = 0xBA
        K_OEM_PLUS = 0xBB
        K_OEM_COMMA = 0xBC
        K_OEM_MINUS = 0xBD
        K_OEM_PERIOD = 0xBE
        K_OEM_2 = 0xBF
        K_OEM_3 = 0xC0
        K_OEM_4 = 0xDB
        K_OEM_5 = 0xDC
        K_OEM_6 = 0xDD
        K_OEM_7 = 0xDE
        K_OEM_8 = 0xDF
        
        KEY_STRING = []
        
        KEY_STRING[M_LEFT] = "Left Mouse Button"
        KEY_STRING[M_RIGHT] = "Right Mouse Button"
        KEY_STRING[M_MIDDLE] = "Middle Mouse Button"

        KEY_STRING[K_BACKSPACE] = "Backspace"
        KEY_STRING[K_TAB] = "Tab"
        KEY_STRING[K_ENTER] = "Enter"
        KEY_STRING[K_SHIFT] = "Shift"
        KEY_STRING[K_CTRL] = "Ctrl"
        KEY_STRING[K_MENU] = "Alt"
        KEY_STRING[K_PAUSE] = "Pause"
        KEY_STRING[K_CAPSLOCK] = "Caps Lock"
        KEY_STRING[K_ESCAPE] = "Escape"
        KEY_STRING[K_SPACE] = "Space"
        KEY_STRING[K_PGUP] = "Page Up"
        KEY_STRING[K_PGDOWN] = "Page Down"
        KEY_STRING[K_END] = "End"
        KEY_STRING[K_HOME] = "Home"
        KEY_STRING[K_LEFT] = "Left"
        KEY_STRING[K_UP] = "Up"
        KEY_STRING[K_RIGHT] = "Right"
        KEY_STRING[K_DOWN] = "Down"
        KEY_STRING[K_PRINTSCREEN] = "Print Screen"
        KEY_STRING[K_INSERT] = "Insert"
        KEY_STRING[K_DELETE] = "Delete"
        KEY_STRING[K_0] = "0"
        KEY_STRING[K_1] = "1"
        KEY_STRING[K_2] = "2"
        KEY_STRING[K_3] = "3"
        KEY_STRING[K_4] = "4"
        KEY_STRING[K_5] = "5"
        KEY_STRING[K_6] = "6"
        KEY_STRING[K_7] = "7"
        KEY_STRING[K_8] = "8"
        KEY_STRING[K_9] = "9"
        KEY_STRING[K_A] = "A"
        KEY_STRING[K_B] = "B"
        KEY_STRING[K_C] = "C"
        KEY_STRING[K_D] = "D"
        KEY_STRING[K_E] = "E"
        KEY_STRING[K_F] = "F"
        KEY_STRING[K_G] = "G"
        KEY_STRING[K_H] = "H"
        KEY_STRING[K_I] = "I"
        KEY_STRING[K_J] = "J"
        KEY_STRING[K_K] = "K"
        KEY_STRING[K_L] = "L"
        KEY_STRING[K_M] = "M"
        KEY_STRING[K_N] = "N"
        KEY_STRING[K_O] = "O"
        KEY_STRING[K_P] = "P"
        KEY_STRING[K_Q] = "Q"
        KEY_STRING[K_R] = "R"
        KEY_STRING[K_S] = "S"
        KEY_STRING[K_T] = "T"
        KEY_STRING[K_U] = "U"
        KEY_STRING[K_V] = "V"
        KEY_STRING[K_W] = "W"
        KEY_STRING[K_X] = "X"
        KEY_STRING[K_Y] = "Y"
        KEY_STRING[K_Z] = "Z"
        KEY_STRING[K_MULTIPLY] = "Numpad *"
        KEY_STRING[K_ADD] = "Numpad +"
        KEY_STRING[K_SUBTRACT] = "Numpad -"
        KEY_STRING[K_DECIMAL] = "Numpad ."
        KEY_STRING[K_DIVIDE] = "Numpad /"
        KEY_STRING[K_NUMPAD0] = "Numpad 0"
        KEY_STRING[K_NUMPAD1] = "Numpad 1"
        KEY_STRING[K_NUMPAD2] = "Numpad 2"
        KEY_STRING[K_NUMPAD3] = "Numpad 3"
        KEY_STRING[K_NUMPAD4] = "Numpad 4"
        KEY_STRING[K_NUMPAD5] = "Numpad 5"
        KEY_STRING[K_NUMPAD6] = "Numpad 6"
        KEY_STRING[K_NUMPAD7] = "Numpad 7"
        KEY_STRING[K_NUMPAD8] = "Numpad 8"
        KEY_STRING[K_NUMPAD9] = "Numpad 9"

        KEY_STRING[K_F1] = "F1"
        KEY_STRING[K_F2] = "F2"
        KEY_STRING[K_F3] = "F3"
        KEY_STRING[K_F4] = "F4"
        KEY_STRING[K_F5] = "F5"
        KEY_STRING[K_F6] = "F6"
        KEY_STRING[K_F7] = "F7"
        KEY_STRING[K_F8] = "F8"
        KEY_STRING[K_F9] = "F9"
        KEY_STRING[K_F10] = "F10"
        KEY_STRING[K_F11] = "F11"
        KEY_STRING[K_F12] = "F12"
        
        #KEY_STRING[K_OEM_PLUS] = "+"
        KEY_STRING[K_OEM_COMMA] = ","
        KEY_STRING[K_OEM_MINUS] = "-"
        KEY_STRING[K_OEM_PERIOD] = "."
        
        if get_os != :unknown
          op = nil
          case get_os
          when :win32
            op = CXJ::INPEX::WIN32
          end
          unless op.nil?
            256.times do |i|
              next unless KEY_STRING[i].nil? || KEY_STRING[i].empty?
              chr = op::MAPVIRTUALKEY.call(i, 2)
              next if chr == 0
              KEY_STRING[i] = [chr].pack("C")
            end
          end
        end
      end
      
      #========================================================================
      # ** Mouse
      #------------------------------------------------------------------------
      #  The mouse.
      #========================================================================
      module Mouse
        
        @@mouse_viewport = nil
        @@mouse_pointer = nil
        @@ox = 0
        @@oy = 0
        @@frame = 0
        @@pattern = 0
        @@ticks_per_frame = 0
        @@tick = 0
        
                
        case get_os
        when :win32
          include CXJ::INPEX::WIN32
        else
          include CXJ::INPEX::UNKNOWN
        end
        
        #--------------------------------------------------------------------
        # * New: Update Frame (Mouse)
        #--------------------------------------------------------------------
        def self.update
          init_pointer
          if(CXJ::INPEX::HIDE_MOUSE_POINTER)
            mouse_x = Mouse.x
            mouse_y = Mouse.y
            if Mouse.in_screen?
              Mouse.show_cursor(false)
            else
              Mouse.show_cursor(true)
            end
          end
          @@mouse_pointer.x = 0 + @@ox
          @@mouse_pointer.y = 0 + @@oy
          @@mouse_pointer.ox = @@ox + width * frame
          @@mouse_pointer.oy = @@oy + height * pattern
          @@mouse_viewport.rect.x = Mouse.x - @@ox
          @@mouse_viewport.rect.y = Mouse.y - @@oy
          @@tick+=1
          if(@@tick == @@ticks_per_frame)
            @@tick = 0
            @@frame = (@@frame + 1) % (bitmap.width / width) if !bitmap.nil? && bitmap.width >= width
          end
        end
        
        #--------------------------------------------------------------------
        # * New: Initialize Mouse Pointer
        #--------------------------------------------------------------------
        def self.init_pointer
          if @@mouse_viewport.nil?
            @@mouse_viewport = Viewport.new(0, 0, CXJ::INPEX::DEFAULT_MOUSE_SIZE[0], CXJ::INPEX::DEFAULT_MOUSE_SIZE[1])
            @@mouse_viewport.z = 300
          end
          if @@mouse_pointer.nil?
            @@mouse_pointer = Sprite.new(@@mouse_viewport)
            @@mouse_pointer.z = 200
            @@mouse_pointer.bitmap = Bitmap.new(32, 32) if CXJ::INPEX::DEFAULT_MOUSE_BITMAP.nil? || CXJ::INPEX::DEFAULT_MOUSE_BITMAP.empty?
            @@mouse_pointer.bitmap = Cache.normal_bitmap(CXJ::INPEX::DEFAULT_MOUSE_BITMAP) unless CXJ::INPEX::DEFAULT_MOUSE_BITMAP.nil? || CXJ::INPEX::DEFAULT_MOUSE_BITMAP.empty?
            @@ox = CXJ::INPEX::DEFAULT_MOUSE_ORIGIN[0]
            @@oy = CXJ::INPEX::DEFAULT_MOUSE_ORIGIN[0]
            @@frame = 0
            @@pattern = CXJ::INPEX::DEFAULT_MOUSE_PATTERN
            @@ticks_per_frame = CXJ::INPEX::DEFAULT_MOUSE_TICKS_PER_FRAME
            @@tick = 0
          end
        end
        
        #--------------------------------------------------------------------
        # * New: Assign Pointer Bitmap
        #--------------------------------------------------------------------
        def self.bitmap=(bitmap)
          init_pointer
          @@mouse_pointer.bitmap = bitmap
          @@ox = 0
          @@oy = 0
          @@frame = 0
          @@pattern = 0
        end
        
        #--------------------------------------------------------------------
        # * New: Pointer Bitmap
        #--------------------------------------------------------------------
        def self.bitmap
          @@mouse_pointer.bitmap
        end
        
        #--------------------------------------------------------------------
        # * New: Set Pointer x-origin
        #--------------------------------------------------------------------
        def self.ox=(ox)
          @@ox = ox
        end
        
        #--------------------------------------------------------------------
        # * New: Set Pointer y-origin
        #--------------------------------------------------------------------
        def self.oy=(oy)
          @@oy = oy
        end
        
        #--------------------------------------------------------------------
        # * New: Pointer x-origin
        #--------------------------------------------------------------------
        def self.ox
          @@ox
        end
        
        #--------------------------------------------------------------------
        # * New: Pointer y-origin
        #--------------------------------------------------------------------
        def self.oy
          @@oy
        end
        
        #--------------------------------------------------------------------
        # * New: Set z-coordinate
        #--------------------------------------------------------------------
        def self.z=(z)
          @@mouse_viewport.z = z
        end
        
        #--------------------------------------------------------------------
        # * New: z-coordinate
        #--------------------------------------------------------------------
        def self.z
          @@mouse_viewport.z
        end
        
        #--------------------------------------------------------------------
        # * New: Set Frame
        #--------------------------------------------------------------------
        def self.frame=(frame)
          @@frame = frame
        end
        
        #--------------------------------------------------------------------
        # * New: Frame
        #--------------------------------------------------------------------
        def self.frame
          @@frame
        end
        
        #--------------------------------------------------------------------
        # * New: Set Pattern
        #--------------------------------------------------------------------
        def self.pattern=(pattern)
          @@pattern = pattern
        end
        
        #--------------------------------------------------------------------
        # * New: Pattern
        #--------------------------------------------------------------------
        def self.pattern
          @@pattern
        end
        
        #--------------------------------------------------------------------
        # * New: Set Width
        #--------------------------------------------------------------------
        def self.width=(width)
          @@mouse_viewport.rect.width = width
        end
        
        #--------------------------------------------------------------------
        # * New: Width
        #--------------------------------------------------------------------
        def self.width
          @@mouse_viewport.rect.width
        end
        
        #--------------------------------------------------------------------
        # * New: Set Height
        #--------------------------------------------------------------------
        def self.height=(height)
          @@mouse_viewport.rect.height = height
        end
        
        #--------------------------------------------------------------------
        # * New: Height
        #--------------------------------------------------------------------
        def self.height
          @@mouse_viewport.rect.height
        end
        
        #--------------------------------------------------------------------
        # * New: Mouse Coordinates
        #--------------------------------------------------------------------
        def self.mouse_coords
          return [-1, -1] if get_os == :unknown
          lpPoint = "\0" * 8
          GETCURSORPOS.call(lpPoint)
          success = SCREENTOCLIENT.call(GETACTIVEWINDOW.call, lpPoint)
          coord = lpPoint.unpack("ll")
          return coord
        end

        #--------------------------------------------------------------------
        # * New: x-coordinate
        #--------------------------------------------------------------------
        def self.x
          mouse_coords[0]
        end

        #--------------------------------------------------------------------
        # * New: y-coordinate
        #--------------------------------------------------------------------
        def self.y
          mouse_coords[1]
        end
        
        #--------------------------------------------------------------------
        # * New: Toggles System Cursor
        #--------------------------------------------------------------------
        def self.show_cursor(show)
          SHOWCURSOR.call(show ? 1 : 0)
        end

        #--------------------------------------------------------------------
        # * New: Checks If Mouse Is In Screen
        #--------------------------------------------------------------------
        def self.in_screen?
          x >= 0 && x < Graphics.width && y >= 0 && y < Graphics.height
        end
        
        #--------------------------------------------------------------------
        # * New: Checks If Left Mouse Button Is Down
        #--------------------------------------------------------------------
        def self.left_press?
          Keyboard.press?(Keys::M_LEFT)
        end
        
        #--------------------------------------------------------------------
        # * New: Checks If Left Mouse Button Is Triggered
        #--------------------------------------------------------------------
        def self.left_trigger?
          Keyboard.trigger?(Keys::M_LEFT)
        end
        
        #--------------------------------------------------------------------
        # * New: Checks If Right Mouse Button Is Down
        #--------------------------------------------------------------------
        def self.right_press?
          Keyboard.press?(Keys::M_RIGHT)
        end
        
        #--------------------------------------------------------------------
        # * New: Checks If Right Mouse Button Is Triggered
        #--------------------------------------------------------------------
        def self.right_trigger?
          Keyboard.trigger?(Keys::M_RIGHT)
        end
        
        #--------------------------------------------------------------------
        # * New: Checks If Middle Mouse Button Is Down
        #--------------------------------------------------------------------
        def self.middle_press?
          Keyboard.press?(Keys::M_MIDDLE)
        end
        
        #--------------------------------------------------------------------
        # * New: Checks If Middle Mouse Button Is Triggered
        #--------------------------------------------------------------------
        def self.middle_trigger?
          Keyboard.trigger?(Keys::M_MIDDLE)
        end
        
        #--------------------------------------------------------------------
        # * New: Checks Custom Mouse Pointer Visibility
        #--------------------------------------------------------------------
        def self.visible
          @@mouse_pointer.visible
        end
        
        #--------------------------------------------------------------------
        # * New: Sets Custom Mouse Pointer Visibility
        #--------------------------------------------------------------------
        def self.visible=(value)
          @@mouse_pointer.visible = value
        end
      end
      
      case get_os
      when :win32
        #======================================================================
        # ** XInputGamepad
        #----------------------------------------------------------------------
        #  The module that handles XInput compatible gamepads.
        #======================================================================
        module XInputGamepad
          XINPUTGETSTATE = Win32API.new("xinput1_3", "XInputGetState", 'LP', 'L')
          
          X_DPAD_UP = 0
          X_DPAD_DOWN = 1
          X_DPAD_LEFT = 2
          X_DPAD_RIGHT = 3
          X_START = 4
          X_BACK = 5
          X_LTHUMB = 6
          X_RTHUMB = 7
          X_LSHOULDER = 8
          X_RSHOULDER = 9
          X_A = 12
          X_B = 13
          X_X = 14
          X_Y = 15
          
          X_SLTRIGGER = 16
          X_SRTRIGGER = 17
          X_STHUMBL_LEFT = 18
          X_STHUMBL_RIGHT = 19
          X_STHUMBL_DOWN = 20
          X_STHUMBL_UP = 21
          X_STHUMBR_LEFT = 22
          X_STHUMBR_RIGHT = 23
          X_STHUMBR_DOWN = 24
          X_STHUMBR_UP = 25
          
          X_S_LTRIGGER = :ltrigger
          X_S_RTRIGGER = :rtrigger
          X_S_THUMBLX = :thumblx
          X_S_THUMBLY = :thumbly
          X_S_THUMBRX = :thumbrx
          X_S_THUMBRY = :thumbry
          X_S_THUMBL = :thumbl
          X_S_THUMBR = :thumbr
          
          #------------------------------------------------------------------
          # * New: Sliders
          #------------------------------------------------------------------
          def self.sliders
            slist = {}
            slist[X_SLTRIGGER] = :ltrigger
            slist[X_SRTRIGGER] = :rtrigger
            slist[X_STHUMBL_LEFT] = :thumblx
            slist[X_STHUMBL_RIGHT] = :thumblx
            slist[X_STHUMBL_DOWN] = :thumbly
            slist[X_STHUMBL_UP] = :thumbly
            slist[X_STHUMBR_LEFT] = :thumbrx
            slist[X_STHUMBR_RIGHT] = :thumbrx
            slist[X_STHUMBR_DOWN] = :thumbry
            slist[X_STHUMBR_UP] = :thumbry
            slist[:thumblx] = :thumbl
            slist[:thumbly] = :thumbl
            slist[:thumbrx] = :thumbr
            slist[:thumbry] = :thumbr
            slist
          end
          
          #------------------------------------------------------------------
          # * New: Linked Sliders
          #  Handy for in-game key binding.
          #------------------------------------------------------------------
          def self.linked_sliders
            slist = {}
            slist[:thumblx] = [X_STHUMBL_LEFT, X_STHUMBL_RIGHT]
            slist[:thumbly] = [X_STHUMBL_DOWN, X_STHUMBL_UP]
            slist[:thumbrx] = [X_STHUMBR_LEFT, X_STHUMBR_RIGHT]
            slist[:thumbry] = [X_STHUMBR_DOWN, X_STHUMBR_UP]
            slist
          end
          
          #------------------------------------------------------------------
          # * New: Sticks
          #------------------------------------------------------------------
          def self.sticks
            slist = []
            slist.push(:thumbl)
            slist.push(:thumbr)
          end
          
          #------------------------------------------------------------------
          # * New: Button Range
          #------------------------------------------------------------------
          def self.get_button_range
            return Array.new(0..25)
          end
          
          @@gamepad = Array.new(4)
          
          #------------------------------------------------------------------
          # * New: Initialization Gamepad
          #------------------------------------------------------------------
          def self.init_gamepad
            4.times do |padno|
              @@gamepad[padno] = {}
              pad = @@gamepad[padno]
              pad[:no_response_timer] = 0
              pad[:press] = [false] * 26
              pad[:repeat] = [false] * 26
              pad[:trigger] = [false] * 26
              pad[:press_time] = [0] * 26
              pad[:slider] = {}
              pad[:slider][:ltrigger] = 0
              pad[:slider][:rtrigger] = 0
              pad[:slider][:thumblx] = 0
              pad[:slider][:thumbly] = 0
              pad[:slider][:thumbrx] = 0
              pad[:slider][:thumbry] = 0
              pad[:threshold] = {}
              pad[:threshold][:ltrigger] = 128
              pad[:threshold][:rtrigger] = 128
              pad[:threshold][:thumbl] = 12000
              pad[:threshold][:thumbr] = 12000
              pad[:deadzone] = {}
              pad[:deadzone][:ltrigger] = 30
              pad[:deadzone][:rtrigger] = 30
              pad[:deadzone][:thumbl] = 7849
              pad[:deadzone][:thumbr] = 8689
            end
          end
          
          init_gamepad
          
          #------------------------------------------------------------------
          # * New: Update Gamepad
          #------------------------------------------------------------------
          def self.update
            4.times do |padno|
              xinput_state = "\0" * 16
              error = XINPUTGETSTATE.call(padno, xinput_state)
              pad = @@gamepad[padno]
              pad[:no_response_timer] = [pad[:no_response_timer] + 1, 300].min
              next unless error == 0
              pad[:no_response_timer] = 0
              xis_data = xinput_state.unpack("LSCCssss")
              buttons = xis_data[1]
              pad[:slider][:ltrigger] = xis_data[2]
              pad[:slider][:rtrigger] = xis_data[3]
              pad[:slider][:thumblx] = xis_data[4]
              pad[:slider][:thumbly] = xis_data[5]
              pad[:slider][:thumbrx] = xis_data[6]
              pad[:slider][:thumbry] = xis_data[7]
              trigs = [:ltrigger, :rtrigger]
              slides = [:thumblx, :thumbly, :thumbrx, :thumbry]
              slide_thres = [:thumbl, :thumbr]
              26.times do |button|
                trigger = false
                if button < 16
                  trigger = buttons & (1 << button) != 0
                elsif button < 18
                  trigger = pad[:slider][trigs[button - 16]] >= pad[:threshold][trigs[button - 16]]
                else
                  thres = pad[:threshold][slide_thres[(button - 18) / 4]]
                  val = pad[:slider][slides[(button - 18) / 2]]
                  trigger = val * ((button - 18) % 2 == 0 ? -1 : 1) >= thres.abs
                end
                unless trigger
                  pad[:press][button] = false
                  pad[:repeat][button] = false
                  pad[:trigger][button] = false
                  pad[:press_time][button] = 0
                  next
                end
                old_val = pad[:press_time][button]
                pad[:press_time][button]+= 1
                pad[:press][button] = true
                pad[:trigger][button] = old_val == 0
                pad[:repeat][button] = old_val == 0 || (old_val >= 32 && old_val % 2 == 0)
              end
            end
          end
          
          #------------------------------------------------------------------
          # * New: Check Pressed
          #------------------------------------------------------------------
          def self.press?(padno, key)
            return @@gamepad[padno][:press][key] unless key.kind_of?(Array)
            key.each do |k|
              unless k.kind_of?(Array)
                state = @@gamepad[padno][:press][k]
                return true if state
                next
              end
              state = true
              k.each do |sk|
                state = @@gamepad[padno][:press][sk]
                break unless state
              end
              return true if state
            end
            return false
          end
          
          #------------------------------------------------------------------
          # * New: Check Repeated
          #------------------------------------------------------------------
          def self.repeat?(padno, key)
            return @@gamepad[padno][:repeat][key] unless key.kind_of?(Array)
            key.each do |k|
              unless k.kind_of?(Array)
                state = @@gamepad[padno][:repeat][k]
                return true if state
                next
              end
              state = true
              k.each do |sk|
                state = @@gamepad[padno][:repeat][sk]
                break unless state
              end
              return true if state
            end
            return false
          end
          
          #------------------------------------------------------------------
          # * New: Check Triggered
          #------------------------------------------------------------------
          def self.trigger?(padno, key)
            return @@gamepad[padno][:trigger][key] unless key.kind_of?(Array)
            key.each do |k|
              unless k.kind_of?(Array)
                state = @@gamepad[padno][:trigger][k]
                return true if state
                next
              end
              state = true
              k.each do |sk|
                state = @@gamepad[padno][:trigger][sk]
                break unless state
              end
              return true if state
            end
            return false
          end
          
          #------------------------------------------------------------------
          # * New: Time Pressed
          #------------------------------------------------------------------
          def self.press_time(padno, key)
            return @@gamepad[padno][:press_time][key]
          end
          
          #------------------------------------------------------------------
          # * New: Get Slider Value
          #------------------------------------------------------------------
          def self.get_slider(padno, key, no_deadzone = false, no_normalize = false)
            val = 0
            div = 0
            dez = 0
            pad = @@gamepad[padno]
            if [:ltrigger, :rtrigger].include?(key)
              val = pad[:slider][key]
              div = 255.0
              dez = pad[:deadzone][key] unless no_deadzone
              val = [val, div].min
              val-= dez
              val = [val, 0].max
              val = val / (div - dez) * (no_normalize ? div : 1)
            else
              div = 32767.0
              use = [:thumbrx, :thumbry, :thumbr]
              use = [:thumblx, :thumbly, :thumbl] if [:thumblx, :thumbly, :thumbl].include?(key)
              sx = pad[:slider][use[0]]
              sy = pad[:slider][use[1]]
              val = Math.hypot(sx, sy)
              dez = pad[:deadzone][use[2]] unless no_deadzone
              angle = Math.atan2(sy, sx)
              val = [val, div].min
              val-= dez
              val = [val, 0].max
              val = val / (div - dez) * (no_normalize ? div : 1)
              val = Math.cos(angle) * val if key == use[0]
              val = Math.sin(angle) * val if key == use[1]
            end
            return val
          end
          
          #------------------------------------------------------------------
          # * New: Get Trigger
          #------------------------------------------------------------------
          def self.get_thumb_angle(padno, key)
            use = [:thumbrx, :thumbry]
            use = [:thumblx, :thumbly] if [:thumblx, :thumbly, :thumbl].include?(key)
            sx = @@gamepad[padno][:slider][use[0]]
            sy = @@gamepad[padno][:slider][use[1]]
            angle = Math.atan2(sy, sx)
            return angle
          end
          
          #------------------------------------------------------------------
          # * New: Get Threshold
          #------------------------------------------------------------------
          def self.get_threshold(padno, key)
            return @@gamepad[padno][:threshold][key]
          end
          
          #------------------------------------------------------------------
          # * New: Set Threshold
          #------------------------------------------------------------------
          def self.set_threshold(padno, key, value)
            @@gamepad[padno][:threshold][key] = value
          end
          
          #------------------------------------------------------------------
          # * New: Get Dead Zone
          #------------------------------------------------------------------
          def self.get_deadzone(padno, key)
            return @@gamepad[padno][:deadzone][key]
          end
          
          #------------------------------------------------------------------
          # * New: Set Dead Zone
          #------------------------------------------------------------------
          def self.set_deadzone(padno, key, value)
            key = :thumbl if [:thumblx, :thumbly].include?(key)
            key = :thumbr if [:thumbrx, :thumbry].include?(key)
            @@gamepad[padno][:deadzone][key] = value
          end
        end
      end
      
      #========================================================================
      # ** Gamepad
      #------------------------------------------------------------------------
      #  The gamepad.
      #========================================================================
      module Gamepad
        @@gamepads = {}
        @@gamepads[:none] = nil
        if get_os == :win32
          @@gamepads[:xinput] = XInputGamepad
        end
        
        @@current_gamepad = [nil, 0]
        
        @@padbind = {}
        
        @@padbind[:LEFT]||= []
        @@padbind[:RIGHT]||= []
        @@padbind[:UP]||= []
        @@padbind[:DOWN]||= []
        
        @@padbind[:A]||= []
        @@padbind[:B]||= []
        @@padbind[:C]||= []
        @@padbind[:X]||= []
        @@padbind[:Y]||= []
        @@padbind[:Z]||= []
        @@padbind[:L]||= []
        @@padbind[:R]||= []
        
        @@padbind[:SHIFT]||= []
        @@padbind[:CTRL]||= []
        @@padbind[:ALT]||= []
        
        @@padbind[:F5]||= []
        @@padbind[:F6]||= []
        @@padbind[:F7]||= []
        @@padbind[:F8]||= []
        @@padbind[:F9]||= []
        
        #--------------------------------------------------------------------
        # * New: Set Current Gamepad
        #--------------------------------------------------------------------
        def self.set_gamepad(sym, num)
          return if sym.nil?
          @@current_gamepad[0] = @@gamepads[sym]
          @@current_gamepad[1] = num
        end
        
        set_gamepad(CXJ::INPEX::DEFAULT_GAMEPAD_TYPE, CXJ::INPEX::DEFAULT_GAMEPAD_NUM)
        
        unless @@current_gamepad[0].nil?
          CXJ::INPEX::DEFAULT_BIND_GAMEPAD.each_pair do |key, val|
            val.each_index do |i|
              val[i] = @@current_gamepad[0].const_get(val[i]) if val[i].kind_of?(Symbol)
            end
            @@padbind[key]||= []
            @@padbind[key].concat(val)
          end
        end
          
        #--------------------------------------------------------------------
        # * New: Button Range
        #--------------------------------------------------------------------
        def self.get_button_range
          return @@current_gamepad[0].get_button_range unless @@current_gamepad[0].nil?
        end
        
        #--------------------------------------------------------------------
        # * New: Update
        #--------------------------------------------------------------------
        def self.update
          @@current_gamepad[0].update unless @@current_gamepad[0].nil?
        end
        
        #--------------------------------------------------------------------
        # * New: Check Pressed
        #--------------------------------------------------------------------
        def self.press?(key)
          return false if @@current_gamepad[0].nil?
          return false if @@padbind[key].nil?
          key = @@padbind[key] if key.kind_of?(Symbol)
          return @@current_gamepad[0].press?(@@current_gamepad[1], key)
        end
        
        #--------------------------------------------------------------------
        # * New: Check Repeated
        #--------------------------------------------------------------------
        def self.repeat?(key)
          return false if @@current_gamepad[0].nil?
          return false if @@padbind[key].nil?
          key = @@padbind[key] if key.kind_of?(Symbol)
          return @@current_gamepad[0].repeat?(@@current_gamepad[1], key)
        end
        
        #--------------------------------------------------------------------
        # * New: Check Triggered
        #--------------------------------------------------------------------
        def self.trigger?(key)
          return false if @@current_gamepad[0].nil?
          return false if @@padbind[key].nil?
          key = @@padbind[key] if key.kind_of?(Symbol)
          return @@current_gamepad[0].trigger?(@@current_gamepad[1], key)
        end
        
        #--------------------------------------------------------------------
        # * New: Time Pressed
        #--------------------------------------------------------------------
        def self.press_time(key)
          return 0 if @@current_gamepad[0].nil?
          return 0 if @@padbind[key].nil?
          key = @@padbind[key] if key.kind_of?(Symbol)
          return @@current_gamepad[0].press_time(@@current_gamepad[1], key)
        end
        
        #--------------------------------------------------------------------
        # * New: Get Slider
        #--------------------------------------------------------------------
        def self.get_slider(key)
          return 0 if @@current_gamepad[0].nil?
          return 0 if @@padbind[key].nil?
          key = @@padbind[key] if key.kind_of?(Symbol)
          key = @@current_gamepad[0].sliders[key]
          return nil if key.nil?
          return @@current_gamepad[0].get_slider(@@current_gamepad[1], key)
        end
        
        #--------------------------------------------------------------------
        # * New: Get Tumb Stick Angle
        #--------------------------------------------------------------------
        def self.get_thumb_angle(key)
          return 0 if @@current_gamepad[0].nil?
          return 0 if @@padbind[key].nil?
          key = @@padbind[key] if key.kind_of?(Symbol)
          return @@current_gamepad[0].get_thumb_angle(@@current_gamepad[1], key)
        end

        #--------------------------------------------------------------------
        # * New: Bind Key
        #--------------------------------------------------------------------
        def self.bind_gamepad(symbol, key)
          @@padbind[symbol]||= []
          @@padbind[symbol].push(key) unless @@padbind[symbol].include?(key)
        end
        
        #--------------------------------------------------------------------
        # * New: Unbind Key
        #--------------------------------------------------------------------
        def self.unbind_gamepad(symbol, key = nil)
          if key.nil?
            @@padbind[symbol] = []
          else
            @@padbind[symbol].delete(key)
          end
        end
        
        #--------------------------------------------------------------------
        # * New: Get Directon (Up, Down, Left, Right)
        #--------------------------------------------------------------------
        def self.dir4
          return 0 if @@current_gamepad[0].nil?
          pad_handle = @@current_gamepad[0]
          padno = @@current_gamepad[1]
          dir_h = [:LEFT, :RIGHT]
          dir_v = [:UP, :DOWN]
          shortest = [nil, 0, nil]
          dir_h.each_index do |i|
            @@padbind[dir_h[i]].each do |k|
              if pad_handle.press?(padno, k)
                pr = pad_handle.press_time(padno, k)
                shortest = [k, pr, dir_h[i]] if shortest[0].nil? || shortest[1] > pr
              end
            end
          end
          dir_k_h = shortest
          shortest = [nil, 0, nil]
          dir_v.each_index do |i|
            @@padbind[dir_v[i]].each do |k|
              if pad_handle.press?(padno, k)
                pr = pad_handle.press_time(padno, k)
                shortest = [k, pr, dir_v[i]] if shortest[0].nil? || shortest[1] > pr
              end
            end
          end
          dir_k_v = shortest
          return 0 if(dir_k_h[2].nil? && dir_k_v[2].nil?)
          cdir = (dir_k_h[1] < dir_k_v[1] ? dir_k_h[2] : dir_k_v[2])
          cdir = (!dir_k_h[2].nil? && !dir_k_v[2].nil? ? cdir : !dir_k_h[2].nil? ? dir_k_h[2] : dir_k_v[2])
          case cdir
          when :LEFT
            return 4
          when :RIGHT
            return 6
          when :UP
            return 8
          when :DOWN
            return 2
          end
          return 0
        end
        
        #--------------------------------------------------------------------
        # * New: Get Direction (All Eight)
        #--------------------------------------------------------------------
        def self.dir8
          return 0 if @@current_gamepad[0].nil?
          pad_handle = @@current_gamepad[0]
          padno = @@current_gamepad[1]
          dir_h = [:LEFT, :RIGHT]
          dir_v = [:UP, :DOWN]
          shortest = [nil, 0, nil]
          dir_h.each_index do |i|
            @@padbind[dir_h[i]].each do |k|
              if pad_handle.press?(padno, k)
                pr = pad_handle.press_time(padno, k)
                shortest = [k, pr, dir_h[i]] if shortest[0].nil? || shortest[1] > pr
              end
            end
          end
          dir_k_h = shortest
          shortest = [nil, 0, nil]
          dir_v.each_index do |i|
            @@padbind[dir_v[i]].each do |k|
              if pad_handle.press?(padno, k)
                pr = pad_handle.press_time(padno, k)
                shortest = [k, pr, dir_v[i]] if shortest[0].nil? || shortest[1] > pr
              end
            end
          end
          dir_k_v = shortest
          hmod = (dir_k_h[2].nil? ? 0 : dir_k_h[2] == :LEFT ? -1 : 1)
          vmod = (dir_k_v[2].nil? ? 0 : dir_k_v[2] == :DOWN ? -3 : 3)
          return 0 if hmod == 0 && vmod == 0
          return hmod + vmod + 5
        end
        
        #--------------------------------------------------------------------
        # * New: Get Shortest Time Pressed On Directions
        #--------------------------------------------------------------------
        def self.dir_shortest_time
          return -1 if @@current_gamepad[0].nil?
          dirs = [:LEFT, :RIGHT, :UP, :DOWN]
          shortest = [nil, 0]
          pad_handle = @@current_gamepad[0]
          padno = @@current_gamepad[1]
          dirs.each do |d|
            @@padbind[d].each do |k|
              if pad_handle.press?(padno, k)
                pr = pad_handle.press_time(padno, k)
                shortest = [k, pr] if shortest[0].nil? || shortest[1] > pr
              end
            end
          end
          return -1 if shortest[0].nil?
          return shortest[1]
        end
      end
      
      #========================================================================
      # ** Keyboard
      #------------------------------------------------------------------------
      #  The keyboard.
      #========================================================================
      module Keyboard
        case get_os
        when :win32
          include CXJ::INPEX::WIN32
        else
          include CXJ::INPEX::UNKNOWN
        end
        
        @@keybind = {}
        @@press_state = []
        @@repeat_state = []
        @@trigger_state = []
        @@press_time = []
        
        @@keybind[:LEFT]||= []
        @@keybind[:RIGHT]||= []
        @@keybind[:UP]||= []
        @@keybind[:DOWN]||= []
        
        @@keybind[:A]||= []
        @@keybind[:B]||= []
        @@keybind[:C]||= []
        @@keybind[:X]||= []
        @@keybind[:Y]||= []
        @@keybind[:Z]||= []
        @@keybind[:L]||= []
        @@keybind[:R]||= []
        
        @@keybind[:SHIFT]||= []
        @@keybind[:CTRL]||= []
        @@keybind[:ALT]||= []
        
        @@keybind[:F5]||= []
        @@keybind[:F6]||= []
        @@keybind[:F7]||= []
        @@keybind[:F8]||= []
        @@keybind[:F9]||= []
        
        CXJ::INPEX::DEFAULT_BIND.each_pair do |key, val|
          @@keybind[key]||= []
          @@keybind[key].concat(val)
        end
        
        #--------------------------------------------------------------------
        # * New: Update
        #--------------------------------------------------------------------
        def self.update
          if @@press_state.empty?
            256.times do |i|
              @@press_state[i] = 0
              @@repeat_state[i] = false
              @@trigger_state[i] = false
              @@press_time[i] = 0
            end
          end
          256.times do |i|
            old_state = @@press_state[i]
            new_state = get_key_state(i)
            @@press_state[i] = new_state
            @@repeat_state[i] = false
            @@trigger_state[i] = false
            if new_state & 0x8000 > 0
              @@press_time[i]+= 1
              @@repeat_state[i] = new_state & 0x0001 > 0
              @@trigger_state[i] = old_state & 0x8000 == 0 if new_state & 0x0001 > 0
            else
              @@press_time[i] = 0
            end
          end
        end
        
        #--------------------------------------------------------------------
        # * New: Get Key State
        #--------------------------------------------------------------------
        def self.get_key_state(key)
          return 0 if get_os == :unknown
          GETASYNCKEYSTATE.call(key)
        end

        #--------------------------------------------------------------------
        # * New: Check Pressed
        #--------------------------------------------------------------------
        def self.press?(key)
          if key.instance_of?(Symbol)
            key = @@keybind[key] if @@keybind.has_key?(key)
            key = CXJ::INPEX::CORE::Keys.const_get(key) if key.instance_of?(Symbol) && CXJ::INPEX::CORE::Keys.constants(false).include?(key)
            return false if key.kind_of?(Symbol)
          end
          return @@press_state[key] & 0x8000 > 0 unless key.kind_of?(Array)
          key.each do |s_key|
            if s_key.kind_of?(Array)
              is_trigger = true
              s_key.each do |ss_key|
                ss_key = CXJ::INPEX::CORE::Keys.const_get(ss_key) if ss_key.instance_of?(Symbol) && CXJ::INPEX::CORE::Keys.constants(false).include?(ss_key)
                is_trigger = press?(ss_key)
                break if !is_trigger
              end
              return true if is_trigger
            else
              s_key = CXJ::INPEX::CORE::Keys.const_get(s_key) if s_key.instance_of?(Symbol) && CXJ::INPEX::CORE::Keys.constants(false).include?(s_key)
              return true if press?(s_key)
            end
          end
          return false
        end
        
        #--------------------------------------------------------------------
        # * New: Check Repeated
        #--------------------------------------------------------------------
        def self.repeat?(key)
          if key.instance_of?(Symbol)
            key = @@keybind[key] if @@keybind.has_key?(key)
            key = CXJ::INPEX::CORE::Keys.const_get(key) if key.instance_of?(Symbol) && CXJ::INPEX::CORE::Keys.constants(false).include?(key)
            return false if key.kind_of?(Symbol)
          end
          return @@repeat_state[key] unless key.kind_of?(Array)
          key.each do |s_key|
            s_key = s_key[0] if s_key.kind_of?(Array) && s_key.size == 1
            next if s_key.kind_of?(Array)
            s_key = CXJ::INPEX::CORE::Keys.const_get(s_key) if s_key.instance_of?(Symbol) && CXJ::INPEX::CORE::Keys.constants(false).include?(s_key)
            return true if repeat?(s_key)
          end
          return false
        end
        
        #--------------------------------------------------------------------
        # * New: Check Triggered
        #--------------------------------------------------------------------
        def self.trigger?(key)
          if key.instance_of?(Symbol)
            key = @@keybind[key] if @@keybind.has_key?(key)
            key = CXJ::INPEX::CORE::Keys.const_get(key) if key.instance_of?(Symbol) && CXJ::INPEX::CORE::Keys.constants(false).include?(key)
            return false if key.kind_of?(Symbol)
          end
          return @@trigger_state[key] unless key.kind_of?(Array)
          key.each do |s_key|
            s_key = s_key[0] if s_key.kind_of?(Array) && s_key.size == 1
            next if s_key.kind_of?(Array)
            s_key = CXJ::INPEX::CORE::Keys.const_get(s_key) if s_key.instance_of?(Symbol) && CXJ::INPEX::CORE::Keys.constants(false).include?(s_key)
            return true if trigger?(s_key)
          end
          return false
        end
        
        #--------------------------------------------------------------------
        # * New: Get Time Pressed
        #--------------------------------------------------------------------
        def self.press_time(key)
          if key.instance_of?(Symbol)
            key = @@keybind[key] if @@keybind.has_key?(key)
            key = CXJ::INPEX::CORE::Keys.const_get(key) if key.instance_of?(Symbol) && CXJ::INPEX::CORE::Keys.constants(false).include?(key)
            return 0 if key.kind_of?(Symbol)
          end
          return @@press_time[key] unless key.kind_of?(Array)
          highest = 0
          key.each do |s_key|
            if s_key.kind_of?(Array)
              lowest = nil
              s_key.each do |ss_key|
                ss_key = CXJ::INPEX::CORE::Keys.const_get(ss_key) if ss_key.instance_of?(Symbol)
                lowest = @@press_time[ss_key] if lowest.nil?
                lowest = [lowest, @@press_time[ss_key]].min
              end
              highest = [highest, lowest].max
            else
              s_key = CXJ::INPEX::CORE::Keys.const_get(s_key) if s_key.instance_of?(Symbol) && CXJ::INPEX::CORE::Keys.constants(false).include?(s_key)
              highest = [highest, @@press_time[s_key]].max
            end
          end
          return highest
        end
        
        #--------------------------------------------------------------------
        # * New: Bind Key
        #--------------------------------------------------------------------
        def self.bind_keyboard(symbol, key)
          @@keybind[symbol]||= []
          @@keybind[symbol].push(key) unless @@keybind[symbol].include?(key)
        end
        
        #--------------------------------------------------------------------
        # * New: Unbind Key
        #--------------------------------------------------------------------
        def self.unbind_keyboard(symbol, key = nil)
          if key.nil?
            @@keybind[symbol] = []
          else
            @@keybind[symbol].delete(key)
          end
        end
        
        #--------------------------------------------------------------------
        # * New: Lists Bound Keys
        #--------------------------------------------------------------------
        def self.get_bound_keys(symbol)
          @@keybind[symbol]||= []
          return Array.new(@@keybind[symbol]) if @@keybind.has_key?(symbol)
        end
        
        #--------------------------------------------------------------------
        # * New: Get Direction (Up, Down, Left, Right)
        #--------------------------------------------------------------------
        def self.dir4
          dirs_h = [:LEFT, :RIGHT]
          dirs_v = [:UP, :DOWN]
          longest_h = [nil, 0]
          longest_v = [nil, 0]
          (dirs_h + dirs_v).each do |dir|
            duration = press_time(dir)
            if dirs_h.include?(dir)
              if duration > longest_h[1]
                unless longest_h[1] > 0
                  longest_h = [dir, duration]
                else
                  longest_h = [nil, 0]
                end
              end
            else
              if duration > longest_v[1]
                unless longest_v[1] > 0
                  longest_v = [dir, duration]
                else
                  longest_v = [nil, 0]
                end
              end
            end
          end
          return 0 if longest_h[1] == 0 && longest_v[1] == 0
          longest = longest_h
          longest = longest_v if (longest_h[1] > longest_v[1] && longest_v[1] > 0) || longest_h[1] == 0
          case longest[0]
          when :LEFT
            return 4
          when :RIGHT
            return 6
          when :UP
            return 8
          when :DOWN
            return 2
          end
        end
        
        #--------------------------------------------------------------------
        # * New: Get Direction (All Eight)
        #--------------------------------------------------------------------
        def self.dir8
          h = (press?(:LEFT) == press?(:RIGHT) ? 0 : press?(:LEFT) ? -1 : 1)
          v = (press?(:UP) == press?(:DOWN) ? 0 : press?(:UP) ? 3 : -3)
          return 0 if h == v
          return 5 + h + v
        end
        
        #--------------------------------------------------------------------
        # * New: Get Shortest Time Pressed On Directions
        #--------------------------------------------------------------------
        def self.dir_shortest_time
          dirs = [:LEFT, :RIGHT, :UP, :DOWN]
          shortest = [nil, 0]
          dirs.each do |d|
            @@keybind[d].each do |k|
              if press?(k)
                pr = press_time(k)
                shortest = [k, pr] if shortest[0].nil? || shortest[1] > pr
              end
            end
          end
          return -1 if shortest[0].nil?
          return shortest[1]
        end
        
        #--------------------------------------------------------------------
        # * New: Get All Triggered Keys
        #--------------------------------------------------------------------
        def self.all_trigger(*triggers)
          list = []
          256.times do |i|
            unless triggers.nil?
              next if triggers.include?(:no_lr) && (0xA0..0xA5).include?(i)
              next if triggers.include?(:only_lr) && (0x10..0x12).include?(i)
              next if triggers.include?(:no_mouse) && [0x01, 0x02, 0x04].include?(i)
            end
            list.push(i) if trigger?(i)
          end
          return list
        end
      end
    end
    
    include CXJ::INPEX::CORE if !INCLUDE_CORE
  end
end

include CXJ::INPEX::CORE if CXJ::INPEX::INCLUDE_CORE

#==============================================================================
# ** Window_SimpleKeyTest
#------------------------------------------------------------------------------
#  This adds a window that can catch key presses.
#==============================================================================

class Window_SimpleKeyTest < Window_Base
  #--------------------------------------------------------------------------
  # * New: Initialization
  #--------------------------------------------------------------------------
  def initialize(keys, triggers = [:no_lr, :no_mouse], *additional)
    w = 160
    h = 90
    x = (Graphics.width - w) / 2
    y = (Graphics.height - h) / 2
    super(x, y, w, h)
    draw_text(0, 0, contents.width, contents.height / 2, "Press a key", 1)
    @keys = keys
    @triggers = triggers
    @triggers = [@triggers] unless @triggers.kind_of?(Array)
    @triggers.concat(additional)
    @timer = Graphics.frame_rate * 10
    @timer_rect = Rect.new(0, contents.height / 2, contents.width, contents.height / 2)
  end
  #--------------------------------------------------------------------------
  # * New: Frame Update
  #--------------------------------------------------------------------------
  def update
    super
    unless @closing || close?
      @timer-= 1
      contents.clear_rect(@timer_rect)
      draw_text(@timer_rect, "(" + (@timer / Graphics.frame_rate + 1).to_s + ")", 1)
      keys = CXJ::INPEX::CORE::Keyboard.all_trigger(*@triggers)
      unless keys.nil? || keys.empty?
        @keys.concat(keys)
        close
      end
      close unless @timer > 0
    end
  end
end

if CXJ::INPEX::HOOK_KEYBOARD_TO_INPUT || CXJ::INPEX::HOOK_GAMEPAD_TO_INPUT
  #============================================================================
  # ** Input
  #============================================================================

  module Input
    class << self
      
      @@enabled = {}
      @@dir_enabled = [true, true, true, true, true, true, true, true, true, true]
      
      #----------------------------------------------------------------------
      # * New: Converts Numerical To Symbol
      #----------------------------------------------------------------------
      def num2sym(num)
        val = nil
        case num
        when 2
          val = :DOWN
        when 4
          val = :LEFT
        when 6
          val = :RIGHT
        when 8
          val = :UP
        when 11
          val = :A
        when 12
          val = :B
        when 13
          val = :C
        when 14
          val = :X
        when 15
          val = :Y
        when 16
          val = :Z
        when 17
          val = :L
        when 18
          val = :R
        end
        val
      end
      
      #----------------------------------------------------------------------
      # * Alias: Update Input
      #----------------------------------------------------------------------
      alias input_update_cxj_inpex update
      def update
        if CXJ::INPEX::HOOK_GAMEPAD_TO_INPUT
          Gamepad.update if CXJ::INPEX::INCLUDE_CORE
          CXJ::INPEX::Gamepad.update if !CXJ::INPEX::INCLUDE_CORE
        end
        if CXJ::INPEX::HOOK_KEYBOARD_TO_INPUT
          Keyboard.update if CXJ::INPEX::INCLUDE_CORE
          CXJ::INPEX::Keyboard.update if !CXJ::INPEX::INCLUDE_CORE
        end
        input_update_cxj_inpex if CXJ::INPEX::ENABLE_COMPATIBILITY
      end
      
      #----------------------------------------------------------------------
      # * Alias: Pressed
      #----------------------------------------------------------------------
      alias input_press_cxj_inpex? press?
      def press?(sym)
        rsym = sym
        sym = num2sym(sym) if sym.kind_of?(Numeric)
        return false unless is_key_enabled?(sym)
        if CXJ::INPEX::HOOK_GAMEPAD_TO_INPUT
          val = Gamepad.press?(sym) if CXJ::INPEX::INCLUDE_CORE
          val = CXJ::INPEX::Gamepad.press?(sym) if !CXJ::INPEX::INCLUDE_CORE
        end
        if CXJ::INPEX::HOOK_KEYBOARD_TO_INPUT && !val
          val = Keyboard.press?(sym) if CXJ::INPEX::INCLUDE_CORE
          val = CXJ::INPEX::Keyboard.press?(sym) if !CXJ::INPEX::INCLUDE_CORE
        end
        val = input_press_cxj_inpex?(rsym) if !val && CXJ::INPEX::ENABLE_COMPATIBILITY
        return val
      end

      
      #----------------------------------------------------------------------
      # * Alias: Repeated
      #----------------------------------------------------------------------
      alias input_repeat_cxj_inpex? repeat?
      def repeat?(sym)
        rsym = sym
        sym = num2sym(sym) if sym.kind_of?(Numeric)
        return false unless is_key_enabled?(sym)
        if CXJ::INPEX::HOOK_GAMEPAD_TO_INPUT
          val = Gamepad.repeat?(sym) if CXJ::INPEX::INCLUDE_CORE
          val = CXJ::INPEX::Gamepad.repeat?(sym) if !CXJ::INPEX::INCLUDE_CORE
        end
        if CXJ::INPEX::HOOK_KEYBOARD_TO_INPUT && !val
          val = Keyboard.repeat?(sym) if CXJ::INPEX::INCLUDE_CORE
          val = CXJ::INPEX::Keyboard.repeat?(sym) if !CXJ::INPEX::INCLUDE_CORE
        end
        val = input_repeat_cxj_inpex?(rsym) if !val && CXJ::INPEX::ENABLE_COMPATIBILITY
        return val
      end
      
      #----------------------------------------------------------------------
      # * Alias: Triggered
      #----------------------------------------------------------------------
      alias input_trigger_cxj_inpex? trigger?
      def trigger?(sym)
        rsym = sym
        sym = num2sym(sym) if sym.kind_of?(Numeric)
        return false unless is_key_enabled?(sym)
        if CXJ::INPEX::HOOK_GAMEPAD_TO_INPUT
          val = Gamepad.trigger?(sym) if CXJ::INPEX::INCLUDE_CORE
          val = CXJ::INPEX::Gamepad.trigger?(sym) if !CXJ::INPEX::INCLUDE_CORE
        end
        if CXJ::INPEX::HOOK_KEYBOARD_TO_INPUT && !val
          val = Keyboard.trigger?(sym) if CXJ::INPEX::INCLUDE_CORE
          val = CXJ::INPEX::Keyboard.trigger?(sym) if !CXJ::INPEX::INCLUDE_CORE
        end
        val = input_trigger_cxj_inpex?(rsym) if !val && CXJ::INPEX::ENABLE_COMPATIBILITY
        return val
      end
      
      #----------------------------------------------------------------------
      # * Alias: Direction (Up, Down, Left, Right)
      #----------------------------------------------------------------------
      alias input_dir4_cxj_inpex dir4
      def dir4
        shortest = -1
        if CXJ::INPEX::HOOK_GAMEPAD_TO_INPUT
          if CXJ::INPEX::INCLUDE_CORE
            shortest = Gamepad.dir_shortest_time
            val = Gamepad.dir4
          else
            shortest = CXJ::INPEX::Gamepad.dir_shortest_time
            val = CXJ::INPEX::Keyboard.dir4
          end
        end
        if CXJ::INPEX::HOOK_KEYBOARD_TO_INPUT
          if CXJ::INPEX::INCLUDE_CORE
            s_key = Keyboard.dir_shortest_time
            val = Keyboard.dir4 if val == 0 || (shortest > -1 && s_key > -1 && s_key <= shortest)
          else
            s_key = CXJ::INPEX::Keyboard.dir_shortest_time
            val = CXJ::INPEX::Keyboard.dir4 if val == 0 || (shortest > -1 && s_key > -1 && s_key <= shortest)
          end
        end
        val = input_dir4_cxj_inpex if val == 0 && CXJ::INPEX::ENABLE_COMPATIBILITY
        return 0 unless(get_dir_enabled(val))
        return val
      end
      
      #----------------------------------------------------------------------
      # * Alias: Direction (All Eight)
      #----------------------------------------------------------------------
      alias input_dir8_cxj_inpex dir8
      def dir8
        val = 0
        if CXJ::INPEX::HOOK_GAMEPAD_TO_INPUT
          val = Gamepad.dir8 if CXJ::INPEX::INCLUDE_CORE
          val = CXJ::INPEX::Gamepad.dir8 if !CXJ::INPEX::INCLUDE_CORE
        end
        if CXJ::INPEX::HOOK_KEYBOARD_TO_INPUT
          if val == 0
            val = Keyboard.dir8 if CXJ::INPEX::INCLUDE_CORE
            val = CXJ::INPEX::Keyboard.dir8 if !CXJ::INPEX::INCLUDE_CORE
          end
        end
        val = input_dir8_cxj_inpex if val == 0 && CXJ::INPEX::ENABLE_COMPATIBILITY
        return 0 unless(get_dir_enabled(val))
        return val
      end
      
      #----------------------------------------------------------------------
      # * New: Set Enabled Status Of Key
      #----------------------------------------------------------------------
      def set_key_enabled(sym, status)
        @@enabled[sym] = status
      end
      
      #----------------------------------------------------------------------
      # * New: Get Enabled Status Of Key
      #----------------------------------------------------------------------
      def is_key_enabled?(sym)
        @@enabled[sym] = true unless @@enabled.has_key?(sym)
        return @@enabled[sym]
      end
      
      #----------------------------------------------------------------------
      # * New: Set Enabled Status Of Direction
      #----------------------------------------------------------------------
      def set_dir_enabled(dir, status)
        @@dir_enabled[dir] = status
      end
      
      #----------------------------------------------------------------------
      # * New: Get Enabled Status Of Direction
      #----------------------------------------------------------------------
      def get_dir_enabled(dir)
        return @@dir_enabled[dir]
      end
    end
  end
end

if CXJ::INPEX::ENABLE_CUSTOM_POINTER
  #============================================================================
  # ** SceneManager
  #----------------------------------------------------------------------------
  #  This module manages scene transitions. For example, it can handle
  # hierarchical structures such as calling the item screen from the main menu
  # or returning from the item screen to the main menu.
  #============================================================================

  module SceneManager
    class << self
      #----------------------------------------------------------------------
      # * Alias: Create Snapshot to Use as Background
      #----------------------------------------------------------------------
      alias scenemanager_snapshot_for_background_cxj_inpex snapshot_for_background
      def snapshot_for_background
        vis = CXJ::INPEX::CORE::Mouse.visible
        CXJ::INPEX::CORE::Mouse.visible = false
        scenemanager_snapshot_for_background_cxj_inpex
        CXJ::INPEX::CORE::Mouse.visible = vis
      end
    end
  end
end

#==============================================================================
# ** Window_Base
#------------------------------------------------------------------------------
#  This is a super class of all windows within the game.
#==============================================================================

class Window_Base < Window

  #--------------------------------------------------------------------------
  # * Alias: Preconvert Control Characters
  #    As a rule, replace only what will be changed into text strings before
  #    starting actual drawing. The character "\" is replaced with the escape
  #    character (\e).
  #--------------------------------------------------------------------------
  alias window_base_convert_escape_characters_cxj_inpex convert_escape_characters
  def convert_escape_characters(text)
    result = window_base_convert_escape_characters_cxj_inpex(text)
    result.gsub!(/\eBKEYI\[(\w+)\]/i) { get_bound_keys_icons($1) }
    result.gsub!(/\eBKEYI\[(\w+),(OR|AND)\]/i) { get_bound_keys_icons($1, ($2.upcase == "AND" ? true : false)) }
    result.gsub!(/\eKEYI\[(\w+)\]/i) { "\eKEY[" + $1.to_s + "]" } if CXJ::INPEX::KEYBOARD_ICONS.nil? || CXJ::INPEX::KEYBOARD_ICONS.empty?
    result.gsub!(/\eKEY\[(\d+)\]/i) { get_key_name($1.to_i) }
    result.gsub!(/\eKEY\[(\w+)\]/i) { get_key_name($1) }
    result.gsub!(/\eBKEY\[(\w+)\]/i) { get_bound_keys($1) }
    result.gsub!(/\eBKEY\[(\w+),(OR|AND)\]/i) { get_bound_keys($1, ($2.upcase == "AND" ? true : false)) }
    result
  end
  
  #--------------------------------------------------------------------------
  # * Control Character Processing
  #     code : the core of the control character
  #            e.g. "C" in the case of the control character \C[1].
  #--------------------------------------------------------------------------
  alias window_base_process_escape_character_cxj_inpex process_escape_character
  def process_escape_character(code, text, pos)
    processed = false
    case code.upcase
    when "KEYI"
      line = text.slice!(/^\[((\d+)|(\w+))\]/i)
      unless line.nil?
        if $2.nil?
          get_key_icon($3, text, pos)
        else
          get_key_icon($2.to_i, text, pos)
        end
      end
    else
      window_base_process_escape_character_cxj_inpex(code, text, pos)
    end
  end
  #--------------------------------------------------------------------------
  # * New: Get Key Name
  #--------------------------------------------------------------------------
  def get_key_name(key)
    if key.kind_of?(String)
      key = CXJ::INPEX::CORE::Keys.const_get(key.to_sym) if CXJ::INPEX::CORE::Keys.constants(false).include?(key.to_sym)
    end
    if key.kind_of?(Symbol)
      key = CXJ::INPEX::CORE::Keys.const_get(key) if CXJ::INPEX::CORE::Keys.constants(false).include?(key)
    end
    return CXJ::INPEX::VOCAB_KEY_UNKNOWN + "_" + key.to_s unless key.kind_of?(Numeric)
    return CXJ::INPEX::CORE::Keys::KEY_STRING[key] unless CXJ::INPEX::CORE::Keys::KEY_STRING[key].nil?
    return CXJ::INPEX::VOCAB_KEY_UNKNOWN + "_" + key.to_s
  end
  
  #--------------------------------------------------------------------------
  # * New: Get Bound Keys
  #--------------------------------------------------------------------------
  def get_bound_keys(key, use_and = false)
    keys = CXJ::INPEX::CORE::Keyboard.get_bound_keys(key.to_sym)
    return CXJ::INPEX::VOCAB_UNDEFINED + "_" + key if keys.nil? || keys.empty?
    str = ""
    keys.each_index do |i|
      str+= ", " if i > 0 && i < keys.size - 1
      str+= " " + (use_and ? CXJ::INPEX::VOCAB_AND : CXJ::INPEX::VOCAB_OR) + " " if keys.size > 1 && i == keys.size - 1
      if keys[i].kind_of?(Array)
        keys[i].each_index do |j|
          str+= " + " if j > 0
          str+= get_key_name(keys[i][j])
        end
      else
        str+= get_key_name(keys[i])
      end
    end
    return str
  end
  
  #--------------------------------------------------------------------------
  # * New: Get Key Icon
  #--------------------------------------------------------------------------
  def get_key_icon(key, text, pos)
    op = nil
    case get_os
    when :win32
      op = CXJ::INPEX::WIN32
    end
    if key.kind_of?(String)
      key = CXJ::INPEX::CORE::Keys.const_get(key.to_sym) if CXJ::INPEX::CORE::Keys.constants(false).include?(key.to_sym)
    end
    if key.kind_of?(Symbol)
      key = CXJ::INPEX::CORE::Keys.const_get(key) if CXJ::INPEX::CORE::Keys.constants(false).include?(key)
    end
    unless key.kind_of?(Numeric)
      text.gsub!(/^/) { get_key_name(key) }
      return
    end
    bitmap = Cache.normal_bitmap(CXJ::INPEX::KEYBOARD_ICONS) unless CXJ::INPEX::KEYBOARD_ICONS.nil? || CXJ::INPEX::KEYBOARD_ICONS.empty?
    w = bitmap.width / 16
    h = CXJ::INPEX::DEFAULT_ICON_HEIGHT
    rect = Rect.new(key % 16 * w, key / 16 * h, w, h)
    CXJ::INPEX::CUSTOM_KEY_ICON.each_pair do |c_key, area|
      if c_key.kind_of?(Symbol)
        c_key = CXJ::INPEX::CORE::Keys.const_get(c_key) if CXJ::INPEX::CORE::Keys.constants(false).include?(c_key)
      end
      next unless c_key.kind_of?(Numeric) || c_key.kind_of?(String)
      if c_key.kind_of?(String) && !op.nil?
        chr = op::MAPVIRTUALKEY.call(key, 2)
        next if chr == 0
        s_key = [chr].pack("C")
        if s_key == c_key
          rect = Rect.new(area[0], area[1], area[2], area[3])
          w = area[2]
          break
        end
      else
        if key == c_key
          rect = Rect.new(area[0], area[1], area[2], area[3])
          w = area[2]
          break
        end
      end
    end
    contents.blt(pos[:x], pos[:y], bitmap, rect)
    pos[:x] += w
  end
  
  #--------------------------------------------------------------------------
  # * New: Get Bound Keys Icons
  #--------------------------------------------------------------------------
  def get_bound_keys_icons(key, use_and = false)
    keys = CXJ::INPEX::CORE::Keyboard.get_bound_keys(key.to_sym)
    return CXJ::INPEX::VOCAB_UNDEFINED + "_" + key if keys.nil? || keys.empty?
    str = ""
    keys.each_index do |i|
      str+= ", " if i > 0 && i < keys.size - 1
      str+= " " + (use_and ? CXJ::INPEX::VOCAB_AND : CXJ::INPEX::VOCAB_OR) + " " if keys.size > 1 && i == keys.size - 1
      if keys[i].kind_of?(Array)
        keys[i].each_index do |j|
          str+= " + " if j > 0
          str+= "\eKEYI[" + keys[i][j].to_s + "]"
        end
      else
        str+= "\eKEYI[" + keys[i].to_s + "]"
      end
    end
    return str
  end
end

if CXJ::INPEX::HOOK_MOUSE_TO_WINDOWS
  #============================================================================
  # ** Window_Selectable
  #----------------------------------------------------------------------------
  #  This window class contains cursor movement and scroll functions.
  #============================================================================

  class Window_Selectable < Window_Base
    #------------------------------------------------------------------------
    # * Frame Update
    #------------------------------------------------------------------------
    alias windows_selectable_update_cxj_inpex_test update
    def update
      windows_selectable_update_cxj_inpex_test
      return unless open? && active
      item_max.times do |i|
        r = Rect.new
        r.set(item_rect(i))
        r.x+= x + padding
        r.y+= y + padding
        if Mouse.x >= r.x && Mouse.x <= r.x + r.width && Mouse.y >= r.y && Mouse.y <= r.y + r.height
          select(i)
          process_ok if ok_enabled? && Mouse.left_trigger?
        end
      end
    end
  end
end

#==============================================================================
# ** Scene_Base
#------------------------------------------------------------------------------
#  This is a super class of all scenes within the game.
#==============================================================================

class Scene_Base
  #--------------------------------------------------------------------------
  # * Alias: Main
  #--------------------------------------------------------------------------
  alias scene_base_main_cxj_inpex main
  def main
    if CXJ::INPEX::DISABLE_F12_RESET
      begin
        scene_base_main_cxj_inpex
      rescue RGSSReset
      end
    else
      scene_base_main_cxj_inpex
    end
  end
  #--------------------------------------------------------------------------
  # * Alias: Update Frame (Basic)
  #--------------------------------------------------------------------------
  alias scene_base_update_basic_cxj_inpex update_basic
  def update_basic
    scene_base_update_basic_cxj_inpex
    if CXJ::INPEX::ENABLE_CUSTOM_POINTER
      Mouse.update if CXJ::INPEX::INCLUDE_CORE
      CXJ::INPEX::Mouse.update if !CXJ::INPEX::INCLUDE_CORE
    end
  end
end                                

Creator: GaryCXJk

Release date: 2013-07-31

Last updated: 2019-07-17

Downloads: 1888

License: DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE