So, you want a Relative Mouse toggle? Here it is... ### DIY GUIDE ###

@CMDR Spadino , thx a bunch for the push in the right direction(y) Respect for sharing knowledge and inspiring others, well done!
The provided solution in the OP didn't work for me at first, but thats a personal thing and is not a value judgement of any kind, can't stretch that enough!

The problem I had was 2 fold. One, the auto return function for absolute movement. The functionality is not provided in the base game, I never needed it, so I was just fighting against it. The second (and the most important) one, the liniair written relative mouse movement routine, with hard coded values. I saw what it tried to do, but it didn't come close to the relative mouse movement routine provided by the game. I have tried to combine the default in game mouse control mechanism with a virtual device and that one came close, but still no cigar. It messed with the absolute movement close to center screen movements and since I love rail guns, it was a no go for me. Abstractions need to help you, and when it comes to aiming anything less than provided by the game is a no go for me.

So I started again, and after a week of tweaking, I got this (be gentle, this is my first python script ever):
Python:
from System import Int16
global relative_x_sens, relative_y_sens, relative_x_range, relative_y_range, rel_x_speed, rel_y_speed,rel_x_speed_curve, rel_y_speed_curve, absolute_curve, controller, absolute_sens

#############################################################################################################################
# User adjustable parameters                                                                                                 #
#############################################################################################################################
                                                                                                                            #
controller = vJoy[0]                                        # the reference to the installed vJoy device                    #
absolute_curve = 3                                            # exponential factor for the ablsolute axises curve                #
absolute_sens = 20                                            # absolute mouse mode sensitivity                                #
relative_x_sens = 20                                        # relative mouse mode x sensitivity                                #
relative_y_sens = 30                                        # relative mouse mode y sensitivity                                #
relative_x_range = 300                                        # relative mouse range for x auto centering                        #
relative_y_range = 300                                        # relative mouse range for y auto centering                        #
rel_x_speed_curve = 1.5                                        # exponential factor for tweeking the x auto centering curve    #
rel_y_speed_curve = 2.2                                        # exponential factor for tweeking the y auto centering curve    #
                                                                                                                            #
#############################################################################################################################

if starting:
    # Init
    system.setThreadTiming(TimingTypes.HighresSystemTimer)
    system.threadExecutionInterval = 5 # loop delay

    max =  Int16.MaxValue*0.5+0.5   #  16384
    min = -Int16.MaxValue*0.5-0.5   # -16384
    mouse_rx = 0; mouse_ry = 0; mouse_x = 0; mouse_y = 0; mouse_x_curved = 0; mouse_y_curved = 0

    # Coordinates for self centering
    a = 0; b = 0; c = 0; d = 0

#Mouse axis definition
mouse_x += mouse.deltaX * absolute_sens          # absolute mouse, lateral
mouse_y += mouse.deltaY * absolute_sens          #                 vertical
mouse_rx += mouse.deltaX * relative_x_sens         # relative mouse, lateral
mouse_ry += mouse.deltaY * relative_y_sens         #                 vertical

# Constraining axises to max values
if (mouse_x > max): mouse_x = max
elif (mouse_x < min): mouse_x = min
if (mouse_y > max): mouse_y = max
elif (mouse_y < min): mouse_y = min

if (mouse_rx > max): mouse_rx = max
elif (mouse_rx < min): mouse_rx = min
if (mouse_ry > max): mouse_ry = max
elif (mouse_ry < min): mouse_ry = min

# Absolute mouse; lightly exponential curved axis
if (mouse_x > 0): mouse_x_curved = math.floor((math.sqrt(mouse_x ** absolute_curve) /2 ) / 64)
if (mouse_x < 0): mouse_x_curved = math.floor(-abs(math.sqrt(abs(mouse_x ** absolute_curve)) / 2 ) / 64)

if (mouse_y > 0): mouse_y_curved = math.floor((math.sqrt(mouse_y ** absolute_curve) /2 ) / 64)
if (mouse_y < 0): mouse_y_curved = math.floor(-abs(math.sqrt(abs(mouse_y ** absolute_curve)) / 2 ) / 64)

