Joymappings

From vice-emu
Revision as of 17:31, 24 March 2023 by Gpz (talk | contribs) (→‎Technical)
Jump to navigation Jump to search

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 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.

Roadmap

Milestone 1

First the SDL port needs to be "modernized" and use the generic code.

  • TODO: make SDL port use the common numeric menu ids (for hotkeys)
  • TODO: load and save the menu actions to .vjm file
saving to file is comemnted out, loading from file is missing altogether

After this, the SDL port should have fully functional UI, Menu actions can be mapped to Joysticks, Joysticks can be mapped, and the controller mappings saved/restored from .vjm files

Milestone 2

Now we need to make the GTK3 port use the generic joystick mapping code, and make .vjm files work

  • TODO: load and save the menu actions to .vjm file
saving to file is comemnted out, loading from file is missing altogether

After this, the GTK3 port can load/save .vjm files. Joysticks and Menu actions can be mapped via .vjm files. Existing Joystick mapping UI should still function (for the directions)

At this point we can make a release, so people can test the new code.

Milestone 3

The last step will be producing a GUI to create the Joystick and Menu action mappings

Tasks

General

TODO: list the relevant files in general section of the code here

  • keep in mind there needs to be a way to map both "paddles" and "joysticks"
  • Dialogs need to written to handle all of this.

TODO: Document the API of the generic code here

GTK3 UI

TODO: list the relevant files in the GTK3 port here

SDL UI

TODO: list the relevant files in the SDL port here

  • 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

Docs

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)