Gamepad to Mouse: Help needed

GPC script programming for Titan Two device. Code examples, how to, questions, requests.

Moderators: The_Rabid_Taco, pablosscripts, bonefisher

Re: Gamepad to Mouse: Help needed

Postby SpecialEffect » Fri Jul 26, 2019 6:30 pm

Massive thanks again. I'll be testing this out first thing next week.
User avatar
SpecialEffect
Command Sergeant Major
Command Sergeant Major
 
Posts: 165
Joined: Mon Apr 07, 2014 3:26 pm

Re: Gamepad to Mouse: Help needed

Postby SpecialEffect » Mon Jul 29, 2019 9:42 am

Absolutely brilliant work Scachi, thank you so much.

I've tweaked the code annotations and speed here:

Code: Select all
#pragma METAINFO("Gamepad 2 Mouse", 1, 01, "Scachi/J Koppe/G Law/B Ellis (SpecialEffect)")
// 29/7/2019
// Created for www.SpecialEffect.org.uk - PUBLIC DOMAIN
// viewtopic.php?f=26&t=13195
// Designed to convert a PS4/Xbox gamepad to Mouse use. Controls are...
 
// LEFT-STICK = MOUSE MOVEMENT
// CROSS/A = LEFT-CLICK
// CIRCLE/B = RIGHT-CLICK
// TRIANGLE/Y = DRAG ON/OFF
// SQUARE/X = AXIS LOCK (X-AXIS / Y-AXIS / FREE MOVEMENT)
// R2/RT = DOUBLE-LEFT-CLICK
 
// HOLD R2/RB + TAP HOME = CHANGE SLOT +1 (e.g. to Forced Xbox 360 Gamepad mode)
// HOLD L2/LB + TAP HOME = CHANGE SLOT -1
 
 
 
// Header file containing mouse related definitions
#include <mouse.gph>
 
 
 
// MOUSE SPEED VARIABLE(0.02 slowest speed)
fix32 sensitivities[] = {0.08,0.02}; // <<- you can add or remove several 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;
 
// DEADZONE
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 {
    // FORCE HID (MOUSE) OUTPUT PROTOCOL.
    // N.B. Tick "Disable Joystick from Multi Interface HID output" in GTuner IV > Device Configuration > Device Options !!!!
    port_connect(PORT_USB_C, PROTOCOL_HID);
}
 
main {
 
     // TOUCH/VIEW/BACK button = SPEEED adjustment
    if(event_active(BUTTON_2)) {
        sensitivity_active= (sensitivity_active+1) % (sizeof(sensitivities)/4);
    }
 
    // TRIANGLE/Y = DRAG ON/OFF
    if(event_active(BUTTON_14)) {
        drag_toggle = !drag_toggle;
    }
 
        // R2/RT = DOUBLE-LEFT CLICK
        if (event_active(BUTTON_5)) combo_run(DoubleLeftClick);
 
        // SQUARE/X = AXIS LOCK (X-AXIS/Y-AXIS/FREE MOVEMENT)
    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 {
    // LEFT-STICK X-AXIS TO MOUSE X-AXIS
    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);
 
    // LEFT-STICK Y-AXIS TO MOUSE Y-AXIS
    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);
 
    // CROSS/A = LEFT-CLICK
    // TRIANGLE/Y = DRAG ON/OFF
    mouse_set(MBUTTON_1, (drag_toggle || get_actual(BUTTON_16)) ? TRUE : FALSE);
 
    // CIRCLE/B = RIGHT-CLICK
    mouse_set(MBUTTON_2, get_actual(BUTTON_15) ? TRUE : FALSE);
 
 
    // Flow control timing
    wait(0); wait(6);
}


And it can be used alongside a very simple extra script for a different slot to force Xbox 360 output protocol (useful for use on Android I found):

Code: Select all
#pragma METAINFO("Standard Gamepad - Xbox 360", 1, 0, "OneSwitch.org.uk")
 
init {
    // Programatically change the output protocol to Multi HID (keyboard/mouse)
    // when this script is loaded.
    port_connect(PORT_USB_C, PROTOCOL_XB360);
}
 
 
main {
 
}
 



What I found with using this on a Windows PC is that some games would completely trap me. As such, if possible, it would be very helpful to have a method to quit games that run in full-screen that have no on-screen exit button. My thought is...

OPTIONS/START (tap) = Escape key (pulsed once for about 0.25 seconds)
OPTIONS/START (hold) = ALT+F4 (pulsed once for about 0.25 seconds)

Can that be done?
User avatar
SpecialEffect
Command Sergeant Major
Command Sergeant Major
 
Posts: 165
Joined: Mon Apr 07, 2014 3:26 pm

Re: Gamepad to Mouse: Help needed

Postby Scachi » Mon Jul 29, 2019 10:39 am

Give this a try, adjust value of "taplimit_escape_altf4" for the tap/press time required.
Please note that I have adjusted the mouse double click function timings to match the "flow control timing" that J2kbr uses in the mouse movement combo. Not sure if I use this "flow control" correctly but it still works for me :wink:
Using 6 instead of 25 ms in the wait commands of the key presses works for me too.
Code: Select all
#pragma METAINFO("Gamepad 2 Mouse", 1, 02, "Scachi/J Koppe/G Law/B Ellis (SpecialEffect)")
// 29/7/2019
// Created for http://www.SpecialEffect.org.uk - PUBLIC DOMAIN
// viewtopic.php?f=26&t=13195
// Designed to convert a PS4/Xbox gamepad to Mouse use. Controls are...
 
// LEFT-STICK = MOUSE MOVEMENT
// CROSS/A = LEFT-CLICK
// CIRCLE/B = RIGHT-CLICK
// TRIANGLE/Y = DRAG ON/OFF
// SQUARE/X = AXIS LOCK (X-AXIS / Y-AXIS / FREE MOVEMENT)
// R2/RT = DOUBLE-LEFT-CLICK
 
// HOLD R2/RB + TAP HOME = CHANGE SLOT +1 (e.g. to Forced Xbox 360 Gamepad mode)
// HOLD L2/LB + TAP HOME = CHANGE SLOT -1
 
 
 
// Header file containing mouse related definitions
#include <mouse.gph>
 
// Header file containing keyboard related definitions
#include <keyboard.gph>
 
// MOUSE SPEED VARIABLE(0.02 slowest speed)
fix32 sensitivities[] = {0.08,0.02}; // <<- you can add or remove several 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;
 
// OPTION/START time limit. In limit -> Escape, longer -> ALT+F4
uint16 taplimit_escape_altf4=250;
 
// DEADZONE
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 {
    // FORCE HID (MOUSE) OUTPUT PROTOCOL.
    // N.B. Tick "Disable Joystick from Multi Interface HID output" in GTuner IV > Device Configuration > Device Options !!!!
    port_connect(PORT_USB_C, PROTOCOL_HID);
}
 
