Site Tools
t2:gpc_scripting:usb_hid
Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
t2:gpc_scripting:usb_hid [2019/11/13 05:43] scachi |
t2:gpc_scripting:usb_hid [2024/04/07 03:00] (current) Scachi [GPC functions] |
||
---|---|---|---|
Line 1: | Line 1: | ||
====== USB HID ====== | ====== USB HID ====== | ||
- | ... WORK IN PROGRESS ... | ||
The Output Protocol "USB Multi Interface HID" is a bit special.\\ | The Output Protocol "USB Multi Interface HID" is a bit special.\\ | ||
Line 11: | Line 10: | ||
You can find a few scripts for this protocol in the Online Resource within GTuner IV: Search for "usb-hid".\\ | You can find a few scripts for this protocol in the Online Resource within GTuner IV: Search for "usb-hid".\\ | ||
- | Some USB Script specific forum links:\\ | + | Some USB HID Script specific links:\\ |
+ | [[https://www.consoletuner.com/wiki/index.php?id=t2:gamepacks:universal_hid|Universal HID Gamepack (USB Multi Interface HID)]]\\ | ||
[[https://www.consoletuner.com/forum/viewtopic.php?f=23&t=9889|USB-HID Anti Recoil (USB Multi Interface HID)]]\\ | [[https://www.consoletuner.com/forum/viewtopic.php?f=23&t=9889|USB-HID Anti Recoil (USB Multi Interface HID)]]\\ | ||
[[https://www.consoletuner.com/forum/viewtopic.php?f=23&t=13612|USB-HID Gamepad 2 Keyboard+Mouse (USB Multi Interface HID)]]\\ | [[https://www.consoletuner.com/forum/viewtopic.php?f=23&t=13612|USB-HID Gamepad 2 Keyboard+Mouse (USB Multi Interface HID)]]\\ | ||
- | ===== Important GPC functions ===== | + | ===== GPC functions ===== |
Important GPC functions for USB HID protocol usage:\\ | Important GPC functions for USB HID protocol usage:\\ | ||
Keyboard: [[t2:keymapping|keymapping]] [[t2:key_passthru|key_passthru]] [[t2:key_check|key_check]] [[t2:key_status|key_status]] [[t2:key_get|key_get]] [[t2:key_set|key_set]] | Keyboard: [[t2:keymapping|keymapping]] [[t2:key_passthru|key_passthru]] [[t2:key_check|key_check]] [[t2:key_status|key_status]] [[t2:key_get|key_get]] [[t2:key_set|key_set]] | ||
\\ | \\ | ||
Mouse: [[t2:mousemapping|mousemapping]] [[t2:mouse_passthru|mouse_passthru]] [[t2:mouse_status|mouse_status]] [[t2:mouse_get|mouse_get]] [[t2:mouse_set|mouse_set]] | Mouse: [[t2:mousemapping|mousemapping]] [[t2:mouse_passthru|mouse_passthru]] [[t2:mouse_status|mouse_status]] [[t2:mouse_get|mouse_get]] [[t2:mouse_set|mouse_set]] | ||
+ | |||
+ | When you want to forward mouse input or keyboard input use the corresponding _passthru function.\\ | ||
+ | |||
+ | **As soon as you want to alter the input before outputting it you need to be careful:** | ||
+ | || The last value set for a mouse filed is kept between main() iterations. Unless mouse_passthru() is called, which will overwrite the value set by the script.|| | ||
+ | **Meaning:** | ||
+ | ||If you use mouse_set() function to alter the mouse status (moving mouse/ pressing buttons) you need to always set all inputs each time (x,y,button,wheels) for the mouse to get no unwanted mouse movements/states. || | ||
+ | More information:\\ | ||
+ | [[https://github.com/J2Kbr/TitanTwo/issues/232|mouse_passthru and mouse_set]] \\ | ||
+ | [[https://github.com/J2Kbr/TitanTwo/issues/235|mouse_set: always set all mouse ouputs -> X/Y/Wheel/Buttons]] | ||
===== Examples ===== | ===== Examples ===== | ||
Line 37: | Line 47: | ||
==== Anti Recoil ==== | ==== Anti Recoil ==== | ||
+ | When mouse button 1 is pressed the anti recoil will be applied. | ||
<code gpc2> | <code gpc2> | ||
#include <mouse.gph> | #include <mouse.gph> | ||
- | // configuration | + | // configuration |
- | const int mouse_speed = 10; // <- should be around 10 or higher, a value too low can stop the mouse from working! | + | // note: when a value of 1 is still to strong anti recoil try a higher value for mouse_speed |
- | const int Relative_X = 0; // anti recoil horizontal | + | const int mouse_speed = 10; // <- should be around 10 or higher, a value too low can stop the mouse from working |
- | const int Relative_Y = 1; // anti recoil vertical | + | int AntiRecoil_X = 0; // anti recoil horizontal |
+ | int AntiRecoil_Y = 1; // anti recoil vertical | ||
// internal | // internal | ||
Line 70: | Line 83: | ||
{ | { | ||
if(!(system_time()%mouse_speed)) { | if(!(system_time()%mouse_speed)) { | ||
- | RX = Relative_X; | + | RX = AntiRecoil_X; |
- | RY = Relative_Y; | + | RY = AntiRecoil_Y; |
mouse_set(MOUSE_X, X+RX); | mouse_set(MOUSE_X, X+RX); | ||
mouse_set(MOUSE_Y, Y+RY); | mouse_set(MOUSE_Y, Y+RY); | ||
Line 80: | Line 93: | ||
</code> | </code> | ||
- | ... WORK IN PROGRESS ... | + | ==== Anti Recoil Decimal ==== |
+ | When mouse button 1 is pressed the anti recoil will be applied, supporting decimal/fix32 values. | ||
+ | <code gpc2> | ||
+ | #include <mouse.gph> | ||
+ | |||
+ | // configuration | ||
+ | fix32 antirecoil_X = 0.0; // anti recoil horizontal | ||
+ | fix32 antirecoil_Y = 0.5; // anti recoil vertical | ||
+ | |||
+ | // advanced configuration | ||
+ | const int MOUSE_SPEED = 10; // <- should be around 10 or higher, a value too low can stop the mouse from working | ||
+ | |||
+ | // internal | ||
+ | uint32 ARTIMER; | ||
+ | int32 X, Y, WHEEL; | ||
+ | int32 RX, RY; | ||
+ | fix32 ARX, ARY; | ||
+ | |||
+ | init { | ||
+ | keymapping(); | ||
+ | mousemapping(); | ||
+ | } | ||
+ | |||
+ | main { | ||
+ | key_passthru(); | ||
+ | |||
+ | X = 0; Y = 0; WHEEL = 0; | ||
+ | RX = 0; RY = 0; | ||
+ | |||
+ | if(mouse_status(MREPORT_UPDATED)) { | ||
+ | mouse_passthru(); // only passthru when there is data to send | ||
+ | X = mouse_status(MOUSE_X); | ||
+ | Y = mouse_status(MOUSE_Y); | ||
+ | WHEEL = mouse_status(MOUSE_WHEEL); | ||
+ | } | ||
+ | |||
+ | if(mouse_status(MBUTTON_1)) | ||
+ | { | ||
+ | ARTIMER += elapsed_time(); | ||
+ | |||
+ | if(!(ARTIMER%MOUSE_SPEED)) { | ||
+ | ARX += (fix32)(antirecoil_X); | ||
+ | ARY += (fix32)(antirecoil_Y); | ||
+ | |||
+ | if (antirecoil_X < 0.0) RX += (int)ceil((ARX)); | ||
+ | else if (antirecoil_X > 0.0) RX += (int)floor((ARX)); | ||
+ | |||
+ | if (antirecoil_Y < 0.0) RY += (int)ceil((ARY)); | ||
+ | else if (antirecoil_Y > 0.0) RY += (int)floor((ARY)); | ||
+ | |||
+ | mouse_set(MOUSE_X, X+RX); | ||
+ | mouse_set(MOUSE_Y, Y+RY); | ||
+ | mouse_set(MOUSE_WHEEL,WHEEL); | ||
+ | ARX = mod(ARX,1.0); | ||
+ | ARY = mod(ARY,1.0); | ||
+ | } | ||
+ | } else { | ||
+ | ARTIMER = MOUSE_SPEED; | ||
+ | ARX = 0.0; ARY = 0.0; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | </code> | ||
+ | |||
+ | ==== Controller to Keyboard ==== | ||
+ | Mapping controller input to keyboard HID output. | ||
+ | === Basic version === | ||
+ | <code gpc2> | ||
+ | #include <keyboard.gph> | ||
+ | #include <mouse.gph> | ||
+ | |||
+ | init { | ||
+ | keymapping(); | ||
+ | mousemapping(); | ||
+ | } | ||
+ | main { | ||
+ | key_passthru(); | ||
+ | if(mouse_status(MREPORT_UPDATED)) { | ||
+ | mouse_passthru(); | ||
+ | } | ||
+ | |||
+ | // dpad up mapping to key E | ||
+ | if(is_active(BUTTON_10)) key_set(KEY_E, TRUE); | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | === Extended version === | ||
+ | To make sure the key is released on release of the button as using KMG capture the key may not be reported as released automatically. | ||
+ | <code gpc2> | ||
+ | #include <keyboard.gph> | ||
+ | #include <mouse.gph> | ||
+ | |||
+ | init { | ||
+ | keymapping(); | ||
+ | mousemapping(); | ||
+ | } | ||
+ | main { | ||
+ | key_passthru(); | ||
+ | if(mouse_status(MREPORT_UPDATED)) { | ||
+ | mouse_passthru(); | ||
+ | } | ||
+ | |||
+ | // dpad up mapping to key E | ||
+ | if(is_active(BUTTON_10)) { | ||
+ | keySet(KEY_E, TRUE); // press | ||
+ | } | ||
+ | if (event_release(BUTTON_10)) { | ||
+ | keySet(KEY_E, FALSE); // release | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void keySet(uint8 key, bool flag) { | ||
+ | if (key_get(key) != flag) { | ||
+ | key_set(key, flag); | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | ==== Keyboard to Keyboard ==== | ||
+ | Mapping keyboard input to keyboard HID output. | ||
+ | Useful for some games where you can't change the key assigned to actions. | ||
+ | <code gpc2> | ||
+ | #include <keyboard.gph> | ||
+ | #include <mouse.gph> | ||
+ | |||
+ | init { | ||
+ | port_connect(PORT_USB_C, PROTOCOL_HID); | ||
+ | keymapping(); | ||
+ | mousemapping(); | ||
+ | } | ||
+ | |||
+ | |||
+ | main { | ||
+ | key_passthru(); | ||
+ | if(mouse_status(MREPORT_UPDATED)) { | ||
+ | mouse_passthru(); | ||
+ | } | ||
+ | |||
+ | // shift <-> ctrl | ||
+ | keyMap(KEY_LEFTSHIFT, KEY_LEFTCONTROL); | ||
+ | keyMap(KEY_LEFTCONTROL, KEY_LEFTSHIFT, FALSE, KEY_LEFTSHIFT); // <-- for circular mapping | ||
+ | |||
+ | // additional shift mapping : alt -> shift | ||
+ | keyMap(KEY_LEFTALT, KEY_LEFTSHIFT, TRUE); // <-- for additional key to same destination | ||
+ | |||
+ | // caps -> alt | ||
+ | keyMap(KEY_CAPSLOCK, KEY_LEFTALT); | ||
+ | |||
+ | // left-> page down | ||
+ | keyMap(KEY_LEFTARROW, KEY_PAGEDOWN); | ||
+ | |||
+ | // right-> page up | ||
+ | keyMap(KEY_RIGHTARROW, KEY_PAGEUP); | ||
+ | } | ||
+ | |||
+ | |||
+ | void keyMap(uint8 keySrc, uint8 keyDst, bool noset, uint8 keyCheck) { | ||
+ | if (key_status(keySrc)) { | ||
+ | if (!keyCheck) key_set(keySrc, FALSE); | ||
+ | else if (!key_status(keyCheck)) key_set(keySrc, FALSE); | ||
+ | keySet(keyDst, TRUE); | ||
+ | } | ||
+ | else if (!noset) key_set(keyDst, FALSE); | ||
+ | } | ||
+ | |||
+ | void keySet(uint8 key, bool flag) { | ||
+ | if (key_get(key) != flag) { | ||
+ | key_set(key, flag); | ||
+ | } | ||
+ | } | ||
+ | </code> |
t2/gpc_scripting/usb_hid.1573641837.txt.gz · Last modified: 2019/11/13 05:43 by scachi