# Writing absolute output to controller
controller.x = filters.deadband(mouse_x_curved, 25)
controller.y = filters.deadband(mouse_y_curved, 25)

# Relative mouse; self centering axis routine
a += mouse.deltaX
b += mouse.deltaX

if filters.stopWatch(True,60): c = a + 0
if filters.stopWatch(True,30): d = b + 0

if (c - d == 0):
    if mouse_rx < -(relative_x_range): mouse_rx += math.sqrt(abs(mouse_rx)) * rel_x_speed_curve
    elif mouse_rx > relative_x_range: mouse_rx -= math.sqrt(abs(mouse_rx)) * rel_x_speed_curve

    if mouse_ry < -(relative_y_range): mouse_ry += math.sqrt(abs(mouse_ry)) * rel_y_speed_curve
    elif mouse_ry > relative_y_range: mouse_ry -= math.sqrt(abs(mouse_ry)) * rel_y_speed_curve

# Writing relative output to controller
controller.rx = filters.deadband(mouse_rx, relative_x_range)
controller.ry = filters.deadband(mouse_ry, relative_y_range)

##### Diagnostics
diagnostics.watch(controller.rx)
diagnostics.watch(controller.ry)
diagnostics.watch(controller.x)
diagnostics.watch(controller.y)

This script does nothing with the SRV. No sliders, no extra faf. It does contain a feeder for absolute mouse movements with a progressive curve, similar to the one in the OP. The feeder for the relative mouse movement is new, and contains a progressive adjustable curve per axis. So you can tweak the Y and X axis apart from each other (same goes for the sensitivities). Myself, I've yaw on x-axis and pitch on y. I role with Q and E. If you need anything different, have fun :) After tweaking for a couple of days, the new relative routine performs the same way as the one the game provides, or at least I can't notice any differences with the way my controller was setup before all this.

Now, to anyone new to this, follow everything in the opening post. Yes, you need to install 2 seperate tools in order to get this to work, but after that you end up with a great virtual controller system you can use for any game. I was sceptical at first, but love it after a week! When you run the above script and get an error about a controller not being found, edit controller = vJoy[0]. The index 0 is the position where the virtual device is found in the collection of virtual VJoy controllers known to the operating system. I have no controllers then the default virtual one, so mine is at 0 (the first, its zero based, sry for the confusion). If you have more then 1 virtual controller, you'll know how to fix this.

Only thing that is missing in the OP is a clear description how to bind all this to ED. Here is where some users tend to go wrong, they think it doesn't work and move on. Which is a waste, because it does work, marvelously.

When you have the virtual controller working, you basically have an XBox controller with 2 joystick. Both are controlled by your mouse. So go to the in game controller options and bind the main joystick movements. Now setup the alternate flight controller options (further down the settings) in the same way. Now, I hear you think "Wait? You said 1 controller with 2 joystick driven by one mouse, how can ED distinguish one stick from the other when setting the bindings?", exactly, it can't. So after setting up the bindings, you end up with the main AND alternate controller doing the same thing. You need to exit the game and edit the bindings file and correct that yourself. You have 2 sticks, so 4 axisses. After setting up the bindings in game, you need to correct 2 axises to the ones ED did not see during configuration. This is crucial. If you don't do this, its not going to work well.

PRO TIP:

While you are in the settings file, bind the same key you use to toggle Flight Assist to the toggle function of the Alternative Controller. The in game settings GUI doesn't let you do it, but the game supports it nonetheless.
 
Last edited:
Both OP and Vandaahl are awesome.

The new script provided by Vandaahl is an improvement from the original
as it removes the jerky movement while aiming with fixed HP in FAOFF.

OP should really take a look and incorporate the change to the main github
 
Only thing that is missing in the OP is a clear description how to bind all this to ED.
You need to exit the game and edit the bindings file and correct that yourself.

Thanks but you didn't do a much better job of describing this either.
What part do we edit exactly? What are the correct values?
Maybe a snip of your correction would help guide us through this.
Thx. o7
X.
 
Man, I'm so glad it's Friday!

tenor2.gif
 
Comprehensive DIY guide for a working and reliable Relative Mouse Toggle

i've no need for this but you sir, you deserve an applause.

