This week has been a real struggle to get the gamepad stuff playing nicely, but I finally figured out the easiest system for gamepad controls and customization: The macro system. It was a bit of a slog to get right, but my decision paid off (any other system would have been more work), and now things are going pretty well. While I have to make some UI adjustments, most of the macro mapping is working now. Some of it still needs testing, but so far so good. Here's an overview of how this will work:
First, the macro skin element has been updated to include a new parameter: map-to. For control_freak cases, local macros will only be added to the list if they're a map-to from a gamepad macro; otherwise they'll be ignored. The map-to value is another key/gamepad/mouse name, like for instance "A" or "F1"; I'm planning to allow mapping to two keys at once for some cases, like for instance when you want a diagonal to act as though two different arrow keys are held down. A typical case might look like this:
macro "macro"
elem
name = "GamepadFace1"
map-to = "Center"
The gamepad buttons supported are as follows; they are not valid as mapping targets, but can map to keys or mouse buttons, and can also be verbified:
GamepadFace1 // Bottom of diamond; A (Xbox), X (PS)
GamepadFace2 // Right of diamond; B (Xbox), Circle (PS)
GamepadFace3 // Left of diamond; X (Xbox), Square (PS)
GamepadFace4 // Top of diamond; Y (Xbox), Triangle (PS)
GamepadL1 // Top left shoulder
GamepadR1 // Top right shoulder
GamepadL2 // Left bottom shoulder/trigger
GamepadR2 // Right bottom shoulder/trigger
GamepadSelect // Select / Back
GamepadStart // Start / Forward
GamepadL3 // Left analog click
GamepadR3 // Right analog click
Two buttons can be combined, e.g. GamepadL3+GamepadR3, to map to a key or verb. When using these for regular verbs, the standard behavior with +REP and +UP applies. In a verb, use [[*]] to substitute the button/combo's current value.
There are also directional "buttons".
GamepadUp
GamepadDown
GamepadLeft
GamepadRight
GamepadUpLeft
GamepadUpRight
GamepadDownLeft
GamepadDownRight
The first four correspond to actual buttons on many controllers. The combos are basically built-in ways of handling two of the cardinal directions together, and it's more or less a cheat so that you can also combine it with a gamepad button, e.g. GamepadUpLeft+GamepadFace1.
Then we have the analog sticks:
GamepadLeftAnalog
GamepadRightAnalog
They can be mapped to a dpad or a mouse, or they can be used in verbs. Verbs will fire regardless of +REP or +UP, and [[x]] and [[y]] will substitute the X and Y axes; [[*]] will substitute x,y. The Y axis is inverted from gamepad norms so that up is positive, fitting with BYOND's coordinate system. (Developers, take note now: It's up to you to check that the x,y values have a total distance no more than 1 plus a fudge factor. The macro will never lie to you, but players will, and you don't want them sending commands for super speed.)
GamepadDpad
GamepadDpad4
These special values can be used for verbs, or can be used as mapping targets. (I didn't have the heart to allow Dpad-to-mouse mapping, because there'd be no fine control.) For instance, GamepadLeftAnalog can map to GamepadDpad for full 8-dir movement, or it can map to GamepadDpad4 to only use the nearest cardinal direction. It does so by "pressing" one the buttons like GamepadUp, or GamepadUpLeft, etc. When you use one of the Dpad values as a verb macro, [[*]] will substitute the direction as a number, and 0 for no direction; +UP is meaningless there but +REP is allowed.
Mouse
MouseLeftButton
MouseRightButton
MouseMiddleButton
The mouse values exist solely as mapping targets. So for instance, you could map GamepadFace3 to MouseLeftButton, GamepadFace4 to MouseMiddleButton, GamepadFace2 to MouseRightButton, and GamepadRightAnalog to Mouse. (Fair warning: mouse movement looks really crappy at low FPS, because the gamepad is only checked on every client tick. But for an action game with a higher framerate, that won't be an issue.) I haven't worked out yet how I want to specify mouse speed, so for the moment it's hard-coded.
With all that in mind, this is what you'd be looking at for the default gamepad setup:
macro "macro"
elem
name = "GamepadUp"
map-to = "North"
...
elem
name = "GamepadDownRight"
map-to = "Southeast"
elem
name = "GamepadFace1"
map-to = "Center"
elem
name = "GamepadLeftAnalog"
map-to = "GamepadDpad"
I'm still working out the details of how and when to apply those defaults; the system I'm using now is acceptable but not great.
BTW, there's also a new joystick.txt file in the cfg dir that will handle mapping, so you can tell your system that the joystick you use has its buttons in a different order. Like for instance, the gamepad I'm testing with has all its face buttons in a weird order. Eventually I'll have a UI for that.
So some pretty exciting things are in the future for 511, and I'll soon be able to move on to other items on the list. This week I added variadic macros to the to-do list, because it looks like that'll be feasible to add without a lot of trouble.
I'm working hard for a better BYOND, so if you appreciate where this is going, don't forget to hit up the donation box. And now that summer is here, albeit unofficially, enjoy the sunshine and warmth while you can--except you guys in the southern hemisphere, to whom I say: keep warm and dream of salt potatoes (look it up), and use your shut-in time to make an awesome game.