Joymappings

From vice-emu
Revision as of 01:21, 24 March 2023 by Compyx (talk | contribs) (Remove some items or move some into the table)
Jump to navigation Jump to search

  • Change the resources "JoyDevice{N}" to use strings with device identifiers instead of an index of the predefined and connected devices. So for example a Logitech F710 controller would be "001:006:046d:c21f" (usb-bus 1, device-no 6, vendor-Id 046d, product-Id c21f). We'll need archdep code to translate the strings into something the underlying arch driver can use, so at least handlers for Windows, MacOS, Linux and the various BSDs.
Relying on the device product/model ID won't be enough: a user can have multiple controllers of the same model.
  • Provide a joymap file per device identifier that can be loaded/edited/deleted, perhaps auto-load when JoyDevice{N} contains such an identifier.
  • Make the joymap files use (UI) action identifiers instead of the "menu paths" SDL does.
  • Make the joymap files human-readable by not doing what SDL does: for example: don't use 0-3 for input type, use ["axis", "button", "hat", "ball"], don't use 0-6 for the 'action' row, use "none" (or leave it out)", "joystick", "keyboard", "ui-action, "pot".
  • keep in mind there needs to be a way to map both "paddles" and "joysticks"
  • Dialogs need to written to handle all of this.

(moved to Joymappings)

Branch fabrizio/3.7-joystick-mapping

Joymappings (WIP) contains details about what this does

The SVN branch branches/fabrizio/3.7-joystick-mapping contains code implementing custom joystick button mapping that isn't SDL-specific. Unfortunately the branch doesn't merge with trunk. As a workaround checking out the branch and doing a diff between the branch and trunk appears to generate a diff that can be applied with patch to "merge" the branch into trunk.

The following instructions assume VICE SVN root to be at $HOME/src/vice, with $HOME/src/vice/trunk being our trunk and $HOME/src/vice/branches/fabrizio/3.7-joystick-mapping being the branch to merge. Doing a make distclean will help with avoiding diff processing autohell files.

A little script like this will do the diff'ing: (Might be an idea to add -q to the diff invocation first to see the changed files and spot any files/patterns that need to excluded with -x [glob])

#!/bin/bash

CWD=$(pwd)

SVN_ROOT=${HOME}/src/vice
TRUNK=trunk
BRANCH=branches/fabrizio/3.7-joystick-mapping
SUBDIR=vice/src/

A=${TRUNK}/${SUBDIR}
B=${BRANCH}/${SUBDIR}

cd ${SVN_ROOT}
diff --strip-trailing-cr -U 3 -r ${A} ${B} -x configure.in -x .automake.out -x autom4te.cache -x *.swp -x gtk3
cd $CWD

The script excludes src/arch/gtk3 because the gtk3/ directory in the branch is far behind trunk, leading to a lot of noise, and massive merge conflicts using svn merge.

Then run:

$ ./script.sh > ~/me-patch.diff
$ cd $HOME/src/vice
$ patch -p0 <~/me-patch.diff

And pray VICE compiles after that.

UPDATE 2023-01-29: Applied above in r42972.
UPDATE II 2023-1-30: Branch and diff are fucked, reverted in trunk.

UPDATE III 2023-2-1: New branch made, waiting for merge

UPDATE IV 2023-2-2: New branch merged

UPDATE V 2023-2-17: Trunk now on par with old SDL about features


For a long time the SDL port has had a joystick mappings file. There are 2 sample ones: data/C64/sdl_joymap_thec64.vjm and data/C64/sdl_joymap_ps3.vjm.

These files contain associations between host joystick actions and emulator actions. Possible actions include a corresponding emulated joystick action, a shortcut to an emulator menu action etc.

The branch branches/fabrizio/3.7-joystick-mapping-2 moves the joystick mappings file to the generic joystick code, therefore making it available to the Gtk3 port as well.

The file name has the form {sdl,gtk3,headless}-joymap-{C64,C64SC,...}.vjm. Its format is documented in a comment in the sample file itself.