and frontier a resounding "booo" for their antics about "skill based" mechanics that merely exploit controller limitations. well, there's another one going down, for anyone to enjoy! \o/
 
Thanks but you didn't do a much better job of describing this either.
What part do we edit exactly? What are the correct values?
Maybe a snip of your correction would help guide us through this.
Thx. o7
X.
Do you have your main controller working (forget about the alternate controller for now)?
In other words, can you fly the ship FA ON with your mouse using VJoy and FreePIE together with the provided script?
 
Last edited:
I'm all about cool control things for ED but I may have missed something.
What is a "relative mouse?" What exactly does this do in-game? And is it better then a (if any) alternative?

For anyone playing FA-off on a regular basis, Relative-Mouse-Axis-Toggle is an absolute necessity. It boggles my mind that FDEV hasn't provided this yet. So thank you, OP, for this fix. I might try it out -- although I'm always scared as hell to dabble in scripts.
 
Both OP and Vandaahl are awesome.

The new script provided by Vandaahl is an improvement from the original
as it removes the jerky movement while aiming with fixed HP in FAOFF.

OP should really take a look and incorporate the change to the main github
Thanks, glad you like it. I got a first draft ready that supports pip management on the mouse wheel. The raw and most complex stuff is working, so if interested, I might update the current one. I'll see if the OP is still around and try to work out an update of the original script.
 
Do you have your main controller working (forget about the alternate controller for now)?
In other words, can you fly the ship FA ON with your mouse using VJoy and FreePIE together with the provided script?

Not really because I already use vJoy for JoystickCurves and it insists in using Vdev01, or whatever it's called.
If I set it to use Vdev02 it stops working. Plus I have to use GlovePIE+PPjoy for my rudder pedals (G27). It's a mess.
I have to iron out those issues first. Thanks for the reply though. Will get back to this later. o7
X.
 
Not really because I already use vJoy for JoystickCurves and it insists in using Vdev01, or whatever it's called.
If I set it to use Vdev02 it stops working. Plus I have to use GlovePIE+PPjoy for my rudder pedals (G27). It's a mess.
I have to iron out those issues first. Thanks for the reply though. Will get back to this later. o7
X.
Ok. Dunno your setup, but adding an axis (like pedals) to the existing script is easy, compared to the other faff I had to go through to get the relative curves to work. So maybe you can bin the current scripted stuff and start from scratch with a clean setup and script. Adding more abstractions to the current equation causes headaches...

Anyway, once you get the main controller to work and mapped thought the game UI, the part you need to go through is this:
When you have the virtual controller working, you basically have an XBox controller with 2 joystick. Both are controlled by your mouse. So go to the in game controller options and bind the main joystick movements. Now setup the alternate flight controller options (further down the settings) in the same way. Now, I hear you think "Wait? You said 1 controller with 2 joystick driven by one mouse, how can ED distinguish one stick from the other when setting the bindings?", exactly, it can't. So after setting up the bindings, you end up with the main AND alternate controller doing the same thing. You need to exit the game and edit the bindings file and correct that yourself. You have 2 sticks, so 4 axisses. After setting up the bindings in game, you need to correct 2 axises to the ones ED did not see during configuration. This is crucial. If you don't do this, its not going to work well.

It basically means, to get the alternate controller mapped, I had to exchange the mapped values in the Bindings.binds file of the alternate controller from this:
XML:
    <YawAxisAlternate>
        <Binding Device="vJoy" Key="Joy_XAxis" />
        <Inverted Value="0" />
        <Deadzone Value="0.00000000" />
    </YawAxisAlternate>
    <PitchAxisAlternate>
        <Binding Device="vJoy" Key="Joy_YAxis" />
        <Inverted Value="0" />
        <Deadzone Value="0.00000000" />
    </PitchAxisAlternate>

to this:
XML:
    <YawAxisAlternate>
        <Binding Device="vJoy" Key="Joy_RXAxis" />
        <Inverted Value="0" />
        <Deadzone Value="0.00000000" />
    </YawAxisAlternate>
    <PitchAxisAlternate>
        <Binding Device="vJoy" Key="Joy_RYAxis" />
        <Inverted Value="0" />
        <Deadzone Value="0.00000000" />
    </PitchAxisAlternate>

