- Install vJoy
- Install FreePIE
- Configure vJoy Device No. 1 with X/Y/Z/Rx/Ry/Rz axis and 2 Buttons
- In FreePIE choose "New file" and copy/paste the script below; save it using an arbitrary name
- Run script (F5)
- Launch e.g. X-Wing Alliance
- Optional: Play imperial march
- Have fun
If you get an error stating joy[0] doesn't exist, make sure vJoy is running, and using the
Configure vJoy
tool, have the virtual joystick device stored in the number 1 slot. After a restart it may switch to slot 2 and render the script unusable.
# X-Wing Alliance FreePIE / vJoy Script v1.4
#
# based on a simple example code-snippet, which can be found here:
# https://gist.github.com/jake-lewis/e89207690cbc777fa82e9ae248b683ab
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Chaos "Fox" Overlord 2024
######################
### Initialization ###
######################
if starting:
rmbKey = Key.X #Key bound to right mouse botton
#Higher values = faster centering
centreX = 0.015
centreY = 0.03
#Sensitivities
sensX = 50
sensY = 50
sensZ = 10
viewSens = 50
#Timings
system.setThreadTiming(TimingTypes.HighresSystemTimer)
system.threadExecutionInterval = 20
#Initial values of axis / latches /etc.
x = 0
y = 0
rx = 0
ry = 0
#For unknown reasons XWA max. Throttle is reached @ -15.933,
# whilst abs(vJoy[0].axisMax) is 16382 (~ 2^15/2) for vJoy-Devices
maxZ = 15933
#For reasons also unknown, only a deltaZ of >= 772 is recognized in XWA,
# thus sufficient to reset the throttle to 100% after e.g. matching target velocity
deltaZ = 772
z = -maxZ
timeKeyPressed = 0
freelook = False
viewLatch = False
moveLatch = False
rmbLatch = False
#############################################################################
### Freelook via Numpad mapped to mouse while middle mouse button pressed ###
#############################################################################
if freelook:
x = 0
y = 0
if timeKeyPressed <= 0:
timeKeyPressed = viewSens
#rx += mouse.deltaX * viewSens
if mouse.deltaX > 0:
keyboard.setKey(Key.NumberPad6, True)
keyboard.setKey(Key.NumberPad6, False)
if mouse.deltaX < 0:
keyboard.setKey(Key.NumberPad4, True)
keyboard.setKey(Key.NumberPad4, False)
#ry += mouse.deltaY * viewSens
if mouse.deltaY > 0:
keyboard.setKey(Key.NumberPad2, True)
keyboard.setKey(Key.NumberPad2, False)
if mouse.deltaY < 0:
keyboard.setKey(Key.NumberPad8, True)
keyboard.setKey(Key.NumberPad8, False)
else:
timeKeyPressed -= system.threadExecutionInterval
if timeKeyPressed < 0:
timeKeyPressed = 0
else:
##############################################
### Mouse axis as Joystick via vJoy-Driver ###
##############################################
if mouse.deltaX:
moveLatch = True
x += mouse.deltaX * sensX
if abs(x) > vJoy[0].axisMax:
x = vJoy[0].axisMax * x / abs(x)
else:
x /= (1.0 + centreX)
if mouse.deltaY:
moveLatch = True
y += mouse.deltaY * sensY
if abs(y) > vJoy[0].axisMax:
y = vJoy[0].axisMax * y / abs(y)
else:
y /= (1.0 + centreY)
###################
### Pre mapping ###
###################
# recenter
if (not freelook and viewLatch):
rx = 0
ry = 0
viewLatch = False
#right mouse button
if (mouse.getPressed(1) or mouse.rightButton):
if (not rmbLatch):
keyboard.setKey(rmbKey, True)
keyboard.setKey(rmbKey, False)
rmbLatch = True
else:
rmbLatch = False
#code for hold freelock
freelook = mouse.getButton(2) or mouse.middleButton
#Throttle via Z-Axis mapped to mouse wheel
if (mouse.wheel):
z += mouse.wheel * sensZ
if abs(z) > maxZ - deltaZ: #Minus deltaZ to prevent Throttel "hang" after matching targets velocity
z = (maxZ - deltaZ) * z / abs(z)
####################
### vJoy mapping ###
####################
### FYI: Standard mapping ###
#vJoy[0].rx = rx
#vJoy[0].ry = ry
#vJoy[0].x = x
#vJoy[0].y = y
#vJoy[0].z = -z
### X-Wing Alliance default "weird" mapping ###
vJoy[0].rx = 0
vJoy[0].ry = 0
vJoy[0].rz = x
vJoy[0].x = 0
vJoy[0].y = -y
vJoy[0].z = -z
#Joystick buttons mapped to mouse buttons
vJoy[0].setButton(0, mouse.getButton(0) or mouse.leftButton)
## Joystick Button 2 (referenced here as 1 because the count starts at 0) without function,
## therefore right mouse button set on top of this script, e.g. "x"(rmbKey = Key.X)
#vJoy[0].setButton(1, mouse.getButton(1) or mouse.rightButton)
####################
### Post mapping ###
####################
#Prevent Throttle "hang" after matching targets velocity
if (mouse.wheel and abs(z) == maxZ-deltaZ):
z = z = maxZ * z / abs(z)
###################
### Diagnostics ###
###################
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(freelook)
diagnostics.watch(moveLatch)
diagnostics.watch(mouse.getButton(0) or mouse.leftButton)
diagnostics.watch(mouse.getButton(1) or mouse.rightButton)
diagnostics.watch(mouse.getButton(2) or mouse.middleButton)
diagnostics.watch(vJoy[0].axisMax)
Once you have completed the above steps, you should be able to control your ship with your mouse movements, use the mouse wheel as throttle, fire your weapons with the left mouse button, (un)link your weapons using the right mouse button and free-look while holding the middle mouse button.