In order to port the feature to the generic code, the event UI_FUNCTION (shortcuts to menu actions) got lost. It was implemented in a very SDL-specific way, and a cross-platform implementation that allows shortcuts from SDL and GTK3 should be written instead.

Mapping file

A line has 4 mandatory columns:

  1. joystick number (zero-based index of the hardware joystick)
  2. input type
    1. axis
    2. button
    3. hat
  3. input index
    • for buttons, it is the zero-based index of the button
    • for axes
      • if the action is 6 (POT_AXIS), it is the zero-based index of the axis
      • otherwise, 0 and 1 are respectively the positive and negative directions of axis 0; 2 and 3 are respectively the positive and negative directions of axis 1 etc. In formulas: axis=inputindex/2 (integer division), direction = positive if inputindex % 2 ==0 , negative if inputindex % 2 ==1.
    • for hats, 0, 1, 2 and 3 are respectively up, down, left and right of hat 0; 4, 5, 6 and 7 are respectively up, down, left and right of hat 1, etc.
  4. action (enum joystick_action_t in joystick.h)
  1. NONE: none
  2. JOYSTICK: emulated joystick action
  3. KEYBOARD: emulated keyboard action
  4. MAP: SDL-only. Only works while the SDL settings menu is active. If a joystick action mapped to this is performed, the user is asked to press a key, which will become a hotkey to select the currently-selected menu
  5. UI_ACTIVATE: go to the settings menu (SDL) show the settings dialog (Gtk3)
  6. UI_FUNCTION: shortcut to a specific UI function. UNSUPPORTED AT THE MOMENT
  7. POT_AXIS: (only for axes of hardware joysticks) the analog value of the axis is the value of the emulated potentiometer

For some actions, more columns are present:

  • JOYSTICK
  1. emulated joystick pin. Same values as reading the corresponding CIA register.
    1. up
    2. down
    3. left
    4. right
    5. fire
    6. fire 2
    7. fire 3

Blacky note: In vice we also emulate snes pads, these need to be able to be controlled as well, and so the emulated joystick pin needs to be renamed (more like emulated joystick input) and extended, some of the old pins/inputs can be reused, and in such a case we get the following:

  1. joystick up / snes pad up
  2. joystick down / snes pad down
  3. joystick left / snes pad left
  4. joystick right / snes pad right
  5. joystick fire 1 / snes pad A button
  6. joystick fire 2 / snes pad B button
  7. joystick fire 3 / snes pad X button
  8. snes pad Y button
  9. snes pad left bumber
  10. snes pad right bumber
  11. snes pad select button
  12. snes pad start button

And this can be extended if other joystick devices become available with more buttons than we currently map for.

  • KEYBOARD
  1. row in the keyboard matrix layout
  2. column in the keyboard matrix layout
  • POT_AXIS
  1. which potentiometer is affected
    1. Pot-X
    2. Pot-Y

Technical

When a hardware joystick action is performed, the selected joystick driver (Gtk3) ui_dispatch_events() (SDL) call joy_axis_event() or joy_button_event() or joy_hat_event(). These functions read what that joystick action is mapped to, and perform the mapped action.

Mappings are stored in the static array joystick_devices, declared in joystick.c, that has one element per registered hardware joystick. Mappings are stored in each element's axis_mapping, button_mapping and hat_mapping, each an array with one element per axis/button/hat. The mappings are initialised from the joystick mappings file, or with default values if no joystick mappings file is present.

Example

Take this sample line from data/C64/sdl_joymap_ps3.vjm

# O -> Space
0 1 1 2 7 4

First column: HW joystick 0

Second column: input type is button (1)

Third column: input index 1, so button 1

Fourth column: action KEYBOARD (2)

Fifth and sixth columns: Space (7 and 4 in the matrix)

Does it really make sense to put the number of the hardware joystick into the mapping file? I'd expect i can use the same mapping file for more than one controller Gpz (talk) 19:09, 20 February 2023 (CET)


TODO

