Difference between revisions of "Lazarus IDE with Gamepad on Linux"

From Lazarus wiki
Jump to navigationJump to search
m (Minor typos.)
(Add directional pad support.)
Line 3: Line 3:
 
There are many utility programs on both Windows and Linux that map events from various kinds of game controller to the keyboard. However many of these, not to mention hardware solutions like the Logitech G600 gamer's mouse, are unable to generate function key presses and releases qualified by the control key etc. On Linux it is possible instead to map events either at the kernel or at the X11 level, neither is particularly well documented and it is possible to end up- particularly in the X11 case- having to use one program to detect an event and a separate one to emit a keyboard sequence.
 
There are many utility programs on both Windows and Linux that map events from various kinds of game controller to the keyboard. However many of these, not to mention hardware solutions like the Logitech G600 gamer's mouse, are unable to generate function key presses and releases qualified by the control key etc. On Linux it is possible instead to map events either at the kernel or at the X11 level, neither is particularly well documented and it is possible to end up- particularly in the X11 case- having to use one program to detect an event and a separate one to emit a keyboard sequence.
  
The example below uses the MXK program http://welz.org.za/projects/mxk to map eight buttons from an NES-style gamepad https://en.wikipedia.org/wiki/File:Super-Famicom-Controller.jpg to the key combinations most commonly used during debugging.
+
The example below uses the MXK program http://welz.org.za/projects/mxk to map eight buttons from an NES-style gamepad https://en.wikipedia.org/wiki/File:Super-Famicom-Controller.jpg to the key combinations most commonly used during debugging. In addition it has useful mappings for the directional pad, but these are commented out by default since a rogue event source can render a system unusable.
  
+
<pre>
#!/usr/local/bin/mxk -dzp
+
#!/usr/local/bin/mxk -dzp
+
 
# Experimental mapping from gamepad to Lazarus debugger. Invoke like
+
# Experimental mapping from gamepad to Lazarus debugger. Invoke like
#
+
#
# mxk -dzp /etc/gamepad-to-Lazarus.mxk
+
# mxk -dzp /etc/gamepad-to-Lazarus.mxk
#
+
#
# Terminate by running interactively using  mxk -a  and issuing the halt
+
# Terminate by running interactively using  mxk -a  and issuing the halt
# command. MarkMLl.
+
# command. MarkMLl.
+
 
# L-shoulder   top2           Run             F9
+
# L-shoulder top2 Run F9
# R-shoulder   pinkie         Stop           Ctrl + F2
+
# R-shoulder pinkie Stop Ctrl + F2
# Select       base3           Compile         Ctrl + F9
+
# Select base3 Compile Ctrl + F9
# Start         base4           Build           Shift + F9
+
# Start base4 Build Shift + F9
# X             trigger         Step over       F8
+
# X trigger Step over F8
# Y             top             Step into       F7
+
# Y top Step into F7
# A             thumb           Step out       Shift + F8
+
# A thumb Step out Shift + F8
# B             thumb2         Step to cursor F4
+
# B thumb2 Step to cursor F4
+
# Pad-up Abs Y -ve Virt1 Call stack Ctrl + Alt + S
# Note that Lazarus's default Stop Ctrl + F2 clashes with KDE's System Settings
+
# Pad-right Abs X +ve Virt2 Breakpoints Ctrl + Alt + B
# -> Shortcuts -> Global Shortcuts -> System Settings -> Switch to Desktop 2.
+
# Pad-down Abs Y +ve Virt3 Find in Files Ctrl + Shift + F
+
# Pad-left Abs X -ve Virt4 Insert ToDo Ctrl + Shift + T
name-source 0 usb gamepad
+
 
start-array 0
+
# Note that Lazarus's default Stop Ctrl + F2 clashes with KDE's System Settings
+
# -> Shortcuts -> Global Shortcuts -> System Settings -> Switch to Desktop 2.
press-array 0 top2 f9/press sync:
+
 
release-array 0 top2 f9/release sync:
+
# The source is identified by a (partial) match of the name. YMMV.
+
 
press-array 0 pinkie leftcontrol/press f2/press sync:
+
name-source 0 usb gamepad
release-array 0 pinkie f2/release leftcontrol/release sync:
+
 
+
# Array 0 maps physical gamepad buttons and virtual buttons derived from the
press-array 0 base3 leftcontrol/press f9/press sync:
+
# directional pad to output key sequences. Edit this to suit the actions you
release-array 0 base3 f9/release leftcontrol/release sync:
+
# want the IDE to perform.
+
 
press-array 0 base4 leftshift/press f9/press sync:
+
start-array 0
release-array 0 base4 f9/release leftshift/release sync:
+
 
+
press-array 0 top2 f9/press sync:
press-array 0 trigger f8/press sync:
+
release-array 0 top2 f9/release sync:
release-array 0 trigger f8/release sync:
+
 
+
press-array 0 pinkie leftcontrol/press f2/press sync:
press-array 0 top f7/press sync:
+
release-array 0 pinkie f2/release leftcontrol/release sync:
release-array 0 top f7/release sync:
+
 
