mirror of
https://github.com/bakustarver/rpgmakermlinux-cicpoffs.git
synced 2025-08-12 02:15:34 +02:00
452 lines
20 KiB
Ruby
452 lines
20 KiB
Ruby
# CRDJ_Input.rb Kawariki MKXP-Z port
|
|
# Date: 2023-06-01
|
|
# TODO: - handle modified configuration
|
|
# - Properly deal with the layout stuff?
|
|
#==============================================================================
|
|
# ** Input
|
|
#-------------------------------------------------------------------------------
|
|
# Created By Cidiomar R. Dias Junior
|
|
# Originally posted at
|
|
#
|
|
# Terms of Use: Credit "Cidiomar R. Dias Junior"
|
|
#
|
|
# Maintained on Hime Works
|
|
#-------------------------------------------------------------------------------
|
|
# ** Description
|
|
#
|
|
# A module that handles input data from a gamepad or keyboard.
|
|
# Managed by symbols rather than button numbers in RGSS3.
|
|
#-------------------------------------------------------------------------------
|
|
# ** Usage
|
|
#
|
|
# Scroll down to the configuration section. It is around line 185.
|
|
# You can set up your key mappings there. Use the reference to get the names
|
|
# of the keys.
|
|
#
|
|
#===============================================================================
|
|
|
|
module CRDJ_Input
|
|
#--------------------------------------------------------------------------
|
|
# * Keymap in symbols
|
|
# To get a key from the keymap, you can use Input.key(sym) or Input:KEYMAP[sym]
|
|
# Or if you want to use a symbol in a input function, just pass the symbol
|
|
# as argument.
|
|
#--------------------------------------------------------------------------
|
|
KEYMAP = {
|
|
LBUTTON: 0x01, RBUTTON: 0x02,
|
|
CANCEL: 0x03, MBUTTON: 0x04,
|
|
XBUTTON1: 0x05, XBUTTON2: 0x06,
|
|
BACK: 0x08, TAB: 0x09,
|
|
CLEAR: 0x0c, RETURN: 0x0d,
|
|
SHIFT: 0x10, CONTROL: 0x11,
|
|
MENU: 0x12, PAUSE: 0x13,
|
|
CAPITAL: 0x14, KANA: 0x15,
|
|
JUNJA: 0x17, FINAL: 0x18,
|
|
HANJA: 0x19,
|
|
ESCAPE: 0x1b, CONVERT: 0x1c,
|
|
NONCONVERT: 0x1d, ACCEPT: 0x1e,
|
|
MODECHANGE: 0x1f, SPACE: 0x20,
|
|
PRIOR: 0x21, NEXT: 0x22,
|
|
END: 0x23, HOME: 0x24,
|
|
LEFT: 0x25, UP: 0x26,
|
|
RIGHT: 0x27, DOWN: 0x28,
|
|
SELECT: 0x29, PRINT: 0x2a,
|
|
EXECUTE: 0x2b, SNAPSHOT: 0x2c,
|
|
INSERT: 0x2d, DELETE: 0x2e,
|
|
HELP: 0x2f, N0: 0x30,
|
|
KEY_1: 0x31, KEY_2: 0x32,
|
|
KEY_3: 0x33, KEY_4: 0x34,
|
|
KEY_5: 0x35, KEY_6: 0x36,
|
|
KEY_7: 0x37, KEY_8: 0x38,
|
|
KEY_9: 0x39, colon: 0x3a,
|
|
semicolon: 0x3b, less: 0x3c,
|
|
equal: 0x3d, greater: 0x3e,
|
|
question: 0x3f, at: 0x40,
|
|
LETTER_A: 0x41, LETTER_B: 0x42,
|
|
LETTER_C: 0x43, LETTER_D: 0x44,
|
|
LETTER_E: 0x45, LETTER_F: 0x46,
|
|
LETTER_G: 0x47, LETTER_H: 0x48,
|
|
LETTER_I: 0x49, LETTER_J: 0x4a,
|
|
LETTER_K: 0x4b, LETTER_L: 0x4c,
|
|
LETTER_M: 0x4d, LETTER_N: 0x4e,
|
|
LETTER_O: 0x4f, LETTER_P: 0x50,
|
|
LETTER_Q: 0x51, LETTER_R: 0x52,
|
|
LETTER_S: 0x53, LETTER_T: 0x54,
|
|
LETTER_U: 0x55, LETTER_V: 0x56,
|
|
LETTER_W: 0x57, LETTER_X: 0x58,
|
|
LETTER_Y: 0x59, LETTER_Z: 0x5a,
|
|
LWIN: 0x5b, RWIN: 0x5c,
|
|
APPS: 0x5d, asciicircum: 0x5e,
|
|
SLEEP: 0x5f, NUMPAD0: 0x60,
|
|
NUMPAD1: 0x61, NUMPAD2: 0x62,
|
|
NUMPAD3: 0x63, NUMPAD4: 0x64,
|
|
NUMPAD5: 0x65, NUMPAD6: 0x66,
|
|
NUMPAD7: 0x67, NUMPAD8: 0x68,
|
|
NUMPAD9: 0x69, MULTIPLY: 0x6a,
|
|
ADD: 0x6b, SEPARATOR: 0x6c,
|
|
SUBTRACT: 0x6d, DECIMAL: 0x6e,
|
|
DIVIDE: 0x6f, F1: 0x70,
|
|
F2: 0x71, F3: 0x72,
|
|
F4: 0x73, F5: 0x74,
|
|
F6: 0x75, F7: 0x76,
|
|
F8: 0x77, F9: 0x78,
|
|
F10: 0x79, F11: 0x7a,
|
|
F12: 0x7b, F13: 0x7c,
|
|
F14: 0x7d, F15: 0x7e,
|
|
F16: 0x7f, F17: 0x80,
|
|
F18: 0x81, F19: 0x82,
|
|
F20: 0x83, F21: 0x84,
|
|
F22: 0x85, F23: 0x86,
|
|
F24: 0x87, NUMLOCK: 0x90,
|
|
SCROLL: 0x91, LSHIFT: 0xa0,
|
|
RSHIFT: 0xa1, LCONTROL: 0xa2,
|
|
RCONTROL: 0xa3, LMENU: 0xa4,
|
|
RMENU: 0xa5, BROWSER_BACK: 0xa6,
|
|
BROWSER_FORWARD: 0xa7, BROWSER_REFRESH: 0xa8,
|
|
BROWSER_STOP: 0xa9, BROWSER_SEARCH: 0xaa,
|
|
BROWSER_FAVORITES: 0xab, BROWSER_HOME: 0xac,
|
|
VOLUME_MUTE: 0xad, VOLUME_DOWN: 0xae,
|
|
VOLUME_UP: 0xaf, MEDIA_NEXT_TRACK: 0xb0,
|
|
MEDIA_PREV_TRACK: 0xb1, MEDIA_STOP: 0xb2,
|
|
MEDIA_PLAY_PAUSE: 0xb3, LAUNCH_MAIL: 0xb4,
|
|
LAUNCH_MEDIA_SELECT: 0xb5, LAUNCH_APP1: 0xb6,
|
|
LAUNCH_APP2: 0xb7, cedilla: 0xb8,
|
|
onesuperior: 0xb9, masculine: 0xba,
|
|
guillemotright: 0xbb, onequarter: 0xbc,
|
|
onehalf: 0xbd, threequarters: 0xbe,
|
|
questiondown: 0xbf, Agrave: 0xc0,
|
|
Aacute: 0xc1, Acircumflex: 0xc2,
|
|
Atilde: 0xc3, Adiaeresis: 0xc4,
|
|
Aring: 0xc5, AE: 0xc6,
|
|
Ccedilla: 0xc7, Egrave: 0xc8,
|
|
Eacute: 0xc9, Ecircumflex: 0xca,
|
|
Ediaeresis: 0xcb, Igrave: 0xcc,
|
|
Iacute: 0xcd, Icircumflex: 0xce,
|
|
Idiaeresis: 0xcf, ETH: 0xd0,
|
|
Ntilde: 0xd1, Ograve: 0xd2,
|
|
Oacute: 0xd3, Ocircumflex: 0xd4,
|
|
Otilde: 0xd5, Odiaeresis: 0xd6,
|
|
multiply: 0xd7, Oslash: 0xd8,
|
|
Ugrave: 0xd9, Uacute: 0xda,
|
|
Ucircumflex: 0xdb, Udiaeresis: 0xdc,
|
|
Yacute: 0xdd, THORN: 0xde,
|
|
ssharp: 0xdf, agrave: 0xe0,
|
|
aacute: 0xe1, acircumflex: 0xe2,
|
|
atilde: 0xe3, adiaeresis: 0xe4,
|
|
PROCESSKEY: 0xe5, ae: 0xe6,
|
|
PACKET: 0xe7, egrave: 0xe8,
|
|
eacute: 0xe9, ecircumflex: 0xea,
|
|
ediaeresis: 0xeb, igrave: 0xec,
|
|
iacute: 0xed, icircumflex: 0xee,
|
|
idiaeresis: 0xef, eth: 0xf0,
|
|
ntilde: 0xf1, ograve: 0xf2,
|
|
oacute: 0xf3, ocircumflex: 0xf4,
|
|
otilde: 0xf5, ATTN: 0xf6,
|
|
CRSEL: 0xf7, EXSEL: 0xf8,
|
|
EREOF: 0xf9, PLAY: 0xfa,
|
|
ZOOM: 0xfb, NONAME: 0xfc,
|
|
PA1: 0xfd, thorn: 0xfe,
|
|
ydiaeresis: 0xff
|
|
}
|
|
|
|
KEYMAP[:WIN] = [KEYMAP[:LWIN], KEYMAP[:RWIN]]
|
|
|
|
#===============================================================================
|
|
# Configuration
|
|
#===============================================================================
|
|
#--------------------------------------------------------------------------
|
|
# * Default Keys, you can configure here instead of by pressing F1.
|
|
#--------------------------------------------------------------------------
|
|
UP = [KEYMAP[:UP]]
|
|
DOWN = [KEYMAP[:DOWN]]
|
|
LEFT = [KEYMAP[:LEFT]]
|
|
RIGHT = [KEYMAP[:RIGHT]]
|
|
A = [KEYMAP[:SHIFT]]
|
|
B = [KEYMAP[:ESCAPE], KEYMAP[:LETTER_X]]
|
|
C = [KEYMAP[:RETURN], KEYMAP[:LETTER_Z]]
|
|
X = []
|
|
Y = []
|
|
Z = []
|
|
L = [KEYMAP[:PRIOR]]
|
|
R = [KEYMAP[:NEXT]]
|
|
F5 = [KEYMAP[:F5]]
|
|
F6 = [KEYMAP[:F6]]
|
|
F7 = [KEYMAP[:F7]]
|
|
F8 = [KEYMAP[:F8]]
|
|
F9 = [KEYMAP[:F9]]
|
|
SHIFT = [KEYMAP[:SHIFT]]
|
|
CTRL = [KEYMAP[:CONTROL]]
|
|
ALT = [KEYMAP[:MENU]]
|
|
|
|
#===============================================================================
|
|
# Rest of script
|
|
#===============================================================================
|
|
#--------------------------------------------------------------------------
|
|
# * Symbol version of default keys.
|
|
#--------------------------------------------------------------------------
|
|
SYM_KEYS = {
|
|
:UP => UP,
|
|
:LEFT => LEFT,
|
|
:DOWN => DOWN,
|
|
:RIGHT => RIGHT,
|
|
:A => A,
|
|
:B => B,
|
|
:C => C,
|
|
:X => X,
|
|
:Y => Y,
|
|
:Z => Z,
|
|
:L => L,
|
|
:R => R,
|
|
:F5 => F5,
|
|
:F6 => F6,
|
|
:F7 => F7,
|
|
:F8 => F8,
|
|
:F9 => F9,
|
|
:SHIFT => SHIFT,
|
|
:CTRL => CTRL,
|
|
:ALT => ALT
|
|
}
|
|
|
|
# Letters that can have accent
|
|
PssbLetters = "AEIOUCNYaeioucny"
|
|
# Accents, in ASCII, configured at runtime to avoid encoding troubles
|
|
Accents = [96.chr, 180.chr, 94.chr, 126.chr, 168.chr].join
|
|
NonCompatChars = [180, 168]
|
|
|
|
module InputExtension
|
|
#--------------------------------------------------------------------------
|
|
# * Determines whether the button corresponding to the symbol sym is
|
|
# currently being pressed.
|
|
#
|
|
# If the button is being pressed, returns TRUE. If not, returns FALSE.
|
|
#
|
|
# if Input.press?(:C)
|
|
# do_something
|
|
# end
|
|
#--------------------------------------------------------------------------
|
|
def press?(keys)
|
|
if keys.is_a?(Numeric)
|
|
k = keys.to_i
|
|
return (self.pressex? k)
|
|
elsif keys.is_a?(Array)
|
|
return keys.any? {|key| self.pressex?(key) }
|
|
elsif keys.is_a?(Symbol)
|
|
if SYM_KEYS.key?(keys)
|
|
return super(keys)
|
|
return SYM_KEYS[keys].any? {|key| self.pressex?(key) }
|
|
elsif KEYMAP.key?(keys)
|
|
k = KEYMAP[keys]
|
|
return self.pressex?(k)
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
end
|
|
|
|
#--------------------------------------------------------------------------
|
|
# * Determines whether the button corresponding to the symbol sym is
|
|
# currently 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.
|
|
#--------------------------------------------------------------------------
|
|
def trigger?(keys)
|
|
if keys.is_a?(Numeric)
|
|
return Input.triggerex?(keys.to_i)
|
|
elsif keys.is_a?(Array)
|
|
return keys.any? {|key| self.triggerex?(key)}
|
|
elsif keys.is_a?(Symbol)
|
|
if SYM_KEYS.key?(keys)
|
|
return super(keys)
|
|
Preload.print "Trigger #{keys} #{SYM_KEYS[keys]} #{x}"
|
|
return SYM_KEYS[keys].any? {|key| self.triggerex?(key)}
|
|
elsif KEYMAP.key?(keys)
|
|
return self.triggerex?(KEYMAP[keys])
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
end
|
|
|
|
#--------------------------------------------------------------------------
|
|
# * Determines whether the button corresponding to the symbol sym is
|
|
# currently being pressed again.
|
|
# Unlike trigger?, takes into account the repeated input of a button being
|
|
# held down continuously.
|
|
#
|
|
# If the button is being pressed, returns TRUE. If not, returns FALSE.
|
|
#--------------------------------------------------------------------------
|
|
def repeat?(keys)
|
|
if keys.is_a?(Numeric)
|
|
key = keys.to_i
|
|
return self.repeatex?(key)
|
|
elsif keys.is_a?(Array)
|
|
return keys.any? {|key| self.repeatex?(key)}
|
|
elsif keys.is_a?(Symbol)
|
|
if SYM_KEYS.key?(keys)
|
|
return super(keys)
|
|
return SYM_KEYS[keys].any? {|key| self.repeatex?(key)}
|
|
elsif KEYMAP.key?(keys)
|
|
return self.repeatex?(KEYMAP[keys])
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
end
|
|
|
|
#--------------------------------------------------------------------------
|
|
# * Determines whether the button corresponding to the symbol sym
|
|
# was released.
|
|
#
|
|
# If the button was released, returns TRUE. If not, returns FALSE.
|
|
#--------------------------------------------------------------------------
|
|
def release?(keys)
|
|
if keys.is_a?(Numeric)
|
|
return self.releaseex? keys.to_i
|
|
elsif keys.is_a?(Array)
|
|
return keys.any? {|key| self.release?(key)}
|
|
elsif keys.is_a?(Symbol)
|
|
if SYM_KEYS.key?(keys)
|
|
return super(keys)
|
|
return SYM_KEYS[keys].any? {|key| self.releaseex?(key)}
|
|
elsif KEYMAP.key?(keys)
|
|
return self.releaseex?(KEYMAP[keys])
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
end
|
|
|
|
#--------------------------------------------------------------------------
|
|
# * Checks the status of the directional buttons, translates the data into
|
|
# a specialized 4-direction input format, and returns the number pad
|
|
# equivalent (2, 4, 6, 8).
|
|
#
|
|
# If no directional buttons are being pressed (or the equivalent), returns 0.
|
|
#--------------------------------------------------------------------------
|
|
# def dir4
|
|
# return 2 if self.press?(DOWN)
|
|
# return 4 if self.press?(LEFT)
|
|
# return 6 if self.press?(RIGHT)
|
|
# return 8 if self.press?(UP)
|
|
# return 0
|
|
# end
|
|
|
|
#--------------------------------------------------------------------------
|
|
# * Checks the status of the directional buttons, translates the data into
|
|
# a specialized 8-direction input format, and returns the number pad
|
|
# equivalent (1, 2, 3, 4, 6, 7, 8, 9).
|
|
#
|
|
#If no directional buttons are being pressed (or the equivalent), returns 0.
|
|
#--------------------------------------------------------------------------
|
|
# def dir8
|
|
# down = self.press?(DOWN)
|
|
# left = self.press?(LEFT)
|
|
# return 1 if down and left
|
|
# right = self.press?(RIGHT)
|
|
# return 3 if down and right
|
|
# up = self.press?(UP)
|
|
# return 7 if up and left
|
|
# return 9 if up and right
|
|
# return 2 if down
|
|
# return 4 if left
|
|
# return 6 if right
|
|
# return 8 if up
|
|
# return 0
|
|
# end
|
|
|
|
#--------------------------------------------------------------------------
|
|
# * Gets the character that correspond to vk using the keyboard layout
|
|
#--------------------------------------------------------------------------
|
|
def get_character(vk)
|
|
# FIXME: do something smarter
|
|
return vk
|
|
end
|
|
|
|
#--------------------------------------------------------------------------
|
|
# * Accents Table, to bo used in conversion from ASCII to UTF8
|
|
#--------------------------------------------------------------------------
|
|
AccentsCharsConv = {
|
|
"A" => ["A", "A", "A", "A", "A"],
|
|
"E" => ["E", "E", "E", 0, "E"],
|
|
"I" => ["I", "I", "I", 0, "I"],
|
|
"O" => ["O", "O", "O", "O", "O"],
|
|
"U" => ["U", "U", "U", 0, "U"],
|
|
"C" => [ 0 , "C", 0 , 0, 0 ],
|
|
"N" => [ 0 , 0, 0 , "N", 0 ],
|
|
"Y" => [ 0 , "Y", 0 , 0, "?"],
|
|
"a" => ["a", "a", "a", "a", "a"],
|
|
"e" => ["e", "e", "e", 0 , "e"],
|
|
"i" => ["i", "i", "i", 0 , "i"],
|
|
"o" => ["o", "o", "o", "o", "o"],
|
|
"u" => ["u", "u", "u", 0 , "u"],
|
|
"c" => [ 0 , "c", 0 , 0 , 0 ],
|
|
"n" => [ 0 , 0 , 0 , "n", 0 ],
|
|
"y" => [ 0 , "y", 0 , 0 , "y"],
|
|
}
|
|
|
|
@last_accent = nil
|
|
|
|
#--------------------------------------------------------------------------
|
|
# * Get inputed string transcoded to UTF8
|
|
#--------------------------------------------------------------------------
|
|
def UTF8String
|
|
result = ""
|
|
31.upto(255) {|key|
|
|
if self.repeat?(key)
|
|
c = self.get_character(key)
|
|
if (cc = c.unpack("C")[0]) and NonCompatChars.include?(cc)
|
|
result += cc.chr
|
|
else
|
|
result += UNICODE_TO_UTF8.convertc if c != ""
|
|
end
|
|
end
|
|
}
|
|
return "" if result == ""
|
|
if @last_accent
|
|
result = @last_accent + result
|
|
@last_accent = nil
|
|
end
|
|
f_result = ""
|
|
jump = false
|
|
for i in 0 ... result.length
|
|
c = result[i]
|
|
if jump
|
|
jump = false
|
|
next
|
|
end
|
|
if Accents.include?c
|
|
if (nc = result[i+1]) != nil
|
|
if PssbLetters.include?(nc)
|
|
if (ac = AccentsCharsConv[nc][Accents.indexc]) != 0
|
|
f_result << ac
|
|
jump = true
|
|
else
|
|
f_result << c
|
|
f_result << nc
|
|
jump = true
|
|
end
|
|
elsif Accents.include?(nc)
|
|
f_result << c
|
|
f_result << nc
|
|
jump = true
|
|
else
|
|
f_result << c
|
|
f_result << nc
|
|
jump = true
|
|
end
|
|
else
|
|
@last_accent = c
|
|
end
|
|
else
|
|
f_result << c
|
|
end
|
|
end
|
|
return f_result
|
|
end
|
|
end
|
|
|
|
Input.singleton_class.prepend InputExtension
|
|
Input.const_set :KEYMAP, KEYMAP
|
|
end
|