This section will list the various tasks that need to be undertaken to properly implement the joystick mappings in the UIs and also make it easily implementable in future UIs. I (Compyx) will be collecting the various tasks here, moving them from other pages in the Wiki so we have a central place to keep track of progress.

The following is just copy/paste from other pages in the Wiki, I'll be reorganizing them into a more workable state later:

General

  • Provide a joymap file per device identifier that can be loaded/edited/deleted, perhaps auto-load when JoyDevice{N} contains such an identifier.
  • keep in mind there needs to be a way to map both "paddles" and "joysticks"
  • Dialogs need to written to handle all of this.

SDL UI

  • SDL1/2 joystick mapping improvements
    • Make the 'extra joystick options' menu show what they are already mapped to
    • Add menu joystick actions mapping support to the 'extra joystick options' menu

Actions

This will be the list of things to do and the place to keep track of progress:

(SDL) Actions to be undertaken for full configurable joystick mappings
Action Description Who Status Depends on Remarks
UUIDs Figure out how to obtain UUIDs for controllers on Linux, BSD, MacOS and Windows ? 0%
SDL UI actions Rework SDL menu system to use UI actions Blacky 0% ?
SDL joycode Make the SDL UI use the new joy mapping code Fabbo 0% ?
Joymap files (generic) Update syntax of joymap files to use a human-readable format (text instead of magic numbers). If the files are easier to read and write users can produce joymaps for controllers they own, which we can then include in VICE. This will be especially handy until we have proper UI support for creating the mappings. Provide a joymap file per device identifier that can be loaded/edited/deleted, perhaps auto-load when JoyDevice{N} contains such an identifier. Make the joymap files use (UI) action identifiers (strings) instead of the "menu paths" SDL does or magic numbers. Fabbo 0% ?
Resources (generic) Change and add resources to use UUIDs for controllers and mapping joymap files to controllers. Get rid of the 0-4 for 'none', 'numpad', 'keyset A', 'keyset B' and 4+ for whatever controller was plugged in first: change Joy%d to strings. ? 0% UUIDs
Hotkeys (generic) Move most of the hotkeys code into arch/shared so the hotkey files and the parser can be shared between UIs. The hotkeys code relies on UI actions, so if we make the hotkeys parser use a callback when it encounters a hotkey definition we can use the hotkeys code for all UIs. For example: void hotkey(int action_id, int keysym, unsigned modifiers). Compyx 0% SDL UI actions
(GTK3) Actions to be undertaken for full configurable joystick mappings
Action Description Who Status Depends on Remarks
UUIDs Figure out how to obtain UUIDs for controllers on Linux, BSD, MacOS and Windows ? 0%
GTK3 UI actions Rework GTK3 menu system to use UI actions Compyx 0% ?
GTK joycode Make the Gtk3 UI use the new joy mapping code ? 0% ?
Joymap files (generic) Update syntax of joymap files to use a human-readable format (text instead of magic numbers). If the files are easier to read and write users can produce joymaps for controllers they own, which we can then include in VICE. This will be especially handy until we have proper UI support for creating the mappings. Provide a joymap file per device identifier that can be loaded/edited/deleted, perhaps auto-load when JoyDevice{N} contains such an identifier. Make the joymap files use (UI) action identifiers (strings) instead of the "menu paths" SDL does or magic numbers. Compyx 0% ?
Resources (generic) Change and add resources to use UUIDs for controllers and mapping joymap files to controllers. Get rid of the 0-4 for 'none', 'numpad', 'keyset A', 'keyset B' and 4+ for whatever controller was plugged in first: change Joy%d to strings. ? 0% UUIDs
Hotkeys (generic) Move most of the hotkeys code into arch/shared so the hotkey files and the parser can be shared between UIs. The hotkeys code relies on UI actions, so if we make the hotkeys parser use a callback when it encounters a hotkey definition we can use the hotkeys code for all UIs. For example: void hotkey(int action_id, int keysym, unsigned modifiers). Compyx 0% SDL UI actions