[RMVX] WINDOWS 10 COMPATIBILITY ISSUE WITH KEY INPUT EXTENDING SCRIPT
Posts
Pages:
1
This script will work perfectly fine on Windows 7 but for some reason won't work on Windows 10. Compatibility mode doesn't change anything no matter what I set it on. RMVX's builtin inputs work just fine but they are rather limited which is why I'm using this script. Here's the script. For the record it's not mine but it states that as clear as day.
Keyboard Input Expansion Script
If someone could explain why this isn't working on Windows 10 that would be great.
Keyboard Input Expansion Script
If someone could explain why this isn't working on Windows 10 that would be great.
@@get_key_state = Win32API.new('user32', 'GetAsyncKeyState', 'i', 'i')
Should be binding this function: https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getasynckeystate
Can't say why it would not work though.
Should be binding this function: https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getasynckeystate
Can't say why it would not work though.
I can't explain why but yes, GetKeyState stopped working (at least inside old Ruby Win32API access) some years ago in Win10. But I can't confirm the same for GetAsyncKeyState from my experience. In a game I was programming for until 2020 we still used it and I know some creators or testers had way newer OS-updates installed than me.
Made a new keyboard-input-method few months ago that I at least can confirm to work on my current Win10 20H2. The module "Keyboard" has to be updated per frame (Keyboard.update) just like the normal "Input" if you wanna use it. Didn't test in RPGXP or RPGVX, it's made for Ace, but should work in all of them.
It utilizes GetKeyboardState which scans ALL keys available and supports "#press?", "#trigger?", "#repeat?" as well as "#toggle?" (for CapsLock, NumLock and ScrollLock which also have their own shortcuts in it).
There is an experimental feature that allows you to scan the order pressed keys are hold. It is needed for "#dir4" and "#dir8" that come with parameters telling it which keys to use (defaults are the arrow-keys up, down, left and right).
What it does NOT support without additional extensions is using keynames, you either have to include that by yourself or use VK's raw values.
~炬燵あ
Made a new keyboard-input-method few months ago that I at least can confirm to work on my current Win10 20H2. The module "Keyboard" has to be updated per frame (Keyboard.update) just like the normal "Input" if you wanna use it. Didn't test in RPGXP or RPGVX, it's made for Ace, but should work in all of them.
It utilizes GetKeyboardState which scans ALL keys available and supports "#press?", "#trigger?", "#repeat?" as well as "#toggle?" (for CapsLock, NumLock and ScrollLock which also have their own shortcuts in it).
There is an experimental feature that allows you to scan the order pressed keys are hold. It is needed for "#dir4" and "#dir8" that come with parameters telling it which keys to use (defaults are the arrow-keys up, down, left and right).
What it does NOT support without additional extensions is using keynames, you either have to include that by yourself or use VK's raw values.
#==============================================================================
# ** Simple Keyboard Input
#------------------------------------------------------------------------------
# © 2022 KotatsuAkira / AkiraKotatsuhime
# Redistribute only with this copyright notice intact.
#==============================================================================
module Keyboard
#--------------------------------------------------------------------------
# * Module Constants
#--------------------------------------------------------------------------
KeyboardState = Win32API.new('user32', 'GetKeyboardState', 'P', 'L')
#--------------------------------------------------------------------------
# * Module Variables
#--------------------------------------------------------------------------
@@result = nil
@@data = ("\0" * 256).force_encoding("ASCII-8BIT")
@@states = Hash.new {|sh, sk| sh[sk] = 0 }
@@pressed_keys = [false] * 256
@@press_order = []
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def self.update
@@result = KeyboardState.call(@@data)
@@pressed_keys = (0..255).select do |sk|
(@@states[sk] = @@data[sk].ord >= 128 ? @@states[sk] + 1 : 0).nonzero?
end
@@states.each_key {|sk| @@states[sk] -= 6 if @@states[sk] >= 30 }
@@pressed_keys.each do |sk|
@@press_order.push(sk) unless @@press_order.include?(sk)
end
@@states.each {|sk, sv| @@press_order.delete(sk) unless sv }
end
#--------------------------------------------------------------------------
# * Check if Key is pressed down
#--------------------------------------------------------------------------
def self.press?(si)
return @@states[si] > 0
end
#--------------------------------------------------------------------------
# * Check if Keypress started right now
#--------------------------------------------------------------------------
def self.trigger?(si)
return @@states[si] == 1
end
#--------------------------------------------------------------------------
# * Check if Keypress has interval
#--------------------------------------------------------------------------
def self.repeat?(si)
st = @@states[si]
return st == 1 || st > 23 && st % 6 == 0
end
#--------------------------------------------------------------------------
# * Check if toggleable Key is active
#--------------------------------------------------------------------------
def self.toggle?(si)
return @@data[si].ord & 1 == 1
end
#--------------------------------------------------------------------------
# * Check if CapsLock is active
#--------------------------------------------------------------------------
def self.caps_lock?
return toggle?(0x14)
end
#--------------------------------------------------------------------------
# * Check if NumLock is active
#--------------------------------------------------------------------------
def self.num_lock?
return toggle?(0x90)
end
#--------------------------------------------------------------------------
# * Check if ScrollLock is active
#--------------------------------------------------------------------------
def self.scroll_lock?
return toggle?(0x91)
end
#--------------------------------------------------------------------------
# * Get even direction Keypress
#--------------------------------------------------------------------------
def self.dir4(su=0x26, sd=0x28, sl=0x25, sr=0x27)
s1 = @@press_order.index(su) || -1
s2 = @@press_order.index(sd) || -1
s3 = @@press_order.index(sl) || -1
s4 = @@press_order.index(sr) || -1
return 8 if s1 > s2 && s1 > s3 && s1 > s4
return 2 if s2 > s1 && s2 > s3 && s2 > s4
return 4 if s3 > s1 && s3 > s2 && s3 > s4
return 6 if s4 > s1 && s4 > s2 && s4 > s3
return 5
end
#--------------------------------------------------------------------------
# * Get even or diagonal direction Keypress
#--------------------------------------------------------------------------
def self.dir8(su=0x26, sd=0x28, sl=0x25, sr=0x27)
s1 = @@press_order.index(su) || -1
s2 = @@press_order.index(sd) || -1
s3 = @@press_order.index(sl) || -1
s4 = @@press_order.index(sr) || -1
if s1 > s2
return s3 > s4 ? 7 : s4 > s3 ? 9 : 8
elsif s2 > s1
return s3 > s4 ? 1 : s4 > s3 ? 3 : 2
else
return s3 > s4 ? 4 : s4 > s3 ? 6 : 5
end
return 5
end
#--------------------------------------------------------------------------
# * Inspect Object
#--------------------------------------------------------------------------
def self.inspect
return "#<Keyboard {#{@@pressed_keys.join(',')}}>"
end
end
~炬燵あ
Took a look at old Ruby docs and yes, that's the case. Try if it's working when you just remove all mentions of the methods "String#force_encoding" and "String#ord" without adding something to replace. It could be that something equal is not needed there in Ruby 1.8.1 (but still necessary in 1.9.2). At some point between XP and Ace the handling of strings and encoding in Ruby received some big changes.
EDIT:
I updated a line in the script that was referencing undefined Array#push_once, a custom-made function I'm commonly using in my scripting-stuff. That little mistake is fixed now.
~炬燵あ
EDIT:
I updated a line in the script that was referencing undefined Array#push_once, a custom-made function I'm commonly using in my scripting-stuff. That little mistake is fixed now.
~炬燵あ
Hey I'm back after a year and a half and I have to say your work is fantastic. I made some slight edits as you suggested along with some edits of my own. Also I found out something weird about that TKG input script. Apparently a lot of the inputs are broken but some like shift, control, and enter keys still work which is very odd. In any case here's what I got.
And here's the one with string usage instead.
I figure if someone tests this out on RPGM XP and the string version doesn't work hopefully the the keycode one will work at least.
#==============================================================================
# ** Simple Keyboard Input RPGM VX Edition
#------------------------------------------------------------------------------
# © 2022 KotatsuAkira / AkiraKotatsuhime
# Redistribute only with this copyright notice intact.
#==============================================================================
# Usage Guide
# Make sure the script is above Main and put Keyboard.Update in the
# Scene_Base update loop.
# To use the functions simply script something like Keyboard.press?(0x11)
# in one of the events you have made. 0x11 is the keycode for CTRL key.
# You can find the rest of the keycodes here at this link.
#
# [url]https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes[/url]
#
# If the link is dead just search for win32api virtual key codes in your
# preferred search engine and something should pop up.
#==============================================================================
module Keyboard
#--------------------------------------------------------------------------
# * Module Constants
#--------------------------------------------------------------------------
KeyboardState = Win32API.new('user32', 'GetKeyboardState', 'P', 'L')
#--------------------------------------------------------------------------
# * Module Variables
#--------------------------------------------------------------------------
@@result = nil
@@data = ("\0" * 256)
@@states = Hash.new {|sh, sk| sh[sk] = 0 }
@@pressed_keys = [false] * 256
@@press_order = []
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def self.update
@@result = KeyboardState.call(@@data)
@@pressed_keys = (0..255).select do |sk|
(@@states[sk] = @@data[sk] >= 128 ? @@states[sk] + 1 : 0).nonzero?
end
@@states.each_key {|sk| @@states[sk] -= 6 if @@states[sk] >= 30 }
@@pressed_keys.each do |sk|
@@press_order.push(sk) unless @@press_order.include?(sk)
end
@@states.each {|sk, sv| @@press_order.delete(sk) unless sv }
end
#--------------------------------------------------------------------------
# * Check if Key is pressed down
#--------------------------------------------------------------------------
def self.press?(si)
return @@states[si] > 0
end
#--------------------------------------------------------------------------
# * Check if Keypress started right now
#--------------------------------------------------------------------------
def self.trigger?(si)
return @@states[si] == 1
end
#--------------------------------------------------------------------------
# * Check if Keypress has interval
#--------------------------------------------------------------------------
def self.repeat?(si)
st = @@states[si]
return st == 1 || st > 23 && st % 6 == 0
end
#--------------------------------------------------------------------------
# * Check if toggleable Key is active
#--------------------------------------------------------------------------
def self.toggle?(si)
return @@data[si].ord & 1 == 1
end
#--------------------------------------------------------------------------
# * Check if CapsLock is active
#--------------------------------------------------------------------------
def self.caps_lock?
return toggle?(0x14)
end
#--------------------------------------------------------------------------
# * Check if NumLock is active
#--------------------------------------------------------------------------
def self.num_lock?
return toggle?(0x90)
end
#--------------------------------------------------------------------------
# * Check if ScrollLock is active
#--------------------------------------------------------------------------
def self.scroll_lock?
return toggle?(0x91)
end
#--------------------------------------------------------------------------
# * Get even direction Keypress
#--------------------------------------------------------------------------
def self.dir4(su=0x26, sd=0x28, sl=0x25, sr=0x27)
s1 = @@press_order.index(su) || -1
s2 = @@press_order.index(sd) || -1
s3 = @@press_order.index(sl) || -1
s4 = @@press_order.index(sr) || -1
return 8 if s1 > s2 && s1 > s3 && s1 > s4
return 2 if s2 > s1 && s2 > s3 && s2 > s4
return 4 if s3 > s1 && s3 > s2 && s3 > s4
return 6 if s4 > s1 && s4 > s2 && s4 > s3
return 5
end
#--------------------------------------------------------------------------
# * Get even or diagonal direction Keypress
#--------------------------------------------------------------------------
def self.dir8(su=0x26, sd=0x28, sl=0x25, sr=0x27)
s1 = @@press_order.index(su) || -1
s2 = @@press_order.index(sd) || -1
s3 = @@press_order.index(sl) || -1
s4 = @@press_order.index(sr) || -1
if s1 > s2
return s3 > s4 ? 7 : s4 > s3 ? 9 : 8
elsif s2 > s1
return s3 > s4 ? 1 : s4 > s3 ? 3 : 2
else
return s3 > s4 ? 4 : s4 > s3 ? 6 : 5
end
return 5
end
#--------------------------------------------------------------------------
# * Inspect Object
#--------------------------------------------------------------------------
def self.inspect
return "#<Keyboard {#{@@pressed_keys.join(',')}}>"
end
end
And here's the one with string usage instead.
#==============================================================================
# ** Simple Keyboard Input RPGM VX Edition (Now with strings!!!!)
#------------------------------------------------------------------------------
# © 2022 KotatsuAkira / AkiraKotatsuhime
# Redistribute only with this copyright notice intact.
#==============================================================================
# Usage Guide
# Make sure the script is above Main and put Keyboard.Update in the
# Scene_Base update loop.
# To use the functions simply script something like Keyboard.press?('A')
# in one of the events you have made. It's case insensitive too so you can
# also do something like Keyboard.press?('a').
#==============================================================================
module Keyboard
#--------------------------------------------------------------------------
# * Module Constants
#--------------------------------------------------------------------------
KeyboardState = Win32API.new('user32', 'GetKeyboardState', 'P', 'L')
KEYCODES = {
'SHIFT' => 0x10,
'CTRL' => 0x11,
'ALT' => 0x12,
'CAPSLOCK' => 0x14,
'SPACE' => 0x20,
'ENTER' => 0x0D,
'TAB' => 0x09,
'ESCAPE' => 0x1B,
'BACKSPACE' => 0x08,
'DELETE' => 0x2E,
'INSERT' => 0x2D,
'HOME' => 0x24,
'END' => 0x23,
'PAGEUP' => 0x21,
'PAGEDOWN' => 0x22,
'LEFT' => 0x25,
'UP' => 0x26,
'RIGHT' => 0x27,
'DOWN' => 0x28,
'A' => 0x41,
'B' => 0x42,
'C' => 0x43,
'D' => 0x44,
'E' => 0x45,
'F' => 0x46,
'G' => 0x47,
'H' => 0x48,
'I' => 0x49,
'J' => 0x4A,
'K' => 0x4B,
'L' => 0x4C,
'M' => 0x4D,
'N' => 0x4E,
'O' => 0x4F,
'P' => 0x50,
'Q' => 0x51,
'R' => 0x52,
'S' => 0x53,
'T' => 0x54,
'U' => 0x55,
'V' => 0x56,
'W' => 0x57,
'X' => 0x58,
'Y' => 0x59,
'Z' => 0x5A,
'0' => 0x30,
'1' => 0x31,
'2' => 0x32,
'3' => 0x33,
'4' => 0x34,
'5' => 0x35,
'6' => 0x36,
'7' => 0x37,
'8' => 0x38,
'9' => 0x39,
'NUM0' => 0x60,
'NUM1' => 0x61,
'NUM2' => 0x62,
'NUM3' => 0x63,
'NUM4' => 0x64,
'NUM5' => 0x65,
'NUM6' => 0x66,
'NUM7' => 0x67,
'NUM8' => 0x68,
'NUM9' => 0x69,
'F1' => 0x70,
'F2' => 0x71,
'F3' => 0x72,
'F4' => 0x73,
'F5' => 0x74,
'F6' => 0x75,
'F7' => 0x76,
'F8' => 0x77,
'F9' => 0x78,
'F10' => 0x79,
'F11' => 0x7A,
'F12' => 0x7B,
'SCROLLLOCK' => 0x91,
'PAUSE' => 0x13,
'PRINTSCREEN' => 0x2C,
':' => 0xBA, # ;
'=' => 0xBB, # =
',' => 0xBC, # ,
'-' => 0xBD, # -
'.' => 0xBE, # .
'/' => 0xBF, # /
'\\' => 0xDC, # \
'`' => 0xC0, # `
'[' => 0xDB, # [
']' => 0xDD, # ]
'\'' => 0xDE, # '
}
#--------------------------------------------------------------------------
# * Module Variables
#--------------------------------------------------------------------------
@@result = nil
@@data = ("\0" * 256)
@@states = Hash.new { |sh, sk| sh[sk] = 0 }
@@pressed_keys = [false] * 256
@@press_order = []
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def self.update
@@result = KeyboardState.call(@@data)
@@pressed_keys = (0..255).select do |sk|
(@@states[sk] = @@data[sk] >= 128 ? @@states[sk] + 1 : 0).nonzero?
end
@@states.each_key { |sk| @@states[sk] -= 6 if @@states[sk] >= 30 }
@@pressed_keys.each do |sk|
@@press_order.push(sk) unless @@press_order.include?(sk)
end
@@states.each { |sk, sv| @@press_order.delete(sk) unless sv }
end
#--------------------------------------------------------------------------
# * Check if Key is pressed down
#--------------------------------------------------------------------------
def self.press?(si)
si = KEYCODES[si.upcase] if KEYCODES.key?(si.upcase)
return @@states[si] > 0
end
#--------------------------------------------------------------------------
# * Check if Keypress started right now
#--------------------------------------------------------------------------
def self.trigger?(si)
si = KEYCODES[si.upcase] if KEYCODES.key?(si.upcase)
return @@states[si] == 1
end
#--------------------------------------------------------------------------
# * Check if Keypress has interval
#--------------------------------------------------------------------------
def self.repeat?(si)
si = KEYCODES[si.upcase] if KEYCODES.key?(si.upcase)
st = @@states[si]
return st == 1 || (st > 23 && st % 6 == 0)
end
#--------------------------------------------------------------------------
# * Check if toggleable Key is active
#--------------------------------------------------------------------------
def self.toggle?(si)
si = KEYCODES[si.upcase] if KEYCODES.key?(si.upcase)
return @@data[si].ord & 1 == 1
end
#--------------------------------------------------------------------------
# * Check if CapsLock is active
#--------------------------------------------------------------------------
def self.caps_lock?
return toggle?('CapsLock')
end
#--------------------------------------------------------------------------
# * Check if NumLock is active
#--------------------------------------------------------------------------
def self.num_lock?
return toggle?('NumLock')
end
#--------------------------------------------------------------------------
# * Check if ScrollLock is active
#--------------------------------------------------------------------------
def self.scroll_lock?
return toggle?('ScrollLock')
end
#--------------------------------------------------------------------------
# * Get even direction Keypress
#--------------------------------------------------------------------------
def self.dir4(su = 'Up', sd = 'Down', sl = 'Left', sr = 'Right')
su = KEYCODES[su.upcase] if KEYCODES.key?(su.upcase)
sd = KEYCODES[sd.upcase] if KEYCODES.key?(sd.upcase)
sl = KEYCODES[sl.upcase] if KEYCODES.key?(sl.upcase)
sr = KEYCODES[sr.upcase] if KEYCODES.key?(sr.upcase)
s1 = @@press_order.index(su) || -1
s2 = @@press_order.index(sd) || -1
s3 = @@press_order.index(sl) || -1
s4 = @@press_order.index(sr) || -1
return 8 if s1 > s2 && s1 > s3 && s1 > s4
return 2 if s2 > s1 && s2 > s3 && s2 > s4
return 4 if s3 > s1 && s3 > s2 && s3 > s4
return 6 if s4 > s1 && s4 > s2 && s4 > s3
return 5
end
#--------------------------------------------------------------------------
# * Get even or diagonal direction Keypress
#--------------------------------------------------------------------------
def self.dir8(su = 'Up', sd = 'Down', sl = 'Left', sr = 'Right')
su = KEYCODES[su.upcase] if KEYCODES.key?(su.upcase)
sd = KEYCODES[sd.upcase] if KEYCODES.key?(sd.upcase)
sl = KEYCODES[sl.upcase] if KEYCODES.key?(sl.upcase)
sr = KEYCODES[sr.upcase] if KEYCODES.key?(sr.upcase)
s1 = @@press_order.index(su) || -1
s2 = @@press_order.index(sd) || -1
s3 = @@press_order.index(sl) || -1
s4 = @@press_order.index(sr) || -1
if s1 > s2
return s3 > s4 ? 7 : (s4 > s3 ? 9 : 8)
elsif s2 > s1
return s3 > s4 ? 1 : (s4 > s3 ? 3 : 2)
else
return s3 > s4 ? 4 : (s4 > s3 ? 6 : 5)
end
return 5
end
#--------------------------------------------------------------------------
# * Inspect Object
#--------------------------------------------------------------------------
def self.inspect
return "#<Keyboard {#{@@pressed_keys.join(',')}}>"
end
end
I figure if someone tests this out on RPGM XP and the string version doesn't work hopefully the the keycode one will work at least.
Pages:
1













