Emulated analog strikes via keydown duration

Official forum for open source FreePIE discussion and development.
Post Reply
Relaxation
One Eyed Hopeful
Posts: 11
Joined: Sat Oct 10, 2015 12:53 pm

Emulated analog strikes via keydown duration

Post by Relaxation »

Hi I'm not fluent with python or much of a programmer, I stumbled upon FreePIE&vJoy combination when looking for an emulated input solution and I initially found a script that looked promising (specificly the braking/acceleration logic, a climbing value over time) but when put into the games I wanted they don't work as intended, ie changing the rate only changes the output so there isn't a weaker strike no matter how fast you let up or the values aren't consistant when its been pressed for the full length of time.

At the moment I only have a binary operation [that works consistantly] and I'm not finding any timing/stopwatch(?) samples to work off that work with FreePIE and the python standard library that was linked doesn't explain a lot of what was used in that script I linked above, which is very frustrating.

Code: Select all

if starting:    
    v = vJoy[0]
    NL_key = Key.Q
    NU_key = Key.R
    NR_key = Key.E

if keyboard.getKeyDown(NL_key):
	v.y = 12000
	v.x = -6000
elif keyboard.getKeyDown(NU_key):
	v.y = 15615
elif keyboard.getKeyDown(NR_key):
	v.y = 12000
	v.x = 6000
else:
	v.y = 0
	v.x = 0 
I'd like a way to get granular values from a 250 ms timeframe? so lets say I only held NU_key down for 125ms it would result in something like v.y = (15615 * (%of250ms)). I assume it would have to be restructured to: time KeyDown then send the value on KeyUp (values over 100% shouldn't matter).
CyberVillain
Petrif-Eyed
Posts: 2166
Joined: Mon Jun 22, 2009 8:36 am
Location: Stockholm, Sweden

Re: Emulated analog strikes via keydown duration

Post by CyberVillain »

A quick example, you should probably fix a class to encapsulate this behavior

Code: Select all

import time

if not keyboard.getKeyDown(Key.A):
	pressed = None
	
if keyboard.getKeyDown(Key.A) and pressed is None:
	pressed = time.time()

x = 0

if pressed != None:
	x = (time.time() - pressed) % 250
	
diagnostics.watch(x)
edit: time.time is in seconds so 0.250 is correct
Relaxation
One Eyed Hopeful
Posts: 11
Joined: Sat Oct 10, 2015 12:53 pm

Re: Emulated analog strikes via keydown duration

Post by Relaxation »

Thank you for responding,

I looked over a mouse to vJ script elsewhere on this forum, of which you were the author, and after reviewing some footage I found the time window was closer to 0.033 seconds [33ms] and I'm coming to the conclusion that perhaps this wasn't as viable as I had guessed after adjusting the above and previously mentioned scripts.

Again thanks for the timer sample to work off of, hope to find a use for it in the future.
HarvesteR
One Eyed Hopeful
Posts: 19
Joined: Mon Jun 15, 2015 10:30 am

Re: Emulated analog strikes via keydown duration

Post by HarvesteR »

At first glance I thought this was the same use case which prompted my PWM-analog-faking script (to fake graduated command through binary control inputs), but after reading through it, this is in fact the exact opposite scenario. You have an analog destination control which you want to actuate via variable duration taps of a binary source input....

This is something which is much easier handled from the game side, but alas, not all games implement control lerping the same, and some do it better than others.

The good news is that there is a FreePIE solution, using VJoy and a script to lerp its axes based on keys:

Code: Select all

Pseudocode (more or less):

# linear interpolation
def Lerp(v0, v1, t):
    return (v1 - v0) * t + v0

if (starting):
    global sharpness
    sharpness = 8

    global tLast
    tLast = 0


#main script loop:

deltaTime = (time.clock() - tLast)
tLast = time.clock()

# control the X axis using the A and D keys

tgtX = 0
if (keyboard.getKey(A)):
     tgtX = tgtX - 1
if (keyboard.getKey(D)):
     tgtX = tgtX + 1

vJoy[0].x = Lerp(vJoy[0].x, tgtX, sharpness * deltaTime)

# that takes care of the X axis using A and D, you'd do the same with other keys and other axes.
Multiplying 'sharpness' with the time delta between each tick of the script means the lerping rate becomes independent of the execution rate of the script itself, so it doesn't matter that much how fast it runs. The axes are always interpolating between their current position and a given 'target' position. The keys you press just set the target, and because each key just increments the target either one way or another, pressing both at the same time will cancel out at zero.

Lastly, I haven't tested this code at all... I'm not sure if it's even good python syntax as it is, but the idea behind it I know will work. This is (essentially) how keyboard controls are processed in KSP.

Hope this helps!

Cheers
Post Reply

Return to “FreePIE”