+
press-array 0 base3 leftcontrol/press f9/press sync:
press-array 0 thumb leftshift/press f8/press sync:
+
release-array 0 base3 f9/release leftcontrol/release sync:
release-array 0 thumb f8/release leftshift/release sync:
+
 
+
press-array 0 base4 leftshift/press f9/press sync:
press-array 0 thumb2 f4/press sync:
+
release-array 0 base4 f9/release leftshift/release sync:
release-array 0 thumb2 f4/release sync:
+
 
+
press-array 0 trigger f8/press sync:
start-target 0 key:f2 key:f4 key:f7 key:f8 key:f9 key:leftshift key:leftcontrol
+
release-array 0 trigger f8/release sync:
connect-node source:0 array:0
+
 
connect-node array:0 target:0
+
press-array 0 top f7/press sync:
lock-source 0
+
release-array 0 top f7/release sync:
+
 
# The key/button allocation and names will depend very much on the input device,
+
press-array 0 thumb leftshift/press f8/press sync:
# and with cheap Chinese peripherals will be anybody's guess. Use evtest to see
+
release-array 0 thumb f8/release leftshift/release sync:
# the raw events, and then refer to codes.c in the mxk source.
+
 
+
press-array 0 thumb2 f4/press sync:
Save that as /etc/gamepad-to-Lazarus.mxk, it may be used both as a script and a configuration file.
+
release-array 0 thumb2 f4/release sync:
 +
 
 +
press-array 0 virt1 leftcontrol/press leftalt/press s/press sync:
 +
release-array 0 virt1 s/release leftalt/release leftcontrol/release sync:
 +
 
 +
press-array 0 virt2 leftcontrol/press leftalt/press b/press sync:
 +
release-array 0 virt2 b/release leftalt/release leftcontrol/release sync:
 +
 
 +
press-array 0 virt3 leftcontrol/press leftshift/press f/press sync:
 +
release-array 0 virt3 f/release leftshift/release leftcontrol/release sync:
 +
 
 +
press-array 0 virt4 leftcontrol/press leftshift/press t/press sync:
 +
release-array 0 virt4 t/release leftshift/release leftcontrol/release sync:
 +
 
 +
# Vectors 1 and 2 map absolute events generated by the directional pad to
 +
# virtual keys, which are subsequently expanded by array 0. YMMV.
 +
 
 +
start-vector 1 x
 +
 
 +
point-vector 1 virt4 0
 +
point-vector 1 virt2 255
 +
point-vector 1 virt255 127
 +
 
 +
start-vector 2 y
 +
 
 +
point-vector 2 virt1 0
 +
point-vector 2 virt3 255
 +
point-vector 2 virt255 127
 +
 
 +
# Declare which keys the target may emit, then wire the nodes together. If you
 +
# don't want the direction pad events then comment out the two lines that have
 +
# vectors 1 and 2 as their source.
 +
 
 +
start-target 0 key:f2 key:f4 key:f7 key:f8 key:f9 key:leftshift key:leftcontrol key:leftalt key:s key:b key:f key:t
 +
connect-node source:0 array:0
 +
connect-node source:0 vector:1
 +
connect-node source:0 vector:2
 +
# connect-node vector:1 array:0
 +
# connect-node vector:2 array:0
 +
connect-node array:0 target:0
 +
lock-source 0
 +
 
 +
# The key/button allocation and names will depend very much on the input device,
 +
# and with cheap Chinese peripherals will be anybody's guess. Use evtest to see
 +
# the raw events, and then refer to codes.c in the mxk source. Again, YMMV.
  
 +
# This script normally lives at http://wiki.freepascal.org/Lazarus_IDE_with_Gamepad_on_Linux
 +
</pre>
  
MXK is sufficiently flexible that it should be possible to map the direction controller such that- for example- the breakpoint and call stack pages popped up, but that is left as an exercise for the reader.
+
Save that as /etc/gamepad-to-Lazarus.mxk, it may be used both as a script and a configuration file.
  
With thanks to Neal Stephenson's "Dr. X" for the initial inspiration.
+
With thanks to Neal Stephenson's "Dr. X" for the initial inspiration, and to Marc Welz for help with the fiddly detail.
  
 
[[Category:Lazarus]]
 
[[Category:Lazarus]]

Revision as of 16:38, 7 February 2019

On occasion, particularly if exploring rarely-visited legacy code, it might be necessary to do an inordinate amount of single stepping. Particularly if afflicted with some degree of RSI, continual use of a PC keyboard's function keys- not to mention obscure control combinations- can become surprisingly uncomfortable; users with chilly workrooms might also appreciate a solution that allows them to keep their hands under a blanket or inside the sleeves of a dressing gown.

