sdl: rumble support

This commit is contained in:
Flyinghead 2019-02-23 01:06:10 +01:00
parent 98271bb3b1
commit 0f5a3ab884
2 changed files with 48 additions and 3 deletions

View File

@ -60,7 +60,7 @@ static void sdl_close_joystick(SDL_JoystickID instance)
{
std::shared_ptr<SDLGamepadDevice> gamepad = SDLGamepadDevice::GetSDLGamepad(instance);
if (gamepad != NULL)
gamepad->Close();
gamepad->close();
}
void input_sdl_init()
@ -72,6 +72,8 @@ void input_sdl_init()
die("error initializing SDL Joystick subsystem");
}
}
if (SDL_WasInit(SDL_INIT_HAPTIC) == 0)
SDL_InitSubSystem(SDL_INIT_HAPTIC);
SDL_SetRelativeMouseMode(SDL_FALSE);
@ -97,6 +99,9 @@ static void set_mouse_position(int x, int y)
// FIXME this shouldn't be done by port. Need something like: handle_events() then get_port(0), get_port(2), ...
void input_sdl_handle(u32 port)
{
if (port == 0) // FIXME hack
SDLGamepadDevice::UpdateRumble();
#define SET_FLAG(field, mask, expr) field =((expr) ? (field & ~mask) : (field | mask))
SDL_Event event;
while (SDL_PollEvent(&event))

View File

@ -1,4 +1,5 @@
#include "../input/gamepad_device.h"
#include "oslib/oslib.h"
#include "sdl.h"
class DefaultInputMapping : public InputMapping
@ -65,13 +66,44 @@ public:
}
else
printf("using custom mapping '%s'\n", input_mapper->name.c_str());
sdl_haptic = SDL_HapticOpenFromJoystick(sdl_joystick);
if (SDL_HapticRumbleInit(sdl_haptic) != 0)
{
SDL_HapticClose(sdl_haptic);
sdl_haptic = NULL;
}
SDL_JoystickID sdl_instance() { return sdl_joystick_instance; }
}
void Close()
virtual void rumble(float power, float inclination, u32 duration_ms) override
{
if (sdl_haptic != NULL)
{
vib_inclination = inclination * power;
vib_stop_time = os_GetSeconds() + duration_ms / 1000.0;
SDL_HapticRumblePlay(sdl_haptic, power, duration_ms);
}
}
virtual void update_rumble() override
{
if (sdl_haptic == NULL)
return;
if (vib_inclination > 0)
{
int rem_time = (vib_stop_time - os_GetSeconds()) * 1000;
if (rem_time <= 0)
vib_inclination = 0;
else
SDL_HapticRumblePlay(sdl_haptic, vib_inclination * rem_time, rem_time);
}
}
void close()
{
printf("SDL: Joystick '%s' on port %d disconnected\n", _name.c_str(), maple_port());
if (sdl_haptic != NULL)
SDL_HapticClose(sdl_haptic);
SDL_JoystickClose(sdl_joystick);
GamepadDevice::Unregister(sdl_gamepads[sdl_joystick_instance]);
sdl_gamepads.erase(sdl_joystick_instance);
@ -90,6 +122,11 @@ public:
else
return NULL;
}
static void UpdateRumble()
{
for (auto pair : sdl_gamepads)
pair.second->update_rumble();
}
protected:
virtual void load_axis_min_max(u32 axis) override
@ -101,6 +138,9 @@ protected:
private:
SDL_Joystick* sdl_joystick;
SDL_JoystickID sdl_joystick_instance;
SDL_Haptic *sdl_haptic;
float vib_inclination = 0;
double vib_stop_time = 0;
static std::map<SDL_JoystickID, std::shared_ptr<SDLGamepadDevice>> sdl_gamepads;
};