Holy87

XInput

Dec 20th, 2016
303
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #===============================================================================
  2. # Interfaccia XInput di Holy87
  3. # Difficoltà utente: ★
  4. # Versione 1.03
  5. # Licenza: CC. Chiunque può scaricare, modificare, distribuire e utilizzare
  6. # lo script nei propri progetti, sia amatoriali che commerciali. Vietata
  7. # l'attribuzione impropria.
  8. #
  9. # changelog
  10. # v1.03 => Fix per l'input controller tramite condizione evento
  11. # v1.02 => Inserita compatibilità con sistemi che non supportano DX11
  12. # v1.01 => Bugfix
  13. #===============================================================================
  14. # Questo script vi permette di utilizzare i controller per PC più moderni, come
  15. # il controller dell'XBox 360/One, PS4 e Logitech. Lo script è subito utilizzabile
  16. # per miglirare i controlli del gioco automaticamente (ad esempio, muovervi con
  17. # le frecce direzionali anziché gli analogici e selezionare con il tasto A),
  18. # inoltre offre le seguenti funzionalità:
  19. # ● Supporto agli analogici: potete ottenere il valore preciso degli stick
  20. #   analogici destro e sinistro e dei grilletti dorsali
  21. # ● Supporto fino a 4 controller, per giochi multigiocatore
  22. # ● Vibrazione: possibiltà di gestire la vibrazione sui 2 diversi motori
  23. # ● Livello batteria: potrete riconoscere se il controller è wireless e lo stato
  24. #   della batteria
  25. # ● Rimappamento tasti: è possibile personalizzare i controlli e sovrascrivere
  26. #   quelli di default di RPG Maker
  27. # ● Utilizzo dello script a 3 strati: alto (semplice), medio e basso (raw)
  28. # Questo script scavalca le impostazioni del game pad del gioco (quella
  29. # finestra che compare quando si preme F1)
  30. #===============================================================================
  31. # Istruzioni: inserire lo script sotto Materials, prima del Main.
  32. # RICHIEDE IL MODULO DI SUPPORTO UNIVERSLE.
  33. # Lo script è plug & play, ma ci sono 3 livelli di interazione (opzionali)
  34. #
  35. # ■ LIVELLO ALTO
  36. # Questo livello è adatto a tutti: comprende semplici metodi per gestire solo la
  37. # vibrazione del controller via eventi in modo semplificato.
  38. # Inoltre puoi ottenere le informazioni sugli analogici, grilletti e batteria
  39. # direttamente da delle variabili di gioco che vengono automaticamente
  40. # aggiornate (leggi la parte della configurazione dello script)
  41. # Puoi assegnare invece gli stati in questo modo: dalla finestra
  42. # degli eventi, selezionate il comando chiama script scrivendo queste righe:
  43. # ● start_vibration(forza) per far vibrare il controller (forza è un valore
  44. #   da 0 a 100). Esempio: start_vibration(50) farà vibrare a metà potenza.
  45. # ● start_vibration(forza_sinistra, forza_destra) per far vibrare il controller
  46. #   con forze diverse destra e sinistra
  47. # ● stop_vibration per fermare la vibrazione
  48. # ● controller_vibration(forza_sinistra, forza_destra, tempo) per far vibrare
  49. #   il controller per x frame determinati dal valore tempo.
  50. # ● controller_plugged_in? se messo in una condizione controlla se un pad
  51. #   è presente.
  52. #
  53. # ■ LIVELLO MEDIO
  54. # Questo livello è adatto a chi se ne intende un po' di script (ma non troppo).
  55. # Si basa sul controllo del modulo Input e richiamabile da qualsiasi posizione
  56. # È possibile utilizzare nuovi simboli per i tasti specifici del controller,
  57. # come DPAD_UP, PAD_Y, :PAD_START, PAD_A ecc... (trovi la lista più in basso)
  58. # nei metodi press? trigger? repeat?
  59. # inoltre questi metodi sono stati arricchiti da un nuovo parametro che consente
  60. # di scegliere quale controller verificare. Ad esempio:
  61. # Input.trigger?(:C, 1) verificherà se il tasto C è premuto sul secondo
  62. # controller.
  63. #                                * ATTENZIONE *
  64. # È possibile usare TUTTI i metodi sottostanti aggiungendo un ulteriore parametro
  65. # che specifica quale dei 4 controller scegliere (con valori da 0 a 3, dove 0
  66. # è il giocaore 1 e 3 il giocatore 4). Se non viene specificato, viene
  67. # automaticamente scelto il controller 1.
  68. # Esempio:
  69. # Input.press?(:LEFT) < controllerà se il tasto sinistra è premuto dal gioc. 1
  70. # Input.press?(:LEFT, 1) < controllerà se sinistra è premuto dal giocatore 2
  71. # Input.press?(:DPAD_LEFT) < controllerà se è stato premuto specificamente il
  72. #       pulsante sinistro del pad direzionale del controller del giocatore 1.
  73. #
  74. # ● Input.battery_level: restituisce il livello di batteria del controller.
  75. #   -1: senza batteria; 0: scarico, 1: basso, 2: medio, 3: carico
  76. #
  77. # ● Input.left_analog / Input.right_analog: restituiscono rispettivamente le
  78. #   coordinate X e Y degli analogici sinistro e destro come hash {:x => 0, :y => 0}
  79. #   Esempio:
  80. #   print Input.left_analog[:x] => se l'analogico è inclinato all'estrema destra,
  81. #   restituirà 32767
  82. #   I valori degli analogici variano da -32767 a 32767 sia per coordinata X che
  83. #   Y, questo significa che se l'analogico è dritto segnerà 0.
  84. #
  85. # ● Input.left_trigger / Input.right_trigger: restituiscono i valori dei
  86. #   grilletti sinistro e destro con un valore che varia da 0 (riposo) a 255
  87. #
  88. # ● Input.vibrate(sinistro, destro, frames)
  89. #   Fa vibrare il controller. Bisogna impostare la potenza dei motori sinistro
  90. #   e destro (valore da 0 a 100) e la durata in frames.
  91. # ● Input.start_vibration(forza): fa vibrare il controller in tempo indefinito
  92. # ● Input.stop_vibration: Interrompe la vibrazione del controller
  93. #
  94. # ● Input.user_control: restituisce l'ultimo tipo di controllo usato come:
  95. #   :controller, significa che è stato usato un controller
  96. #   :legacy, significa che il giocatore sta usando la tastira o un vecchio pad
  97. #   compatibile Direct 2D (i vecchi controller senza analogico).
  98. #
  99. # ■ LIVELLO BASSO
  100. # Si tratta della comunicazione al livello più basso del controller, dove ricevi
  101. # i dati RAW del gamepad. Se sai gestire questo livello, probabilmente non hai
  102. # neanche bisogno di questa documentazione in quanto ti basterà guardare le
  103. # descrizioni dei metodi contenute negli script.
  104. # ● XInput.get_state restituisce una classe rappresentante l'istanziazione della
  105. #   struttura dello stato del controller, ossia XInput_State con i seguenti
  106. #   attributi (o nil se non è collegato alcun controller):
  107. #   packet_number restituisce il numero del pacchetto. Il numero differisce
  108. #   dallo stato del controller, se non è cambiato allora lo stato  del
  109. #   controller non è cambiato.
  110. #   game_pad restituisce lo stato dei pulsanti come classe Game_Pad ed ha i
  111. #   seguenti metodi e attributi:
  112. #   buttons restituisce un intero indicante i pulsanti premuti. Si tratta di un
  113. #   intero a 16 bit dove ogni bit rappresenta lo stato di un pulsante. Ad
  114. #   esempio, 2 in binario corrisponde a 0000000000000010, il secondo bit a
  115. #   1 indica che è premuto il tasto giù del D-PAD.
  116. #   Altro esempio: 6 in binario corrisponde a 0000000000000110, il secondo bit
  117. #   è sempre il tasto giù mentre il terzo è il tasto sinistra: il giocatore sta
  118. #   premendo giù e sinistra contemporaneamente. Per evitare di impazzire, puoi
  119. #   utilizzare il metodo 'keymap_state' per ottenere un hash con tutti i pulsanti
  120. #   premuti (le chiavi dell'hash sono i pulsanti, il valore è true se sono
  121. #   normali pulsanti e intero se sono analogici o grilletti rappresentanti il
  122. #       loro valore)
  123. #   Puoi anche usare il metodo button_pressed?(costante) per controllare se
  124. #   un determinato pulsante, rappresentato da una costante definita in basso,
  125. #   è premuto. Alcune costanti: GAMEPAD_LEFT_SHOULDER, GAMEPAD_A, GAMEPAD_BACK
  126. #   Esempio d'uso:
  127. #       XInput.get_state.game_pad.button_pressed?(XInput::PAD_X)
  128. #           restituisce true se il tasto X del controller è premuto
  129. #       XInput.get_state.keymap_state.keys
  130. #           restituisce l'array dei pulsanti premuti, es. [:DPAD_UP, :LEFT_SHOULDER]
  131. #
  132. # ● XInput.get_battery_info: restituisce le informazioni sulla batteria come
  133. #           oggetto XInput_BatteryInformation che ha 2 attributi:
  134. #           battery_type restituisce il tipo di batteria, che può essere
  135. #           BATTERY_TYPE_WIRED se il controller è a cavo (no wireless)
  136. #         BATTERY_TYPE_ALKALINE se alimentato con pile alcaline (le classiche stilo)
  137. #         BATTERY_TYPE_NIMH se alimentato con batteria ricaricabile al litio
  138. #         BATTERY_TYPE_UNKNOWN se la batteria è sconosciuta.
  139. #           Queste costanti rappresentano rispettivamente i valori 1, 2, 3 e 4.
  140. #           battery_level restituisce il livello di carica, che può essere
  141. #           BATTERY_LEVEL_EMPTY se il controller è scarico
  142. #       BATTERY_LEVEL_LOW se la batteria è quasi scarica
  143. #       BATTERY_LEVEL_MEDIUM se la batteria è sul livello medio
  144. #       BATTERY_LEVEL_FULL se la batteria è carica.
  145. #           Queste costanti rappresentano rispettivamente i valori 0, 1, 2 e 3.
  146. #
  147. # ● XInput.set_vibration(forza_sinistra, forza_destra) fa vibrare il controller.
  148. #           Imposta la forza a 0 per farlo smettere. Il valore forza va da 0 a 65535
  149. #
  150. #       Deadzone: Per evitare che imprecisioni sul pad facciano risultare analogici e
  151. #       grilletti come premuti/mossi, è stata predisposta una "zona morta"
  152. #       che impone una quantità minima di spostamento per specificare quando un
  153. #       analogico è spostato rispetto al centro o quando il grilletto è premuto,
  154. #       secondo le linee guida delle DirectX. Puoi modificare queste deadzone a
  155. #   piacimento modificando le costanti LEFT_THUMB_DEADZONE, RIGHT_THUMB_DEADZONE
  156. #   e TRIGGER_THRESHOLD.
  157. #
  158. # ■ IMPOSTAZIONI GIOCATORE
  159. # È possibile definire le impostazioni del controller del giocatore che sono
  160. # memorizzate in $game_system.
  161. # ● xinput_key_set: restituisce l'hash contenenti le impostazioni della mappatura
  162. #   dei pulsanti (inizialmente è come definito in DEFAULT_KEY_SET). Puoi anche
  163. #   personalizzare i pulsanti, ad esempio
  164. #   $game_system.ximput_key_set[:L] = :LEFT_THUMB imposterà la funzione L al tasto
  165. #   L3 del controller.
  166. # ● vibration_enabled? restituisce se la vibrazione è attiva
  167. # ● set_vibration_enabled(valore) imposta la funzione di vibrazione
  168. # ● set_vibration_rate(valore) imposta la potenza della vibrazione con un valore
  169. #   da 0 a 100
  170. # Nota: queste impostazioni non valgono se si usa direttamente XInput, bisogna
  171. #   usare i comandi evento o il modulo Input.
  172. #===============================================================================
  173.  
  174.  
  175. #===============================================================================
  176. # ** XInput_Settings
  177. #-------------------------------------------------------------------------------
  178. # Settings section
  179. #===============================================================================
  180. module XInput_Settings
  181.   DEFAULT_KEY_SET = {
  182.       :UP     => :DPAD_UP,
  183.       :DOWN   => :DPAD_DOWN,
  184.       :LEFT   => :DPAD_LEFT,
  185.       :RIGHT  => :DPAD_RIGHT,
  186.       :START  => :PAD_START,    #not really used by RPG Maker
  187.       :SELECT => :PAD_BACK,     #not used too
  188.       :L      => :LEFT_SHOULDER,
  189.       :R      => :RIGHT_SHOULDER,
  190.       :A      => :PAD_Y,
  191.       :B      => :PAD_B,
  192.       :C      => :PAD_A,
  193.       :X      => :PAD_X,
  194.       :Y      => :LEFT_THUMB,
  195.       :Z      => :RIGHT_THUMB
  196.   }
  197.  
  198.   VOCABS = {
  199.       :DPAD_UP        => 'D Su',
  200.       :DPAD_DOWN      => 'D Giù',
  201.       :DPAD_LEFT      => 'D Sinistra',
  202.       :DPAD_RIGHT     => 'D Destra',
  203.       :PAD_START      => 'Start',
  204.       :PAD_BACK       => 'Indietro/Select',
  205.       :LEFT_SHOULDER  => 'Dorsale sinistro',
  206.       :RIGHT_SHOULDER => 'Dorsale destro',
  207.       :PAD_A          => 'A',
  208.       :PAD_B          => 'B',
  209.       :LEFT_THUMB     => 'Levetta sinistra',
  210.       :PAD_X          => 'X',
  211.       :PAD_Y          => 'Y',
  212.       :RIGHT_THUMB    => 'Levetta destra',
  213.       :R_TRIG         => 'Grilletto destro',
  214.       :L_TRIG         => 'Grilletto sinistro',
  215.       :L_AXIS_X       => 'Analogico sinistro (asse X)',
  216.       :L_AXIS_Y       => 'Analogico sinistro (asse Y)',
  217.       :R_AXIS_X       => 'Analogico destro (asse X)',
  218.       :R_AXIS_Y       => 'Analogico destro (asse Y)',
  219.       :L_AXIS_LEFT      => 'Analogico a sinistra',
  220.       :L_AXIS_RIGHT     => 'Analogico a destra',
  221.       :L_AXIS_UP            => 'Analogico su',
  222.       :L_AXIS_DOWN      => 'Analogico giù',
  223.       :R_AXIS_LEFT      => 'Analogico destro a sinistra',
  224.       :R_AXIS_RIGHT     => 'Analogico destro a destra',
  225.       :R_AXIS_UP            => 'Analogico destro su',
  226.       :R_AXIS_DOWN      => 'Analogico destro giù',
  227.   }
  228.  
  229.   # Sistema di memorizzazione in variabili e switch. Imposta
  230.   # la costante sotto come true per fare in modo che lo stato
  231.   # degli analogici, grilletti e batteria vengano memorizzati
  232.   # in variabili, lascia false se non vuoi usarli.
  233.   VARIABLE_SYSTEM = false
  234.   # Variabili e switch dove leggere lo stato del controller.
  235.   LEFT_TRIGGER_VAR  = 110 # variabile valore grilletto sinistro
  236.   RIGHT_TRIGGER_VAR = 111 # variabile valore grilletto destro
  237.   LEFT_AXIS_X_VAR   = 112 # variabile valore analog. sinistro X
  238.   LEFT_AXIS_Y_VAR   = 113 # variabile valore analog. sinistro Y
  239.   RIGHT_AXIS_X_VAR  = 114 # variabile valore analog. destro X
  240.   RIGHT_AXIS_Y_VAR  = 115 # variabile valore analog. destro Y
  241.   # Livello batteria: -1 se non c'è (perché con filo), 0 scarica
  242.   # 1 bassa, 2 media e 3 piena.
  243.   BATTERY_LEVEL     = 116 # variabile livello della batteria
  244.   # Connessione PAD: questo switch sarà ON se un pad è conesso
  245.   PLUGGED_SW        = 110 # switch di stato di connessione del pad
  246.  
  247.     # Quanto bisogna inclinare l'analogico per fargli riconoscere una direzione
  248.   # in genere questo parametro viene definito zona morta
  249.     ANALOG_DIRECTION_MIN = 16300 # max 32767
  250. end
  251.  
  252. # ---------ATTENZIONE: MODIFICARE SOTTO QUESTO PARAGRAFO COMPORTA SERI RISCHI
  253. #           PER IL CORRETTO FUNZIONAMENTO DELLO SCRIPT! -------------
  254.  
  255.  
  256.  
  257. $imported = {} if $imported == nil
  258. $imported['H87-XInput'] = 1.0
  259. unless $imported['H87_UniversalModule']
  260.   raise('Questo script richiede il modulo universale di Holy87.')
  261. end
  262. #===============================================================================
  263. # ** XInput
  264. #-------------------------------------------------------------------------------
  265. # Core module for controller connection
  266. #===============================================================================
  267. module XInput
  268.   XINPUT_FLAG_GAMEPAD     = 0x01
  269.   #--------------------------------------------------------------------------
  270.   # * Battery constants
  271.   #--------------------------------------------------------------------------
  272.   BATTERY_DEVTYPE_GAMEPAD = 0x00
  273.   BATTERY_TYPE_WIRED      = 0x01
  274.   BATTERY_TYPE_ALKALINE   = 0x02
  275.   BATTERY_TYPE_NIMH       = 0x03
  276.   BATTERY_TYPE_UNKNOWN    = 0xFF
  277.   BATTERY_LEVEL_EMPTY     = 0x00
  278.   BATTERY_LEVEL_LOW       = 0x01
  279.   BATTERY_LEVEL_MEDIUM    = 0x02
  280.   BATTERY_LEVEL_FULL      = 0x03
  281.   #--------------------------------------------------------------------------
  282.   # * Button constants
  283.   #--------------------------------------------------------------------------
  284.   GAMEPAD_DPAD_UP         = 0x0001
  285.   GAMEPAD_DPAD_DOWN       = 0x0002
  286.   GAMEPAD_DPAD_LEFT       = 0x0004
  287.   GAMEPAD_DPAD_RIGHT      = 0x0008
  288.   GAMEPAD_START           = 0x0010
  289.   GAMEPAD_BACK            = 0x0020
  290.   GAMEPAD_LEFT_THUMB      = 0x0040
  291.   GAMEPAD_RIGHT_THUMB     = 0x0080
  292.   GAMEPAD_LEFT_SHOULDER   = 0x0100
  293.   GAMEPAD_RIGHT_SHOULDER  = 0x0200
  294.   GAMEPAD_A               = 0x1000
  295.   GAMEPAD_B               = 0x2000
  296.   GAMEPAD_X               = 0x4000
  297.   GAMEPAD_Y               = 0x8000
  298.   #--------------------------------------------------------------------------
  299.   # * Deadzones
  300.   #--------------------------------------------------------------------------
  301.   LEFT_THUMB_DEADZONE     = 7849
  302.   RIGHT_THUMB_DEADZONE    = 8689
  303.   TRIGGER_THRESHOLD       = 30
  304.   #--------------------------------------------------------------------------
  305.   # * Error states
  306.   #--------------------------------------------------------------------------
  307.   ERROR_SUCCESS           = 0
  308.   ERROR_DEVICE_NOT_CONNECTED = 1167
  309.   DEVICE_NOT_GAMEPAD      = 538976288
  310.   #--------------------------------------------------------------------------
  311.   # * Supported keys
  312.   #--------------------------------------------------------------------------
  313.   GAMEPAD_KEYS = {
  314.       :DPAD_UP            => GAMEPAD_DPAD_UP,
  315.       :DPAD_DOWN          => GAMEPAD_DPAD_DOWN,
  316.       :DPAD_LEFT          => GAMEPAD_DPAD_LEFT,
  317.       :DPAD_RIGHT         => GAMEPAD_DPAD_RIGHT,
  318.       :PAD_START          => GAMEPAD_START,
  319.       :PAD_BACK           => GAMEPAD_BACK,
  320.       :LEFT_THUMB         => GAMEPAD_LEFT_THUMB,
  321.       :RIGHT_THUMB        => GAMEPAD_RIGHT_THUMB,
  322.       :RIGHT_SHOULDER     => GAMEPAD_RIGHT_SHOULDER,
  323.       :LEFT_SHOULDER      => GAMEPAD_LEFT_SHOULDER,
  324.       :PAD_A              => GAMEPAD_A,
  325.       :PAD_B              => GAMEPAD_B,
  326.       :PAD_X              => GAMEPAD_X,
  327.       :PAD_Y              => GAMEPAD_Y}
  328.   #--------------------------------------------------------------------------
  329.   # * Tries to load DirectX11 (Windows 7 or above)
  330.   #--------------------------------------------------------------------------
  331.   def self.try_load_dx11
  332.     begin
  333.       @x_get = Win32API.new('Xinput1_4', 'XInputGetState', 'IP', 'V')
  334.       @x_set = Win32API.new('Xinput1_4', 'XInputSetState', 'IP', 'L')
  335.       @x_cap = Win32API.new('Xinput1_4', 'XInputGetCapabilities','IIP', 'I')
  336.       @x_gbi = Win32API.new('Xinput1_4', 'XInputGetBatteryInformation', 'ILP', 'I')
  337.       @directx = 11
  338.       true
  339.     rescue
  340.       puts('DirectX 11 not installed, can\'t get battery info')
  341.       false
  342.     end
  343.   end
  344.   #--------------------------------------------------------------------------
  345.   # * Tries to load DirectX10 (Windows Vista or above)
  346.   #--------------------------------------------------------------------------
  347.   def self.try_load_dx10
  348.     begin
  349.       @x_get = Win32API.new('XINPUT9_1_0', 'XInputGetState', 'IP', 'V')
  350.       @x_set = Win32API.new('XINPUT9_1_0', 'XInputSetState', 'IP', 'L')
  351.       @x_cap = Win32API.new('XINPUT9_1_0', 'XInputGetCapabilities','IIP', 'I')
  352.       @directx = 10
  353.       true
  354.     rescue
  355.       puts('DirectX10 not installed, can\'t use XInput module.')
  356.       false
  357.     end
  358.   end
  359.   #--------------------------------------------------------------------------
  360.   # * Simply does nothing
  361.   #--------------------------------------------------------------------------
  362.   def self.try_load_dx09; @directx = 9; end
  363.   #--------------------------------------------------------------------------
  364.   # * Loads the proper library
  365.   #--------------------------------------------------------------------------
  366.   def self.load_libraries
  367.     return if try_load_dx11
  368.     return if try_load_dx10
  369.     try_load_dx09
  370.   end
  371.   #--------------------------------------------------------------------------
  372.   # * Gets the controller keys state
  373.   # @param [Index] index
  374.   # @return [XInput_State]
  375.   #--------------------------------------------------------------------------
  376.   def self.get_state(index = 0)
  377.     return nil if @x_get.nil?
  378.     buffer = ' ' * 16
  379.     error = @x_get.call(index, buffer)
  380.     error == ERROR_SUCCESS ? XInput_State.new(buffer) : nil
  381.   end
  382.   #--------------------------------------------------------------------------
  383.   # * Gets the hash containing all the pressed keys
  384.   # @param [Integer] index
  385.   # @return [Hash]
  386.   #--------------------------------------------------------------------------
  387.   def self.get_key_state(index = 0)
  388.     state = get_state(index)
  389.     state != nil ? state.game_pad.keymap_state : {}
  390.   end
  391.   #--------------------------------------------------------------------------
  392.   # * Sets the controller vibration
  393.   # @param [Integer] l_strenght     value between 0 and 65535
  394.   # @param [Integer] r_strenght     value between 0 and 65535
  395.   # @param [Integer] index          controller index
  396.   # @return [Integer]               ERROR_SUCCESS/ERROR_DEVICE_NOT_CONNECTED
  397.   #--------------------------------------------------------------------------
  398.   def self.set_vibration(l_strenght, r_strenght, index = 0)
  399.     return ERROR_DEVICE_NOT_CONNECTED if @x_set.nil?
  400.     l_strenght = [l_strenght, 65535].min
  401.     r_strenght = [r_strenght, 65535].min
  402.     @x_set.call(index, [l_strenght, r_strenght].pack('SS'))
  403.   end
  404.   #--------------------------------------------------------------------------
  405.   # * Returns if the controller is plugged in
  406.   # @param [Integer] controller_index
  407.   #--------------------------------------------------------------------------
  408.   def self.controller_plugged_in?(controller_index = 0)
  409.     get_state(controller_index) != nil
  410.   end
  411.   #--------------------------------------------------------------------------
  412.   # * Gets the battery information
  413.   # @param [Integer] index
  414.   # @return [XInput_BatteryInformation]
  415.   #--------------------------------------------------------------------------
  416.   def self.get_battery_info(index = 0)
  417.     return if @x_gbi.nil?
  418.     buffer = ' ' * 8
  419.     result = @x_gbi.call(index, BATTERY_DEVTYPE_GAMEPAD, buffer)
  420.     result == ERROR_SUCCESS ? XInput_BatteryInformation.new(buffer) : nil
  421.   end
  422.     #--------------------------------------------------------------------------
  423.   # * Returns the default key set
  424.   #--------------------------------------------------------------------------
  425.     def self.default_key_set; XInput_Settings::DEFAULT_KEY_SET.clone; end
  426.   #--------------------------------------------------------------------------
  427.   # * Returns the controller capabilities
  428.   # @param [XInput_Capability] index
  429.   #--------------------------------------------------------------------------
  430.   def self.controller_capabilities(index = 0)
  431.     return if @x_cap.nil?
  432.     buffer = ' ' * 18
  433.     @x_cap.call(index, XINPUT_FLAG_GAMEPAD, buffer)
  434.     XInput_Capability.new(buffer)
  435.   end
  436.   #--------------------------------------------------------------------------
  437.   # * Checks if in your PC is installed DX10 or above
  438.   #--------------------------------------------------------------------------
  439.   def self.directx_capable?; @directx >= 10; end
  440. end # xinput
  441.  
  442. #===============================================================================
  443. # ** Vocab
  444. #-------------------------------------------------------------------------------
  445. # Gamepad keys vocabs
  446. #===============================================================================
  447. module Vocab
  448.   #--------------------------------------------------------------------------
  449.   # * Gamepad key vocab
  450.   # @param [Symbol] key
  451.   #--------------------------------------------------------------------------
  452.   def self.gamepad_key(key)
  453.     XInput_Settings::VOCABS[key]
  454.   end
  455. end # vocab
  456.  
  457. #===============================================================================
  458. # ** XInput_State
  459. #-------------------------------------------------------------------------------
  460. # Controller state
  461. #===============================================================================
  462. class XInput_State
  463.   attr_reader :packet_number
  464.   #--------------------------------------------------------------------------
  465.   # * Object initializazion
  466.   # @param [String] input_data
  467.   #--------------------------------------------------------------------------
  468.   def initialize(input_data)
  469.     inp = input_data.unpack('LSCCssss')
  470.     @packet_number = inp[0]
  471.         keys = inp[1]
  472.         tl = inp[2]; tr = inp[3]
  473.     lx = inp[4]; ly = inp[5]
  474.     rx = inp[6]; ry = inp[7]
  475.     @game_pad = Game_Pad.new(keys, tl, tr, lx.to_i, ly.to_i, rx.to_i, ry.to_i)
  476.   end
  477.   #--------------------------------------------------------------------------
  478.   # * Returns the game pad status
  479.   # @return [Game_Pad]
  480.   #--------------------------------------------------------------------------
  481.   def game_pad; @game_pad; end
  482. end
  483.  
  484. #===============================================================================
  485. # ** XInput_BatteryInformation
  486. #-------------------------------------------------------------------------------
  487. # Battery information container
  488. #===============================================================================
  489. class XInput_BatteryInformation
  490.   attr_reader :battery_type   # 1: Wired, 2: Alkhaline, 3: Nimh, 4: Unknown
  491.   attr_reader :battery_level  # 0: Empy,  1: Low, 2: Medium, 3: High
  492.   #--------------------------------------------------------------------------
  493.   # * Object initialization
  494.   # @param [String] buffer
  495.   #--------------------------------------------------------------------------
  496.   def initialize(buffer)
  497.     result = buffer.unpack('CC')
  498.     @battery_type = result[0]
  499.     @battery_level = result[1]
  500.   end
  501.   #--------------------------------------------------------------------------
  502.   # * Gets if battery level is low
  503.   #--------------------------------------------------------------------------
  504.   def battery_low?
  505.     wireless? && @battery_level <= XInput::BATTERY_LEVEL_LOW
  506.   end
  507.   #--------------------------------------------------------------------------
  508.   # * Gets if the controller is wireless
  509.   #--------------------------------------------------------------------------
  510.   def wireless?
  511.     @battery_type == XInput::BATTERY_TYPE_ALKALINE ||
  512.       @battery_type == XInput::BATTERY_TYPE_NIMH
  513.   end
  514.   #--------------------------------------------------------------------------
  515.   # * Gets if the controller is wired
  516.   #--------------------------------------------------------------------------
  517.   def wired?
  518.     @battery_type == XInput::BATTERY_TYPE_WIRED
  519.   end
  520.   #--------------------------------------------------------------------------
  521.   # * To String (for screen printable)
  522.   #--------------------------------------------------------------------------
  523.   def to_s
  524.     case @battery_type
  525.       when XInput::BATTERY_TYPE_ALKALINE
  526.         type = 'Alkaline'
  527.       when XInput::BATTERY_TYPE_WIRED
  528.         type = 'Wired'
  529.       when XInput::BATTERY_TYPE_NIMH
  530.         type = 'Nimh'
  531.       else
  532.         type = 'Unknown'
  533.     end
  534.     case @battery_level
  535.       when XInput::BATTERY_LEVEL_EMPTY
  536.         level = 'Empty'
  537.       when XInput::BATTERY_LEVEL_LOW
  538.         level = 'Low'
  539.       when XInput::BATTERY_LEVEL_MEDIUM
  540.         level = 'Medium'
  541.       when XInput::BATTERY_LEVEL_FULL
  542.         level = 'Full'
  543.       else
  544.         level = 'Unknown'
  545.     end
  546.     sprintf('Type: %s, Level: %s', type, level)
  547.   end
  548. end
  549.  
  550. #===============================================================================
  551. # ** XInput_Capability
  552. #-------------------------------------------------------------------------------
  553. # Contains informations about the connected controller.
  554. #===============================================================================
  555. class XInput_Capability
  556.   # @attr[Integer] type
  557.   # @attr[Integer] sub_yupe
  558.   # @attr[Integer] flags
  559.   attr_reader :type # XINPUT_DEVTYPE_GAMEPAD
  560.   attr_reader :sub_type
  561.   attr_reader :flags
  562.   #--------------------------------------------------------------------------
  563.   # * Object initializazion
  564.   # @param [String] buffer
  565.   #--------------------------------------------------------------------------
  566.   def initialize(buffer)
  567.     data = buffer.unpack('CCSSCCssssCC')
  568.     @type = data[0]
  569.     @sub_type = data[1]
  570.     @flags = data[2]
  571.     @game_pad = Game_Pad.new(data[3], data[4], data[5], data[6], data[7], data[8], data[9])
  572.     @vibration = XInput_Vibration.new(data[10], data[11])
  573.   end
  574.   #--------------------------------------------------------------------------
  575.   # * Returns the game pad status
  576.   # @return [Game_Pad]
  577.   #--------------------------------------------------------------------------
  578.   def game_pad; @game_pad; end
  579.   #--------------------------------------------------------------------------
  580.   # * Returns the game pad status
  581.   # @return [XInput_Vibration]
  582.   #--------------------------------------------------------------------------
  583.   def vibration; @vibration; end
  584. end #xinput_capability
  585.  
  586. #===============================================================================
  587. # ** Game_Pad
  588. #-------------------------------------------------------------------------------
  589. # Gamepad keys structure
  590. #===============================================================================
  591. class Game_Pad
  592.   # @attr[Integer] buttons
  593.   # @attr[Integer] left_trigger
  594.   # @attr[Integer] right_trigger
  595.   # @attr[Integer] thumb_lx
  596.   # @attr[Integer] thumb_ly
  597.   # @attr[Integer] thumb_rx
  598.   # @attr[Integer] thumb_ry
  599.   attr_reader :buttons        # buttons pressed in integer value
  600.   attr_reader :left_trigger   # LT key, value from 0 to 255
  601.   attr_reader :right_trigger  # RT key, value from 0 to 255
  602.   attr_reader :thumb_lx       # left analog X, value between -32768 and 32767
  603.   attr_reader :thumb_ly       # left analog Y, value between -32768 and 32767
  604.   attr_reader :thumb_rx       # right analog X, value between -32768 and 32767
  605.   attr_reader :thumb_ry       # right analog Y, value between -32768 and 32767
  606.   #--------------------------------------------------------------------------
  607.   # * Object initialization
  608.   # @param [String] buttons     integer with buttons pressed
  609.   # @param [Integer] lt         left trigger value (0 to 255)
  610.   # @param [Integer] rt         right trigger value (0 to 255)
  611.   # @param [Integer] lx         left stick x axis (-32768 to 32767)
  612.   # @param [Integer] ly         left stick y axis (-32768 to 32767)
  613.   # @param [Integer] rx         right stick x axis (-32768 to 32767)
  614.   # @param [Integer] ry         right stick y axis (-32768 to 32767)
  615.   #--------------------------------------------------------------------------
  616.   def initialize(buttons, lt, rt, lx, ly, rx, ry)
  617.     @buttons = buttons
  618.     @left_trigger = adjust_trigger(lt, XInput::TRIGGER_THRESHOLD)
  619.     @right_trigger = adjust_trigger(rt, XInput::TRIGGER_THRESHOLD)
  620.     left = normalize(lx, ly, XInput::LEFT_THUMB_DEADZONE)
  621.     right = normalize(rx, ry, XInput::RIGHT_THUMB_DEADZONE)
  622.     @thumb_lx = (lx * left).to_i
  623.     @thumb_ly = (ly * -left).to_i
  624.     @thumb_rx = (rx * right).to_i
  625.     @thumb_ry = (ry * -right).to_i
  626.   end
  627.   #--------------------------------------------------------------------------
  628.   # * Returns true if the pad button is pressed
  629.   # @param [Integer] button_const (integer value)
  630.   # @return [Boolean]
  631.   #--------------------------------------------------------------------------
  632.   def button_pressed?(button_const)
  633.     @buttons | button_const == @buttons # or for bit comparator
  634.   end
  635.   #--------------------------------------------------------------------------
  636.   # * Gets a keymap state with (true/false) if buttons, values if analog.
  637.   # @return [Hash]
  638.   #--------------------------------------------------------------------------
  639.   def keymap_state
  640.     if @keymap_state.nil?
  641.       @keymap_state = {}
  642.       XInput::GAMEPAD_KEYS.each_pair {|key, value|
  643.         @keymap_state[key] = true if button_pressed?(value)
  644.       }
  645.       @keymap_state[:L_AXIS_X] = @thumb_lx if @thumb_lx != 0
  646.       @keymap_state[:L_AXIS_Y] = @thumb_ly if @thumb_ly != 0
  647.       @keymap_state[:R_AXIS_X] = @thumb_rx if @thumb_rx != 0
  648.       @keymap_state[:R_AXIS_Y] = @thumb_ry if @thumb_ry != 0
  649.       @keymap_state[:R_TRIG]   = @right_trigger if @right_trigger > 0
  650.       @keymap_state[:L_TRIG]   = @left_trigger if @left_trigger > 0
  651.             min = XInput_Settings::ANALOG_DIRECTION_MIN
  652.             if @keymap_state[:L_AXIS_X]
  653.                 @keymap_state[:L_AXIS_RIGHT] = true if @keymap_state[:L_AXIS_X] > min
  654.                 @keymap_state[:L_AXIS_LEFT] = true if @keymap_state[:L_AXIS_X] < -min
  655.             end
  656.             if @keymap_state[:L_AXIS_Y]
  657.                 @keymap_state[:L_AXIS_DOWN] = true if @keymap_state[:L_AXIS_Y] > min
  658.                 @keymap_state[:L_AXIS_UP] = true if @keymap_state[:L_AXIS_Y] < -min
  659.             end
  660.             if @keymap_state[:R_AXIS_X]
  661.                 @keymap_state[:R_AXIS_RIGHT] = true if @keymap_state[:R_AXIS_X] > min
  662.                 @keymap_state[:R_AXIS_LEFT] = true if @keymap_state[:R_AXIS_X] < -min
  663.             end
  664.             if @keymap_state[:R_AXIS_Y]
  665.                 @keymap_state[:R_AXIS_DOWN] = true if @keymap_state[:R_AXIS_Y] > min
  666.                 @keymap_state[:R_AXIS_UP] = true if @keymap_state[:R_AXIS_Y] < -min
  667.             end
  668.     end
  669.     @keymap_state
  670.   end
  671.   #--------------------------------------------------------------------------
  672.   # * Checks if the analog stick is over the dead zone
  673.   # @param [Integer] x
  674.   # @param [Integer] y
  675.   # @param [Integer] deadzone
  676.   #--------------------------------------------------------------------------
  677.   def normalize(x, y, deadzone)
  678.     magnitude = Math.sqrt(x*x + y*y)
  679.     if magnitude > deadzone
  680.       magnitude = [magnitude, 32767].min
  681.       magnitude -= deadzone
  682.       normalized_magnitude = magnitude / (32767 - deadzone)
  683.     else
  684.       normalized_magnitude = 0
  685.     end
  686.     normalized_magnitude
  687.   end
  688.   #--------------------------------------------------------------------------
  689.   # * Checks if the trigger is over the dead zone
  690.   # @param [Integer] value
  691.   # @param [Integer] threshold
  692.   #--------------------------------------------------------------------------
  693.   def adjust_trigger(value, threshold)
  694.     return 0 if value <= threshold
  695.     magnitude = 255 / (255 - threshold)
  696.     ((value - threshold) * magnitude).to_i
  697.   end
  698.   #--------------------------------------------------------------------------
  699.   # * To string
  700.   # @return [String]
  701.   #--------------------------------------------------------------------------
  702.   def to_s; keymap_state.to_s; end
  703. end
  704.  
  705. #===============================================================================
  706. # ** XInput_Vibration
  707. #-------------------------------------------------------------------------------
  708. # Contains informations about the controller motors. If left and right values
  709. # are 0, the controller doesn not support vibration.
  710. #===============================================================================
  711. class XInput_Vibration
  712.   attr_reader :left_motor_speed   # left motor speed. 0 to 65535
  713.   attr_reader :right_motor_speed  # right motor speed. 0 to 65535
  714.   #--------------------------------------------------------------------------
  715.   # * Object initialization
  716.   # @param [Integer] left_m
  717.   # @param [Integer] right_m
  718.   #--------------------------------------------------------------------------
  719.   def initialize(left_m, right_m)
  720.     @left_motor_speed = left_m
  721.     @right_motor_speed = right_m
  722.   end
  723. end
  724.  
  725. #===============================================================================
  726. # ** Game_System
  727. #-------------------------------------------------------------------------------
  728. # Controller settings container
  729. #===============================================================================
  730. class Game_System
  731.   #--------------------------------------------------------------------------
  732.   # * Custom key set
  733.   # @param [Integer] controller_index
  734.   # @return [Hash]
  735.   #--------------------------------------------------------------------------
  736.   def xinput_key_set(controller_index = 0)
  737.     @xinput_key_set ||= create_default_key_set
  738.     @xinput_key_set[controller_index]
  739.   end
  740.   #--------------------------------------------------------------------------
  741.   # * Checks if the vibration is enabled
  742.   # @param [Integer] controller_index
  743.   #--------------------------------------------------------------------------
  744.   def vibration_enabled?(controller_index = 0)
  745.     @xinput_vibration ||= {}
  746.     @xinput_vibration[controller_index] ||= true
  747.   end
  748.   #--------------------------------------------------------------------------
  749.   # * Sets the vibration enable option
  750.   # @param [Boolean] value
  751.   # @param [Integer] controller_index
  752.   #--------------------------------------------------------------------------
  753.   def set_vibration_enabled(value, controller_index = 0)
  754.     @xinput_vibration ||= {}
  755.     @xinput_vibration[controller_index] = value
  756.   end
  757.   #--------------------------------------------------------------------------
  758.   # * Keys conversion (for user key settings)
  759.   # @param [Symbol] original_key
  760.   # @param [Integer] controller_index
  761.   #--------------------------------------------------------------------------
  762.   def adjust_buttons(original_key, controller_index = 0)
  763.     if xinput_key_set(controller_index).include?(original_key)
  764.       xinput_key_set(controller_index)[original_key]
  765.     else
  766.       original_key
  767.     end
  768.   end
  769.   #--------------------------------------------------------------------------
  770.   # * Default key set initialization (from script settings)
  771.   #--------------------------------------------------------------------------
  772.   def create_default_key_set
  773.     @xinput_key_set = {}
  774.     (0..3).each {|pad_index|
  775.       @xinput_key_set[pad_index] = XInput.default_key_set
  776.     }
  777.     @xinput_key_set
  778.   end
  779.   #--------------------------------------------------------------------------
  780.   # * gets the vibration power settings
  781.   #--------------------------------------------------------------------------
  782.   def vibration_rate(pad_index = 0)
  783.     @vibration_rate ||= [100] * 4
  784.     @vibration_rate[pad_index]
  785.   end
  786.   #--------------------------------------------------------------------------
  787.   # * Sets the vibration power setting
  788.   # @param [Integer] rate
  789.   # @param [Integer] pad_index
  790.   #--------------------------------------------------------------------------
  791.   def set_vibration_rate(rate, pad_index = 0)
  792.     @vibration_rate ||= [100] * 4
  793.     @vibration_rate[pad_index] = [[0, rate].max, 100].min
  794.   end
  795.     #--------------------------------------------------------------------------
  796.   # * Gets the vibration power
  797.   # @param [Integer] pad_index
  798.   # @return [Integer]
  799.   #--------------------------------------------------------------------------
  800.   def calc_vibration_power(pad_index = 0)
  801.     65535 * vibration_rate(pad_index) / 100
  802.     end
  803. end # game_system
  804.  
  805. #===============================================================================
  806. # ** Input
  807. #-------------------------------------------------------------------------------
  808. # Input redefinition
  809. #===============================================================================
  810. module Input
  811.   # input normalization from conditional branch fix
  812.   NORMALIZER = {2 => :DOWN, 4 => :LEFT, 6 => :RIGHT, 8 => :UP, 11 => :A,
  813.   12 => :B, 13 => :C, 14 => :X, 15 => :Y, 16 => :Z, 17 => :L, 18 => :R}
  814.   #--------------------------------------------------------------------------
  815.   # * Variable initialization
  816.   #--------------------------------------------------------------------------
  817.   @key_timing = {0 => {}, 1 => {}, 2 => {}, 3 => {}}
  818.   @key_state = {0 => {}, 1 => {}, 2 => {}, 3 => {}}
  819.   @controller_plugged = [false] * 4
  820.   @vibration_state = [0] * 4
  821.   #---------------- ----------------------------------------------------------
  822.   # * Method aliases
  823.   #--------------------------------------------------------------------------
  824.   # noinspection ALL
  825.   class << self
  826.     alias h87controller_update update
  827.     alias legacy_trigger? trigger?
  828.     alias legacy_press? press?
  829.     alias legacy_repeat? repeat?
  830.   end
  831.   #--------------------------------------------------------------------------
  832.   # * Update process
  833.   #--------------------------------------------------------------------------
  834.   def self.update
  835.     h87controller_update
  836.     update_xinput
  837.   end
  838.   #--------------------------------------------------------------------------
  839.   # * Game pad updating process
  840.   #--------------------------------------------------------------------------
  841.   def self.update_xinput
  842.     update_keystate
  843.     update_controller_used
  844.     update_vibration
  845.   end
  846.   #--------------------------------------------------------------------------
  847.   # * Returns the controller connection state
  848.   # @param [Integer] pad_index
  849.   # @return [Boolean]
  850.   #--------------------------------------------------------------------------
  851.   def self.controller_connected?(pad_index = 0)
  852.     @controller_plugged[pad_index]
  853.   end
  854.   #--------------------------------------------------------------------------
  855.   # * Keydown
  856.   #--------------------------------------------------------------------------
  857.   def self.trigger?(key, controller_index = 0)
  858.     if controller_used?(controller_index)
  859.       @last_input_used = :controller
  860.       real_key = adjust_button(key, controller_index)
  861.       timing = @key_timing[controller_index][real_key]
  862.       timing == 0
  863.     else
  864.       result = legacy_trigger?(key)
  865.       @last_input_used = :legacy if result
  866.       result
  867.     end
  868.   end
  869.   #--------------------------------------------------------------------------
  870.   # * Key pressed
  871.   #--------------------------------------------------------------------------
  872.   def self.press?(key, pad_index = 0)
  873.     if controller_used?(pad_index)
  874.       key = normalize_input(key) if key.is_a?(Integer)
  875.       @last_input_used = :controller
  876.       @key_state[pad_index].include?(adjust_button(key, pad_index))
  877.     else
  878.       result = legacy_press?(key)
  879.       @last_input_used = :legacy if result
  880.       result
  881.     end
  882.   end
  883.   #--------------------------------------------------------------------------
  884.   # * Cursor moving
  885.   #--------------------------------------------------------------------------
  886.   def self.repeat?(key, controller_index = 0)
  887.     if controller_used?(controller_index)
  888.       @last_input_used = :controller
  889.       real_key = adjust_button(key, controller_index)
  890.       timing = @key_timing[controller_index][real_key]
  891.       timing != nil and (timing == 0 or timing == 30 or timing > 30 and timing % 5 == 0)
  892.     else
  893.       result = legacy_repeat?(key)
  894.       @last_input_used = :legacy if result
  895.       result
  896.     end
  897.   end
  898.   #--------------------------------------------------------------------------
  899.   # * Normalizes input from a conditional branch code
  900.   #--------------------------------------------------------------------------
  901.   def self.normalize_input(key)
  902.     NORMALIZER[key]
  903.   end
  904.   #--------------------------------------------------------------------------
  905.   # * Gets the proper controller key
  906.   #--------------------------------------------------------------------------
  907.   def self.adjust_button(key, pad_index = 0)
  908.     if $game_system
  909.       $game_system.adjust_buttons(key, pad_index)
  910.     elsif XInput_Settings::DEFAULT_KEY_SET[key]
  911.       XInput_Settings::DEFAULT_KEY_SET[key]
  912.     else
  913.       key
  914.     end
  915.   end
  916.   #--------------------------------------------------------------------------
  917.   # * Direction pressed
  918.   #--------------------------------------------------------------------------
  919.   def self.dir4(controller_index = 0)
  920.     return 2 if press?(:DOWN, controller_index)
  921.     return 4 if press?(:LEFT, controller_index)
  922.     return 6 if press?(:RIGHT, controller_index)
  923.     return 8 if press?(:UP, controller_index)
  924.     0
  925.   end
  926.   #--------------------------------------------------------------------------
  927.   # * Eight directions pressed
  928.   #--------------------------------------------------------------------------
  929.   def self.dir8(controller_index = 0)
  930.     return 1 if press?(:DOWN, controller_index) and press?(:LEFT, controller_index)
  931.     return 3 if press?(:DOWN, controller_index) and press?(:RIGHT, controller_index)
  932.     return 7 if press?(:UP, controller_index)   and press?(:LEFT, controller_index)
  933.     return 9 if press?(:UP, controller_index)   and press?(:RIGHT, controller_index)
  934.     dir4(controller_index)
  935.   end
  936.   #--------------------------------------------------------------------------
  937.   # * Checks if the controller is being used
  938.   #--------------------------------------------------------------------------
  939.   def self.controller_used?(controller_index = 0)
  940.     @controller_plugged[controller_index] && @controller_used[controller_index]
  941.   end
  942.   #--------------------------------------------------------------------------
  943.   # * Vibration update process
  944.   #--------------------------------------------------------------------------
  945.   def self.update_vibration
  946.     (0..3).each {|pad_index|
  947.       if @vibration_state[pad_index] > 0
  948.         @vibration_state[pad_index] -= 1
  949.         XInput.set_vibration(0, 0, pad_index) if @vibration_state[pad_index] == 0
  950.       end
  951.     }
  952.   end
  953.   #--------------------------------------------------------------------------
  954.   # * Manually stops the vibration
  955.   #--------------------------------------------------------------------------
  956.   def self.stop_vibration(controller_index = 0)
  957.     @vibration_state[controller_index] = 0
  958.   end
  959.   #--------------------------------------------------------------------------
  960.   # * Starts the vibration with no time limit
  961.   #--------------------------------------------------------------------------
  962.   def self.start_vibration(l_strenght, r_strenght = l_strenght, controller_index = 0)
  963.     l_strenght = [[0, l_strenght].max, 100].min * adjust_vibration(controller_index) / 100
  964.     r_strenght = [[0, r_strenght].max, 100].min * adjust_vibration(controller_index) / 100
  965.     @vibration_state[controller_index] = -1
  966.     XInput.set_vibration(l_strenght, r_strenght, controller_index)
  967.   end
  968.   #--------------------------------------------------------------------------
  969.   # * Pad keys update process
  970.   #--------------------------------------------------------------------------
  971.   def self.update_keystate
  972.     @old_key_state = @key_state
  973.     (0..3).each {|pad_index|
  974.       update_keys(pad_index)
  975.       update_key_variables if pad_index == 0
  976.     }
  977.   end
  978.   #--------------------------------------------------------------------------
  979.   # * Single pad update process
  980.   #--------------------------------------------------------------------------
  981.   def self.update_keys(controller_index = 0)
  982.     state = XInput.get_state(controller_index)
  983.     if state && state.packet_number != XInput::DEVICE_NOT_GAMEPAD
  984.       @controller_plugged[controller_index] = true
  985.       @key_state[controller_index] = state.game_pad.keymap_state
  986.       @key_timing[controller_index].each_key { |key|
  987.         @key_timing[controller_index][key] = nil unless @key_state[controller_index].keys.include?(key)
  988.       }
  989.       @key_state[controller_index].each_key {|key|
  990.         if @old_key_state[controller_index].keys.include?(key)
  991.           @key_timing[controller_index][key] ||= -1
  992.           @key_timing[controller_index][key] += 1
  993.         else
  994.           @key_timing[controller_index][key] = 0
  995.         end
  996.       }
  997.     else
  998.       @controller_plugged[controller_index] = false
  999.     end
  1000.   end
  1001.   #--------------------------------------------------------------------------
  1002.   # * Updates the game variables
  1003.   #--------------------------------------------------------------------------
  1004.   def self.update_key_variables
  1005.     return unless XInput_Settings::VARIABLE_SYSTEM
  1006.     return unless $game_variables
  1007.     $game_switches[XInput_Settings::PLUGGED_SW] = controller_connected?
  1008.     return unless controller_connected?
  1009.     $game_variables[XInput_Settings::LEFT_TRIGGER_VAR] = left_trigger
  1010.     $game_variables[XInput_Settings::RIGHT_TRIGGER_VAR] = right_trigger
  1011.     $game_variables[XInput_Settings::LEFT_AXIS_X_VAR] = left_analog[:x]
  1012.     $game_variables[XInput_Settings::LEFT_AXIS_Y_VAR] = left_analog[:y]
  1013.     $game_variables[XInput_Settings::RIGHT_AXIS_X_VAR] = right_analog[:x]
  1014.     $game_variables[XInput_Settings::RIGHT_AXIS_Y_VAR] = right_analog[:y]
  1015.     $game_variables[XInput_Settings::BATTERY_LEVEL] = battery_level
  1016.   end
  1017.   #--------------------------------------------------------------------------
  1018.   # * Controller check update process
  1019.   #--------------------------------------------------------------------------
  1020.   def self.update_controller_used
  1021.     @controller_used = {}
  1022.     (0..3).each {|i|
  1023.       @controller_used[i] = @key_state[i].size > 0
  1024.     }
  1025.   end
  1026.   #--------------------------------------------------------------------------
  1027.   # * Returns the last used controls (:controller or :legacy)
  1028.   #--------------------------------------------------------------------------
  1029.   def self.used_control; @last_input_used; end
  1030.   #--------------------------------------------------------------------------
  1031.   # * Vibration activation
  1032.   # @param [Float] l_strenght       value from 0 to 100
  1033.   # @param [Float] r_strenght       value from 0 to 100
  1034.   # @param [Integer] timing         frames (1/60 second)
  1035.   # @param [Integer] pad_index      pad index
  1036.   #--------------------------------------------------------------------------
  1037.   def self.vibrate(l_strenght, r_strenght, timing, pad_index = 0)
  1038.     l_strenght = [[0, l_strenght].max, 100].min * adjust_vibration(pad_index) / 100
  1039.     r_strenght = [[0, r_strenght].max, 100].min * adjust_vibration(pad_index) / 100
  1040.     XInput.set_vibration(l_strenght, r_strenght, pad_index)
  1041.     @vibration_state[pad_index] = timing
  1042.   end
  1043.   #--------------------------------------------------------------------------
  1044.   # * Adjusts the vibration power due to user settings
  1045.   # @return [Integer]
  1046.   #--------------------------------------------------------------------------
  1047.   def self.adjust_vibration(pad_index = 0)
  1048.     $game_system ? $game_system.calc_vibration_power(pad_index) : 0
  1049.   end
  1050.   #--------------------------------------------------------------------------
  1051.   # * Gets the left analog stick coordinates
  1052.   # @param [Integer] controller_index
  1053.   # @return [Array]
  1054.   #--------------------------------------------------------------------------
  1055.   def self.left_analog(controller_index = 0)
  1056.     result = {:x => 0, :y => 0}
  1057.     if @key_state[controller_index][:L_AXIS_X]
  1058.       result[:x] = @key_state[controller_index][:L_AXIS_X]
  1059.     end
  1060.     if @key_state[controller_index][:L_AXIS_Y]
  1061.       result[:y] = @key_state[controller_index][:L_AXIS_Y]
  1062.     end
  1063.     result
  1064.   end
  1065.   #--------------------------------------------------------------------------
  1066.   # * Gets the right analog stick coordinates
  1067.   # @param [Integer] controller_index
  1068.   # @return [Array]
  1069.   #--------------------------------------------------------------------------
  1070.   def self.right_analog(controller_index = 0)
  1071.     result = {:x => 0, :y => 0}
  1072.     if @key_state[controller_index][:R_AXIS_X]
  1073.       result[:x] = @key_state[controller_index][:R_AXIS_X]
  1074.     end
  1075.     if @key_state[controller_index][:R_AXIS_Y]
  1076.       result[:y] = @key_state[controller_index][:R_AXIS_Y]
  1077.     end
  1078.     result
  1079.   end
  1080.   #--------------------------------------------------------------------------
  1081.   # * Returns the left trigger value (value between 0 and 255)
  1082.   # @return [Integer]
  1083.   #--------------------------------------------------------------------------
  1084.   def self.left_trigger(controller_index = 0)
  1085.     if @key_state[controller_index][:L_TRIG]
  1086.       @key_state[controller_index][:L_TRIG]
  1087.     else
  1088.       0
  1089.     end
  1090.   end
  1091.   #--------------------------------------------------------------------------
  1092.   # * Returns the right trigger value (value between 0 and 255)
  1093.   # @return [Integer]
  1094.   #--------------------------------------------------------------------------
  1095.   def self.right_trigger(controller_index = 0)
  1096.     if @key_state[controller_index][:R_TRIG]
  1097.       @key_state[controller_index][:R_TRIG]
  1098.     else
  1099.       0
  1100.     end
  1101.   end
  1102.   #--------------------------------------------------------------------------
  1103.   # * Gets the battery level of a selected controller
  1104.   # return values: -1: wired controller; 0: empty, 1: low, 2: medium, 3: high
  1105.   # @return [Integer]
  1106.   #--------------------------------------------------------------------------
  1107.   def self.battery_level(controller_index = 0)
  1108.     battery_info = XInput.get_battery_info(controller_index)
  1109.     return -2 if battery_info.nil?
  1110.     battery_info.battery_type == 0 ? -1 : battery_info.battery_level
  1111.   end
  1112. end # input
  1113.  
  1114. #===============================================================================
  1115. # ** Game_Interpreter
  1116. #-------------------------------------------------------------------------------
  1117. # easy method calls
  1118. #===============================================================================
  1119. class Game_Interpreter
  1120.   #--------------------------------------------------------------------------
  1121.   # * Call vibration process
  1122.   # @param [Integer] l_strenght
  1123.   # @param [Integer] r_strenght
  1124.   # @param [Integer] timing
  1125.   # @param [Integer] pad_index
  1126.   #--------------------------------------------------------------------------
  1127.   def controller_vibration(l_strenght, r_strenght, timing, pad_index = 0)
  1128.     Input.vibrate(l_strenght, r_strenght, timing, pad_index)
  1129.   end
  1130.   #--------------------------------------------------------------------------
  1131.   # * Starts the vibration with no time limit
  1132.   # @param [Integer] l_strenght
  1133.   # @param [Integer] r_strenght
  1134.   # @param [Integer] pad_index
  1135.   #--------------------------------------------------------------------------
  1136.   def start_vibration(l_strenght, r_strenght = l_strenght, pad_index = 0)
  1137.     Input.start_vibration(l_strenght, r_strenght, pad_index)
  1138.   end
  1139.   #--------------------------------------------------------------------------
  1140.   # * Stops the vibration
  1141.   #--------------------------------------------------------------------------
  1142.   def stop_vibration(pad_index = 0)
  1143.     Input.stop_vibration(pad_index)
  1144.   end
  1145.   #--------------------------------------------------------------------------
  1146.   # * Returns the controller plugged state
  1147.   #--------------------------------------------------------------------------
  1148.   def controller_plugged_in?(pad_index = 0)
  1149.     Input.controller_connected?(pad_index)
  1150.   end
  1151. end # game_interpreter
  1152.  
  1153. # Starting load libraries
  1154. XInput.load_libraries
RAW Paste Data