main {
 
     // TOUCH/VIEW/BACK button = SPEED adjustment
    if(event_active(BUTTON_2)) {
        sensitivity_active= (sensitivity_active+1) % (sizeof(sensitivities)/4);
    }
 
    // TRIANGLE/Y = DRAG ON/OFF
    if(event_active(BUTTON_14)) {
        drag_toggle = !drag_toggle;
    }
 
    // R2/RT = DOUBLE-LEFT CLICK
    if (event_active(BUTTON_5)) combo_run(DoubleLeftClick);
 
    // SQUARE/X = AXIS LOCK (X-AXIS/Y-AXIS/FREE MOVEMENT)
    if(event_active(BUTTON_17)) {
        axis_lock = (axis_lock + 1) %3;
    }
 
        // OPTIONS/START (TAP) = Escape key
        if (event_release(BUTTON_3)) {
            if (time_active(BUTTON_3) <= taplimit_escape_altf4) combo_run(Escape);
            else combo_run(AltF4);
        }
 
        // OPTIONS/START (TAP) = ALT+F4
 
 
    // 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 Escape {
        // press
        key_set(KEY_ESCAPE,TRUE);
        wait(0); wait(25);
        // release
        key_set(KEY_ESCAPE,FALSE);
        wait(0);
}
 
combo AltF4 {
        // press
        key_set(KEY_LEFTALT,TRUE);
        key_set(KEY_F4,TRUE);
        wait(0); wait(25);
        // release
        key_set(KEY_LEFTALT,FALSE);
        key_set(KEY_F4,FALSE);
        wait(0);
}
 
combo DoubleLeftClick {
        mouse_set(MBUTTON_1,  TRUE); wait(0); wait(6); // click
        mouse_set(MBUTTON_1, FALSE); wait(0); wait(6); // release
        mouse_set(MBUTTON_1,  TRUE); wait(0); wait(6); // click
        mouse_set(MBUTTON_1, FALSE); wait(0); // release
}
 
combo Gamepad2Mouse {
    // LEFT-STICK X-AXIS TO MOUSE X-AXIS
    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);
 
    // LEFT-STICK Y-AXIS TO MOUSE Y-AXIS
    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);
 
    // CROSS/A = LEFT-CLICK
    // TRIANGLE/Y = DRAG ON/OFF
    mouse_set(MBUTTON_1, (drag_toggle || get_actual(BUTTON_16)) ? TRUE : FALSE);
 
    // CIRCLE/B = 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: 2009
Joined: Wed May 11, 2016 6:25 am
Location: Germany

Re: Gamepad to Mouse: Help needed

Postby SpecialEffect » Mon Jul 29, 2019 12:04 pm

Thanks so much. I've made a mistake though in practice. The following I think would be the final requests...

1. Options (tap) = ALT+F4 (pulsed once)
2. Options (hold) = Escape (held until you release Options)
3. D-pad = cursor keys
4. Right-stick = slow mouse (for precise control immediately at your finger tips).

In practice, I tried the game Proteus, and it required a held Escape press to quit. Alt-F4 I can't imagine will ever be needed to be held.

Thanks again for all the help. Fantastic forum.
User avatar
SpecialEffect
Command Sergeant Major
Command Sergeant Major
 
Posts: 165
Joined: Mon Apr 07, 2014 3:26 pm

Re: Gamepad to Mouse: Help needed

Postby Scachi » Mon Jul 29, 2019 2:44 pm

Sorry about the formatting / indentation.. pasting the code messes up the tabs a bit
By default the left stick is used and its active sensitivity.
When there is input from the right stick above the set deadzone then it will use the right stick and its sensitivity index set.
This is done for the active axis only. So you can move fast Y and fine adjust x at the same time (as long as no axis lock is set).

Changed the OPTION tap/hold as you have mentioned. Dpad->Cursor is added too.

Code: Select all
#pragma METAINFO("Gamepad 2 Mouse", 1, 03, "Scachi/J Koppe/G Law/B Ellis (SpecialEffect)")
// 29/7/2019
// Created for http://www.SpecialEffect.org.uk - PUBLIC DOMAIN
// viewtopic.php?f=26&t=13195
// Designed to convert a PS4/Xbox gamepad to Mouse use. Controls are...
 
// LEFT-STICK = MOUSE MOVEMENT , adjustable sensitivity with TOUCH/VIEW/BACK button
// RIGHT_STICK = MOUSE MOVEMENT , fixed sensitivity (index sensitivity_right_stick)
// CROSS/A = LEFT-CLICK
// CIRCLE/B = RIGHT-CLICK
// TRIANGLE/Y = DRAG ON/OFF
// SQUARE/X = AXIS LOCK (X-AXIS / Y-AXIS / FREE MOVEMENT)
// R2/RT = DOUBLE-LEFT-CLICK
// OPTION/START = tap->keyboard: ALT+F4 (pulse), hold->keyboard: ESCAPE (hold)
// DPAD = keyboard: cursor/arrow keys
 
// HOLD R2/RB + TAP HOME = CHANGE SLOT +1 (e.g. to Forced Xbox 360 Gamepad mode)
// HOLD L2/LB + TAP HOME = CHANGE SLOT -1
 
 
 
// Header file containing mouse related definitions
#include <mouse.gph>
 
// Header file containing keyboard related definitions
#include <keyboard.gph>
 
// MOUSE SPEED VARIABLE(0.02 slowest speed)
fix32 sensitivities[] = {0.08,0.02}; // <<- you can add or remove several 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;
// sensitivity index to use for right stick
uint8 sensitivity_right_stick=1;
 
// OPTION/START time limit. In limit -> ALT+F4 , longer hold -> ESCAPE as long as button is hold
uint16 taplimit_altf4=250;
 
// DEADZONE
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 {
    // FORCE HID (MOUSE) OUTPUT PROTOCOL.
    // N.B. Tick "Disable Joystick from Multi Interface HID output" in GTuner IV > Device Configuration > Device Options !!!!
    port_connect(PORT_USB_C, PROTOCOL_HID);
}
 
