Glitchfinder
Staff
By: Glitchfinder
Introduction
Glitchfinder's Gamepad Input Module is an advanced scripting tool that provides full scripted access to to check any and all buttons and axes on an XInput-compatible gamepad. It is useful in the sense that it will not break the default Input module, and because it allows far more use of modern gamepads than you would get from default RMXP or default RMVX. It also does not need to be updated, aside from the default call to Input.update that is used in most cases. It also does not break default scripts or events that use input.
Features
- Check any button on the gamepad
- Doesn't break the default Input module
- Does not break events or scripts that call the default Input module
- Automatically updated by the default Input module
- Allows you to check to see if a button has been released
- Works with all XInput-compatible controllers
- Doesn't crash on F12
Screenshots
Since this script has no visual elements, a screenshot cannot be taken.
Script
Code:
#≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡
# ** Glitchfinder's Gamepad Input Module [RPG Maker XP] [RPG Maker VX]
# Version 1.00
#------------------------------------------------------------------------------
# This script helps scripters to use an XInput-compatible gamepad with their
# games.
#==============================================================================
# * Version History
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# Version 1.00 ------------------------------------------------- (2010-08-20)
# - Initial version
# - Author: Glitchfinder
#==============================================================================
# * Instructions
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# Place this script above Main, and below the default scripts. (I realize this
# is obvious to most, but some people don't get it.)
#
# You must also place Input.dll into the game's main project folder, since
# this script needs it to access the XInput functions it uses.
#
# This module is automatically updated by the default Input module, which
# means that the only time you need to call the update method is in a scene
# that does not update the default Input module.
#
# This module does not break the functionality of the default Input module.
#
# To use this module to check a gamepad button, simply use one of the four
# methods (press?(button[, index]), trigger?(button[, index]),
# repeat?(button[, index]), or release?(button[, index])), where button is the
# constant of the button you want to check. Button may also be used as
# Gamepad::BUTTONNAME. For a list of acceptable button names, look below the
# header, in the section that declares button constants. The methods use index
# to determine which gamepad to check. If no index is given, they will check
# gamepad 0. Index is a value from 0 to 3.
#
# To use this module to check a gamepad trigger or joystick, simply use one of
# the four methods (axis_press?(axis[, index]), axis_trigger?(axis[, index]),
# axis_repeat?(axis[, index]), or axis_release?(axis[, index])), where axis is
# the constant of the axis you want to check. Axis may also be used as
# Gamepad::AXISNAME. For a list of acceptable axis names, look below the
# header, in the section that declares axis constants. The methods use index
# to determine which gamepad to check. If no index is given, they will check
# gamepad 0. Index is a value from 0 to 3.
#
# To use this module to check the value on a gamepad triger or joystick axis,
# use one of the two methods (axis_value(axis[, index]),
# real_axis_value(axis[, index])), where axis is the constant of the axis you
# want to check. Axis may also be used as Gamepad::AXISNAME. For a list of
# acceptable axis names, look below the header, in the section that declares
# axis constants. The methods use index to determine which gamepad to check.
# If no index is given, they will check gamepad 0. Index is a value from 0 to
# 3. The difference between these two methods is that real_axis_value() will
# always return the current value, while axis_value will return 0 if the
# axis falls within its dead zone.
#
# To use this module to cause a gamepad to "rumble", or vibrate, use the
# vibrate() method. Details for that are below, in the method list.
#==============================================================================
# * Method List
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# Gamepad.update
# Updates gamepad input. Calls to this method are not necessary unless the
# default Input module is not being updated.
#
# Gamepad.press?(button[, index])
# Determines whether the gamepad button determined by button is currently
# being pressed. If the button is being pressed, returns true. If not,
# returns false. Uses index to determine the gamepad to check, from 0 to 3.
# The index defaults to 0.
#
# Gamepad.trigger?(button[, index])
# Determines whether the gamepad button determined by button is being
# pressed again. "Pressed again" is seen as time having passed between the
# button being not pressed and being pressed. If the button is being
# pressed, returns true. If not, returns false. Uses index to determine the
# gamepad to check, from 0 to 3. The index defaults to 0.
#
# Gamepad.repeat?(button[, index])
# Determines whether the gamepad button determined by button is being
# pressed again. Unlike trigger?(), this takes into account the repeat input
# of a button being held down continuously. If the button is being pressed,
# returns true. If not, returns false. Uses index to determine the gamepad
# to check, from 0 to 3. The index defaults to 0.
#
# Gamepad.release?(button[, index])
# Determines whether the gamepad button determined by button has just been
# released. If the button has been released, returns true. If not, returns
# false. Uses index to determine the gamepad to check, from 0 to 3. The
# index defaults to 0.
#
# Gamepad.axis_press?(axis[, index])
# Determines whether the gamepad axis determined by axis is currently being
# pressed. If the button is being pressed, returns true. If not, returns
# false. Uses index to determine the gamepad to check, from 0 to 3. The
# index defaults to 0.
#
# Gamepad.axis_trigger?(axis[, index])
# Determines whether the gamepad axis determined by axis is being pressed
# again. "Pressed again" is seen as time having passed between the button
# being not pressed and being pressed. If the button is being pressed,
# returns true. If not, returns false. Uses index to determine the gamepad
# to check, from 0 to 3. The index defaults to 0.
#
# Gamepad.axis_repeat?(axis[, index])
# Determines whether the gamepad axis determined by axis is being pressed
# again. Unlike trigger?(), this takes into account the repeat input of a
# button being held down continuously. If the button is being pressed,
# returns true. If not, returns false. Uses index to determine the gamepad
# to check, from 0 to 3. The index defaults to 0.
#
# Gamepad.axis_release?(axis[, index])
# Determines whether the gamepad axis determined by axis has just been
# released. If the button has been released, returns true. If not, returns
# false. Uses index to determine the gamepad to check, from 0 to 3. The
# index defaults to 0.
#
# Gamepad.axis_value(axis[, index])
# Returns the current value of the gamepad axis determined by axis. The
# gamepad checked is determined by index, from 0 to 3. The value for index
# is 0 if none is provided. If the value for the axis falls within the dead
# zone specified for that axis, then axis_value() will return 0.
#
# Gamepad.real_axis_value(axis[, index])
# Returns the current value of the gamepad axis determined by axis. The
# gamepad checked is determined by index, from 0 to 3. The value for index
# is 0 if none is provided. This method ignores the dead zone for the axis,
# and will always return the current value.
#
# Gamepad.vibrate(left_motor, right_motor, frames[, index])
# Causes the motors to vibrate for the number of frames specified. The
# values for left_motor and right_motor range from 0 to 65535, though the
# motors themselves may differ in function, as they do in an Xbox 360
# controller, resulting in a different "feel" depending on the motor you
# select. Uses index to determine the gamepad to check, from 0 to 3. The
# index defaults to 0.
#==============================================================================
# * Known Issues
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# This script currently has trouble with the vibrate method, which does not
# allow you to set one motor independently of the other. This part of a
# planned update sometime in the future.
#==============================================================================
# * Glitchfinder's Advice
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# This script is meant for people with a medium or advanced level of scripting
# knowledge and ability, or for those using scripts that require this module.
#==============================================================================
# * Contact
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# Glitchfinder, the author of this script, may be contacted through his
# website, found at [url=http://www.glitchkey.com]http://www.glitchkey.com[/url]
#
# You may also find Glitchfinder at [url=http://www.hbgames.org]http://www.hbgames.org[/url]
#==============================================================================
# * Usage
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# This script may be used with the following terms and conditions:
#
# 1. This script is free to use in any noncommercial project. If you wish to
# use this script in a commercial (paid) project, please contact
# Glitchfinder at his website.
# 2. This script may only be hosted at the following domains:
# [url=http://www.glitchkey.com]http://www.glitchkey.com[/url]
# [url=http://www.hbgames.org]http://www.hbgames.org[/url]
# 3. If you wish to host this script elsewhere, please contact Glitchfinder.
# 4. If you wish to translate this script, please contact Glitchfinder. He
# will need the web address that you plan to host the script at, as well
# as the language this script is being translated to.
# 5. This header must remain intact at all times.
# 6. Glitchfinder remains the sole owner of this code. He may modify or
# revoke this license at any time, for any reason.
# 7. Any code derived from code within this script is owned by Glitchfinder,
# and you must have his permission to publish, host, or distribute his
# code.
# 8. This license applies to all code derived from the code within this
# script.
# 9. If you use this script within your project, you must include visible
# credit to Glitchfinder, within reason.
#≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡
#==============================================================================
# ** Gamepad
#------------------------------------------------------------------------------
# This module performs gamepad input processing
#==============================================================================
module Gamepad
#--------------------------------------------------------------------------
# * Declare Button Constants
#--------------------------------------------------------------------------
DPAD_UP = 0 # Directional pad up button
DPAD_DOWN = 1 # Directional pad down button
DPAD_LEFT = 2 # Directional pad left button
DPAD_RIGHT = 3 # Directional pad right button
START = 4 # Start button
BACK = 5 # Back button
LEFT_THUMB = 6 # Left thumb button
RIGHT_THUMB = 7 # Right thumb button
LEFT_SHOULDER = 8 # Left shoulder button
RIGHT_SHOULDER = 9 # Right shoulder button
A = 10 # A button
B = 11 # B button
X = 12 # X Button
Y = 13 # Y Button
#--------------------------------------------------------------------------
# * Declare Axis Constants
#--------------------------------------------------------------------------
LEFT_TRIGGER = 0 # Left trigger axis (0 to 255)
RIGHT_TRIGGER = 1 # Right trigger axis (0 to 255)
LX = 2 # Left thumbstick x axis (-32768 to 32767)
LY = 3 # Left thumbstick y axis (-32768 to 32767)
RX = 4 # Right thumbstick x axis (-32768 to 32767)
RY = 5 # Right thumbstick y axis (-32768 to 32767)
#--------------------------------------------------------------------------
# * Declare Module Variables
#--------------------------------------------------------------------------
begin
# Declare API calls
@gamepadGetCapabilities = Win32API.new('Input.dll',
'GamepadGetCapabilities', 'IIP', 'I')
@gamepadGetDSoundAudioDeviceGuids = Win32API.new('Input.dll',
'GamepadGetDSoundAudioDeviceGuids', 'IPP', 'I')
@gamepadGetState = Win32API.new('Input.dll', 'GamepadGetState', 'IP', 'I')
@gamepadSetState = Win32API.new('Input.dll', 'GamepadSetState', 'IP', 'I')
# Declare blank structures
@capabilities = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0].pack('c2S2c2s4S2')
@gamepad = [0, 0, 0, 0, 0, 0, 0].pack('Sc2s4')
@state = [0, 0, 0, 0, 0, 0, 0, 0].pack('ISc2s4')
@vibrate = [0, 0].pack('n2')
@gamepadGetCapabilities.call(0, 0, @capabilities)
@capabilities.unpack('C2S2C2n6')
# Create blank button array
@buttons = Array.new(14, false)
# Create a blank axis array
@axis = Array.new(6, false)
values = Array.new(6, 0)
zones = [30, 30, 7849, 7849, 8689, 8689]
# Declare controller information storage
@controllers = {}
# Declare default controller information
@controllers.default = {
'Active' => false, # Controller active flag
'Change ID' => 0, # Current state change ID
'Press' => @buttons.clone, # Flags for button press state
'Trigger' => @buttons.clone, # Flags for button trigger state
'Repeat' => @buttons.clone, # Flags for button repeat state
'Release' => @buttons.clone, # Flags for button release state
'Repeat Timer' => Array.new(14, 0), # Timer for button repeat state
'Base Repeat' => 15, # Base time for repeat flag (frames)
'Axes' => Array.new(6, 0), # Axis values
'Axis Dead Zones' => zones.clone, # Dead zone for the axes
'Axis Press' => @axis.clone, # Flags for axis press state
'Axis Trigger' => @axis.clone, # Flags for axis trigger state
'Axis Repeat' => @axis.clone, # Flags for axis repeat state
'Axis Release' => @axis.clone, # Flags for axis release state
'Axis Repeat Timer' => values.clone, # Timer for axis repeat state
'Vibrate State' => [0, 0], # Current vibrate state
'Vibrate Timer' => 0, # Current vibrate timer
'Vibrate Repeat Timer' => 0, # Current rumbe repeat timer
'Vibrate Minimum Timer' => 0 # Min. time before changing vibrate
}
# Iterate through the total number of controllers allowed
for i in 0..3
# Add a new controller to the controller array
@controllers[i] = @controllers.default.clone
end
end
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def self.update
# Iterate through all controllers
for i in 0..3
# Set up a blank state structure
state = @state
# Detect the controller state
success = @gamepadGetState.call(i, state)
# If the state was successfully obtained
if success == 1
# Set the controller to active
@controllers[i]['Active'] = true
# Backup the previous button states
controller = @controllers[i].clone
# Reset the controller button states
@controllers[i]['Press'] = @buttons.clone
@controllers[i]['Trigger'] = @buttons.clone
@controllers[i]['Repeat'] = @buttons.clone
@controllers[i]['Release'] = @buttons.clone
@controllers[i]['Axis Press'] = @axis.clone
@controllers[i]['Axis Trigger'] = @axis.clone
@controllers[i]['Axis Repeat'] = @axis.clone
@controllers[i]['Axis Release'] = @axis.clone
# Unpack the controller state
state = state.unpack('ISC2s4')
# If the controller state has changed
if state[0] != @controllers[i]['Change ID']
# Add the controller button states to the controller state
@controllers[i]['Press'][0] = (state[1] & 0x00000001 == 0x00000001)
@controllers[i]['Press'][1] = (state[1] & 0x00000002 == 0x00000002)
@controllers[i]['Press'][2] = (state[1] & 0x00000004 == 0x00000004)
@controllers[i]['Press'][3] = (state[1] & 0x00000008 == 0x00000008)
@controllers[i]['Press'][4] = (state[1] & 0x00000010 == 0x00000010)
@controllers[i]['Press'][5] = (state[1] & 0x00000020 == 0x00000020)
@controllers[i]['Press'][6] = (state[1] & 0x00000040 == 0x00000040)
@controllers[i]['Press'][7] = (state[1] & 0x00000080 == 0x00000080)
@controllers[i]['Press'][8] = (state[1] & 0x0100 == 0x0100)
@controllers[i]['Press'][9] = (state[1] & 0x0200 == 0x0200)
@controllers[i]['Press'][10] = (state[1] & 0x1000 == 0x1000)
@controllers[i]['Press'][11] = (state[1] & 0x2000 == 0x2000)
@controllers[i]['Press'][12] = (state[1] & 0x4000 == 0x4000)
@controllers[i]['Press'][13] = (state[1] & 0x8000 == 0x8000)
# Add the controller trigger states to the current controller state
@controllers[i]['Axes'][0] = state[2]
@controllers[i]['Axes'][1] = state[3]
# Add the controller thumb coords to the current controller state
@controllers[i]['Axes'][2] = state[4]
@controllers[i]['Axes'][3] = state[5]
@controllers[i]['Axes'][4] = state[6]
@controllers[i]['Axes'][5] = state[7]
end
# Iterate through the buttons
for button in 0...@controllers[i]['Press'].size
# If the button is pressed, and the repeat count is at 0
if ((@controllers[i]['Press'][button] == true) &&
(@controllers[i]['Repeat Timer'][button] <= 0))
# Set the button to repeat
@controllers[i]['Repeat'][button] = true
# Get the base repeat time
repeat_timer = @controllers[i]['Base Repeat']
# Reset the repeat timer
@controllers[i]['Repeat Timer'][button] = repeat_timer
# If the repeat timer is above 0
elsif @controllers[i]['Repeat Timer'][button] > 0
# Cycle down the repeat timer
@controllers[i]['Repeat Timer'][button] -= 1
end
# If the button is pressed, and it wasn't pressed previously
if ((@controllers[i]['Press'][button] == true) &&
(controller['Press'][button] == false))
# Set the button to trigger
@controllers[i]['Trigger'][button] = true
# If the button is not pressed, and it was previously
elsif ((@controllers[i]['Press'][button] == false) &&
(controller['Press'][button] == true))
# Set the button to release
@controllers[i]['Release'][button] = true
end
end
# Iterate through the buttons
for axis in 0...@controllers[i]['Axes'].size
# If the trigger is greater than the dead zone, set it to pressed
if (@controllers[i]['Axes'][axis].abs >
@controllers[i]['Axis Dead Zones'][axis])
# Set the axis to pressed
@controllers[i]['Axis Press'][axis] = true
end
# If the axis is pressed, and the repeat count is at 0
if ((@controllers[i]['Axis Press'][axis] == true) &&
(@controllers[i]['Axis Repeat Timer'][axis] <= 0))
# Set the axis to repeat
@controllers[i]['Axis Repeat'][axis] = true
# Get the base repeat time
repeat_timer = @controllers[i]['Base Repeat']
# Reset the repeat timer
@controllers[i]['Axis Repeat Timer'][axis] = repeat_timer
# If the repeat timer is above 0
elsif @controllers[i]['Axis Repeat Timer'][axis] > 0
# Cycle down the repeat timer
@controllers[i]['Axis Repeat Timer'][axis] -= 1
end
# If the axis is pressed, and it wasn't pressed previously
if ((@controllers[i]['Axis Press'][axis] == true) &&
(controller['Axis Press'][axis] == false))
# Set the axis to trigger
@controllers[i]['Axis Trigger'][axis] = true
# If the axis is not pressed, and it was previously
elsif ((@controllers[i]['Press'][axis] == false) &&
(controller['Axis Press'][axis] == true))
# Set the axis to release
@controllers[i]['Axis Release'][axis] = true
end
end
# If the controller is set to vibrate
if @controllers[i]['Vibrate Timer'] > 0
# If the vibrate repeat timer has reached 0
if @controllers[i]['Vibrate Repeat Timer'] <= 0
# Get the current vibration values
left_motor = @controllers[i]['Vibrate State'][0] - 1
right_motor = @controllers[i]['Vibrate State'][1] - 1
# Correct the motor values
left_motor = 0 if left_motor < 0
right_motor = 0 if right_motor < 0
# Create the vibration state structure
vibrate = [left_motor, right_motor].pack('n2')
# Reset the controller vibrate state
@gamepadSetState.call(i, vibrate)
# Pack the current vibrate state
vibrate_state = @controllers[i]['Vibrate State'].pack('n2')
# Set the vibrate state to the current controller vibrate state
@gamepadSetState.call(i, vibrate_state)
# Reset the vibrate repeat timer
@controllers[i]['Vibrate Repeat Timer'] = Graphics.frame_rate
# If the vibrate repeat timer is greater than 0
else
# Decrement the vibrate repeat timer
@controllers[i]['Vibrate Repeat Timer'] -= 1
end
# Decrement the vibrate timer
@controllers[i]['Vibrate Timer'] -= 1
# If the vibrate timer is 0, and the vibrate state is still set
elsif ((@controllers[i]['Vibrate Timer'] <= 0) &&
(@controllers[i]['Vibrate State'] != [0, 0]))
# Reset the vibrate state
@controllers[i]['Vibrate State'] = [0, 0]
# Set the vibrate repeat timer to 1/3 of a second
@controllers[i]['Vibrate Repeat Timer'] = Graphics.frame_rate / 3
# If the vibrate timer is 0 and the vibrate state is cleared
elsif ((@controllers[i]['Vibrate Timer'] <= 0) &&
(@controllers[i]['Vibrate State'] == [0, 0]))
# If the vibrate repeat timer is running
if @controllers[i]['Vibrate Repeat Timer'] >= 0
# Decrement the vibrate repeat timer
@controllers[i]['Vibrate Repeat Timer'] -= 1
# If the timer has run out
else
# Reset the vibrate repeat timer
@controllers[i]['Vibrate Repeat Timer'] = 0
# Reset the controller vibrate state
@gamepadSetState.call(i, @vibrate)
end
end
# If the controller's minimum vibrate update timer is running
if @controllers[i]['Vibrate Minimum Timer'] > 0
# Decrement the timer
@controllers[i]['Vibrate Minimum Timer'] -= 1
end
# If the controller is not connected, or the state could not be read
elsif success == 2 || success == -1
# Set the controller to inactive
@controllers[i]['Active'] = false
end
end
end
#--------------------------------------------------------------------------
# * Get Button Pressed State
# button : button number
# index : controller number (0 to 3)
#--------------------------------------------------------------------------
def self.press?(button, index = 0)
# Return false if the controller is inactive
return false if @controllers[index]['Active'] == false
# Return button pressed state
return @controllers[index]['Press'][button]
end
#--------------------------------------------------------------------------
# * Get Button Triggered State
# button : button number
# index : controller number (0 to 3)
#--------------------------------------------------------------------------
def self.trigger?(button, index = 0)
# Return false if the controller is inactive
return false if @controllers[index]['Active'] == false
# Return button triggered state
return @controllers[index]['Trigger'][button]
end
#--------------------------------------------------------------------------
# * Get Button Repeated State
# button : button number
# index : controller number (0 to 3)
#--------------------------------------------------------------------------
def self.repeat?(button, index = 0)
# Return false if the controller is inactive
return false if @controllers[index]['Active'] == false
# Return button repeated state
return @controllers[index]['Repeat'][button]
end
#--------------------------------------------------------------------------
# * Get Button Released State
# button : button number
# index : controller number (0 to 3)
#--------------------------------------------------------------------------
def self.release?(button, index = 0)
# Return false if the controller is inactive
return false if @controllers[index]['Active'] == false
# Return button released state
return @controllers[index]['Release'][button]
end
#--------------------------------------------------------------------------
# * Get Axis Pressed State
# axis : axis number
# index : controller number (0 to 3)
#--------------------------------------------------------------------------
def self.axis_press?(axis, index = 0)
# Return false if the controller is inactive
return false if @controllers[index]['Active'] == false
# Return axis pressed state
return @controllers[index]['Axis Press'][axis]
end
#--------------------------------------------------------------------------
# * Get Axis Triggered State
# axis : axis number
# index : controller number (0 to 3)
#--------------------------------------------------------------------------
def self.axis_trigger?(axis, index = 0)
# Return false if the controller is inactive
return false if @controllers[index]['Active'] == false
# Return axis triggered state
return @controllers[index]['Axis Trigger'][axis]
end
#--------------------------------------------------------------------------
# * Get Axis Repeated State
# axis : axis number
# index : controller number (0 to 3)
#--------------------------------------------------------------------------
def self.axis_repeat?(axis, index = 0)
# Return false if the controller is inactive
return false if @controllers[index]['Active'] == false
# Return axis repeated state
return @controllers[index]['Axis Repeat'][axis]
end
#--------------------------------------------------------------------------
# * Get Axis Released State
# axis : axis number
# index : controller number (0 to 3)
#--------------------------------------------------------------------------
def self.axis_release?(axis, index = 0)
# Return false if the controller is inactive
return false if @controllers[index]['Active'] == false
# Return axis released state
return @controllers[index]['Axis Release'][axis]
end
#--------------------------------------------------------------------------
# * Get Axis Value
# axis : axis number
# index : controller number (0 to 3)
#--------------------------------------------------------------------------
def self.axis_value(axis, index = 0)
# Set a temporary variable to the axis value
value = self.real_axis_value(axis, index)
# Return axis value
return value unless value.abs < @controllers[index]['Axis Dead Zones'][axis]
# Return 0 if the axis is within the dead zone
return 0
end
#--------------------------------------------------------------------------
# * Get Real Axis Value
# axis : axis number
# index : controller number (0 to 3)
#--------------------------------------------------------------------------
def self.real_axis_value(axis, index = 0)
# Return the axis value
return @controllers[index]['Axes'][axis]
end
#--------------------------------------------------------------------------
# * Set Controller to Vibrate
# left_motor : left motor value (0 to 65535)
# right_motor : right motor value (0 to 65535)
# frames : number of frames to vibrate
# index : controller number (0 to 3)
#--------------------------------------------------------------------------
def self.vibrate(left_motor, right_motor, frames, index = 0)
# Return false if the vibrate has updated too recently
return false if @controllers[index]['Vibrate Minimum Timer'] > 0
# Set the controller vibrate timer to the number of frames
@controllers[index]['Vibrate Timer'] = frames
# Correct the motor values if out of range
left_motor = 0 if left_motor < 0
left_motor = 65535 if left_motor > 65535
right_motor = 0 if right_motor < 0
right_motor = 65535 if right_motor > 65535
# Set the controller motor values
@controllers[index]['Vibrate State'] = [left_motor.to_i, right_motor.to_i]
# Set the minimum update timer
@controllers[index]['Vibrate Minimum Timer'] = Graphics.frame_rate / 4
# Return true if the vibrate was successfully set
return true
end
#--------------------------------------------------------------------------
# * Initialize Module
#--------------------------------------------------------------------------
begin
# Force an initial update of the gamepad
self.update
end
end
#==============================================================================
# ** Input
#------------------------------------------------------------------------------
# This module performs input processing
#==============================================================================
module Input
# Add class data
class << self
#------------------------------------------------------------------------
# * Alias Methods
#------------------------------------------------------------------------
# If the update method has not been aliased
unless method_defined?(:glitch_gamepad_input_update)
# Alias the update method
alias glitch_gamepad_input_update update
end
#------------------------------------------------------------------------
# * Frame Update
#------------------------------------------------------------------------
def update
# Call original method
glitch_gamepad_input_update
# Update Gamepad module
Gamepad.update
end
end
end
Requirements
This script requires Glitchfinder's Input.dll file to be placed in the game directory.
Instructions
Place this script above Main, and below the default scripts. (I realize this is obvious to most, but some people don't get it.)
You must also place Input.dll into the game's main project folder, since this script needs it to access the XInput functions it uses.
This module is automatically updated by the default Input module, which means that the only time you need to call the update method is in a scene that does not update the default Input module.
This module does not break the functionality of the default Input module.
To use this module to check a gamepad button, simply use one of the four methods (press?(button[, index]), trigger?(button[, index]), repeat?(button[, index]), or release?(button[, index])), where button is the constant of the button you want to check. Button may also be used as Gamepad::BUTTONNAME. For a list of acceptable button names, look below the header, in the section that declares button constants. The methods use index to determine which gamepad to check. If no index is given, they will check gamepad 0. Index is a value from 0 to 3.
To use this module to check a gamepad trigger or joystick, simply use one of the four methods (axis_press?(axis[, index]), axis_trigger?(axis[, index]), axis_repeat?(axis[, index]), or axis_release?(axis[, index])), where axis is the constant of the axis you want to check. Axis may also be used as Gamepad::AXISNAME. For a list of acceptable axis names, look below the header, in the section that declares axis constants. The methods use index to determine which gamepad to check. If no index is given, they will check gamepad 0. Index is a value from 0 to 3.
To use this module to check the value on a gamepad triger or joystick axis, use one of the two methods (axis_value(axis[, index]), real_axis_value(axis[, index])), where axis is the constant of the axis you want to check. Axis may also be used as Gamepad::AXISNAME. For a list of acceptable axis names, look below the header, in the section that declares axis constants. The methods use index to determine which gamepad to check. If no index is given, they will check gamepad 0. Index is a value from 0 to 3. The difference between these two methods is that real_axis_value() will always return the current value, while axis_value will return 0 if the axis falls within its dead zone.
To use this module to cause a gamepad to "rumble", or vibrate, use the vibrate() method. Details for that are below, in the method list.
Method List
Gamepad.update
Updates gamepad input. Calls to this method are not necessary unless the default Input module is not being updated.
Gamepad.press?(button[, index])
Determines whether the gamepad button determined by button is currently being pressed. If the button is being pressed, returns true. If not, returns false. Uses index to determine the gamepad to check, from 0 to 3. The index defaults to 0.
Gamepad.trigger?(button[, index])
Determines whether the gamepad button determined by button is being pressed again. "Pressed again" is seen as time having passed between the button being not pressed and being pressed. If the button is being pressed, returns true. If not, returns false. Uses index to determine the gamepad to check, from 0 to 3. The index defaults to 0.
Gamepad.repeat?(button[, index])
Determines whether the gamepad button determined by button is being pressed again. Unlike trigger?(), this takes into account the repeat input of a button being held down continuously. If the button is being pressed, returns true. If not, returns false. Uses index to determine the gamepad to check, from 0 to 3. The index defaults to 0.
Gamepad.release?(button[, index])
Determines whether the gamepad button determined by button has just been released. If the button has been released, returns true. If not, returns false. Uses index to determine the gamepad to check, from 0 to 3. The index defaults to 0.
Gamepad.axis_press?(axis[, index])
Determines whether the gamepad axis determined by axis is currently being pressed. If the button is being pressed, returns true. If not, returns false. Uses index to determine the gamepad to check, from 0 to 3. The index defaults to 0.
Gamepad.axis_trigger?(axis[, index])
Determines whether the gamepad axis determined by axis is being pressed again. "Pressed again" is seen as time having passed between the button being not pressed and being pressed. If the button is being pressed, returns true. If not, returns false. Uses index to determine the gamepad to check, from 0 to 3. The index defaults to 0.
Gamepad.axis_repeat?(axis[, index])
Determines whether the gamepad axis determined by axis is being pressed again. Unlike trigger?(), this takes into account the repeat input of a button being held down continuously. If the button is being pressed, returns true. If not, returns false. Uses index to determine the gamepad to check, from 0 to 3. The index defaults to 0.
Gamepad.axis_release?(axis[, index])
Determines whether the gamepad axis determined by axis has just been released. If the button has been released, returns true. If not, returns false. Uses index to determine the gamepad to check, from 0 to 3. The index defaults to 0.
Gamepad.axis_value(axis[, index])
Returns the current value of the gamepad axis determined by axis. The gamepad checked is determined by index, from 0 to 3. The value for index is 0 if none is provided. If the value for the axis falls within the dead zone specified for that axis, then axis_value() will return 0.
Gamepad.real_axis_value(axis[, index])
Returns the current value of the gamepad axis determined by axis. The gamepad checked is determined by index, from 0 to 3. The value for index is 0 if none is provided. This method ignores the dead zone for the axis, and will always return the current value.
Gamepad.vibrate(left_motor, right_motor, frames[, index])Causes the motors to vibrate for the number of frames specified. The values for left_motor and right_motor range from 0 to 65535, though the motors themselves may differ in function, as they do in an Xbox 360 controller, resulting in a different "feel" depending on the motor you select. Uses index to determine the gamepad to check, from 0 to 3. The index defaults to 0.
Known Issues
This script currently has trouble with the vibrate method, which does not allow you to set one motor independently of the other. This part of a planned update sometime in the future.
Terms and Conditions
- This script is free to use in any noncommercial project. If you wish to use this script in a commercial (paid) project, please contact Glitchfinder at his website.
- This script may only be hosted at the following domains:
http://www.glitchkey.com
http://www.hbgames.org - If you wish to host this script elsewhere, please contact Glitchfinder.
- If you wish to translate this script, please contact Glitchfinder. He will need the web address that you plan to host the script at, as well as the language this script is being translated to.
- The script header must remain intact at all times.
- Glitchfinder remains the sole owner of this code. He may modify or revoke this license at any time, for any reason.
- Any code derived from code within this script is owned by Glitchfinder, and you must have his permission to publish, host, or distribute his code.
- This license applies to all code derived from the code within this script.
- If you use this script within your project, you must include visible credit to Glitchfinder, within reason.