Post subject: EmuLua functions: Getting the most out of input.get()
Editor, Skilled player (1171)
Joined: 9/27/2008
Posts: 1085
First, the basics of input.get() It is a function that you call without any parameters. It returns a table containing true for all key values representing keys currently pressed on the keyboard, as well as whether mouse buttons are pressed and coordinates of the mouse relative to the emulator's window. I could, for example, put keys = input.get() somewhere in my code, and somewhere else, I can simply do if keys["A"] then to check whether the A key is currently held. Having good control over input.get() means that your script has interactivity beyond just you tinkering with its code and changing its internal variables. You can have code that changes these internal variables on the fly, or even run many different functions, at a press of a single key, whenever you want. Sure beats restarting the script from scratch just because you didn't like its opacity. What are all the key values? I could put a list here, but I feel it would be vastly more informative to give you a lua script for yourself to test instead. Run it, and press any keys you desire to find out the key's name. Download KeyCheck_v1.lua
Language: lua

local function KeyCheck() local T= input.get() local y= 2 for k,v in pairs(T) do gui.text(2,y,k) y=y+10 end end gui.register(KeyCheck)
Tried this script yet? There are a few caveats with this script, such as the fact it makes no attempt to screen out things like xmouse or ymouse. On the other hand, the script does reveal every key currently held, and I really hope you have no trouble picking past the xmouse and ymouse to find out what the key is. We'll improve on this script later, after I explain better ways of dealing with input.get(). How do we detect when the user presses a key? I've already outlined how one could detect when a key is held, by having typed keys = input.get() and later if keys["A"] then as an example of looking for when the A key is held. However, there are times we want to execute code only once per key press. Maybe you're counting how many times the user pressed space, and you don't want the counter zooming upwards at a rapid pace when it's being held. My favorite method for detecting a key press in EmuLua stuff is as follows: Download PressKey.lua
Language: lua

local keys, lastkeys= input.get(), input.get() local function UpdateKeys() lastkeys= keys; keys= input.get() end local function Press(k) return keys[k] and (not lastkeys[k]) end local function Fn() -- Test function to use the above. UpdateKeys() -- Call this once, and only once per loop! if Press("space") then print("Congratulations! You pressed space! Have a cookie.") end if Press("A") then print("That's the keyboard's A key! That's not a controller A button!") end end gui.register(Fn)
In the code above, I keep two tables. keys is the current keys held, and lastkeys keeps whatever was held a rather short moment ago. I need this so I can tell the moment the user pushes the key down, and not repeatedly run the same code when it is instead held. This is pretty crucial to detecting key presses. Hopefully, UpdateKeys() and Press(k) are short enough that you don't need me to identify what they do. I should hope even a beginner can understand what the code does. There is one further bit of trickery with input.get() one can do. One that makes it easier to handle binding functions to hotkeys in lua code, so to speak. From the above code, you might be doing something like this:
Language: lua

if Press(SomeLetter) then --Insert code or function calls here end if Press(SomeOtherLetter) then --Insert even more code, or possibly function calls here end --Repeat for every function. Wow, this feels inconvenient.
However, when copying or moving this code around, you might end up having to mess with the tabs or spaces to keep it readable. Or if making a new function, you have to add a call here. For you coders, there is a way to streamline the function creation and, at the same time, let the lua code call the function at a key press, without needing to add a call elsewhere in code. My method is simply as follows: Download EmuLuaHotkeyFn.lua
Language: lua

local keys, lastkeys= input.get(), input.get() local function UpdateKeys() lastkeys= keys; keys= input.get() end local KF= {} local function KeyFunctions() UpdateKeys() for key,v in pairs(keys) do if not lastkeys[key] then if KF[key] then KF[key]() end end end end gui.register(KeyFunctions) KF["space"]= function () print("That thing you pressed is the space bar.") end KF["A"]= function () print("Please insert more useful code here.") end
KeyFunctions() uses pairs(keys) to walk through all the currently held keys, and specifically checks if they were pressed or simply held by using lastkeys. If a key was indeed pressed and not held since last update, it will look into KF to see if there exists something there. If so, it will call it as a function. As for creating functions to be placed into table KF, note how I do it. I pick a key, use it as an index for KF, and set whatever I indexed equal to a function, which I define on the spot. I don't need to add a function call to some sort of Master List of function calls, as KeyFunctions() handles that for me for any functions I stick into table KF. But that is more for larger scale projects that use numerous different functions for all the keyboard hotkeys you need to set. In any case, I said earlier that I would improve on the KeyCheck script above, and I will. All it takes is a minor tweak to KeyFunctions. Instead of calling a function in KF, we'll just stick what key we got into some string, which we'll display on screen... Download KeyCheck_v2.lua
Language: lua

local keys, lastkeys= input.get(), input.get() local function UpdateKeys() lastkeys= keys; keys= input.get() end local LastPress= "Nothing, yet." local function KeyCheck2() UpdateKeys() for key,v in pairs(keys) do if not lastkeys[key] then LastPress= key end end gui.text(2,2,LastPress) end gui.register(KeyCheck2)
Now it's a lot less messy of a display. It shows just one key, the last one you've pressed, none of this mess with xmouse and all that. These are a few things that come to mind when handling input.get(). It's a very useful function, and if you ever want to create some interaction with any script, knowing a few tricks can really help with some problems of how to deal with the user's input in a clean way. But if all you make are throwaway scripts that only display RAM values, with possibly a few calculations to them... None of this will really apply. But when you start stepping into a point where you think something along the lines of "I hate having to edit and restart this script just to change this one value over and over," consider the idea of implementing input.get() into the code to change value for you.
Dragos-san
Other
Joined: 11/4/2019
Posts: 21
Location: Apple Macbook Pro (Early 2015)
So I have no experience programming, but... What if you could use that program to form a sort of mobility file? Ie input.get() results will automatically record on a separate document. Then it looks a lot better visually to newbies like me and human speedrunners. Like this: [Frame 1] A-press + B-press [Frame 2] A-release + B-hold [Frame 3] A-press + B-release + C-press
Thank you and have a nice week! :)