Detecting F1 Keyboard Settings?

Wavelength

MSD Strong
Global Mod
Joined
Jul 22, 2014
Messages
5,624
Reaction score
5,104
First Language
English
Primarily Uses
RMVXA
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?)
 

Shaz

Veteran
Veteran
Joined
Mar 2, 2012
Messages
40,098
Reaction score
13,704
First Language
English
Primarily Uses
RMMV
I've moved this thread to RGSS3 Script Requests. Please be sure to post your threads in the correct forum next time. Thank you.
 
Last edited by a moderator:

Milena

The woman of many questions
Veteran
Joined
Jan 26, 2014
Messages
1,281
Reaction score
106
First Language
Irish
Primarily Uses
N/A
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.
 

Wavelength

MSD Strong
Global Mod
Joined
Jul 22, 2014
Messages
5,624
Reaction score
5,104
First Language
English
Primarily Uses
RMVXA
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?
 

cremnophobia

Veteran
Veteran
Joined
Dec 10, 2013
Messages
216
Reaction score
97
Primarily Uses
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:
{ :C => ["Space", "Enter"], :B => ["Esc", "Num 0"], :A => "Shift" }
What about the gamepad?

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.
 

Wavelength

MSD Strong
Global Mod
Joined
Jul 22, 2014
Messages
5,624
Reaction score
5,104
First Language
English
Primarily Uses
RMVXA
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:
{ :C => ["Space", "Enter"], :B => ["Esc", "Num 0"], :A => "Shift" }
What about the gamepad?

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. :)

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.
 
Last edited by a moderator:

cremnophobia

Veteran
Veteran
Joined
Dec 10, 2013
Messages
216
Reaction score
97
Primarily Uses
module 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
Examples:

Code:
F1.button_assign         # including gamepadF1.button_assign(true)   # including gamepadF1.button_assign(false)  # excluding gamepad
Example output:
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"]}
 
Last edited by a moderator:

Wavelength

MSD Strong
Global Mod
Joined
Jul 22, 2014
Messages
5,624
Reaction score
5,104
First Language
English
Primarily Uses
RMVXA
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.
 

Zeriab

Huggins!
Veteran
Joined
Mar 20, 2012
Messages
1,268
Reaction score
1,422
First Language
English
Primarily Uses
RMXP
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.
 

Wavelength

MSD Strong
Global Mod
Joined
Jul 22, 2014
Messages
5,624
Reaction score
5,104
First Language
English
Primarily Uses
RMVXA
Thanks for the heads-up, Zeriab.  I'll make sure that the script can read settings that have been changed during the current session.
 

cremnophobia

Veteran
Veteran
Joined
Dec 10, 2013
Messages
216
Reaction score
97
Primarily Uses
I asked for a bit of direction and you gave me an entire script to help me achieve what I was trying to do.
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 suggest you check whether the same applied for Ace.
No, saving is done by pressing the OK button. Did you know you can bind buttons like Enter to :DOWN, :CTRL or :F9?
 

Wavelength

MSD Strong
Global Mod
Joined
Jul 22, 2014
Messages
5,624
Reaction score
5,104
First Language
English
Primarily Uses
RMVXA
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.
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.
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.
 

Users Who Are Viewing This Thread (Users: 0, Guests: 1)

Latest Threads

Latest Posts

Latest Profile Posts

Couple hours of work. Might use in my game as a secret find or something. Not sure. Fancy though no? :D
Holy stink, where have I been? Well, I started my temporary job this week. So less time to spend on game design... :(
Cartoonier cloud cover that better fits the art style, as well as (slightly) improved blending/fading... fading clouds when there are larger patterns is still somewhat abrupt for some reason.
Do you Find Tilesetting or Looking for Tilesets/Plugins more fun? Personally I like making my tileset for my Game (Cretaceous Park TM) xD
How many parameters is 'too many'??

Forum statistics

Threads
105,864
Messages
1,017,056
Members
137,573
Latest member
nikisknight
Top