main {
 
     // TOUCH/VIEW/BACK button = SPEED adjustment
    if(event_active(BUTTON_2)) {
        sensitivity_active= (sensitivity_active+1) % (sizeof(sensitivities)/4);
    }
 
    // TRIANGLE/Y = DRAG ON/OFF
    if(event_active(BUTTON_14)) {
        drag_toggle = !drag_toggle;
    }
 
    // R2/RT = DOUBLE-LEFT CLICK
    if (event_active(BUTTON_5)) combo_run(DoubleLeftClick);
 
    // SQUARE/X = AXIS LOCK (X-AXIS/Y-AXIS/FREE MOVEMENT)
    if(event_active(BUTTON_17)) {
        axis_lock = (axis_lock + 1) %3;
    }
 
        // OPTIONS/START release, (TAP) = ALT+F4 (pulse) or ESCAPE (release)
        if (event_release(BUTTON_3)) {
            if (time_active(BUTTON_3) < taplimit_altf4) combo_run(AltF4); // short tap
            else combo_restart(Escape); // longer hold
        }
        // OPTIONS/START (HOLD) = Escape (hold as long button is hold)
        if (check_active(BUTTON_3,taplimit_altf4)) combo_run(Escape);
 
        // Run the combo that converts DPAD to Cursor Keys
        combo_run(DPad2Cursor);
 
    // 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 AltF4 {
        // press
        key_set(KEY_LEFTALT,TRUE);
        key_set(KEY_F4,TRUE);
        wait(0); wait(25);
        // release
        key_set(KEY_LEFTALT,FALSE);
        key_set(KEY_F4,FALSE);
        wait(0);
}
 
 
combo Escape {
        // button active AND key not active -> set key pressed
        if ( is_active(BUTTON_3) && !key_get(KEY_ESCAPE)) key_set(KEY_ESCAPE,TRUE);
        // button not active AND key active -> set key released
        if (!is_active(BUTTON_3) &&  key_get(KEY_ESCAPE)) key_set(KEY_ESCAPE,FALSE);
 
        // Flow control timing
        wait(0);
        wait(6);
}
 
 
combo DPad2Cursor {   
      // UP : button active AND key not active -> set key pressed
        if ( get_actual(BUTTON_10) && !key_get(KEY_UPARROW        )) key_set(KEY_UPARROW    ,  TRUE);
        // UP : button not active AND key active -> set key released
        if (!get_actual(BUTTON_10) &&  key_get(KEY_UPARROW        )) key_set(KEY_UPARROW    ,  FALSE);
 
        // DOWN : button active AND key not active -> set key pressed
        if ( get_actual(BUTTON_11) && !key_get(KEY_DOWNARROW    )) key_set(KEY_DOWNARROW,  TRUE);
        // DOWN : button not active AND key active -> set key released
        if (!get_actual(BUTTON_11) &&  key_get(KEY_DOWNARROW    )) key_set(KEY_DOWNARROW,  FALSE);
 
        // LEFT : button active AND key not active -> set key pressed
        if ( get_actual(BUTTON_12) && !key_get(KEY_LEFTARROW    )) key_set(KEY_LEFTARROW,  TRUE);
        // DOWN : button not active AND key active -> set key released
        if (!get_actual(BUTTON_12) &&  key_get(KEY_LEFTARROW    )) key_set(KEY_LEFTARROW,  FALSE);
 
        // RIGHT : button active AND key not active -> set key pressed
        if (get_actual(BUTTON_13) && !key_get(KEY_RIGHTARROW    )) key_set(KEY_RIGHTARROW, TRUE);
        // RIGHT : button  not active AND key active -> set key released
        if (!get_actual(BUTTON_13) &&  key_get(KEY_RIGHTARROW    )) key_set(KEY_RIGHTARROW, FALSE);
 
        // Flow control timing
        wait(0);
        wait(6);
}
 
 
combo DoubleLeftClick {
        mouse_set(MBUTTON_1,  TRUE); wait(0); wait(6); // click
        mouse_set(MBUTTON_1, FALSE); wait(0); wait(6); // release
        mouse_set(MBUTTON_1,  TRUE); wait(0); wait(6); // click
        mouse_set(MBUTTON_1, FALSE); wait(0); // release
}
 
 
combo Gamepad2Mouse {
 
        // use left stick and sensitivity_active index by default
        uint8 STICK_X=STICK_2_X;
        uint8 STICK_Y=STICK_2_Y;
        uint8 sensitivity_x_use=sensitivity_active;
        uint8 sensitivity_y_use=sensitivity_active;
 
        // per axis: when right stick is > deadzone use it and its sensitivity index
        if (abs(get_actual(STICK_1_X)) > deadzone ) {
                STICK_X = STICK_1_X;
                sensitivity_x_use=sensitivity_right_stick;
        }
        if (abs(get_actual(STICK_1_Y)) > deadzone ) {
                STICK_Y = STICK_1_Y;
                sensitivity_y_use=sensitivity_right_stick;
        }
 
        // STICK X-AXIS TO MOUSE Y-AXIS
        if((axis_lock==0 || axis_lock==1) && abs(get_actual(STICK_X)) > deadzone) {
                mouse_set(MOUSE_X, (int16)(get_actual(STICK_X) * sensitivities[sensitivity_x_use]));
        } else mouse_set(MOUSE_X, 0);
 
        // STICK Y-AXIS TO MOUSE Y-AXIS
    if((axis_lock==0 || axis_lock==2) && abs(get_actual(STICK_Y)) > deadzone) {
        mouse_set(MOUSE_Y, (int16)(get_actual(STICK_Y) * sensitivities[sensitivity_y_use]));
    } else mouse_set(MOUSE_Y, 0);
 
 
    // CROSS/A = LEFT-CLICK
    // TRIANGLE/Y = DRAG ON/OFF
    mouse_set(MBUTTON_1, (drag_toggle || get_actual(BUTTON_16)) ? TRUE : FALSE);
 
 
    // CIRCLE/B = 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: 2009
Joined: Wed May 11, 2016 6:25 am
Location: Germany

Re: Gamepad to Mouse: Help needed

Postby SpecialEffect » Tue Jul 30, 2019 10:39 am

Superb. Thank you again. No problems at all quitting the games I have in Steam. Brilliant.

If you have time, two small things remain to my mind...

1. LED brightness and colour.
Would be great to have a variable to tweak the LED brightness and default colour. Blue slightly dimmer the default.


2. LED colour change when DRAG active.
Suggest Red, but facility to change for colour-blind users.

Fantastic script this has turned out to be. :)

Cheers again all,

Barrie
User avatar
SpecialEffect
Command Sergeant Major
Command Sergeant Major
 
Posts: 165
Joined: Mon Apr 07, 2014 3:26 pm

Re: Gamepad to Mouse: Help needed

Postby Scachi » Tue Jul 30, 2019 11:58 am

Another option to handle the configuration is adding an "Interactivate Configuration" to the script ?
I could add this if you want to.

You have to use the IC icon and click the settings then instead of having to change the code.
This allows to easily add the same script with different settings to multiple slots then.
Just install it to different slots and configure each one differently via the menu.

Your two small things added:
Code: Select all
#pragma METAINFO("Gamepad 2 Mouse", 1, 04, "Scachi/J Koppe/G Law/B Ellis (SpecialEffect)")
// 29/7/2019
// Created for http://www.SpecialEffect.org.uk - PUBLIC DOMAIN
// viewtopic.php?f=26&t=13195
// Designed to convert a PS4/Xbox gamepad to Mouse use. Controls are...
 
// LEFT-STICK = MOUSE MOVEMENT , adjustable sensitivity with TOUCH/VIEW/BACK button
// RIGHT_STICK = MOUSE MOVEMENT , fixed sensitivity (index sensitivity_right_stick)
// CROSS/A = LEFT-CLICK
// CIRCLE/B = RIGHT-CLICK
// TRIANGLE/Y = DRAG ON/OFF
// SQUARE/X = AXIS LOCK (X-AXIS / Y-AXIS / FREE MOVEMENT)
// R2/RT = DOUBLE-LEFT-CLICK
// OPTION/START = tap->keyboard: ALT+F4 (pulse), hold->keyboard: ESCAPE (hold)
// DPAD = keyboard: cursor/arrow keys
 
