Open tmackay opened 4 years ago
Great work! There should be no hardcoded delay - ideally there should be a timer and a dynamic delay which is easy to do (save timer and sleep only the remainder of a configurable loop delay, or at least a preprocessor defined value if not configurable). That makes slow machines not sleep at all while faster ones run as intended. The whole stick input part has been a mess and relative mouse movements should be fixed as well.
From what I can tell it effectively is dynamic - the loop is not going constantly, it seems to be event driven from the USB read (like a blocking read with timeout perhaps?). It should spend most of it's time waiting for an event, then when one is available it parses the input immediately, much quicker than the time between events. The fixed delay just ensures it spends at least 10ms (yes, should be configurable) before further waiting for the next blocking read if events are always ready (continuous and rapid stick movement).
If a slow computer is using all it's CPU on the stick there won't be much left for the game ie. this should be sleeping or waiting for a blocking read (mostly the latter) for the vast majority of the time.
After a bit more thought, I have relocated the sleep so it doesn't execute after a USB read timeout, creating windows of potential latency. This way it only really applies to rapid successive events such as stick movement. I don't feel so bad about hardcoding it to 10ms as the read timeout itself is hard coded to 100ms already. I can see some constants defined in g13.hpp and will find a home for it there.
I've been giving this a good test run in WoW and I've found the stick input to be quite flaky (bound to keys).
Looking into it, I've made some efficiency improvements. Firstly, I removed the expensive coordinate transform which was being performed every sample - instead pre-transforming the zone instead. However I have not implemented the centre or bounds calibration yet - it only applies to stickzones and TBH, I don't see the value when the bounds could simply be tweaked beforehand and don't require high resolution anyway.
This actually increased CPU usage (from around 3% to 7%) as now individual samples are processed faster and we simply read more of them - so I also added a 10ms delay in the main loop. This should not introduce latency, but limits the maximum sample frequency when the stick is rapidly moving to an unnoticeable 100Hz. This drastically reduced CPU utilization (to <1%) and seems much more responsive/reliable now.
It also seems to have eliminated (or reduced the frequency of) a USB async cancel timeout warning I was receiving occasionally.