Joy_XAxis -> Joy_RXAxis
Joy_YAxis -> Joy_RYAxis

Thats it.
 
Ok. Dunno your setup, but adding an axis (like pedals) to the existing script is easy, compared to the other faff I had to go through to get the relative curves to work. So maybe you can bin the current scripted stuff and start from scratch with a clean setup and script. Adding more abstractions to the current equation causes headaches...

Anyway, once you get the main controller to work and mapped thought the game UI, the part you need to go through is this:


It basically means, to get the alternate controller mapped, I had to exchange the mapped values in the Bindings.binds file of the alternate controller from this:
XML:
    <YawAxisAlternate>
        <Binding Device="vJoy" Key="Joy_XAxis" />
        <Inverted Value="0" />
        <Deadzone Value="0.00000000" />
    </YawAxisAlternate>
    <PitchAxisAlternate>
        <Binding Device="vJoy" Key="Joy_YAxis" />
        <Inverted Value="0" />
        <Deadzone Value="0.00000000" />
    </PitchAxisAlternate>

to this:
XML:
    <YawAxisAlternate>
        <Binding Device="vJoy" Key="Joy_RXAxis" />
        <Inverted Value="0" />
        <Deadzone Value="0.00000000" />
    </YawAxisAlternate>
    <PitchAxisAlternate>
        <Binding Device="vJoy" Key="Joy_RYAxis" />
        <Inverted Value="0" />
        <Deadzone Value="0.00000000" />
    </PitchAxisAlternate>

Joy_XAxis -> Joy_RXAxis
Joy_YAxis -> Joy_RYAxis

Thats it.
(y)
 
Not sure I've experienced a use case for this but I want to pimp the Logitech MX Ergo. An update to the only other trackball I can tolerate , the M570.

It has a few features related to this. One is a button to make that changes the mouse movement to fine movements. The other is it can be linked to two computers.

It has other features, such as 7 buttons and you can alter its rest angle between two settings. The fine movement button was really what I was thinking about here.
 
Great script. I made two additions of my own that I find useful:

Code:
# Fixes drifting when using headlook key (my headlook key is backslash)
if keyboard.getPressed(Key.Backslash):
    if isEnabled:
        isEnabled = False           
    else:
        isEnabled = True
        mouseX -= mouse.deltaX
        mouseY -= mouse.deltaY
        mouseRX -= mouse.deltaX
        mouseRY -= mouse.deltaY

# centers when switching to FA-On from FA-Off (my FA-on/off key is Z)
if keyboard.getPressed(Key.Z):
    mouseX = 0
    mouseY = 0
    mouseXcurved = 0
    mouseYcurved = 0

For the above to work, you have to add a new variable named isEnabled, like so:

Code:
if starting:
    # Timer, for auto-centering
    system.setThreadTiming(TimingTypes.HighresSystemTimer)
    system.threadExecutionInterval = 1 # loop delay - controls how often the script updates -- 5 is fine, lower for more updates (1 = 1000 times per second, 2 = 500, etc.)   
    # Devices and axis initializing
    device = vJoy[0]
    max =  Int16.MaxValue*0.5+0.5   #  16384
    min = -Int16.MaxValue*0.5-0.5   # -16384
    mouseX    = 0; mouseY    = 0; mouseXcurved = 0; mouseYcurved = 0; mouseRX = 0; mouseRY = 0; joyX = 0; joyY = 0; joyXcurved = 0; joyYcurved = 0   
    # Coordinates for self centering
    a = 0; b = 0; c = 0; d = 0
    # toggle -- added
    isEnabled = True

And then encapsulate the guts of the script in an if block that checks isEnabled, like so:

Code:
if isEnabled:
    # axis definition
    mouseX += mouse.deltaX * absolute_sens      # absolute mouse, lateral
    mouseY += mouse.deltaY * absolute_sens      #                 vertical
    mouseRX += mouse.deltaX * relative_x_sens   # relative mouse, lateral
    mouseRY += mouse.deltaY * relative_y_sens   #                 vertical
    ... the rest of the code

Also, thanks Vandaahl -- I very much enjoyed your modifications.
 
Last edited:
Top Bottom