Gamepad to Mouse: Help needed

GPC2 script programming for Titan Two. Code examples, questions, requests.

Gamepad to Mouse: Help needed

Postby SpecialEffect » Wed Jul 24, 2019 10:29 am

Looking for someone to help build a script that can do the following:

1. Convert Xbox One/PS4 gamepads (INPUT-B/USB-B) to Mouse output (OUTPUT/USB-C).

2. Use clearly labeled variables / annotation.

3. CROSS/A = LEFT-CLICK CIRCLE/B = RIGHT-CLICK TRIANGLE/Y = LEFT-CLICK TOGGLE (DRAG)

4. X = LOCK X-AXIS/LOCK Y-AXIS/FREE MOVEMENT

5. TOUCH-CLICK/VIEW/BACK/SELECT = change speed of mouse movement (slow/standard)

6. Allow the user to change slots using HOME + L1/R1 (as normal).

This would be immensely useful for some disabled users on PC (e.g. those swapping between a GUI in MAME-UI and the actual games). It may work on the new Apple iOS13 update too (via a USB adapter), which would be amazing for accessibility.

Any and all help very much appreciated.

Barre Ellis (R&D)
www.SpecialEffect.org.uk
User avatar
SpecialEffect
Sergeant Major of the Army
Sergeant Major of the Army
 
Posts: 203
Joined: Mon Apr 07, 2014 3:26 pm

Re: Gamepad to Mouse: Help needed

Postby J2Kbr » Wed Jul 24, 2019 8:12 pm

Hello Barrie,

Below the script I sent you over email extended with your above suggestions. Tested on PC and it worked. :smile0517:

Code: Select all
// Header file containing mouse related definitions
#include <mouse.gph>
 
// Variable to change the mouse movement sensitivity
fix32 sensitivity = 0.35;
 
// Toogle variable for mouse left drag
bool drag_toggle;
 
init {
    // Programatically change the output protocol to Multi HID (keyboard/mouse)
    // when this script is loaded.
    port_connect(PORT_USB_C, PROTOCOL_HID);
}
 
main {
    // TOUCH-CLICK decreases the mouse movement sensitivity
    if(event_active(BUTTON_2)) {
        if(sensitivity > 0.0) {
            sensitivity -= 0.05;
        }
    }
 
    // OPTION increases the mouse movement sensitivity
    if(event_active(BUTTON_3)) {
        if(sensitivity < 2.0) {
            sensitivity += 0.05;
        }
    }
 
    // Set mouse left drag toggle based on the button TRIANGLE
    if(event_active(BUTTON_14)) {
        drag_toggle = !drag_toggle;
    }
 
    // Run the combo that converts the gamepad input to mouse output. The combo
    // works as flow control to not overflow the host with mouse data packets.
    combo_run(Gamepad2Mouse);
}
 
combo Gamepad2Mouse {
    // Convert the gamepad X axis to mouse X movement
    if(abs(get_actual(STICK_1_X)) > 20f) {
        mouse_set(MOUSE_X, (int16)(get_actual(STICK_1_X) * sensitivity));
    }
 
    // Convert the gamepad Y axis to mouse Y movement
    if(abs(get_actual(STICK_1_Y)) > 20f) {
        mouse_set(MOUSE_Y, (int16)(get_actual(STICK_1_Y) * sensitivity));
    }
 
    // Convert the button CROSS to mouse left click
    // Also the button TRIANGLE to mouse left drag based on the toggle
    mouse_set(MBUTTON_1, (drag_toggle || get_actual(BUTTON_16)) ? TRUE : FALSE);
 
    // Convert the button CIRCLE to mouse right click
    mouse_set(MBUTTON_2, get_actual(BUTTON_15) ? TRUE : FALSE);
 
    // Flow control timing
    wait(0); wait(6);
}
 
ConsoleTuner Support Team
User avatar
J2Kbr
General of the Army
General of the Army
 
Posts: 20323
Joined: Tue Mar 18, 2014 1:39 pm

Re: Gamepad to Mouse: Help needed

Postby SpecialEffect » Thu Jul 25, 2019 11:22 am

