osd: Added support for mapping files to sdlgame joystick provider and made it default with SDL.

This changes behaviour, however I think it's a net positive:
* Most games using Steam Input or SDL2 to read game controllers have
  this behaviour, so users have come to expect it.
* This module is better at giving meaningful names to buttons on
  common controller, and assigning axes consistently.
* Button/axis mapping files using a widely-used format are supported.
* The old behaviour is still available with `-joystickprovider sdljoy`
  if anyone wants it.

The new option for controller mapping files is in the general OSD
options rather than SDL options as it can be extended to DirectInput in
the future.
This commit is contained in:
Vas Crabb 2023-01-14 03:07:57 +11:00
parent e817a3d0c8
commit bf2707f4c7
5 changed files with 243 additions and 155 deletions

View File

@ -1,10 +1,10 @@
.. _mame-commandline-universal: .. _mame-commandline-universal:
Universal Commandline Options Universal Command-line Options
============================= ==============================
This section contains configuration options that are applicable to *all* MAME This section contains configuration options that are applicable to *all* MAME
sub-builds (both SDL and Windows native). configurations (both including both SDL and Windows native).
.. contents:: :local: .. contents:: :local:
@ -450,7 +450,7 @@ overwritten.
.. _mame-commandline-romident: .. _mame-commandline-romident:
**-romident** [*path\\to\\romstocheck.zip*] **-romident** [*path/to/romstocheck.zip*]
Attempts to identify ROM files, if they are known to MAME, in the specified Attempts to identify ROM files, if they are known to MAME, in the specified
.zip file or directory. This command can be used to try and identify ROM .zip file or directory. This command can be used to try and identify ROM
@ -693,6 +693,31 @@ OSD-related Options
mame ibm5150 -uimodekey DEL mame ibm5150 -uimodekey DEL
.. _mame-commandline-controllermap:
**-controller_map** / **-ctrlmap** *<filename>*
Path to a text file containing game controller button and axis mappings in
the format used by SDL2 and Steam. Must use an ASCII-compatible text
encoding with native line endings (e.g. CRLF on Windows). Currently only
supported when using the ``sdlgame`` joystick provider.
A `community-sourced list of game controller mappings
<https://github.com/gabomdq/SDL_GameControllerDB>`_ can be found on GitHub.
Besides using a text editor, several tools are available for creating game
controller mappings, including `SDL2 Gamepad Mapper
<https://gitlab.com/ryochan7/sdl2-gamepad-mapper/-/releases>`_ and SDL2
ControllerMap which is `supplied with SDL
<https://github.com/libsdl-org/SDL/releases/latest>`_. You can also
configure your controller in Steams Big Picture mode, then copy the
mappings from ``SDL_GamepadBind`` entries in the **config.vdf** file found
in the **config** folder inside your Steam installation folder.
Example:
.. code-bock:: bash
mame -controller_map gamecontrollerdb.txt sf2ce
.. _mame-commandline-uifontprovider: .. _mame-commandline-uifontprovider:
**-uifontprovider** *<module>* **-uifontprovider** *<module>*
@ -1058,7 +1083,7 @@ Core Search Path Options
Example: Example:
.. code-block:: bash .. code-block:: bash
mame -homepath c:\mame\lua mame -homepath C:\mame\lua
.. _mame-commandline-rompath: .. _mame-commandline-rompath:
@ -1073,7 +1098,7 @@ Core Search Path Options
Example: Example:
.. code-block:: bash .. code-block:: bash
mame -rompath c:\mame\roms;c:\roms\another mame -rompath C:\mame\roms;C:\roms\another
.. _mame-commandline-hashpath: .. _mame-commandline-hashpath:
@ -1088,7 +1113,7 @@ Core Search Path Options
Example: Example:
.. code-block:: bash .. code-block:: bash
mame -hashpath c:\mame\hash;c:\roms\softlists mame -hashpath C:\mame\hash;C:\roms\softlists
.. _mame-commandline-samplepath: .. _mame-commandline-samplepath:
@ -1103,7 +1128,7 @@ Core Search Path Options
Example: Example:
.. code-block:: bash .. code-block:: bash
mame -samplepath c:\mame\samples;c:\roms\samples mame -samplepath C:\mame\samples;C:\roms\samples
.. _mame-commandline-artpath: .. _mame-commandline-artpath:
@ -1118,7 +1143,7 @@ Core Search Path Options
Example: Example:
.. code-block:: bash .. code-block:: bash
mame -artpath c:\mame\artwork;c:\emu\shared-artwork mame -artpath C:\mame\artwork;C:\emu\shared-artwork
.. _mame-commandline-ctrlrpath: .. _mame-commandline-ctrlrpath:
@ -1134,7 +1159,7 @@ Core Search Path Options
Example: Example:
.. code-block:: bash .. code-block:: bash
mame -ctrlrpath c:\mame\ctrlr;c:\emu\controllers mame -ctrlrpath C:\mame\ctrlr;C:\emu\controllers
.. _mame-commandline-inipath: .. _mame-commandline-inipath:
@ -1163,7 +1188,7 @@ Core Search Path Options
Example: Example:
.. code-block:: bash .. code-block:: bash
mame -inipath c:\users\thisuser\documents\mameini mame -inipath C:\Users\thisuser\documents\mameini
.. _mame-commandline-fontpath: .. _mame-commandline-fontpath:
@ -1178,7 +1203,7 @@ Core Search Path Options
Example: Example:
.. code-block:: bash .. code-block:: bash
mame -fontpath c:\mame\;c:\emu\artwork\mamefonts mame -fontpath C:\mame\;C:\emu\artwork\mamefonts
.. _mame-commandline-cheatpath: .. _mame-commandline-cheatpath:
@ -1193,7 +1218,7 @@ Core Search Path Options
Example: Example:
.. code-block:: bash .. code-block:: bash
mame -cheatpath c:\mame\cheat;c:\emu\cheats mame -cheatpath C:\mame\cheat;C:\emu\cheats
.. _mame-commandline-crosshairpath: .. _mame-commandline-crosshairpath:
@ -1208,7 +1233,7 @@ Core Search Path Options
Example: Example:
.. code-block:: bash .. code-block:: bash
mame -crosshairpath c:\mame\crsshair;c:\emu\artwork\crosshairs mame -crosshairpath C:\mame\crsshair;C:\emu\artwork\crosshairs
.. _mame-commandline-pluginspath: .. _mame-commandline-pluginspath:
@ -1222,7 +1247,7 @@ Core Search Path Options
Example: Example:
.. code-block:: bash .. code-block:: bash
mame -pluginspath c:\mame\plugins;c:\emu\lua mame -pluginspath C:\mame\plugins;C:\emu\lua
.. _mame-commandline-languagepath: .. _mame-commandline-languagepath:
@ -1237,7 +1262,7 @@ Core Search Path Options
Example: Example:
.. code-block:: bash .. code-block:: bash
mame -languagepath c:\mame\language;c:\emu\mame-languages mame -languagepath C:\mame\language;C:\emu\mame-languages
.. _mame-commandline-swpath: .. _mame-commandline-swpath:
@ -1251,7 +1276,7 @@ Core Search Path Options
Example: Example:
.. code-block:: bash .. code-block:: bash
mame -swpath c:\mame\software;c:\emu\mydisks mame -swpath C:\mame\software;C:\emu\mydisks
.. _mame-commandline-coreoutdir: .. _mame-commandline-coreoutdir:
@ -1276,7 +1301,7 @@ Core Output Directory Options
Example: Example:
.. code-block:: bash .. code-block:: bash
mame -cfg_directory c:\mame\cfg mame -cfg_directory C:\mame\cfg
.. _mame-commandline-nvramdirectory: .. _mame-commandline-nvramdirectory:
@ -1294,7 +1319,7 @@ Core Output Directory Options
Example: Example:
.. code-block:: bash .. code-block:: bash
mame -nvram_directory c:\mame\nvram mame -nvram_directory C:\mame\nvram
.. _mame-commandline-inputdirectory: .. _mame-commandline-inputdirectory:
@ -1311,7 +1336,7 @@ Core Output Directory Options
Example: Example:
.. code-block:: bash .. code-block:: bash
mame -input_directory c:\mame\inp mame -input_directory C:\mame\inp
.. _mame-commandline-statedirectory: .. _mame-commandline-statedirectory:
@ -1328,7 +1353,7 @@ Core Output Directory Options
Example: Example:
.. code-block:: bash .. code-block:: bash
mame -state_directory c:\mame\sta mame -state_directory C:\mame\sta
.. _mame-commandline-snapshotdirectory: .. _mame-commandline-snapshotdirectory:
@ -1344,7 +1369,7 @@ Core Output Directory Options
Example: Example:
.. code-block:: bash .. code-block:: bash
mame -snapshot_directory c:\mame\snap mame -snapshot_directory C:\mame\snap
.. _mame-commandline-diffdirectory: .. _mame-commandline-diffdirectory:
@ -1363,7 +1388,7 @@ Core Output Directory Options
Example: Example:
.. code-block:: bash .. code-block:: bash
mame -diff_directory c:\mame\diff mame -diff_directory C:\mame\diff
.. _mame-commandline-commentdirectory: .. _mame-commandline-commentdirectory:
@ -1380,7 +1405,7 @@ Core Output Directory Options
Example: Example:
.. code-block:: bash .. code-block:: bash
mame -comment_directory c:\mame\comments mame -comment_directory C:\mame\comments
.. _mame-commandline-savestate: .. _mame-commandline-savestate:
@ -4015,7 +4040,7 @@ HTTP Server Options
Example: Example:
.. code-block:: bash .. code-block:: bash
mame apple2 -http -http_port 6502 -http_root c:\users\me\appleweb\root mame apple2 -http -http_port 6502 -http_root C:\Users\me\appleweb\root
.. _mame-commandline-portaudio: .. _mame-commandline-portaudio:

View File

@ -35,6 +35,7 @@
#include <algorithm> #include <algorithm>
#include <cctype> #include <cctype>
#include <cstddef> #include <cstddef>
#include <cstring>
#include <iterator> #include <iterator>
#include <memory> #include <memory>
#include <optional> #include <optional>
@ -523,7 +524,7 @@ int lookup_sdl_code(const char *scode)
while (sdl_lookup_table[i].code >= 0) while (sdl_lookup_table[i].code >= 0)
{ {
if (!strcmp(scode, sdl_lookup_table[i].name)) if (!std::strcmp(scode, sdl_lookup_table[i].name))
return sdl_lookup_table[i].code; return sdl_lookup_table[i].code;
i++; i++;
} }
@ -1939,18 +1940,33 @@ public:
{ {
SDL_SetHint(SDL_HINT_ACCELEROMETER_AS_JOYSTICK, "0"); SDL_SetHint(SDL_HINT_ACCELEROMETER_AS_JOYSTICK, "0");
auto &sdlopts = downcast<sdl_options const &>(*options());
bool const sixaxis_mode = sdlopts.sixaxis();
init_joystick(); init_joystick();
if (!have_joystick()) if (!have_joystick())
return; return;
m_initialized_game_controller = !SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER); m_initialized_game_controller = !SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER);
if (!m_initialized_game_controller) if (m_initialized_game_controller)
{
char const *const mapfile = sdlopts.controller_mapping_file();
if (mapfile && *mapfile && std::strcmp(mapfile, OSDOPTVAL_NONE))
{
auto const count = SDL_GameControllerAddMappingsFromFile(mapfile);
if (0 <= count)
osd_printf_verbose("Game Controller: %d controller mapping(s) added from file [%s].\n", count, mapfile);
else
osd_printf_error("Game Controller: Error adding mappings from file [%s]: %s.\n", mapfile, SDL_GetError());
}
}
else
{
osd_printf_warning("Could not initialize SDL Game Controller: %s.\n", SDL_GetError()); osd_printf_warning("Could not initialize SDL Game Controller: %s.\n", SDL_GetError());
}
sdl_joystick_module_base::input_init(machine); sdl_joystick_module_base::input_init(machine);
bool const sixaxis_mode = downcast<const sdl_options *>(options())->sixaxis();
osd_printf_verbose("Game Controller: Start initialization\n"); osd_printf_verbose("Game Controller: Start initialization\n");
for (int physical_stick = 0; physical_stick < SDL_NumJoysticks(); physical_stick++) for (int physical_stick = 0; physical_stick < SDL_NumJoysticks(); physical_stick++)
{ {
@ -1970,6 +1986,14 @@ public:
create_game_controller_device(machine, physical_stick, ctrl); create_game_controller_device(machine, physical_stick, ctrl);
} }
static int const joy_event_types[] = {
int(SDL_JOYAXISMOTION),
int(SDL_JOYBALLMOTION),
int(SDL_JOYHATMOTION),
int(SDL_JOYBUTTONDOWN),
int(SDL_JOYBUTTONUP),
int(SDL_JOYDEVICEADDED),
int(SDL_JOYDEVICEREMOVED) };
static int const event_types[] = { static int const event_types[] = {
int(SDL_JOYAXISMOTION), int(SDL_JOYAXISMOTION),
int(SDL_JOYBALLMOTION), int(SDL_JOYBALLMOTION),
@ -1983,7 +2007,10 @@ public:
int(SDL_CONTROLLERBUTTONUP), int(SDL_CONTROLLERBUTTONUP),
int(SDL_CONTROLLERDEVICEADDED), int(SDL_CONTROLLERDEVICEADDED),
int(SDL_CONTROLLERDEVICEREMOVED) }; int(SDL_CONTROLLERDEVICEREMOVED) };
if (m_initialized_game_controller)
sdl_event_manager::instance().subscribe(event_types, this); sdl_event_manager::instance().subscribe(event_types, this);
else
sdl_event_manager::instance().subscribe(joy_event_types, this);
osd_printf_verbose("Game Controller: End initialization\n"); osd_printf_verbose("Game Controller: End initialization\n");
} }
@ -2036,6 +2063,7 @@ public:
// for devices supported by the game controller API, this is received before the corresponding SDL_JOYDEVICEADDED // for devices supported by the game controller API, this is received before the corresponding SDL_JOYDEVICEADDED
case SDL_CONTROLLERDEVICEADDED: case SDL_CONTROLLERDEVICEADDED:
if (m_initialized_game_controller)
{ {
SDL_GameController *const ctrl = SDL_GameControllerOpen(sdlevent.cdevice.which); SDL_GameController *const ctrl = SDL_GameControllerOpen(sdlevent.cdevice.which);
if (!ctrl) if (!ctrl)

View File

@ -44,6 +44,19 @@ RSB Button Button^ Button^ Button^
^ optional ^ optional
At least the vast majority of controllers report 8-bit trigger
resolution and 10-bit stick resolution, even when the physical controls
use digital switches. Resolution can't be used to reliably detect
nominal analog axes controlled by switches.
Some arcade sticks report unknown or gamepad subtype, but have a single
digital joystick with a switch to select between controlling the D-pad,
left stick and right stick. You can't assume that all three can be
controlled at the same time.
Many controllers don't correctly report the absence of analog sticks.
There are multiple physical button layouts for arcade sticks, for There are multiple physical button layouts for arcade sticks, for
example: example:
@ -68,17 +81,26 @@ Hori Real Arcade Pro VX-SA Kai, Razer Atrox
B X Y LB B X Y LB
A LT RT RB A LT RT RB
Hori Real Arcade Pro.V Kai, Mayflash F300, Mayflash F500 Hori Real Arcade Pro.V Kai, Mad Catz EGO Arcade Stick, Mayflash F300, Mayflash F500
X Y RB LB X Y RB LB
A B RT LT A B RT LT
Mad Catz Brawl Stick Mad Catz WWE All Stars Brawl Stick
X Y LB LT X Y LB LT
A B RB RT A B RB RT
Arcade pads typically have six face buttons, and come with different Arcade pads typically have six face buttons, and come with different
layouts corresponding to the latter two arcade stick layouts, with the layouts corresponding to the latter two arcade stick layouts, with the
rightmost column on the shoulder buttons. rightmost column on the shoulder buttons. Examples of face button
layouts:
Mad Catz Street Fighter IV FightPad, PowerA FUSION Wired FightPad
X Y RB
A B RT
Hori Pad EX Turbo 2, Mad Catz WWE All Stars BrawlPad, Mortal Kombat X Fight Pad, PDP Versus Fighting Pad
X Y LB
A B RB
Dance mats usually have this layout: Dance mats usually have this layout:

View File

@ -2,21 +2,22 @@
// copyright-holders:Aaron Giles // copyright-holders:Aaron Giles
/*************************************************************************** /***************************************************************************
osdepend.c osdobj_common.h
OS-dependent code interface. OS-dependent code interface.
***************************************************************************/ ***************************************************************************/
#include "modules/lib/osdobj_common.h" #include "osdobj_common.h"
#include "modules/debugger/debug_module.h"
#include "modules/font/font_module.h" #include "modules/font/font_module.h"
#include "modules/input/input_module.h" #include "modules/input/input_module.h"
#include "modules/sound/sound_module.h"
#include "modules/debugger/debug_module.h"
#include "modules/netdev/netdev_module.h"
#include "modules/midi/midi_module.h" #include "modules/midi/midi_module.h"
#include "modules/monitor/monitor_module.h" #include "modules/monitor/monitor_module.h"
#include "modules/netdev/netdev_module.h"
#include "modules/sound/sound_module.h"
#include "osdnet.h" #include "osdnet.h"
#include "watchdog.h" #include "watchdog.h"
@ -34,6 +35,7 @@ const options_entry osd_options::s_option_entries[] =
#else #else
{ OSDOPTION_UIMODEKEY, "auto", core_options::option_type::STRING, "key to enable/disable MAME controls when emulated system has keyboard inputs" }, { OSDOPTION_UIMODEKEY, "auto", core_options::option_type::STRING, "key to enable/disable MAME controls when emulated system has keyboard inputs" },
#endif // SDLMAME_MACOSX #endif // SDLMAME_MACOSX
{ OSDOPTION_CONTROLLER_MAP_FILE ";ctrlmap", OSDOPTVAL_NONE, core_options::option_type::PATH, "game controller mapping file" },
{ nullptr, nullptr, core_options::option_type::HEADER, "OSD FONT OPTIONS" }, { nullptr, nullptr, core_options::option_type::HEADER, "OSD FONT OPTIONS" },
{ OSD_FONT_PROVIDER, OSDOPTVAL_AUTO, core_options::option_type::STRING, "provider for UI font: " }, { OSD_FONT_PROVIDER, OSDOPTVAL_AUTO, core_options::option_type::STRING, "provider for UI font: " },
@ -283,8 +285,8 @@ void osd_common_t::register_options()
REGISTER_MODULE(m_mod_man, LIGHTGUNINPUT_WIN32); REGISTER_MODULE(m_mod_man, LIGHTGUNINPUT_WIN32);
REGISTER_MODULE(m_mod_man, LIGHTGUN_NONE); REGISTER_MODULE(m_mod_man, LIGHTGUN_NONE);
REGISTER_MODULE(m_mod_man, JOYSTICKINPUT_SDLJOY);
REGISTER_MODULE(m_mod_man, JOYSTICKINPUT_SDLGAME); REGISTER_MODULE(m_mod_man, JOYSTICKINPUT_SDLGAME);
REGISTER_MODULE(m_mod_man, JOYSTICKINPUT_SDLJOY);
REGISTER_MODULE(m_mod_man, JOYSTICKINPUT_WINHYBRID); REGISTER_MODULE(m_mod_man, JOYSTICKINPUT_WINHYBRID);
REGISTER_MODULE(m_mod_man, JOYSTICKINPUT_DINPUT); REGISTER_MODULE(m_mod_man, JOYSTICKINPUT_DINPUT);
REGISTER_MODULE(m_mod_man, JOYSTICKINPUT_XINPUT); REGISTER_MODULE(m_mod_man, JOYSTICKINPUT_XINPUT);

View File

@ -2,30 +2,40 @@
// copyright-holders:Aaron Giles // copyright-holders:Aaron Giles
/*************************************************************************** /***************************************************************************
osdepend.h osdobj_common.h
OS-dependent code interface. OS-dependent code interface.
*******************************************************************c********/ *******************************************************************c********/
#pragma once
#ifndef MAME_OSD_LIB_OSDOBJ_COMMON_H #ifndef MAME_OSD_LIB_OSDOBJ_COMMON_H
#define MAME_OSD_LIB_OSDOBJ_COMMON_H #define MAME_OSD_LIB_OSDOBJ_COMMON_H
#pragma once
#include "osdcore.h" #include "osdcore.h"
#include "osdepend.h" #include "osdepend.h"
#include "modules/osdmodule.h" #include "modules/osdmodule.h"
#include "modules/output/output_module.h" #include "modules/output/output_module.h"
#include "emuopts.h" #include "emuopts.h"
#include "strformat.h" #include "strformat.h"
#include <iosfwd>
#include <list> #include <list>
#include <string>
#include <memory>
#include <unordered_map>
#include <vector>
//============================================================ //============================================================
// Defines // Defines
//============================================================ //============================================================
#define OSDOPTION_UIMODEKEY "uimodekey" #define OSDOPTION_UIMODEKEY "uimodekey"
#define OSDOPTION_CONTROLLER_MAP_FILE "controller_map"
#define OSDCOMMAND_LIST_MIDI_DEVICES "listmidi" #define OSDCOMMAND_LIST_MIDI_DEVICES "listmidi"
#define OSDCOMMAND_LIST_NETWORK_ADAPTERS "listnetwork" #define OSDCOMMAND_LIST_NETWORK_ADAPTERS "listnetwork"
@ -98,6 +108,7 @@ public:
// keyboard mapping // keyboard mapping
const char *ui_mode_key() const { return value(OSDOPTION_UIMODEKEY); } const char *ui_mode_key() const { return value(OSDOPTION_UIMODEKEY); }
const char *controller_mapping_file() const { return value(OSDOPTION_CONTROLLER_MAP_FILE); }
// debugging options // debugging options
const char *debugger() const { return value(OSDOPTION_DEBUGGER); } const char *debugger() const { return value(OSDOPTION_DEBUGGER); }