evilC wrote:I previously mentioned how to get better timers, but I realised that I did not point out that as far as I can tell, part of your code is not doing what you think it is.
DllCall("Sleep", UInt, 2) will not sleep for 2ms surely, will it not sleep for the min system granularity? (Probably ~15ms)
Code: Select all
start := A_TickCount
Loop 100 {
DllCall("Sleep", UInt, 2)
}
MsgBox % (A_TickCount - start) / 100
On my work system , I get ~7, not 2
If you want to get a "smooth" glide, you probably do not want sleep (Use QPX or MicroTimer instead)
To address your previous comments (Better late than never!), my general point was that your current code is based on cursor position, which suffers from a number of drawbacks:
1) You have to do calculations to find the delta change. If the cursor hits the edge of the screen, you get none.
2) Detecting that the user moved the mouse (stop glide) requires further calculations (It looks like you are saying "Well the glide alone would have put the cursor here, so if it is somewhere else, the user moved the mouse")
If you used RawInput to detect input, and a mouse_event dllcall to do the glide, then you could just check each RawInput packet for the LLMHF_INJECTED flag - if it is set, then the movement was caused your dllcall, if it is not set, the movement came from the real mouse, and so stop the glide.
Hi C !
Glad you are back!
Thanks for taking the time to go through my script. You are the only one that can help me with this madness!
Same results happen on my machine too with your code but this is not representative of how my script works. Turning
Critical On makes a huge difference but try out the snippet below for a 1 ms sleep:
Code: Select all
Critical On
TimePeriod:=1
DllCall("Winmm\timeBeginPeriod", UInt, TimePeriod)
DllCall("QueryPerformanceFrequency", "Int64*", cFr)
DllCall("QueryPerformanceCounter", "Int64*", cT0)
Loop 100 {
DllCall("Sleep", UInt, 1)
}
DllCall("QueryPerformanceCounter", "Int64*", cT1)
MsgBox % 1000*(cT1-cT0)/(100*cFr)
DllCall("Winmm\timeEndPeriod", UInt, TimePeriod)
1)
It is given that your RawInput approach has different usecases (e.g mouse + FPS games where the pointer might be locked in the center of the screen). You are right that my coordinate calculation approach might/should fail at these cases (FPS are untested, point&click strategy games work ok).
On the other hand, the extent of such instances is very limited and the practicality of playing Counterstrike on a touchpad is arguable. There is no "desktop use" scenario in which you would desire your cursor to continue gliding past the edge of the available screen. I do not want to sound dogmatic but none come to mind (it has been tested with multiple monitor setups and it works fine).
Stopping the pointers' gliding movement when hitting the edge of the screen is a constraint you always will have to enforce and a very good one to have (reduces CPU load, you can use frictionless gliding, etc).
2)
Exactly, that is how it works. The glide moves pointer at position A, sleep, get current position B, compare two coordinates, if not position A=B, user moved pointer. A detail worth pointing out here is that if the user has moved the pointer, I need to know position B (+tickcount) anyway since it is the first data point of the monitoring data for a possible new glide. Also, the time it takes for these actions is consistent making the gliding smooth-looking.
I agree that in the Gliding Loop I need to:
get tickcount, get cursor position and compare two integers which in the case of the user not moving the pointer are useless data. I like a lot the idea of improving this and would like to improve it. If RawInput works better for this I would like to try it.
Please correct my misunderstanding, when you spot any, but my worries about RawInput are the following:
a) Will it be faster? How many RawInput packets will I have to get and check for the injected flag? If I perform a buffered read I assume it will be minimum one packet, since you read your own movement. Will it be more than two or two if the user moves? Will it include other unrelated packets I must filter? [As I have noticed even simple things as calling functions are slowing my script down, I am afraid this overhead might make it slower or it might run on irregular timings (depending on number of packets in buffer etc.) making the gliding irregular].
b) In the case of unbuffered read do I risk missing the non-injected packet?
c) More importantly, I see very odd situations in regards with touchpad devices and their drivers. There are undetectable right clicks, non-standard behaviour for gestures, pre-processing of touch data etc. Reading on-screen position may not be the best but it is universal. The "traditional mouse" workings may work similarly or predictably in most cases but each touchpad I have encountered seems “custom” in the way things are implemented and I am concerned that would make RawInput hard to use.
d) I have no idea how RawInput works as far as the time/tickcount that each input happened.
Actually, if you still think that it would be OK and you have a snippet I could start with I can try it out and see how things work.