There are many utility programs on both Windows and Linux that map events from various kinds of game controller to the keyboard. However many of these, not to mention hardware solutions like the Logitech G600 gamer's mouse, are unable to generate function key presses and releases qualified by the control key etc. On Linux it is possible instead to map events either at the kernel or at the X11 level, neither is particularly well documented and it is possible to end up- particularly in the X11 case- having to use one program to detect an event and a separate one to emit a keyboard sequence.

The example below uses the MXK program http://welz.org.za/projects/mxk to map eight buttons from an NES-style gamepad https://en.wikipedia.org/wiki/File:Super-Famicom-Controller.jpg to the key combinations most commonly used during debugging. In addition it has useful mappings for the directional pad, but these are commented out by default since a rogue event source can render a system unusable.

#!/usr/local/bin/mxk -dzp

# Experimental mapping from gamepad to Lazarus debugger. Invoke like
#
# mxk -dzp /etc/gamepad-to-Lazarus.mxk
#
# Terminate by running interactively using  mxk -a  and issuing the halt
# command. MarkMLl.

# L-shoulder	top2			Run		F9
# R-shoulder	pinkie			Stop		Ctrl + F2
# Select	base3			Compile		Ctrl + F9
# Start		base4			Build		Shift + F9
# X		trigger			Step over	F8
# Y		top			Step into	F7
# A		thumb			Step out	Shift + F8
# B		thumb2			Step to cursor	F4
# Pad-up	Abs Y -ve	Virt1	Call stack	Ctrl + Alt + S
# Pad-right	Abs X +ve	Virt2	Breakpoints	Ctrl + Alt + B
# Pad-down	Abs Y +ve	Virt3	Find in Files	Ctrl + Shift + F
# Pad-left	Abs X -ve	Virt4	Insert ToDo	Ctrl + Shift + T

# Note that Lazarus's default Stop Ctrl + F2 clashes with KDE's System Settings
# -> Shortcuts -> Global Shortcuts -> System Settings -> Switch to Desktop 2.

# The source is identified by a (partial) match of the name. YMMV.

name-source 0 usb gamepad

# Array 0 maps physical gamepad buttons and virtual buttons derived from the
# directional pad to output key sequences. Edit this to suit the actions you
# want the IDE to perform.

start-array 0

press-array 0 top2 f9/press sync:
release-array 0 top2 f9/release sync:

press-array 0 pinkie leftcontrol/press f2/press sync:
release-array 0 pinkie f2/release leftcontrol/release sync:

press-array 0 base3 leftcontrol/press f9/press sync:
release-array 0 base3 f9/release leftcontrol/release sync:

press-array 0 base4 leftshift/press f9/press sync:
release-array 0 base4 f9/release leftshift/release sync:

press-array 0 trigger f8/press sync:
release-array 0 trigger f8/release sync:

press-array 0 top f7/press sync:
release-array 0 top f7/release sync:

press-array 0 thumb leftshift/press f8/press sync:
release-array 0 thumb f8/release leftshift/release sync:

press-array 0 thumb2 f4/press sync:
release-array 0 thumb2 f4/release sync:

press-array 0 virt1 leftcontrol/press leftalt/press s/press sync:
release-array 0 virt1 s/release leftalt/release leftcontrol/release sync:

press-array 0 virt2 leftcontrol/press leftalt/press b/press sync:
release-array 0 virt2 b/release leftalt/release leftcontrol/release sync:

press-array 0 virt3 leftcontrol/press leftshift/press f/press sync:
release-array 0 virt3 f/release leftshift/release leftcontrol/release sync:

press-array 0 virt4 leftcontrol/press leftshift/press t/press sync:
release-array 0 virt4 t/release leftshift/release leftcontrol/release sync:

# Vectors 1 and 2 map absolute events generated by the directional pad to
# virtual keys, which are subsequently expanded by array 0. YMMV.

start-vector 1 x

point-vector 1 virt4 0
point-vector 1 virt2 255
point-vector 1 virt255 127

start-vector 2 y

point-vector 2 virt1 0
point-vector 2 virt3 255
point-vector 2 virt255 127

# Declare which keys the target may emit, then wire the nodes together. If you
# don't want the direction pad events then comment out the two lines that have
# vectors 1 and 2 as their source.

start-target 0 key:f2 key:f4 key:f7 key:f8 key:f9 key:leftshift key:leftcontrol key:leftalt key:s key:b key:f key:t
connect-node source:0 array:0
connect-node source:0 vector:1
connect-node source:0 vector:2
# connect-node vector:1 array:0
# connect-node vector:2 array:0
connect-node array:0 target:0
lock-source 0

# The key/button allocation and names will depend very much on the input device,
# and with cheap Chinese peripherals will be anybody's guess. Use evtest to see
# the raw events, and then refer to codes.c in the mxk source. Again, YMMV.

# This script normally lives at http://wiki.freepascal.org/Lazarus_IDE_with_Gamepad_on_Linux

Save that as /etc/gamepad-to-Lazarus.mxk, it may be used both as a script and a configuration file.

With thanks to Neal Stephenson's "Dr. X" for the initial inspiration, and to Marc Welz for help with the fiddly detail.