// HOLD R2/RB + TAP HOME = CHANGE SLOT +1 (e.g. to Forced Xbox 360 Gamepad mode)
// HOLD L2/LB + TAP HOME = CHANGE SLOT -1
 
/*** CONFIGURATION SECTION START ***/
 
// LED brightness
fix32 brightness=60f;
// known colors, use first letter: 'B'lue, 'R'ed, 'G'reen, 'P'urple, 'C'yan, 'Y'ellow, 'W'hite;
uint8 color_default    ='B'// default color used
uint8 color_drag         ='R'// color for active drag
 
// MOUSE SPEED VARIABLE(0.02 slowest speed)
fix32 sensitivities[]             = {0.08,0.02}; // <<- you can add or remove several 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;
// sensitivity index to use for right stick
uint8 sensitivity_right_stick=1;
 
// OPTION/START time limit. In limit -> ALT+F4 , longer hold -> ESCAPE as long as button is hold
uint16 taplimit_altf4=250;
 
// DEADZONE
fix32 deadzone = 20f;
 
/*** CONFIGURATION SECTION END ***/
 
 
 
// Header file containing mouse related definitions
#include <mouse.gph>
 
// Header file containing keyboard related definitions
#include <keyboard.gph>
 
// 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 {
    // FORCE HID (MOUSE) OUTPUT PROTOCOL.
    // N.B. Tick "Disable Joystick from Multi Interface HID output" in GTuner IV > Device Configuration > Device Options !!!!
    port_connect(PORT_USB_C, PROTOCOL_HID);
        // set default color
        ColorLED(color_default,brightness);
}
 
main {
 
     // TOUCH/VIEW/BACK button = SPEED adjustment
    if(event_active(BUTTON_2)) {
        sensitivity_active= (sensitivity_active+1) % (sizeof(sensitivities)/4);
    }
 
    // TRIANGLE/Y = DRAG ON/OFF
    if(event_active(BUTTON_14)) {
        drag_toggle = !drag_toggle;
                if (drag_toggle) ColorLED(color_drag,brightness);
                else ColorLED(color_default,brightness);
    }
 
    // R2/RT = DOUBLE-LEFT CLICK
    if (event_active(BUTTON_5)) combo_run(DoubleLeftClick);
 
    // SQUARE/X = AXIS LOCK (X-AXIS/Y-AXIS/FREE MOVEMENT)
    if(event_active(BUTTON_17)) {
        axis_lock = (axis_lock + 1) %3;
    }
 
        // OPTIONS/START release, (TAP) = ALT+F4 (pulse) or ESCAPE (release)
        if (event_release(BUTTON_3)) {
            if (time_active(BUTTON_3) < taplimit_altf4) combo_run(AltF4); // short tap
            else combo_restart(Escape); // longer hold
        }
        // OPTIONS/START (HOLD) = Escape (hold as long button is hold)
        if (check_active(BUTTON_3,taplimit_altf4)) combo_run(Escape);
 
        // Run the combo that converts DPAD to Cursor Keys
        combo_run(DPad2Cursor);
 
    // 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 AltF4 {
        // press
        key_set(KEY_LEFTALT,TRUE);
        key_set(KEY_F4,TRUE);
        wait(0); wait(25);
        // release
        key_set(KEY_LEFTALT,FALSE);
        key_set(KEY_F4,FALSE);
        wait(0);
}
 
 
combo Escape {
        // button active AND key not active -> set key pressed
        if ( is_active(BUTTON_3) && !key_get(KEY_ESCAPE)) key_set(KEY_ESCAPE,TRUE);
        // button not active AND key active -> set key released
        if (!is_active(BUTTON_3) &&  key_get(KEY_ESCAPE)) key_set(KEY_ESCAPE,FALSE);
 
        // Flow control timing
        wait(0);
        wait(6);
}
 
 
combo DPad2Cursor {   
      // UP : button active AND key not active -> set key pressed
        if ( get_actual(BUTTON_10) && !key_get(KEY_UPARROW        )) key_set(KEY_UPARROW    ,  TRUE);
        // UP : button not active AND key active -> set key released
        if (!get_actual(BUTTON_10) &&  key_get(KEY_UPARROW        )) key_set(KEY_UPARROW    ,  FALSE);
 
        // DOWN : button active AND key not active -> set key pressed
        if ( get_actual(BUTTON_11) && !key_get(KEY_DOWNARROW    )) key_set(KEY_DOWNARROW,  TRUE);
        // DOWN : button not active AND key active -> set key released
        if (!get_actual(BUTTON_11) &&  key_get(KEY_DOWNARROW    )) key_set(KEY_DOWNARROW,  FALSE);
 
        // LEFT : button active AND key not active -> set key pressed
        if ( get_actual(BUTTON_12) && !key_get(KEY_LEFTARROW    )) key_set(KEY_LEFTARROW,  TRUE);
        // DOWN : button not active AND key active -> set key released
        if (!get_actual(BUTTON_12) &&  key_get(KEY_LEFTARROW    )) key_set(KEY_LEFTARROW,  FALSE);
 
        // RIGHT : button active AND key not active -> set key pressed
        if (get_actual(BUTTON_13) && !key_get(KEY_RIGHTARROW    )) key_set(KEY_RIGHTARROW, TRUE);
        // RIGHT : button  not active AND key active -> set key released
        if (!get_actual(BUTTON_13) &&  key_get(KEY_RIGHTARROW    )) key_set(KEY_RIGHTARROW, FALSE);
 
        // Flow control timing
        wait(0);
        wait(6);
}
 
 
combo DoubleLeftClick {
        mouse_set(MBUTTON_1,  TRUE); wait(0); wait(6); // click
        mouse_set(MBUTTON_1, FALSE); wait(0); wait(6); // release
        mouse_set(MBUTTON_1,  TRUE); wait(0); wait(6); // click
        mouse_set(MBUTTON_1, FALSE); wait(0); // release
}
 
 
combo Gamepad2Mouse {
 
        // use left stick and sensitivity_active index by default
        uint8 STICK_X=STICK_2_X;
        uint8 STICK_Y=STICK_2_Y;
        uint8 sensitivity_x_use=sensitivity_active;
        uint8 sensitivity_y_use=sensitivity_active;
 
        // per axis: when right stick is > deadzone use it and its sensitivity index
        if (abs(get_actual(STICK_1_X)) > deadzone ) {
                STICK_X = STICK_1_X;
                sensitivity_x_use=sensitivity_right_stick;
        }
        if (abs(get_actual(STICK_1_Y)) > deadzone ) {
                STICK_Y = STICK_1_Y;
                sensitivity_y_use=sensitivity_right_stick;
        }
 
        // STICK X-AXIS TO MOUSE Y-AXIS
        if((axis_lock==0 || axis_lock==1) && abs(get_actual(STICK_X)) > deadzone) {
                mouse_set(MOUSE_X, (int16)(get_actual(STICK_X) * sensitivities[sensitivity_x_use]));
        } else mouse_set(MOUSE_X, 0);
 
        // STICK Y-AXIS TO MOUSE Y-AXIS
    if((axis_lock==0 || axis_lock==2) && abs(get_actual(STICK_Y)) > deadzone) {
        mouse_set(MOUSE_Y, (int16)(get_actual(STICK_Y) * sensitivities[sensitivity_y_use]));
    } else mouse_set(MOUSE_Y, 0);
 
 
    // CROSS/A = LEFT-CLICK
    // TRIANGLE/Y = DRAG ON/OFF
    mouse_set(MBUTTON_1, (drag_toggle || get_actual(BUTTON_16)) ? TRUE : FALSE);
 
 
    // CIRCLE/B = RIGHT-CLICK
    mouse_set(MBUTTON_2, get_actual(BUTTON_15) ? TRUE : FALSE);
 
    // Flow control timing
    wait(0); wait(6);
}
 
 
void ColorLED(uint8 color, fix32 brightness) {
        static uint8 last_color=255;
        static fix32 last_brightness=100f;
 
        if (color == last_color && brightness == last_brightness) return;
        last_color             = color;
        last_brightness = brightness;
 
        uint8 c1,c2,c3,c4;
        if             (color=='B') c1=1;
        else if (color=='R') c2=1;
        else if (color=='G') c3=1;
        else if (color=='P') c4=1;
        else if (color=='C') { c1=1; c3=1; }
        else if (color=='Y') { c2=1; c3=1; }
        else if (color=='W') { c1=1; c2=1, c3=1; c4=1; }
 
        led_reset();
 
        if (brightness==0.0) brightness=100f;
        if (c1) led_set(LED_1,brightness,0);
        if (c2) led_set(LED_2,brightness,0);
        if (c3) led_set(LED_3,brightness,0);
        if (c4) led_set(LED_4,brightness,0);
}
User avatar
Scachi
Brigadier General
Brigadier General
 
Posts: 2009
Joined: Wed May 11, 2016 6:25 am
Location: Germany

Re: Gamepad to Mouse: Help needed

Postby SpecialEffect » Tue Jul 30, 2019 12:30 pm

I wasn't aware this was possible. Yes, I'm definitely interested in this idea. Sounds really helpful. Thanks again for the update. Works brilliantly.

One extra option that would be good is a BASIC mode, that disables latching, axis lock, double-click, quitting.... Just giving you the basic sticks = mouse, CROSS = left-click, CIRCLE = right-click, BACK/Touch-click = speed change... Nothing else. That might be nice.
User avatar
SpecialEffect
Command Sergeant Major
Command Sergeant Major
 
Posts: 165
Joined: Mon Apr 07, 2014 3:26 pm

Re: Gamepad to Mouse: Help needed

Postby Scachi » Tue Jul 30, 2019 5:12 pm

SpecialEffect wrote:I wasn't aware this was possible. Yes, I'm definitely interested in this idea. Sounds really helpful. Thanks again for the update. Works brilliantly.

One extra option that would be good is a BASIC mode, that disables latching, axis lock, double-click, quitting.... Just giving you the basic sticks = mouse, CROSS = left-click, CIRCLE = right-click, BACK/Touch-click = speed change... Nothing else. That might be nice.

I haven't tested everything so some stuff might not be working.
Install it to a slot and click on the gear like icon or press F9 to preview the Interactive Configuration when you have the script openend in the "GTuner IV, GPC Script IDE".
This is what it will look like:
ic_pad2mouse.jpg
ic_pad2mouse.jpg (149 KiB) Viewed 83 times



I have put the definition of the Interactive Configuration at the end of the file.
The loading of the values is done in the the init{} section. I have put a comment there.
Changes to the configuration in the code will have no effect now.

I am away for a few days now so here is it to test, maybe you are lucky and it just works or you find someone else to fix bugs before I am back again :wink:

Code: Select all
#pragma METAINFO("Gamepad 2 Mouse", 1, 05, "Scachi/J Koppe/G Law/B Ellis (SpecialEffect)")
// 29/7/2019
// Created for http://www.SpecialEffect.org.uk - PUBLIC DOMAIN
// viewtopic.php?f=26&t=13195
// Designed to convert a PS4/Xbox gamepad to Mouse use. Controls are...
 
// LEFT-STICK = MOUSE MOVEMENT , adjustable sensitivity with TOUCH/VIEW/BACK button
// RIGHT_STICK = MOUSE MOVEMENT , fixed sensitivity (index sensitivity_right_stick)
// CROSS/A = LEFT-CLICK
// CIRCLE/B = RIGHT-CLICK
// TRIANGLE/Y = DRAG ON/OFF
// SQUARE/X = AXIS LOCK (X-AXIS / Y-AXIS / FREE MOVEMENT)
// R2/RT = DOUBLE-LEFT-CLICK
// OPTION/START = tap->keyboard: ALT+F4 (pulse), hold->keyboard: ESCAPE (hold)
// DPAD = keyboard: cursor/arrow keys
 
// HOLD R2/RB + TAP HOME = CHANGE SLOT +1 (e.g. to Forced Xbox 360 Gamepad mode)
// HOLD L2/LB + TAP HOME = CHANGE SLOT -1
 
// I HAVE PUT THE INTERACTIVE CONFIGURATION DEFINITION AT THE END OF THE SCRIPT
// manual changes to the configuration in the code will have no effect now.
 
 
/*** CONFIGURATION SECTION START ***/
 
// LED brightness
fix32 brightness=60f;
// known colors, use first letter: 'B'lue, 'R'ed, 'G'reen, 'P'urple, 'C'yan, 'Y'ellow, 'W'hite;
uint8 color_default    ='B'// default color used
uint8 color_drag         ='R'// color for active drag
 
// MOUSE SPEED VARIABLE(0.02 slowest speed)
fix32 sensitivities[]             = {0.08,0.02, 0.00}; // always 3 values, set to 0.00 for not using one
// sensitivity_active uses first entry of sensitivities array as default, index 0 first value
uint8 sensitivity_active        =0;
// sensitivity index to use for right stick
fix32 sensitivity_right_stick;
 
// DEADZONE
fix32 deadzone = 20f;
 
// ALLOW USAGE OF DRAG
bool drag_allowed=TRUE;
 
// ALLOW LEFT_DOUBLE_CLICK
bool left_double_click_allowed=TRUE;
 
// ALLOW USAGE OF AXIS LOCKING
bool axis_lock_allowed=TRUE;
 
 
 
// ALOW DPAP TO CURSOR
bool dpad_to_cursor_allowed=TRUE;
 
// ALLOW USAGE OF Keyboard ALT+F4 & ESCAPE
bool altf4_escape_allowed=TRUE;
 
// OPTION/START time limit. In limit -> ALT+F4 , longer hold -> ESCAPE as long as button is hold
uint16 altf4_taplimit=250;
 
/*** CONFIGURATION SECTION END ***/
 
 
 
// Header file containing mouse related definitions
#include <mouse.gph>
 
// Header file containing keyboard related definitions
#include <keyboard.gph>
 
// 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;
 
// flag if at least one valid sensitivity value was found
bool sensitivity_all_zero;
 
init {
    // FORCE HID (MOUSE) OUTPUT PROTOCOL.
    // N.B. Tick "Disable Joystick from Multi Interface HID output" in GTuner IV > Device Configuration > Device Options !!!!
    port_connect(PORT_USB_C, PROTOCOL_HID);
 
/* INTERACTIVE CONFIGURATION HANDLING / VALUE LOADING !!! START !!! */
        // load slots interactive configuration storage memory
        pmem_load();
 
        pmem_read(0, &brightness);
 
        // convert combox box value to char as the color function requires char:
        //        'B'lue, 'R'ed, 'G'reen, 'P'urple, 'C'yan, 'Y'ellow, 'W'hite;
        uint8 char_colors[] = { 'B','R','G','P','C','Y','W',};
        pmem_read(4, &color_default);
        color_default=char_colors[color_default]; // translate to char
        pmem_read(5, &color_drag);   
        color_drag=char_colors[color_drag]; // translate to char
 
        drag_allowed = (pmem_read(6) >> 0) & 0b1;
        left_double_click_allowed = (pmem_read(6) >> 1) & 0b1;
        axis_lock_allowed = (pmem_read(6) >> 2) & 0b1;
 
        pmem_read(16, &deadzone);
        pmem_read(20,&sensitivities[0]);
        pmem_read(24,&sensitivities[1]);
        pmem_read(28,&sensitivities[2]);
        /* check if at least one sensitivity is set */
        sensitivity_all_zero=TRUE;
        uint8 i=0;
        for (i=0; i<(sizeof(sensitivities)/4);i++)
        {
            if (sensitivities[i] > 0.0) sensitivity_all_zero=FALSE; // a valid value found
        }
 
        pmem_read(46,&sensitivity_right_stick);
 
 
        altf4_escape_allowed  = (pmem_read(50) >> 0) & 0b1;
        dpad_to_cursor_allowed= (pmem_read(50) >> 1) & 0b1;
        pmem_read(51, &altf4_taplimit);
/* INTERACTIVE CONFIGURATION HANDLING / VALUE LOADING !!! END !!! */
 
        // set default color
        ColorLED(color_default,brightness);
}
 
main {
 
     // TOUCH/VIEW/BACK button = SPEED adjustment
        if (!sensitivity_all_zero) {
                if(event_active(BUTTON_2)) {
                        while (sensitivities[sensitivity_active]==0.0)
                            sensitivity_active= (sensitivity_active+1) % (sizeof(sensitivities)/4);
                }
        }
 
    // TRIANGLE/Y = DRAG ON/OFF
        if (drag_allowed) {
                if(event_active(BUTTON_14)) {
                        drag_toggle = !drag_toggle;
                        if (drag_toggle) ColorLED(color_drag,brightness);
                        else ColorLED(color_default,brightness);
                }
        }
 
    // R2/RT = DOUBLE-LEFT CLICK
        if (left_double_click_allowed) {
                if (event_active(BUTTON_5)) combo_run(DoubleLeftClick);
        }
 
    // SQUARE/X = AXIS LOCK (X-AXIS/Y-AXIS/FREE MOVEMENT)
        if (axis_lock_allowed) {
                if(event_active(BUTTON_17)) {
                        axis_lock = (axis_lock + 1) %3;
                }
        }
 
        // OPTIONS/START release, (TAP) = ALT+F4 (pulse) or ESCAPE (release)
        if (altf4_escape_allowed) {
            if (event_release(BUTTON_3)) {
                if (time_active(BUTTON_3) < altf4_taplimit) combo_run(AltF4); // short tap
                else combo_restart(Escape); // longer hold
            }
            // OPTIONS/START (HOLD) = Escape (hold as long button is hold)
            if (check_active(BUTTON_3,altf4_taplimit)) combo_run(Escape);
        }
 
        // Run the combo that converts DPAD to Cursor Keys
        if (dpad_to_cursor_allowed) {
            combo_run(DPad2Cursor);
        }
 
    // 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 AltF4 {
        // press
        key_set(KEY_LEFTALT,TRUE);
        key_set(KEY_F4,TRUE);
        wait(0); wait(25);
        // release
        key_set(KEY_LEFTALT,FALSE);
        key_set(KEY_F4,FALSE);
        wait(0);
}
 
 
combo Escape {
        // button active AND key not active -> set key pressed
        if ( is_active(BUTTON_3) && !key_get(KEY_ESCAPE)) key_set(KEY_ESCAPE,TRUE);
        // button not active AND key active -> set key released
        if (!is_active(BUTTON_3) &&  key_get(KEY_ESCAPE)) key_set(KEY_ESCAPE,FALSE);
 
        // Flow control timing
        wait(0);
        wait(6);
}
 
 
combo DPad2Cursor {   
      // UP : button active AND key not active -> set key pressed
        if ( get_actual(BUTTON_10) && !key_get(KEY_UPARROW        )) key_set(KEY_UPARROW    ,  TRUE);
        // UP : button not active AND key active -> set key released
        if (!get_actual(BUTTON_10) &&  key_get(KEY_UPARROW        )) key_set(KEY_UPARROW    ,  FALSE);
 
        // DOWN : button active AND key not active -> set key pressed
        if ( get_actual(BUTTON_11) && !key_get(KEY_DOWNARROW    )) key_set(KEY_DOWNARROW,  TRUE);
        // DOWN : button not active AND key active -> set key released
        if (!get_actual(BUTTON_11) &&  key_get(KEY_DOWNARROW    )) key_set(KEY_DOWNARROW,  FALSE);
 
        // LEFT : button active AND key not active -> set key pressed
        if ( get_actual(BUTTON_12) && !key_get(KEY_LEFTARROW    )) key_set(KEY_LEFTARROW,  TRUE);
        // DOWN : button not active AND key active -> set key released
        if (!get_actual(BUTTON_12) &&  key_get(KEY_LEFTARROW    )) key_set(KEY_LEFTARROW,  FALSE);
 
        // RIGHT : button active AND key not active -> set key pressed
        if (get_actual(BUTTON_13) && !key_get(KEY_RIGHTARROW    )) key_set(KEY_RIGHTARROW, TRUE);
        // RIGHT : button  not active AND key active -> set key released
        if (!get_actual(BUTTON_13) &&  key_get(KEY_RIGHTARROW    )) key_set(KEY_RIGHTARROW, FALSE);
 
        // Flow control timing
        wait(0);
        wait(6);
}
 
 
combo DoubleLeftClick {
        mouse_set(MBUTTON_1,  TRUE); wait(0); wait(6); // click
        mouse_set(MBUTTON_1, FALSE); wait(0); wait(6); // release
        mouse_set(MBUTTON_1,  TRUE); wait(0); wait(6); // click
        mouse_set(MBUTTON_1, FALSE); wait(0); // release
}
 
 
combo Gamepad2Mouse {
 
        // use left stick and sensitivity_active index by default
        uint8 STICK_X=STICK_2_X;
        uint8 STICK_Y=STICK_2_Y;
        fix32 sensitivity_x=sensitivities[sensitivity_active];
        fix32 sensitivity_y=sensitivities[sensitivity_active];
 
        // per axis: when right stick is > deadzone use it and its sensitivity index
        if (sensitivity_right_stick > 0.0) {
                if (abs(get_actual(STICK_1_X)) > deadzone ) {
                        STICK_X = STICK_1_X;
                        sensitivity_x=sensitivity_right_stick;
                }
                if (abs(get_actual(STICK_1_Y)) > deadzone ) {
                        STICK_Y = STICK_1_Y;
                        sensitivity_y=sensitivity_right_stick;
                }
        }
 
        // STICK X-AXIS TO MOUSE Y-AXIS
        if((axis_lock==0 || axis_lock==1) && abs(get_actual(STICK_X)) > deadzone) {
                mouse_set(MOUSE_X, (int16)(get_actual(STICK_X) * sensitivity_x));
        } else mouse_set(MOUSE_X, 0);
 
        // STICK Y-AXIS TO MOUSE Y-AXIS
    if((axis_lock==0 || axis_lock==2) && abs(get_actual(STICK_Y)) > deadzone) {
        mouse_set(MOUSE_Y, (int16)(get_actual(STICK_Y) * sensitivity_y));
    } else mouse_set(MOUSE_Y, 0);
 
 
    // CROSS/A = LEFT-CLICK
    // TRIANGLE/Y = DRAG ON/OFF
        if (drag_allowed) {
            mouse_set(MBUTTON_1, (drag_toggle || get_actual(BUTTON_16)) ? TRUE : FALSE);
        } else {
            mouse_set(MBUTTON_1, get_actual(BUTTON_16) ? TRUE : FALSE);
        }
 
 
    // CIRCLE/B = RIGHT-CLICK
    mouse_set(MBUTTON_2, get_actual(BUTTON_15) ? TRUE : FALSE);
 
    // Flow control timing
    wait(0); wait(6);
}
 
 
void ColorLED(uint8 color, fix32 brightness) {
        static uint8 last_color=255;
        static fix32 last_brightness=100f;
 
        if (color == last_color && brightness == last_brightness) return;
        last_color             = color;
        last_brightness = brightness;
 
        uint8 c1,c2,c3,c4;
        if             (color=='B') c1=1;
        else if (color=='R') c2=1;
        else if (color=='G') c3=1;
        else if (color=='P') c4=1;
        else if (color=='C') { c1=1; c3=1; }
        else if (color=='Y') { c2=1; c3=1; }
        else if (color=='W') { c1=1; c2=1, c3=1; c4=1; }
 
        led_reset();
 
        if (brightness==0.0) brightness=100f;
        if (c1) led_set(LED_1,brightness,0);
        if (c2) led_set(LED_2,brightness,0);
        if (c3) led_set(LED_3,brightness,0);
        if (c4) led_set(LED_4,brightness,0);
}
 
 
/* INTERACTIVE CONFIGURATION
 
<cfgdesc>
[Gamepad 2 Mouse Information]
collapsible=1
shortdesc     = <<<MULTILINE
29/7/2019 <b>Created for http://www.SpecialEffect.org.uk - PUBLIC DOMAIN</b><div align="right"><a href="viewtopic.php?f=26&t=13195">Forum Post</a></div>
<b>Designed to convert a PS4/Xbox gamepad to Mouse use.</b>
<table border="1" cellspacing="0" cellpadding="2"><tr bgcolor="#f2f3f4"><td><b>Control</b></td><td>Function</td></tr>
<tr><td><b>LEFT-STICK</b></td><td>MOUSE: MOVEMENT , adjustable sensitivity with TOUCH/VIEW/BACK button</td></tr>
<tr><td><b>RIGHT_STICK</b></td><td>MOUSE: MOVEMENT , fixed sensitivity (index sensitivity_right_stick)</td></tr>
<tr><td><b>CROSS/A</b></td><td>MOUSE: LEFT-CLICK</td></tr>
<tr><td><b>CIRCLE/B</b></td><td>MOUSE: RIGHT-CLICK</td></tr>
<tr><td><b>TRIANGLE/Y</b></td><td>MOUSE: DRAG ON/OFF (Left Mouse Button Hold)</td></tr>
<tr><td><b>SQUARE/X</b></td><td>MOUSE: AXIS LOCK (X-Axis / Y-Axis / Free Movement)</td></tr>
<tr><td><b>R2/RT</b></td><td>MOUSE: DOUBLE-LEFT-CLICK</td></tr>
<tr><td><b>OPTION/START</b></td><td>KEYBOARD: Tap->ALT+F4 (pulse), Hold->ESCAPE (hold)</td></tr>
<tr><td><b>DPAD</b></td><td>KEYBOARD: Cursor/Arrow keys</td></tr>
<tr><td><b>HOLD R2/RB + TAP HOME</b></td><td>CHANGE SLOT +1 (e.g. to Forced Xbox 360 Gamepad mode)</td></tr>
<tr><td><b>HOLD L2/LB + TAP HOME</b></td><td>CHANGE SLOT -1</td></tr>
</table>
MULTILINE
control   = info
 
[SPACE]
control        = space
default        = 15
 
[Configuration]
collapsible=0
shortdesc     = <<<MULTILINE
Customize the controls/settings
MULTILINE
control   = info
 
[Preconfigured Settings]
shortdesc     = <<<MULTILINE
<b>Click "SAVE and RUN" button after clicking one of the presets</b> to activate the new settings.
When you click "OK" to close the Interactive Configuration you have to manually reload the active slot for the changes to apply.
MULTILINE
control        = config
item      = Default (All Features enabled):00500000000107#10:001400000000147B0000051F00000000#2E:0000051F0300FA
item      = Basic (Enabled 'Movement,LeftCLick,RightClick,Speed Selection'):00500000020100#10:001400000000147B0000051F00000000#2E:0000051F0000FA
 
[LED Feedback]
collapsible=1
shortdesc     =
control   = info
 
[LED Brightness]
group            = true
shortdesc    = <<<MULTILINE
Brightness of LED
MULTILINE
byteoffset= 0
bitsize        = 32
control        = spinboxf
default        = 800
decimals    = 1
step            = 5
minimum        = 00
maximum        = 1000
 
[LED Default Color]
group            = true
shortdesc    = <<<MULTILINE
 
Default LED Color
MULTILINE
byteoffset= 4
bitsize        = 8
control   = combobox
default        = 0
item            = Blue
item            = Red
item            = Green
item            = Purple
item            = Cyan
item            = Yellow
item            = White
 
[LED DRAG Color]
group            = true
shortdesc    = <<<MULTILINE
 
LED Color when DRAG (left mouse button hold) is active
MULTILINE
byteoffset= 5
bitsize        = 8
control   = combobox
default        = 1
item            = Blue
item            = Red
item            = Green
item            = Purple
item            = Cyan
item            = Yellow
item            = White
 
[Mouse Settings]
collapsible=1
shortdesc     =
control   = info
 
[Mouse Button Features]
group            = true
shortdesc    = <<<MULTILINE
<b><u>Buttons</u></b>
MULTILINE
control   = info
 
[Mouse Drag]
group            = true
shortdesc    = <<<MULTILINE
 
<b>Mouse Drag</b> - Left Mouse Button Hold
Button <b>TRIANGLE/Y</b> will toggle Left Mouse Button Hold On/OFF when allowed.
MULTILINE
byteoffset= 6
bitsize        = 1
bitoffset = 0
control        = checkbox
default        = 1
item             = Allow Use of Mouse Drag
 
[Mouse Double Click]
group            = true
shortdesc    = <<<MULTILINE
 
<b>Mouse Double-Left-Click</b> - Left Mouse Button Double CLick
Button <b>R2/RT</b> will do a Double-Left-Click when allowed.
MULTILINE
byteoffset= 6
bitsize        = 1
bitoffset = 1
control        = checkbox
default        = 1
item             = Allow Use of Double-Left-Click
 
[Mouse Axis Lock]
group            = true
shortdesc    = <<<MULTILINE
 
<b>Mouse Axis Lock </b> - Toggle Lock of Mouse Movement Axis
Button <b>SQUARE/X</b> will cycle through Allowed : X-Axis , Y-Axis , Free
MULTILINE
byteoffset= 6
bitsize        = 1
bitoffset = 2
control        = checkbox
default        = 1
item             = Allow Use of Mouse Axis Lock
 
[Mouse Movement Features]
group            = true
shortdesc    = <<<MULTILINE
 
<b><u>Movement</u></b>
MULTILINE
control   = info
 
 
[Stick Deadzone]
group            = true
shortdesc    = <<<MULTILINE
 
<b>Stick Deadzone</b> value for mouse movement.
The deadzone defines the minimum required movement of the sticks to start moving the mouse.
Higher value -> more stick movement required
MULTILINE
byteoffset= 16
bitsize        = 32
control        = spinboxf
default        = 200
decimals    = 1
step            = 01
minimum        = 050
maximum        = 1000
 
[Left Stick Mouse Settings Information]
group            = true
shortdesc    = <<<MULTILINE
 
<b>The Left Stick Mouse speeds</b> can be cycled through with <b>TOUCH/VIEW/BACK button</b>.
Sensitivity values set to 0.00 will disable the setting.
Example: If you want to have use two different speed only set 3. to value 0.00
To disable the Left Sticks Mouse movement completely set all values to 0.00
MULTILINE
control   = info
 
[LEFT STICK Mouse Sensitivity 1]
group            = true
shortdesc    = <<<MULTILINE
 
<b>LEFT STICK 1. Sensitivity</b> (higher value->faster movement) To disable set this to 0.00
MULTILINE
byteoffset= 20
bitsize        = 32
control        = spinboxf
default        = 008
decimals    = 2
step            = 001
minimum        = 000
maximum        = 200
 
[LEFT STICK Mouse Sensitivity 2]
group            = true
shortdesc    = <<<MULTILINE
 
<b>LEFT STICK 2. Sensitivity</b> (higher->faster, lower->slower) To disable set this to 0.00
MULTILINE
byteoffset= 24
bitsize        = 32
control        = spinboxf
default        = 002
decimals    = 2
step            = 001
minimum        = 000
maximum        = 200
 
[LEFT STICK Mouse Sensitivity 3]
group            = true
shortdesc    = <<<MULTILINE
 
<b>LEFT STICK 3. Sensitivity</b> (higher->faster, lower->slower) To disable set this to 0.00
MULTILINE
byteoffset= 28
bitsize        = 32
control        = spinboxf
default        = 000
decimals    = 2
step            = 001
minimum        = 000
maximum        = 200
 
[Right Stick Mouse Settings Information]
group            = true
shortdesc    = <<<MULTILINE
 
<b><font color="DARKRED">The Right Stick</font> Mouse speed</b> has one speed only.
To disable the Right Sticks Mouse movement completely set the value to 0.00
MULTILINE
control   = info
 
 
[RIGHT STICK Mouse Sensitivity]
group            = true
shortdesc    = <<<MULTILINE
 
<b><font color="DARKRED">RIGHT</font> STICK Sensitivity</b> (higher->faster, lower->slower) To disable set this to 0.00
MULTILINE
byteoffset= 46
bitsize        = 32
control        = spinboxf
default        = 002
decimals    = 2
step            = 001
minimum        = 000
maximum        = 200
 
 
[Keyboard Settings]
collapsible=1
shortdesc     =
control   = info
 
[DPAD CURSOR]
group            = true
shortdesc    = <<<MULTILINE
 
<b>Keyboard Cursor/Arrow</b>
<b>DPAD DIRECTION</b> will press the corresponding Cursor/Arrow key
MULTILINE
byteoffset= 50
bitsize        = 1
bitoffset = 1
control        = checkbox
default        = 1
item             = Allow Use of DPAD to CURSOR keys
 
[Escape AltF4]
group            = true
shortdesc    = <<<MULTILINE
 
<b>Keyboard Escape and ALT+F4</b>
Button <b>OPTION/START</b>
A <b>short press</b> will send the keys <b>ALT+F4</b>
A <b>longer hold</b> will send the key <b>ESCAPE</b>
MULTILINE
byteoffset= 50
bitsize        = 1
bitoffset = 0
control        = checkbox
default        = 1
item             = Allow Use of ALT+4 and ESCAPE
 
[Escape AltF4 Tap Limit]
group            = true
shortdesc    = <<<MULTILINE
 
<b>Tap Time Limit in milliseconds </b>
Button hold time lower than value will send ALT+F4, longer will send ESCAPE
MULTILINE
byteoffset= 51
bitsize        = 16
control        = spinbox
default        = 250
step            = 1
minimum        = 150
maximum        = 1000
 
</cfgdesc>
*/

 
User avatar
Scachi
Brigadier General
Brigadier General
 
Posts: 2009
Joined: Wed May 11, 2016 6:25 am
Location: Germany

Re: Gamepad to Mouse: Help needed

Postby SpecialEffect » Wed Jul 31, 2019 2:09 pm

Brilliant. Love it! Seems spot on.

I tried on iOS13, and no luck getting a connection either through USB nor via Bluetooth PS4. Hopefully with a Bluetooth Multi HID device protocol update to the T2 this might work. I fear Apple have a block on even acknowledging the Titan though as it appears on an Android device, but not iOS. I've left them some feedback to say it would be fantastic to broaden the range of controllers that can attach to the iPad for simulated touch-mode and traditional gaming.

If you'd be up for it, I was wondering if you might consider a related script to accompany this it, giving some extra accessibility features for a standard gamepad? And then allow the users to swap between the two (gamepad/mouse protocol) if needed.

Huge thanks again. Really fantastic script.
User avatar
SpecialEffect
Command Sergeant Major
Command Sergeant Major
 
Posts: 165
Joined: Mon Apr 07, 2014 3:26 pm

PreviousNext

Return to GPC Script Programming (Titan Two)

Who is online

Users browsing this forum: No registered users and 8 guests