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