Thank you, Jefferson. Fantastic to see the T2 able to act as a mouse. I've tweaked the code a little below...

Code: Select all
// Header file containing mouse related definitions
#include <mouse.gph>
 
// Variable to change the mouse movement sensitivity (lower number = less sensitive)
fix32 sensitivity = 0.10;
 
// Toogle variable for mouse left drag
bool drag_toggle;
 
init {
    // Programatically change the output protocol to Multi HID (keyboard/mouse)
    // when this script is loaded.
    port_connect(PORT_USB_C, PROTOCOL_HID);
}
 
main {
    // TOUCH-CLICK decreases the mouse movement sensitivity
    if(event_active(BUTTON_2)) {
        if(sensitivity > 0.05) {
            sensitivity -= 0.05;
        }
    }
 
    // OPTION increases the mouse movement sensitivity
    if(event_active(BUTTON_3)) {
        if(sensitivity < 0.06) {
            sensitivity += 0.05;
        }
    }
 
    // Set mouse left drag toggle based on the button TRIANGLE
    if(event_active(BUTTON_14)) {
        drag_toggle = !drag_toggle;
    }
 
    // Run the combo that converts the gamepad input to mouse output. The combo
    // works as flow control to not overflow the host with mouse data packets.
    combo_run(Gamepad2Mouse);
}
 
combo Gamepad2Mouse {
    // Convert the gamepad X axis to mouse X movement
    if(abs(get_actual(STICK_2_X)) > 20f) {
        mouse_set(MOUSE_X, (int16)(get_actual(STICK_2_X) * sensitivity));
    }
 
    // Convert the gamepad Y axis to mouse Y movement
    if(abs(get_actual(STICK_2_Y)) > 20f) {
        mouse_set(MOUSE_Y, (int16)(get_actual(STICK_2_Y) * sensitivity));
    }
 
    // Convert the button CROSS to mouse left click
    // Also the button TRIANGLE to mouse left drag based on the toggle
    mouse_set(MBUTTON_1, (drag_toggle || get_actual(BUTTON_16)) ? TRUE : FALSE);
 
    // Convert the button CIRCLE to mouse right click
    mouse_set(MBUTTON_2, get_actual(BUTTON_15) ? TRUE : FALSE);
 
    // Flow control timing
    wait(0); wait(6);
}
 



Simple code adjustments are to make cursor movement much slower (far too quick as it was). Also changed the mouse movement to be via the left-stick (stick 2). Much more likely to be the default choice of an accessibility controller. Some issues to iron out are...

1. I'm finding it's very hard to get good control of the cursor. Faster speeds only give me diagonals. Slow speeds sometimes only work in one or two directions. Maybe some filtering is needed/deadzone slightly increased? Tried with both a PS4 and XB1 joypad with the same problems.

2. It would be good to have just two or three speed options on a single button, for simplicity. So Touch-pad/Back/Select cycling slow/medium/fast speeds.

3. It would be great to have the "X"/Square button act as a way to cycle between X-axis movement only/Y-axis movement only/X+Y movement. Not essential, but helpful for some activities and for accuracy.

Going to try this now on an Android device and next week (all being well) on iOS13 Beta. Feels close! Thanks again.
User avatar
SpecialEffect
Sergeant Major of the Army
Sergeant Major of the Army
 
Posts: 203
Joined: Mon Apr 07, 2014 3:26 pm

Re: Gamepad to Mouse: Help needed

Postby SpecialEffect » Thu Jul 25, 2019 12:08 pm

I tested this Mouse to Gamepad script on an Android device and have found that it's detecting both mouse output + Multi HID gamepad output at the same time, making for very confusing use.

4. Is there a way to block gamepad output in a script? Or would a different Mouse only output protocol be needed perhaps?

5. Here's a video of the strange mouse pointer behaviour (diagonals and failing to register):https://youtu.be/yjMnK1qORvk

6. Would it be possible to make a special control swap between Mouse mode and Gamepad mode without having to change a slot? E.g. hold HOME and tap Back/Select/Touch-click to change to gamepad mode, and then back-again? That might be very useful too.

Sorry for all the asks!
User avatar
SpecialEffect
Sergeant Major of the Army
Sergeant Major of the Army
 
Posts: 203
Joined: Mon Apr 07, 2014 3:26 pm

Re: Gamepad to Mouse: Help needed

Postby CelticMagic » Thu Jul 25, 2019 1:50 pm

Hey Barrie
its summit to do with that combo function.
Not sure what but if yuo try this which has a simple loop counter instead it seems ok.
Note I change the speed buttons to RB & LB as I only had old controller to hand to test with.
Graham


Code: Select all
 
// Header file containing mouse related definitions
#include <mouse.gph>
 
// Variable to change the mouse movement sensitivity
fix32 sensitivity = 0.1;
 
// Toogle variable for mouse left drag
bool drag_toggle;
int16 loop_counter = 0;
 
init {
    // Programatically change the output protocol to Multi HID (keyboard/mouse)
    // when this script is loaded.
    port_connect(PORT_USB_C, PROTOCOL_HID);
}
 
main {
    // TOUCH-CLICK decreases the mouse movement sensitivity
    if(event_active(BUTTON_7)) {
        if(sensitivity > 0.0) {
            sensitivity -= 0.05;
        }
    }
 
    // OPTION increases the mouse movement sensitivity
    if(event_active(BUTTON_4)) {
        if(sensitivity < 2.0) {
            sensitivity += 0.05;
        }
    }
 
    // Set mouse left drag toggle based on the button TRIANGLE
    if(event_active(BUTTON_14)) {
        drag_toggle = !drag_toggle;
    }
 
    // Run the combo that converts the gamepad input to mouse output. The combo
    // works as flow control to not overflow the host with mouse data packets.
 
if ( loop_counter < 10)    { loop_counter++; }
else
 {
    loop_counter=0;
    // Convert the gamepad X axis to mouse X movement
    if(abs(get_actual(STICK_1_X)) > 20f) {
        mouse_set(MOUSE_X, (int16)(get_actual(STICK_1_X) * sensitivity));
    }
 
    // Convert the gamepad Y axis to mouse Y movement
    if(abs(get_actual(STICK_1_Y)) > 20f) {
        mouse_set(MOUSE_Y, (int16)(get_actual(STICK_1_Y) * sensitivity));
    }
    mouse_set(MBUTTON_1, (drag_toggle || get_actual(BUTTON_16)) ? TRUE : FALSE);
 
    // Convert the button CIRCLE to mouse right click
    mouse_set(MBUTTON_2, get_actual(BUTTON_15) ? TRUE : FALSE);
 }
 
//    combo_run(Gamepad2Mouse);
}
 
User avatar
CelticMagic
Private First Class
Private First Class
 
Posts: 2
Joined: Mon Jul 17, 2017 5:24 pm

Re: Gamepad to Mouse: Help needed

Postby J2Kbr » Thu Jul 25, 2019 2:10 pm

SpecialEffect wrote:4. Is there a way to block gamepad output in a script? Or would a different Mouse only output protocol be needed perhaps?

Yes, there is. In the Device Configuration panel (Gtuner IV) check the option "Disable Joystick from Multi Interface HID output". :smile0517:
ConsoleTuner Support Team
User avatar
J2Kbr
General of the Army
General of the Army
 
Posts: 20323
Joined: Tue Mar 18, 2014 1:39 pm

Re: Gamepad to Mouse: Help needed

Postby SpecialEffect » Thu Jul 25, 2019 4:18 pm

Even with your code, Graham, I'm still finding the translation between stick input and mouse output is bad. If I push the stick North, East, South, West I don't get anything like a nice 90 degree angle in mouse pointer movement. Thanks for trying. Maybe it's something in the driver that's not quite translating PS4/Xbox One controllers nicely.

On point 4. That's brilliant Jefferson and makes use much better, especially testing on Android OS and I'm sure it will be the case for Apple iOS13 Beta. We're very close now!

Barrie
User avatar
SpecialEffect
Sergeant Major of the Army
Sergeant Major of the Army
 
Posts: 203
Joined: Mon Apr 07, 2014 3:26 pm

Re: Gamepad to Mouse: Help needed

Postby Scachi » Thu Jul 25, 2019 5:47 pm

The Titan Two will use the last number send to the mouse axis when there is no new one send.
There is some code missing to set the mouse axis value to zero when the movement for that axis is not active or below the deadzone. This will fix the ghost diagonal movement.

I have added that + deadzone variable and multiple sensitivity values to cycle through with Option button.
You can add or remove numbers from the sensitivities array if you want to.

Touchclick has no action assigned at the moment..
Code: Select all
#pragma METAINFO("Gamepad 2 Mouse", 1, 00, "forum")
 
// Header file containing mouse related definitions
#include <mouse.gph>
 
// Variable to change the mouse movement sensitivity (lower number = less sensitive)
fix32 sensitivities[] = {0.05,0.125,0.25,0.5}; // <<- you can add or remove values here as you like using fix32 number n.n
// sensitivity_active uses first entry of sensitivities array as default, index 0 first value
uint8 sensitivity_active=0;
 
// do not move mouse on stick movements lower than deadzone value
fix32 deadzone = 20f;
 
// Toogle variable for mouse left drag
bool drag_toggle;
 
init {
    // Programatically change the output protocol to Multi HID (keyboard/mouse)
    // when this script is loaded.
    port_connect(PORT_USB_C, PROTOCOL_HID);
}
 
main {
    // TOUCH-CLICK decreases the mouse movement sensitivity
/*   
        if(event_active(BUTTON_2)) {
        if(sensitivity > 0.05) {
            sensitivity -= 0.05;
        }
    }
*/

 
    // OPTION cycle through sensitivity
    if(event_active(BUTTON_3)) {
        sensitivity_active= (sensitivity_active+1) % (sizeof(sensitivities)/4);
    }
 
    // Set mouse left drag toggle based on the button TRIANGLE
    if(event_active(BUTTON_14)) {
        drag_toggle = !drag_toggle;
    }
 
    // Run the combo that converts the gamepad input to mouse output. The combo
    // works as flow control to not overflow the host with mouse data packets.
    combo_run(Gamepad2Mouse);
}
 
combo Gamepad2Mouse {
    // Convert the gamepad X axis to mouse X movement
    if(abs(get_actual(STICK_2_X)) > deadzone) {
        mouse_set(MOUSE_X, (int16)(get_actual(STICK_2_X) * sensitivities[sensitivity_active]));
    } else mouse_set(MOUSE_X, 0);
 
    // Convert the gamepad Y axis to mouse Y movement
    if(abs(get_actual(STICK_2_Y)) > deadzone) {
        mouse_set(MOUSE_Y, (int16)(get_actual(STICK_2_Y) * sensitivities[sensitivity_active]));
    } else mouse_set(MOUSE_Y, 0);
 
    // Convert the button CROSS to mouse left click
    // Also the button TRIANGLE to mouse left drag based on the toggle
    mouse_set(MBUTTON_1, (drag_toggle || get_actual(BUTTON_16)) ? TRUE : FALSE);
 
    // Convert the button CIRCLE to mouse right click
    mouse_set(MBUTTON_2, get_actual(BUTTON_15) ? TRUE : FALSE);
 
    // Flow control timing
    wait(0); wait(6);
}
 
User avatar
Scachi
Brigadier General
Brigadier General
 
Posts: 3044
Joined: Wed May 11, 2016 6:25 am
Location: Germany

Re: Gamepad to Mouse: Help needed

Postby SpecialEffect » Thu Jul 25, 2019 9:10 pm

Thank you so much Scachi (and everyone else). That works so much better. I'd never have worked that out myself, so huge thanks. Works great on PC and Android. Will test on iOS13 Beta ASAP.

That leaves a few things to get this perfect to me....

1. Speed tweaks - as it's a bit too fast - (I'll do this thanks to the nice code suggestion).
2. Axis lock. Press X to cycle between only x-axis working/only y-axis working/free movement.

Image

3. RT/R2 = double-left-click (for those unable to do this quickly enough).
User avatar
SpecialEffect
Sergeant Major of the Army
Sergeant Major of the Army
 
Posts: 203
Joined: Mon Apr 07, 2014 3:26 pm

Re: Gamepad to Mouse: Help needed

Postby Scachi » Fri Jul 26, 2019 1:13 am

Axis locking cycle with Square button and double click with R2 added:
Code: Select all
#pragma METAINFO("Gamepad 2 Mouse", 1, 01, "forum")
 
// Header file containing mouse related definitions
#include <mouse.gph>
 
// Variable to change the mouse movement sensitivity (lower number = less sensitive)
fix32 sensitivities[] = {0.05,0.125,0.25,0.5}; // <<- you can add or remove values here as you like using fix32 number n.n
// sensitivity_active uses first entry of sensitivities array as default, index 0 first value
uint8 sensitivity_active=0;
 
// do not move mouse on stick movements lower than deadzone value
fix32 deadzone = 20f;
 
// Toogle variable for mouse left drag
bool drag_toggle;
 
// Toggle variable for axis lock. limit axis movement to: 0=x&y, 1=x, 2=y
uint8 axis_lock;
 
init {
    // Programatically change the output protocol to Multi HID (keyboard/mouse)
    // when this script is loaded.
    port_connect(PORT_USB_C, PROTOCOL_HID);
}
 
main {
    // TOUCH-CLICK decreases the mouse movement sensitivity
/*   
        if(event_active(BUTTON_2)) {
        if(sensitivity > 0.05) {
            sensitivity -= 0.05;
        }
    }
*/

 
    // OPTION cycle through sensitivity
    if(event_active(BUTTON_3)) {
        sensitivity_active= (sensitivity_active+1) % (sizeof(sensitivities)/4);
    }
 
    // Set mouse left drag toggle based on the button TRIANGLE
    if(event_active(BUTTON_14)) {
        drag_toggle = !drag_toggle;
    }
 
        // Double Left Click on the button R2/RT
        if (event_active(BUTTON_5)) combo_run(DoubleLeftClick);
 
        // axis lock , allow x&y, x only, y only on the button SQUARE/X
    if(event_active(BUTTON_17)) {
        axis_lock = (axis_lock + 1) %3;
    }
 
    // Run the combo that converts the gamepad input to mouse output. The combo
    // works as flow control to not overflow the host with mouse data packets.
    combo_run(Gamepad2Mouse);
}
 
combo DoubleLeftClick {
        mouse_set(MBUTTON_1, TRUE); wait(0); wait(6); // click
        wait(6); // release
        mouse_set(MBUTTON_1, TRUE); wait(0); wait(6); // click
        wait(6); // release
}
 
combo Gamepad2Mouse {
    // Convert the gamepad X axis to mouse X movement
    if((axis_lock==0 || axis_lock==1) && abs(get_actual(STICK_2_X)) > deadzone) {
        mouse_set(MOUSE_X, (int16)(get_actual(STICK_2_X) * sensitivities[sensitivity_active]));
    } else mouse_set(MOUSE_X, 0);
 
    // Convert the gamepad Y axis to mouse Y movement
    if((axis_lock==0 || axis_lock==2) && abs(get_actual(STICK_2_Y)) > deadzone) {
        mouse_set(MOUSE_Y, (int16)(get_actual(STICK_2_Y) * sensitivities[sensitivity_active]));
    } else mouse_set(MOUSE_Y, 0);
 
    // Convert the button CROSS to mouse left click
    // Also the button TRIANGLE to mouse left drag based on the toggle
    mouse_set(MBUTTON_1, (drag_toggle || get_actual(BUTTON_16)) ? TRUE : FALSE);
 
    // Convert the button CIRCLE to mouse right click
    mouse_set(MBUTTON_2, get_actual(BUTTON_15) ? TRUE : FALSE);
 
    // Flow control timing
    wait(0); wait(6);
}
User avatar
Scachi
Brigadier General
Brigadier General
 
Posts: 3044
Joined: Wed May 11, 2016 6:25 am
Location: Germany

Next

Return to GPC2 Script Programming

Who is online

Users browsing this forum: No registered users and 132 guests