Hi all - I've searched for about an hour on our forums and Google, to little avail. Hopefully someone can tell me whether this is possible or not.
Most of my Ace games have extra commands for buttons - such as "Hold SHIFT to skip this sequence" or "Press D to fire a flare" (on the map). I know that players can use the F1 "Keyboard" (or "Gamepad") menu to change their key bindings, and I'm fine with that. But if possible, I'd like to add a feature that detects, for example, what keyboard button the user has assigned to "Game Button A" (by default, SHIFT), so that I can display "Hold (whatever button they've set) to skip this sequence" instead.
Is there any way to do this in Ruby (or otherwise)? The progress made on scripts to change keyboard bindings make me think that it's possible, but all of the F1 functionality seems pretty obscure to me.
(Or, alternatively, if this isn't possible, is there any practical way to have the player change their keybindings from an in-game options menu rather than F1, so that I can set variables that track which keyboard button to display at the moment the player changes their keybindings?)
Detecting F1 Keyboard Settings?
● ARCHIVED · READ-ONLY
-
-
I've moved this thread to RGSS3 Script Requests. Please be sure to post your threads in the correct forum next time. Thank you.
-
http://www.rpgmakervxace.net/topic/17352-inpex/
Sometimes you need extra ways to control the game, and sometimes the amount of available buttons and keys isn't enough for the game. Or, you don't want people, especially non-RPG Maker users, to rely on F1 to change the gamepad and / or keyboard settings. -
Thank you very much for that link, Milena! I really appreciate it.
It looks like I can use that script to allow players to bind keys to symbols during gameplay - and if I study the script I can likely find where to set the appropriate variables so I can track them. Not sure if I can stop them from then re-changing it using F1 but that's something of a Garbage-In-Garbage-Out situation. So this seems like a decent workaround for most cases.
But if there's a way (either with simple RGSS commands or with scripts) to record/get the keybindings that the player has set with F1, that would be even better - it would be a cleaner solution to what I want to do and would require a lot less effort to get right. Anyone know whether it can be done? -
Reading is definitely possible. It isn't simple though. The question is what do you expect such a method to return?
{ "Space" => :C, "Enter" => :C, "Esc" => :B, "Num 0" => :B, "Shift" => :A }Code:What about the gamepad?{ :C => ["Space", "Enter"], :B => ["Esc", "Num 0"], :A => "Shift" }
You also have to decide how to handle multiple or no assignment at all. Yeah, that's irrelevant for the request, but it's something you have to think about.
I also think you'd be better off with using an alternative Input implementation. That way you can control (not only read) the button assignments. -
Thanks a lot for your response, Cremnophobia. :)Reading is definitely possible. It isn't simple though. The question is what do you expect such a method to return?
{ "Space" => :C, "Enter" => :C, "Esc" => :B, "Num 0" => :B, "Shift" => :A }Code:What about the gamepad?{ :C => ["Space", "Enter"], :B => ["Esc", "Num 0"], :A => "Shift" }
You also have to decide how to handle multiple or no assignment at all. Yeah, that's irrelevant for the request, but it's something you have to think about.
I also think you'd be better off with using an alternative Input implementation. That way you can control (not only read) the button assignments.
What I'm trying to figure out, specifically, is what kind of syntax (etc.) that can reference the F1 Key bindings that the player has set. This topic was moved to RGSS3 Script Requests, but (unless it would be necessary to access information about the player's F1 Bindings - and maybe it is, for all I know) I don't need an entire script.
Great question about what I want to return. I think an array for each game symbol with all key bindings would work. For example, the "C" symbol might be bound to Enter, Spacebar, Z, and Gamepad Button 3. An array returning all four of those would be the best thing; second best would probably be giving each key (Enter, Spacebar, etc.) its own return value (both of these would return 'C').
From there, I can write code to look through the array (or the set of variables), see if a certain value exists, and prioritize which key to show the player (so that an onscreen picture would say "Hit [Enter] to move on" even if Spacebar, Z, and Gamepad Button 3 also do the same).
It sounds like this might be possible, and I'm very excited for the possibility! I'd really appreciate any direction you could give me if you know how. -
Examples:Spoilermodule F1 class F1Error < StandardError end private if false # Vista and newer dll_name = 'advapi32' func_name = 'RegGetValueW' else # XP SP2 and newer dll_name = 'shlwapi' func_name = 'SHRegGetValueW' end DLL = DL.dlopen(dll_name) GETVALUE = DL::CFunc.new(DLL[func_name], DL::TYPE_LONG, func_name, :stdcall) HKEY_CURRENT_USER = -0x7FFF_FFFF RRF_RT_REG_BINARY = 0x0000_0008 to_wcs = ->(arg) { "#{arg}\0".encode('UTF-16LE') } SUBKEY = to_wcs.call('Software\Enterbrain\RGSS3') BUTTONASSIGN = to_wcs.call('ButtonAssign') BUTTONASSIGN_LUT = Array.new(0xFF, nil) BUTTONASSIGN_LUT[2] = :DOWN BUTTONASSIGN_LUT[4] = :LEFT BUTTONASSIGN_LUT[6] = :RIGHT BUTTONASSIGN_LUT[8] = :UP BUTTONASSIGN_LUT[11] = :A BUTTONASSIGN_LUT[12] = :B BUTTONASSIGN_LUT[13] = :C BUTTONASSIGN_LUT[14] = :X BUTTONASSIGN_LUT[15] = :Y BUTTONASSIGN_LUT[16] = :Z BUTTONASSIGN_LUT[17] = :L BUTTONASSIGN_LUT[18] = :R BUTTONASSIGN_LUT[21] = :SHIFT BUTTONASSIGN_LUT[22] = :CTRL BUTTONASSIGN_LUT[23] = :ALT BUTTONASSIGN_LUT[25] = :F5 BUTTONASSIGN_LUT[26] = :F6 BUTTONASSIGN_LUT[27] = :F7 BUTTONASSIGN_LUT[28] = :F8 BUTTONASSIGN_LUT[29] = :F9 KEYBOARD_BUTTONS = %w(Space Enter Esc Num\ 0 Shift Z X C V B A S D W Q) GAMEPAD_BUTTONS = (1..10).each_with_object([]) { |n, a| a << "Button #{n}" } def self.button_assign_make_hash(data, include_gamepad = true) hash = Hash.new { |h, k| h[k] = [] } conv = ->(button_name) { hash[BUTTONASSIGN_LUT[data.shift]] << button_name } if include_gamepad GAMEPAD_BUTTONS.each(&conv) else data.shift(GAMEPAD_BUTTONS.length) end KEYBOARD_BUTTONS.each(&conv) hash.delete(nil) hash end def self.button_assign_check_size(expected_size, actual_size_packed) actual_size = actual_size_packed.unpack('L')[0] if actual_size != expected_size fail(F1Error, "unexpected ButtonAssign data size (#{actual_size})") end end public def self.button_assign(include_gamepad = true) expected_size = GAMEPAD_BUTTONS.length + KEYBOARD_BUTTONS.length size = [expected_size].pack('L') data = "\0" * expected_size status = GETVALUE.call([ HKEY_CURRENT_USER, DL::CPtr[SUBKEY], DL::CPtr[BUTTONASSIGN], RRF_RT_REG_BINARY, 0, DL::CPtr[data], DL::CPtr[size] ]) status == 0 || fail(F1Error, "reading registry failed (#{status})") button_assign_check_size(expected_size, size) button_assign_make_hash(data.bytes.to_a, include_gamepad) endend
Code:Example output:F1.button_assign # including gamepadF1.button_assign(true) # including gamepadF1.button_assign(false) # excluding gamepad
Code:{:A=>["Button 1", "Shift"], :B=>["Button 2", "Esc", "Num 0", "X"], :C=>["Button3", "Space", "Enter", "Z"], :X=>["Button 4", "A"], :Y=>["Button 5", "S"], :Z=>["Button 6", "D"], :L=>["Button 7", "W"], :R=>["Button 8", "Q"]} -
Wow.
I am just floored right now. I'm so excited, humbled, and shocked by both your generosity and skill - I asked for a bit of direction and you gave me an entire script to help me achieve what I was trying to do. And I'm honestly having a hard time even coming up with the right words to express my appreciation, because this is amazing.
Thank you so much, Cremnophobia. Please let me know if there's any way I can pay back the favor.
I'm going to try implementing it into a custom control scheme in the next few days, and I'll post how it goes. -
For RGSS any changes the player did in the F1 menu was only saved in the registry when you exited the game.
I suggest you check whether the same applied for Ace. -
Thanks for the heads-up, Zeriab. I'll make sure that the script can read settings that have been changed during the current session.
-
What kind of directions did you expect? Obviously, you have some programming experience, but I don't how much and what exactly you know. If you (or anyone else) would like to see something specifically explained, then feel free to ask.I asked for a bit of direction and you gave me an entire script to help me achieve what I was trying to do.
No, saving is done by pressing the OK button. Did you know you can bind buttons like Enter to :DOWN, :CTRL or :F9?I suggest you check whether the same applied for Ace. -
Please don't take what I said as any kind of negative thing! I meant that you went way above and beyond and I really appreciate it. When I originally asked the question I thought I might be able to check the settings directly in Ruby without visiting Windows DLLs/registries, and I see now that it's necessary. It's something I would have had an extremely hard time doing myself.What kind of directions did you expect? Obviously, you have some programming experience, but I don't how much and what exactly you know. If you (or anyone else) would like to see something specifically explained, then feel free to ask.I am just floored right now. I'm so excited, humbled, and shocked by both your generosity and skill - I asked for a bit of direction and you gave me an entire script to help me achieve what I was trying to do. And I'm honestly having a hard time even coming up with the right words to express my appreciation, because this is amazing.
-
[HELP] I am using http://www.rpgmakervxace.net/topic/17352-inpex/
this is the picture:

but the script can't be used for menu. the menu can update and change icon button