mirror of
https://github.com/libretro/RetroArch.git
synced 2025-02-22 02:30:56 +00:00
Support variable strength for rumble motors.
This commit is contained in:
parent
aa882c3515
commit
c7db4aff64
4
driver.c
4
driver.c
@ -309,10 +309,10 @@ void driver_set_nonblock_state(bool nonblock)
|
||||
g_extern.audio_data.nonblock_chunk_size : g_extern.audio_data.block_chunk_size;
|
||||
}
|
||||
|
||||
bool driver_set_rumble_state(unsigned port, enum retro_rumble_effect effect, bool enable)
|
||||
bool driver_set_rumble_state(unsigned port, enum retro_rumble_effect effect, uint16_t strength)
|
||||
{
|
||||
if (driver.input && driver.input_data && driver.input->set_rumble)
|
||||
return driver.input->set_rumble(driver.input_data, port, effect, enable);
|
||||
return driver.input->set_rumble(driver.input_data, port, effect, strength);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
4
driver.h
4
driver.h
@ -335,7 +335,7 @@ typedef struct input_driver
|
||||
const char *ident;
|
||||
|
||||
void (*grab_mouse)(void *data, bool state);
|
||||
bool (*set_rumble)(void *data, unsigned port, enum retro_rumble_effect effect, bool state);
|
||||
bool (*set_rumble)(void *data, unsigned port, enum retro_rumble_effect effect, uint16_t state);
|
||||
} input_driver_t;
|
||||
|
||||
struct rarch_viewport;
|
||||
@ -497,7 +497,7 @@ uintptr_t driver_get_current_framebuffer(void);
|
||||
retro_proc_address_t driver_get_proc_address(const char *sym);
|
||||
|
||||
// Used by RETRO_ENVIRONMENT_GET_RUMBLE_INTERFACE
|
||||
bool driver_set_rumble_state(unsigned port, enum retro_rumble_effect effect, bool enable);
|
||||
bool driver_set_rumble_state(unsigned port, enum retro_rumble_effect effect, uint16_t strength);
|
||||
|
||||
extern driver_t driver;
|
||||
|
||||
|
@ -334,10 +334,10 @@ static void dinput_grab_mouse(void *data, bool state)
|
||||
IDirectInputDevice8_Acquire(di->mouse);
|
||||
}
|
||||
|
||||
static bool dinput_set_rumble(void *data, unsigned port, enum retro_rumble_effect effect, bool state)
|
||||
static bool dinput_set_rumble(void *data, unsigned port, enum retro_rumble_effect effect, uint16_t strength)
|
||||
{
|
||||
struct dinput_input *di = (struct dinput_input*)data;
|
||||
return input_joypad_set_rumble(di->joypad, port, effect, state);
|
||||
return input_joypad_set_rumble(di->joypad, port, effect, strength);
|
||||
}
|
||||
|
||||
const input_driver_t input_dinput = {
|
||||
|
@ -107,7 +107,7 @@ const char *input_joypad_name(const rarch_joypad_driver_t *driver, unsigned joyp
|
||||
}
|
||||
|
||||
bool input_joypad_set_rumble(const rarch_joypad_driver_t *driver,
|
||||
unsigned port, enum retro_rumble_effect effect, bool state)
|
||||
unsigned port, enum retro_rumble_effect effect, uint16_t strength)
|
||||
{
|
||||
if (!driver || !driver->set_rumble)
|
||||
return false;
|
||||
@ -116,7 +116,7 @@ bool input_joypad_set_rumble(const rarch_joypad_driver_t *driver,
|
||||
if (joy_index < 0 || joy_index >= MAX_PLAYERS)
|
||||
return false;
|
||||
|
||||
return driver->set_rumble(joy_index, effect, state);
|
||||
return driver->set_rumble(joy_index, effect, strength);
|
||||
}
|
||||
|
||||
bool input_joypad_pressed(const rarch_joypad_driver_t *driver,
|
||||
|
@ -66,7 +66,7 @@ typedef struct rarch_joypad_driver
|
||||
bool (*button)(unsigned, uint16_t);
|
||||
int16_t (*axis)(unsigned, uint32_t);
|
||||
void (*poll)(void);
|
||||
bool (*set_rumble)(unsigned, enum retro_rumble_effect, bool); // Optional
|
||||
bool (*set_rumble)(unsigned, enum retro_rumble_effect, uint16_t); // Optional
|
||||
const char *(*name)(unsigned);
|
||||
|
||||
const char *ident;
|
||||
@ -83,7 +83,7 @@ int16_t input_joypad_analog(const rarch_joypad_driver_t *driver,
|
||||
unsigned port, unsigned index, unsigned id, const struct retro_keybind *binds);
|
||||
|
||||
bool input_joypad_set_rumble(const rarch_joypad_driver_t *driver,
|
||||
unsigned port, enum retro_rumble_effect effect, bool state);
|
||||
unsigned port, enum retro_rumble_effect effect, uint16_t strength);
|
||||
|
||||
int16_t input_joypad_axis_raw(const rarch_joypad_driver_t *driver,
|
||||
unsigned joypad, unsigned axis);
|
||||
|
@ -285,10 +285,10 @@ static void linuxraw_input_free(void *data)
|
||||
free(data);
|
||||
}
|
||||
|
||||
static bool linuxraw_set_rumble(void *data, unsigned port, enum retro_rumble_effect effect, bool state)
|
||||
static bool linuxraw_set_rumble(void *data, unsigned port, enum retro_rumble_effect effect, uint16_t strength)
|
||||
{
|
||||
linuxraw_input_t *linuxraw = (linuxraw_input_t*)data;
|
||||
return input_joypad_set_rumble(linuxraw->joypad, port, effect, state);
|
||||
return input_joypad_set_rumble(linuxraw->joypad, port, effect, strength);
|
||||
}
|
||||
|
||||
static void linuxraw_input_poll(void *data)
|
||||
|
@ -214,10 +214,10 @@ static void sdl_input_free(void *data)
|
||||
free(data);
|
||||
}
|
||||
|
||||
static bool sdl_set_rumble(void *data, unsigned port, enum retro_rumble_effect effect, bool state)
|
||||
static bool sdl_set_rumble(void *data, unsigned port, enum retro_rumble_effect effect, uint16_t strength)
|
||||
{
|
||||
sdl_input_t *sdl = (sdl_input_t*)data;
|
||||
return input_joypad_set_rumble(sdl->joypad, port, effect, state);
|
||||
return input_joypad_set_rumble(sdl->joypad, port, effect, strength);
|
||||
}
|
||||
|
||||
static void sdl_poll_mouse(sdl_input_t *sdl)
|
||||
|
@ -57,6 +57,7 @@ struct udev_joypad
|
||||
int num_effects;
|
||||
int effects[2]; // [0] - strong, [1] - weak
|
||||
bool has_set_ff[2];
|
||||
uint16_t strength[2];
|
||||
|
||||
char *ident;
|
||||
char *path;
|
||||
@ -177,7 +178,7 @@ end:
|
||||
udev_device_unref(dev);
|
||||
}
|
||||
|
||||
static bool udev_set_rumble(unsigned i, enum retro_rumble_effect effect, bool state)
|
||||
static bool udev_set_rumble(unsigned i, enum retro_rumble_effect effect, uint16_t strength)
|
||||
{
|
||||
struct udev_joypad *pad = &g_pads[i];
|
||||
|
||||
@ -186,6 +187,30 @@ static bool udev_set_rumble(unsigned i, enum retro_rumble_effect effect, bool st
|
||||
if (pad->num_effects < 2)
|
||||
return false;
|
||||
|
||||
if (pad->strength[effect] == strength)
|
||||
return true;
|
||||
|
||||
if (pad->has_set_ff[effect] && strength != pad->strength[effect])
|
||||
{
|
||||
struct input_event play;
|
||||
memset(&play, 0, sizeof(play));
|
||||
play.type = EV_FF;
|
||||
play.code = pad->effects[effect];
|
||||
play.value = 0;
|
||||
if (write(pad->fd, &play, sizeof(play)) < (ssize_t)sizeof(play))
|
||||
{
|
||||
RARCH_ERR("[udev]: Failed to set rumble effect %u on pad %u.\n",
|
||||
effect, i);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ioctl(pad->fd, EVIOCRMFF, (void*)(uintptr_t)pad->effects[effect]) < 0)
|
||||
RARCH_WARN("[udev]: Failed to remove effect.\n");
|
||||
|
||||
pad->has_set_ff[effect] = false;
|
||||
pad->effects[effect] = -1;
|
||||
}
|
||||
|
||||
// Have to defer the force feedback settings to here.
|
||||
// For some reason, effects are getting dropped when they're set at init.
|
||||
// Setting at init seems to work for pads which are hotplugged ...
|
||||
@ -199,8 +224,8 @@ static bool udev_set_rumble(unsigned i, enum retro_rumble_effect effect, bool st
|
||||
e.id = -1;
|
||||
switch (effect)
|
||||
{
|
||||
case RETRO_RUMBLE_STRONG: e.u.rumble.strong_magnitude = 0xc000; break;
|
||||
case RETRO_RUMBLE_WEAK: e.u.rumble.weak_magnitude = 0xc000; break;
|
||||
case RETRO_RUMBLE_STRONG: e.u.rumble.strong_magnitude = strength; break;
|
||||
case RETRO_RUMBLE_WEAK: e.u.rumble.weak_magnitude = strength; break;
|
||||
default: return false;
|
||||
}
|
||||
|
||||
@ -212,13 +237,14 @@ static bool udev_set_rumble(unsigned i, enum retro_rumble_effect effect, bool st
|
||||
|
||||
pad->has_set_ff[effect] = true;
|
||||
pad->effects[effect] = e.id;
|
||||
pad->strength[effect] = strength;
|
||||
}
|
||||
|
||||
struct input_event play;
|
||||
memset(&play, 0, sizeof(play));
|
||||
play.type = EV_FF;
|
||||
play.code = pad->effects[effect];
|
||||
play.value = state;
|
||||
play.value = strength != 0;
|
||||
if (write(pad->fd, &play, sizeof(play)) < (ssize_t)sizeof(play))
|
||||
{
|
||||
RARCH_ERR("[udev]: Failed to set rumble effect %u on pad %u.\n",
|
||||
|
@ -269,10 +269,10 @@ static void x_grab_mouse(void *data, bool state)
|
||||
x11->grab_mouse = state;
|
||||
}
|
||||
|
||||
static bool x_set_rumble(void *data, unsigned port, enum retro_rumble_effect effect, bool state)
|
||||
static bool x_set_rumble(void *data, unsigned port, enum retro_rumble_effect effect, uint16_t strength)
|
||||
{
|
||||
x11_input_t *x11 = (x11_input_t*)data;
|
||||
return input_joypad_set_rumble(x11->joypad, port, effect, state);
|
||||
return input_joypad_set_rumble(x11->joypad, port, effect, strength);
|
||||
}
|
||||
|
||||
const input_driver_t input_x = {
|
||||
|
@ -180,21 +180,17 @@ static void update_input(void)
|
||||
{
|
||||
static bool old_start;
|
||||
static bool old_select;
|
||||
uint16_t strength_strong = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2) ? 0x4000 : 0xffff;
|
||||
uint16_t strength_weak = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2) ? 0x4000 : 0xffff;
|
||||
bool start = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START);
|
||||
bool select = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT);
|
||||
if (old_start != start)
|
||||
{
|
||||
fprintf(stderr, "Strong rumble: %s.\n", start ? "ON": "OFF");
|
||||
if (!rumble.set_rumble_state(0, RETRO_RUMBLE_STRONG, start))
|
||||
fprintf(stderr, "Strong rumble; failed to set state.\n");
|
||||
}
|
||||
rumble.set_rumble_state(0, RETRO_RUMBLE_STRONG, start * strength_strong);
|
||||
|
||||
if (old_select != select)
|
||||
{
|
||||
fprintf(stderr, "Weak rumble: %s.\n", select ? "ON": "OFF");
|
||||
if (!rumble.set_rumble_state(0, RETRO_RUMBLE_WEAK, select))
|
||||
fprintf(stderr, "Weak rumble; failed to set state.\n");
|
||||
}
|
||||
rumble.set_rumble_state(0, RETRO_RUMBLE_WEAK, select * strength_weak);
|
||||
|
||||
old_start = start;
|
||||
old_select = select;
|
||||
|
@ -531,10 +531,10 @@ enum retro_rumble_effect
|
||||
|
||||
// Sets rumble state for joypad plugged in port 'port'. Rumble effects are controlled independently,
|
||||
// and setting e.g. strong rumble does not override weak rumble.
|
||||
// Should only be called when rumble state changes.
|
||||
// Strength has a range of [0, 0xffff].
|
||||
//
|
||||
// Returns true if rumble state request was honored. Calling this before first retro_run() is likely to return false.
|
||||
typedef bool (*retro_set_rumble_state_t)(unsigned port, enum retro_rumble_effect effect, bool enable);
|
||||
typedef bool (*retro_set_rumble_state_t)(unsigned port, enum retro_rumble_effect effect, uint16_t strength);
|
||||
struct retro_rumble_interface
|
||||
{
|
||||
retro_set_rumble_state_t set_rumble_state;
|
||||
|
Loading…
x
Reference in New Issue
Block a user