Last active
August 16, 2022 10:07
-
-
Save cyberluke/baaadd29bd01fcd6d6e47de3569c3482 to your computer and use it in GitHub Desktop.
FreePIE_Thrustmaster_HOTAS_Gameport_Win10.py - Mark II Weapon System converting PS/2 keyboard input to vJoy joystick device (need to create vJoy joystick manually: in vJoy configuration check: X,Y,Z,Rx,Ry,Rz,Slider,Slider2 and POV select 1 - continuous), number of buttons: 8
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
if starting: | |
import time | |
import math | |
#The following is the tweakaxis function. Don't change this unless you know how to program. Call on this function in the Axis Rebinds section. | |
def tweakaxis(input, input_range_min, adjusted_center, input_range_max, dband): | |
if input >= adjusted_center: | |
return filters.ensureMapRange(input, adjusted_center + dband, input_range_max, 0, 1000) | |
elif input <= adjusted_center: | |
return filters.ensureMapRange(input, input_range_min, adjusted_center - dband, -1000, 0) | |
else: | |
return 0 | |
#The tweakaxis function's variables explained: | |
#input:-------------This specifies the input (usually a real joystick axis) to be modified. | |
#input_range_min:---The value of the input to map to the tweaked output's full minimum. Use -1000 for an unchanged endpoint on conventional joysticks. | |
#adjusted_center:---The value of the input to map to the tweaked output's center. Assign a new center point to your joystick's axis with this value. | |
#input_range_max:---The value of the input to map to the tweaked output's full maximum. Use 1000 for an unchanged endpoint on conventional joysticks. | |
#dband:-------------Deadband. The distance that you must move the input away from adjusted_center before the smallest value is output. | |
#Tips: | |
#input_range_min and _max can be changed to alter the effective range of an axis on a physical device. | |
#For example, it can be used to halve the stick travel distance for the full range of outputs by using a _min of -500 and a _max of 500. | |
#If making asymmetrical changes to the input_range values, remember to consider whether adjusted_center needs to bisect those values. | |
#Using values for these vars with absolute value greater than 1000 (again, for most sticks) will result in more precision by sacrificing access to the output values at the extremities. | |
#tweakaxis() is meant to be composed, including with itself. The order matters greatly. The true power of the script lies here. | |
#Enclose every set of functions in this before setting a vJoy axis equal to it: | |
def vJR(input): | |
return filters.ensureMapRange(input, -1000, 1000, -vJoy[0].axisMax, vJoy[0].axisMax) | |
#Curve functions: | |
#Basic x^n curve: | |
def powcv(input, curvepower, min = -1000, max = 1000): | |
if input >= 0: | |
return filters.ensureMapRange(math.pow(input, curvepower), 0, math.pow(max, curvepower), 0, max) | |
else: | |
return filters.ensureMapRange(-math.pow(-input, curvepower), -math.pow(-min, curvepower), 0, min, 0) | |
#Fancy -((1-x)^n)+1 curve, made origin-symmetric: | |
#Use 0 << n << 1 for best results, with small f''(x) for small x and large f''(x) for large x. | |
def revrootcv(input, curvepower, min = -1000, max = 1000): | |
if input >= 0: | |
return filters.ensureMapRange(1-math.pow(1-filters.ensureMapRange(input, 0, max, 0, 1), curvepower), 0, 1, 0, max) | |
else: | |
return filters.ensureMapRange(-1+math.pow(1-filters.ensureMapRange(-input, 0, -min, 0, 1), curvepower), -1, 0, min, 0) | |
#Master-controlled scaling for inputs: | |
#The variable limits created converge on the center of whichever function is directly inside it. | |
#"master" switch made to easily determine which control to use. | |
def mscale(input, master = 0): | |
if master == 0: #Positional master | |
scalevalue = filters.ensureMapRange(-joystick[2].x, 0, 1000, 0.15, 1) | |
if joystick[2].x > 990: | |
scalevalue = 0 | |
return input * scalevalue | |
elif master == 1: #Rotational master | |
scalevalue = filters.ensureMapRange(joystick[2].zRotation, -990, 990, 0, 1) | |
return input * scalevalue | |
else: | |
return 0 | |
#Change axis_mult if 'Windows output: vJoy' axes have the wrong range of motion. | |
# (They should match the correspondingly bound values of | |
# 'Windows output: Physical' 1 and 2 exactly.) | |
axis_mult = (vJoy[0].axisMax / 1000) | |
t0 = time.clock() | |
#Joystick button to keyboard button variable function | |
def jkey(j_index, j_button, keybind): | |
if joystick[j_index].getDown(j_button): | |
keyboard.setKeyDown(keybind) | |
else: | |
keyboard.setKeyUp(keybind) | |
#Joystick button to keyboard button variable function | |
def keyj(Key, j_button): | |
if keyboard.getKeyDown(Key): | |
vJoy[0].setButton(j_button, 1) | |
else: | |
vJoy[0].setButton(j_button, 0) | |
def keyCodeToNumber(key): | |
if (key == Key.D1): | |
return -16535 | |
if (key == Key.D2): | |
return -12258 | |
if (key == Key.D3): | |
return -8192 | |
if (key == Key.D4): | |
return -4096 | |
if (key == Key.D5): | |
return 0 | |
if (key == Key.D6): | |
return 4096 | |
if (key == Key.D7): | |
return 8192 | |
if (key == Key.D8): | |
return 12258 | |
if (key == Key.D9): | |
return 16535 | |
#Joystick button to keyboard button variable function | |
def keyaxis(key): | |
if keyboard.getKeyDown(key): | |
vJoy[0].z = keyCodeToNumber(key) | |
#Joystick button to vJoy button variable function | |
def jvjb(j_index, j_button, vjoy_button): | |
if joystick[j_index].getDown(j_button): | |
vJoy[0].setButton(vjoy_button, 1) | |
else: | |
vJoy[0].setButton(vjoy_button, 0) | |
#Axis rebinds | |
#Adding 1 before multiplying by axis_mult seems to compensate for | |
# a one step offset in the vJoy driver itself. | |
vJoy[0].x = (joystick[0].x + 1 ) * axis_mult | |
vJoy[0].y = (joystick[0].y + 1 ) * axis_mult | |
#vJoy[0].z = (joystick[0].zRotation + 1 ) * axis_mult | |
#vJoy[0].slider = (joystick[2].sliders[0] * -1 + 1 ) * axis_mult | |
#vJoy[0].dial = (joystick[2].sliders[0] * -1 + 1 ) * axis_mult | |
if (joystick[2].zRotation != 1000): | |
#vJoy[0].rz = (joystick[2].zRotation * -1 + 1 ) * axis_mult | |
vJoy[0].rz = 10*vJR(mscale(tweakaxis(joystick[2].zRotation, -1000, 0, 0, 1))) | |
elif (joystick[2].sliders[0] != 1000): | |
vJoy[0].rz = -10*vJR(mscale(tweakaxis(joystick[2].sliders[0], -1000, 0, 0, 1))) | |
else: | |
vJoy[0].rz = 0 | |
vJoy[0].setAnalogPov(0, joystick[0].pov[0]) | |
joystick[0].pov[0]=0 | |
joystick[0].pov[1]=0 | |
joystick[1].pov[0]=0 | |
joystick[1].pov[1]=0 | |
#Button rebinds | |
jvjb(0, 0, 0) | |
jvjb(0, 1, 1) | |
jvjb(0, 2, 2) | |
jvjb(0, 3, 3) | |
jvjb(0, 4, 4) | |
jvjb(0, 5, 5) | |
jvjb(0, 6, 6) | |
jvjb(0, 7, 7) | |
keyaxis(Key.D1) | |
keyaxis(Key.D2) | |
keyaxis(Key.D3) | |
keyaxis(Key.D4) | |
keyaxis(Key.D5) | |
keyaxis(Key.D6) | |
keyaxis(Key.D7) | |
keyaxis(Key.D8) | |
keyaxis(Key.D9) | |
#FreePIE "Watch" tab joystick state monitors | |
#System values for vJoy simulated device | |
diagnostics.watch(joystick[2].sliders[0]) | |
diagnostics.watch(joystick[2].zRotation) | |
diagnostics.watch("Windows output: vJoy") | |
diagnostics.watch(joystick[0].getDown(0)) | |
diagnostics.watch(joystick[0].getDown(1)) | |
diagnostics.watch(joystick[0].getDown(2)) | |
diagnostics.watch(joystick[0].getDown(3)) | |
diagnostics.watch(joystick[0].getDown(4)) | |
diagnostics.watch(joystick[0].getDown(5)) | |
diagnostics.watch(joystick[0].getDown(6)) | |
diagnostics.watch(joystick[0].getDown(7)) | |
diagnostics.watch(joystick[0].getDown(8)) | |
diagnostics.watch(joystick[0].getDown(9)) | |
diagnostics.watch(joystick[0].getDown(10)) | |
diagnostics.watch(joystick[0].getDown(11)) | |
diagnostics.watch(joystick[0].getDown(12)) | |
diagnostics.watch(joystick[0].getDown(13)) | |
diagnostics.watch(joystick[0].getDown(14)) | |
diagnostics.watch(joystick[0].getDown(15)) | |
diagnostics.watch(joystick[0].sliders[0]) | |
diagnostics.watch(joystick[0].sliders[1]) | |
diagnostics.watch(joystick[0].x) | |
diagnostics.watch(joystick[0].y) | |
diagnostics.watch(joystick[0].z) | |
#diagnostics.watch(joystick[0].xRotation)) FreePIE does not support these two values | |
#diagnostics.watch(joystick[0].yRotation)) EDIT: Jan 2015: It does now! | |
diagnostics.watch(joystick[0].zRotation) | |
diagnostics.watch(joystick[0].pov[0]) | |
diagnostics.watch(joystick[0].pov[1]) | |
#vJoy driver internal values | |
# (axes only, vJoy driver button values are not readable in FreePIE) | |
diagnostics.watch("vJoy driver values") | |
diagnostics.watch(vJoy[0].x) | |
diagnostics.watch(vJoy[0].y) | |
diagnostics.watch(vJoy[0].z) | |
diagnostics.watch(vJoy[0].rx) | |
diagnostics.watch(vJoy[0].ry) | |
diagnostics.watch(vJoy[0].rz) | |
diagnostics.watch(vJoy[0].slider) | |
diagnostics.watch(vJoy[0].dial) | |
#Physical joystick 1 | |
diagnostics.watch("Windows output: Physical 1") | |
diagnostics.watch(joystick[1].getDown(0)) | |
diagnostics.watch(joystick[1].getDown(1)) | |
diagnostics.watch(joystick[1].getDown(2)) | |
diagnostics.watch(joystick[1].getDown(3)) | |
diagnostics.watch(joystick[1].getDown(4)) | |
diagnostics.watch(joystick[1].getDown(5)) | |
diagnostics.watch(joystick[1].getDown(6)) | |
diagnostics.watch(joystick[1].getDown(7)) | |
diagnostics.watch(joystick[1].sliders[0]) | |
diagnostics.watch(joystick[1].x) | |
diagnostics.watch(joystick[1].y) | |
diagnostics.watch(joystick[1].zRotation) | |
diagnostics.watch(joystick[1].pov[0]) | |
#Script execution time tracker | |
totaltime = time.clock() - t0 | |
diagnostics.watch(totaltime) | |
"""""" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment