Re: Gamepad to Mouse: Help needed
Posted: Fri Jul 26, 2019 6:30 pm
Massive thanks again. I'll be testing this out first thing next week.
High-performance gaming devices.
https://www.consoletuner.com/forum/
https://www.consoletuner.com/forum/viewtopic.php?f=26&t=13195
#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);
}
#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 {
}
#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);
}
#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);
}
#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);
}
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.
#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>
*/