sdl: use gamecontroller api for initial btn/axis binding
This commit is contained in:
parent
a39199d379
commit
d1fbbac0ae
|
@ -41,7 +41,7 @@ static void sdl_open_joystick(int index)
|
|||
INFO_LOG(INPUT, "SDL: Cannot open joystick %d", index + 1);
|
||||
return;
|
||||
}
|
||||
std::shared_ptr<SDLGamepadDevice> gamepad = std::make_shared<SDLGamepadDevice>(index < MAPLE_PORTS ? index : -1, pJoystick);
|
||||
std::shared_ptr<SDLGamepadDevice> gamepad = std::make_shared<SDLGamepadDevice>(index < MAPLE_PORTS ? index : -1, index, pJoystick);
|
||||
SDLGamepadDevice::AddSDLGamepad(gamepad);
|
||||
}
|
||||
|
||||
|
@ -59,9 +59,17 @@ void input_sdl_init()
|
|||
// We want joystick events even if we loose focus
|
||||
SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1");
|
||||
if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0)
|
||||
{
|
||||
die("SDL: error initializing Joystick subsystem");
|
||||
|
||||
std::string db = get_readonly_data_path("gamecontrollerdb.txt");
|
||||
int rv = SDL_GameControllerAddMappingsFromFile(db.c_str());
|
||||
if (rv < 0)
|
||||
{
|
||||
db = get_readonly_config_path("gamecontrollerdb.txt");
|
||||
rv = SDL_GameControllerAddMappingsFromFile(db.c_str());
|
||||
}
|
||||
if (rv > 0)
|
||||
DEBUG_LOG(INPUT ,"%d mappings loaded from %s", rv, db.c_str());
|
||||
}
|
||||
if (SDL_WasInit(SDL_INIT_HAPTIC) == 0)
|
||||
SDL_InitSubSystem(SDL_INIT_HAPTIC);
|
||||
|
|
|
@ -21,34 +21,88 @@ public:
|
|||
set_axis(DC_AXIS_Y2, 3, false);
|
||||
dirty = false;
|
||||
}
|
||||
};
|
||||
|
||||
class Xbox360InputMapping : public InputMapping
|
||||
{
|
||||
public:
|
||||
Xbox360InputMapping()
|
||||
DefaultInputMapping(int joystick_idx) : DefaultInputMapping()
|
||||
{
|
||||
name = "Xbox 360";
|
||||
set_button(DC_BTN_A, 0);
|
||||
set_button(DC_BTN_B, 1);
|
||||
set_button(DC_BTN_X, 2);
|
||||
set_button(DC_BTN_Y, 3);
|
||||
set_button(DC_BTN_START, 7);
|
||||
if (SDL_IsGameController(joystick_idx))
|
||||
{
|
||||
SDL_GameController *sdl_controller = SDL_GameControllerOpen(joystick_idx);
|
||||
name = SDL_GameControllerName(sdl_controller);
|
||||
INFO_LOG(INPUT, "SDL: using SDL game controller mappings for '%s'", name.c_str());
|
||||
|
||||
set_axis(DC_AXIS_X, 0, false);
|
||||
set_axis(DC_AXIS_Y, 1, false);
|
||||
set_axis(DC_AXIS_LT, 2, false);
|
||||
set_axis(DC_AXIS_RT, 5, false);
|
||||
set_axis(DC_DPAD_LEFT, 6, false);
|
||||
set_axis(DC_DPAD_UP, 7, false);
|
||||
dirty = false;
|
||||
auto map_button = [&](SDL_GameControllerButton sdl_btn, DreamcastKey dc_btn) {
|
||||
SDL_GameControllerButtonBind bind = SDL_GameControllerGetBindForButton(sdl_controller, sdl_btn);
|
||||
if (bind.bindType == SDL_CONTROLLER_BINDTYPE_BUTTON)
|
||||
set_button(dc_btn, bind.value.button);
|
||||
else if (bind.bindType == SDL_CONTROLLER_BINDTYPE_HAT)
|
||||
{
|
||||
int dir;
|
||||
switch (bind.value.hat.hat_mask)
|
||||
{
|
||||
case SDL_HAT_UP:
|
||||
dir = 0;
|
||||
break;
|
||||
case SDL_HAT_DOWN:
|
||||
dir = 1;
|
||||
break;
|
||||
case SDL_HAT_LEFT:
|
||||
dir = 2;
|
||||
break;
|
||||
case SDL_HAT_RIGHT:
|
||||
dir = 3;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
set_button(dc_btn, ((bind.value.hat.hat + 1) << 8) | dir);
|
||||
}
|
||||
};
|
||||
map_button(SDL_CONTROLLER_BUTTON_A, DC_BTN_A);
|
||||
map_button(SDL_CONTROLLER_BUTTON_B, DC_BTN_B);
|
||||
map_button(SDL_CONTROLLER_BUTTON_X, DC_BTN_X);
|
||||
map_button(SDL_CONTROLLER_BUTTON_Y, DC_BTN_Y);
|
||||
map_button(SDL_CONTROLLER_BUTTON_START, DC_BTN_START);
|
||||
map_button(SDL_CONTROLLER_BUTTON_DPAD_UP, DC_DPAD_UP);
|
||||
map_button(SDL_CONTROLLER_BUTTON_DPAD_DOWN, DC_DPAD_DOWN);
|
||||
map_button(SDL_CONTROLLER_BUTTON_DPAD_LEFT, DC_DPAD_LEFT);
|
||||
map_button(SDL_CONTROLLER_BUTTON_DPAD_RIGHT, DC_DPAD_RIGHT);
|
||||
map_button(SDL_CONTROLLER_BUTTON_BACK, EMU_BTN_MENU);
|
||||
map_button(SDL_CONTROLLER_BUTTON_LEFTSHOULDER, DC_BTN_C); // service
|
||||
map_button(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, DC_BTN_Z); // test
|
||||
|
||||
auto map_axis = [&](SDL_GameControllerAxis sdl_axis, DreamcastKey dc_axis) {
|
||||
SDL_GameControllerButtonBind bind = SDL_GameControllerGetBindForAxis(sdl_controller, sdl_axis);
|
||||
if (bind.bindType != SDL_CONTROLLER_BINDTYPE_AXIS)
|
||||
return false;
|
||||
|
||||
bool invert_axis = false;
|
||||
const char *s = SDL_GameControllerGetStringForAxis(sdl_axis);
|
||||
if (s != nullptr && s[strlen(s) - 1] == '~')
|
||||
invert_axis = true;
|
||||
set_axis(dc_axis, bind.value.axis, invert_axis);
|
||||
return true;
|
||||
};
|
||||
map_axis(SDL_CONTROLLER_AXIS_LEFTX, DC_AXIS_X);
|
||||
map_axis(SDL_CONTROLLER_AXIS_LEFTY, DC_AXIS_Y);
|
||||
map_axis(SDL_CONTROLLER_AXIS_RIGHTX, DC_AXIS_X2);
|
||||
map_axis(SDL_CONTROLLER_AXIS_RIGHTY, DC_AXIS_Y2);
|
||||
if (!map_axis(SDL_CONTROLLER_AXIS_TRIGGERLEFT, DC_AXIS_LT))
|
||||
map_button(SDL_CONTROLLER_BUTTON_LEFTSHOULDER, EMU_BTN_TRIGGER_LEFT);
|
||||
if (!map_axis(SDL_CONTROLLER_AXIS_TRIGGERRIGHT, DC_AXIS_RT))
|
||||
map_button(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, EMU_BTN_TRIGGER_RIGHT);
|
||||
|
||||
SDL_GameControllerClose(sdl_controller);
|
||||
dirty = false;
|
||||
}
|
||||
else
|
||||
INFO_LOG(INPUT, "using default mapping");
|
||||
}
|
||||
};
|
||||
|
||||
class SDLGamepadDevice : public GamepadDevice
|
||||
{
|
||||
public:
|
||||
SDLGamepadDevice(int maple_port, SDL_Joystick* sdl_joystick) : GamepadDevice(maple_port, "SDL"), sdl_joystick(sdl_joystick)
|
||||
SDLGamepadDevice(int maple_port, int joystick_idx, SDL_Joystick* sdl_joystick) : GamepadDevice(maple_port, "SDL"), sdl_joystick(sdl_joystick)
|
||||
{
|
||||
_name = SDL_JoystickName(sdl_joystick);
|
||||
sdl_joystick_instance = SDL_JoystickInstanceID(sdl_joystick);
|
||||
|
@ -56,19 +110,7 @@ public:
|
|||
INFO_LOG(INPUT, "SDL: Opened joystick %d on port %d: '%s' unique_id=%s", sdl_joystick_instance, maple_port, _name.c_str(), _unique_id.c_str());
|
||||
|
||||
if (!find_mapping())
|
||||
{
|
||||
if (_name == "Microsoft X-Box 360 pad")
|
||||
{
|
||||
input_mapper = std::make_shared<Xbox360InputMapping>();
|
||||
INFO_LOG(INPUT, "using Xbox 360 mapping");
|
||||
}
|
||||
else
|
||||
{
|
||||
input_mapper = std::make_shared<DefaultInputMapping>();
|
||||
INFO_LOG(INPUT, "using default mapping");
|
||||
}
|
||||
save_mapping();
|
||||
}
|
||||
input_mapper = std::make_shared<DefaultInputMapping>(joystick_idx);
|
||||
else
|
||||
INFO_LOG(INPUT, "using custom mapping '%s'", input_mapper->name.c_str());
|
||||
sdl_haptic = SDL_HapticOpenFromJoystick(sdl_joystick);
|
||||
|
@ -77,7 +119,6 @@ public:
|
|||
SDL_HapticClose(sdl_haptic);
|
||||
sdl_haptic = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
virtual void rumble(float power, float inclination, u32 duration_ms) override
|
||||
|
|
Loading…
Reference in New Issue