04-07-2012 12:30 PM
Hello Logitech Gurus and the like!
So I got my G510 a couple of months ago now, and I have been hooked on making scripts for it. As I code Java on a regular basis, the possibilities of this keyboard software is awesome. I have already made tons of small scripts, but there's one thing that I haven't been able to wrap my head around.
I think the knowledge I'm lacking is polling. This way of thinking is entirely new to me.
This is basically what I wanted to do: (It doesn't really serve anything more than an dose of aesthetic awesomeness)
I'm playing FPS/TPS, and I would love a script that replaces the grenade-button. My plan is that when you hold it down, the keyboard backlight will slowly change from Green -> Red, (my keyboard backlight is green by default), depending on the grenade fuse timer. (In this case, I would want it to be red after 3600 milliseconds). I would also like it to reset to green when I release it, even if it's not done with it's color-cycle.
My problem is the whole "holding the g-button down" thing. I tried with two functions, where one is the press, and the other is the release, but I'm not quite sure how variables work in LUA, and how it should be executed without multi-threading.
I have been looking around for polling examples, but they seem a bit too complex.
I hope you guys can help me, with either an example, a guide, good advice, or a simple solution to my problem.
Thanks a bunch!
Solved! Go to Solution.
04-07-2012 12:50 PM - edited 04-07-2012 12:52 PM
i have a "simple" example here: http://www.logitechusers.com/game-profiles-macros-
it works for one G-Series only. those for 2 G-Series are more complicated... there you find also complete scripts with key-handlers integrated ..
all variables are global in Lua unless you define it "local". you can drop variable-setup in the "PROFILE_ACTIVATED" event or simply drop them in the script-body.
note: that there are plenty undocumented functions working in the "limited" G-Lua. No IO functions, but math and string stuff .. just try them ...
there are plenty color-fade scripts out there .. check the other forum or search this one for "OnEvent" .. i think its the best way to find scripts ..
04-07-2012 01:01 PM
I've never considered a color fade to keep track of timers. That's a cool idea, although not easy to create.
h0rse's script is fully capable of getting you to your goal and he's quite knowledgeable to help you through it. He has another app that's even more fun with LCD functions.
04-07-2012 01:45 PM - edited 04-07-2012 02:16 PM
Thanks both for the replies, and thanks h0rse for the links.
Could you by any chance explain the whole thing about SetMKeyState?
I read around that this is an important factor, but I don't see why, as I probably don't fully understand what it does exactly.
Or am I completely mistaken?
EDIT: I have fiddled around, and it seems like my biggest problem is not being able to interrupt the script once it's running. So far the furthest I have gotten, is a simple while loop. .__. God I suck at this.
04-07-2012 02:40 PM - edited 04-07-2012 04:32 PM
Well, let me explain the problem with the default scripts and how we get around it with SetMKeyState.
As it stands, OnEvent gets called when a G/M key is pressed and when the G/M key is released. Once inside OnEvent, no new events can be called until you exit OnEvent. This prevents you from putting in an infinite loop, because you could not handle any new events.
In order to have scripts perform actions while a key is down, or to loop until a particular event takes place, you'd need a way to have OnEvent called continuously, even when normal events are not taking place. We do this by creating a new event at the end of OnEvent calls. SetMKeyState() is the only means we have to create an event, so this is used.
You also need to make sure the SetMKeyState() calls don't multiply. For every SetMKeyState() you call, you get 2 events and if you called setMKeyState() in both those events, it will multiply and eventually crash. This also applies to G presses. So you need to have SetMKeyState() calls only happen at the end of the previous SetMKeyState() (M_RELEASE events on the proper key and family). To add one more wrinkle, you have to be able to figure out if the script created that M_RELEASE event, or if the user does, because that can cause your SetMKeyState calls to multiple.
Once you have all this in place, you have created a polling system. OnEvent is called every X milliseconds (16ms seems to be a good number due to the LGS software polling at that rate) allowing you to test elapsed times and perform scripts even when normal events are not being called.
Ok, that was not a quick description, but hopefully it helps.
One more thing, for functions that you wish to loop, I like to use coroutines, so you can yield at all time tests, or at the end of each loop to allow for OnEvent to exit and resume once the next polled event happens.
04-07-2012 03:16 PM
Brilliant! Thanks. That answered a lot of my questions. (Though it also posed a few new ones. Heh.)
I'll fiddle about with it some more I guess, when I got the time.
With this information I should be able to decode the code h0rse posted.
My thanks to you both!
04-08-2012 07:00 AM - edited 04-08-2012 07:02 AM
It works! I have fiddled around and tried a couple of things, and it seems like it works just as it should.
It's probably not at all written in a correct and proper way, but hey.. At least it works. I would love if someone could tell me what is wrong with this, as there's bound to be something!
function OnEvent(event, arg) if (event == "PROFILE_ACTIVATED") then loop = 0 counter = 0 SetBacklightColor(0, 255, 0, "kb") end if (event == "G_PRESSED" and arg == 2) then PressKey("g") loop = 1 counter = 0 Loop() end if (event == "M_RELEASED" and arg == 3) then Loop() end if (event == "G_RELEASED" and arg == 2) then ReleaseKey("g") Stoploop() end end function Loop() counter = counter + 1 if counter <= 255 then SetBacklightColor(0 + counter, 255 - counter, 0, "kb") else SetBacklightColor(255, 0, 0, "kb") end Sleep(15) if counter >= 300 then Stoploop() elseif loop == 1 then SetMKeyState(3) else Stoploop() end end function Stoploop() loop = 0 counter = 0 SetBacklightColor(0, 255, 0, "kb") end
Thanks for the help getting me this far.
04-08-2012 08:56 AM - edited 04-08-2012 08:57 AM
The only thing I'd do differently is within Loop(), I'd check if loop is on before doing anything else. It won't matter in your current use, but if you set Loop in the main body of OnEvent, it'll do unnecessary changes when it's not wanted. Assuming you might have other uses for Loop().