Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save ChaosFoxOverlord/5b8d59b3591f02f4f3b2701e51fa6547 to your computer and use it in GitHub Desktop.
Save ChaosFoxOverlord/5b8d59b3591f02f4f3b2701e51fa6547 to your computer and use it in GitHub Desktop.
FreePIE and vJoy: Mouse as joystick for X-Wing Alliance, TFTC and others

Installation and Usage

  1. Install vJoy
  2. Install FreePIE
  3. Configure vJoy Device No. 1 with X/Y/Z/Rx/Ry/Rz axis and 2 Buttons
  4. In FreePIE choose "New file" and copy/paste the script below; save it using an arbitrary name
  5. Run script (F5)
  6. Launch e.g. X-Wing Alliance
  7. Optional: Play imperial march
  8. 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.

Script

# 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)

Conclusion

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.

Links

Steam Community Guide

Credits

Based on a Gist by Jake Lewis

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment