Skip to content

Commit

Permalink
Merge pull request #824 from Manorhos/rumble
Browse files Browse the repository at this point in the history
Add wrappers for SDL 2.0.9 rumble functions
  • Loading branch information
Cobrand authored Dec 12, 2018
2 parents 4697a26 + 64a936c commit b6fa720
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 10 deletions.
7 changes: 6 additions & 1 deletion changelog.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
In this file will be listed the changes, especially the breaking ones that one should be careful of
when upgrading from a version of rust-sdl2 to another.

### v0.32.1 (unreleased)

[PR #824](https://github.com/Rust-SDL2/rust-sdl2/pull/824):
Added `controller::set_rumble` and `joystick::set_rumble`, wrappers for `SDL_GameControllerRumble` and `SDL_JoystickRumble` respectively.

### v0.32

[PR #790](https://github.com/Rust-SDL2/rust-sdl2/pull/790): Added missing `window_id` field to `Event::DropFile`
Expand Down Expand Up @@ -41,7 +46,7 @@ Fix `ClipboardUtil::set_clipboard_text` to return an Ok when it went well.
Add `video::border_size -> Result<(u16, u16, u16, u16), String>` equivalent of `SDL_GetWindowBorderSize()`

[PR #732](https://github.com/Rust-SDL2/rust-sdl2/pull/732):
Implemented `From<(u8, u8, u8)>` and `From<(u8, u8, u8, u8)>` for `pixels::Color`.
Implemented `From<(u8, u8, u8)>` and `From<(u8, u8, u8, u8)>` for `pixels::Color`.
`Canvas.set_draw_color` can now be called with tuples or other types which implements `Into<pixels::Color>`

[PR #279](https://github.com/Rust-SDL2/rust-sdl2/pull/729)
Expand Down
21 changes: 20 additions & 1 deletion examples/game-controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,37 @@ fn main() {
}
}

let controller =
let mut controller =
match controller {
Some(c) => c,
None => panic!("Couldn't open any controller"),
};

println!("Controller mapping: {}", controller.mapping());

let (mut lo_freq, mut hi_freq) = (0, 0);

for event in sdl_context.event_pump().unwrap().wait_iter() {
use sdl2::event::Event;
use sdl2::controller::Axis;

match event {
Event::ControllerAxisMotion{ axis: Axis::TriggerLeft, value: val, .. } => {
// Trigger axes go from 0 to 32767, so this should be okay
lo_freq = (val as u16) * 2;
match controller.set_rumble(lo_freq, hi_freq, 15000) {
Ok(()) => println!("Set rumble to ({}, {})", lo_freq, hi_freq),
Err(e) => println!("Error setting rumble to ({}, {}): {:?}", lo_freq, hi_freq, e),
}
}
Event::ControllerAxisMotion{ axis: Axis::TriggerRight, value: val, .. } => {
// Trigger axes go from 0 to 32767, so this should be okay
hi_freq = (val as u16) * 2;
match controller.set_rumble(lo_freq, hi_freq, 15000) {
Ok(()) => println!("Set rumble to ({}, {})", lo_freq, hi_freq),
Err(e) => println!("Error setting rumble to ({}, {}): {:?}", lo_freq, hi_freq, e),
}
}
Event::ControllerAxisMotion{ axis, value: val, .. } => {
// Axis motion is an absolute value in the range
// [-32768, 32767]. Let's simulate a very rough dead
Expand Down
39 changes: 33 additions & 6 deletions examples/joystick.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,15 @@ fn main() {
}

// Print the joystick's power level, if a joystick was found.
match joystick {
let mut joystick = match joystick {
Some(j) => {
println!("\"{}\" power level: {:?}", j.name(), j.power_level().unwrap());
j
},
None => panic!("Couldn't open any joystick"),
}
};

let (mut lo_freq, mut hi_freq) = (0, 0);

for event in sdl_context.event_pump().unwrap().wait_iter() {
use sdl2::event::Event;
Expand All @@ -48,10 +51,34 @@ fn main() {
println!("Axis {} moved to {}", axis_idx, val);
}
}
Event::JoyButtonDown{ button_idx, .. } =>
println!("Button {} down", button_idx),
Event::JoyButtonUp{ button_idx, .. } =>
println!("Button {} up", button_idx),
Event::JoyButtonDown{ button_idx, .. } => {
println!("Button {} down", button_idx);
if button_idx == 0 {
lo_freq = 65535;
} else if button_idx == 1 {
hi_freq = 65535;
}
if button_idx < 2 {
match joystick.set_rumble(lo_freq, hi_freq, 15000) {
Ok(()) => println!("Set rumble to ({}, {})", lo_freq, hi_freq),
Err(e) => println!("Error setting rumble to ({}, {}): {:?}", lo_freq, hi_freq, e),
}
}
}
Event::JoyButtonUp{ button_idx, .. } => {
println!("Button {} up", button_idx);
if button_idx == 0 {
lo_freq = 0;
} else if button_idx == 1 {
hi_freq = 0;
}
if button_idx < 2 {
match joystick.set_rumble(lo_freq, hi_freq, 15000) {
Ok(()) => println!("Set rumble to ({}, {})", lo_freq, hi_freq),
Err(e) => println!("Error setting rumble to ({}, {}): {:?}", lo_freq, hi_freq, e),
}
}
}
Event::JoyHatMotion{ hat_idx, state, .. } =>
println!("Hat {} moved to {:?}", hat_idx, state),
Event::Quit{..} => break,
Expand Down
2 changes: 1 addition & 1 deletion scripts/travis-install-sdl2.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

set -xueo pipefail

wget https://www.libsdl.org/release/SDL2-2.0.8.tar.gz -O sdl2.tar.gz
wget https://www.libsdl.org/release/SDL2-2.0.9.tar.gz -O sdl2.tar.gz
tar xzf sdl2.tar.gz
pushd SDL2-* && ./configure && make && sudo make install && popd
wget -q https://www.libsdl.org/projects/SDL_ttf/release/SDL2_ttf-2.0.14.tar.gz
Expand Down
31 changes: 31 additions & 0 deletions src/sdl2/controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,37 @@ impl GameController {

unsafe { sys::SDL_GameControllerGetButton(self.raw, raw_button) != 0 }
}

/// Set the rumble motors to their specified intensities, if supported.
/// Automatically resets back to zero after `duration_ms` milliseconds have passed.
///
/// # Notes
///
/// The value range for the intensities is 0 to 0xFFFF.
///
/// Do *not* use `std::u32::MAX` or similar for `duration_ms` if you want
/// the rumble effect to keep playing for a long time, as this results in
/// the effect ending immediately after starting due to an overflow.
/// Use some smaller, "huge enough" number instead.
pub fn set_rumble(&mut self,
low_frequency_rumble: u16,
high_frequency_rumble: u16,
duration_ms: u32)
-> Result<(), IntegerOrSdlError>
{
let result = unsafe {
sys::SDL_GameControllerRumble(self.raw,
low_frequency_rumble,
high_frequency_rumble,
duration_ms)
};

if result != 0 {
Err(IntegerOrSdlError::SdlError(get_error()))
} else {
Ok(())
}
}
}

impl Drop for GameController {
Expand Down
33 changes: 32 additions & 1 deletion src/sdl2/joystick.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ impl JoystickSubsystem {
}

/// Attempt to open the joystick at index `joystick_index` and return it.
pub fn open(&self, joystick_index: u32)
pub fn open(&self, joystick_index: u32)
-> Result<Joystick, IntegerOrSdlError> {
use common::IntegerOrSdlError::*;
let joystick_index = try!(validate_int(joystick_index, "joystick_index"));
Expand Down Expand Up @@ -344,6 +344,37 @@ impl Joystick {
}
}
}

/// Set the rumble motors to their specified intensities, if supported.
/// Automatically resets back to zero after `duration_ms` milliseconds have passed.
///
/// # Notes
///
/// The value range for the intensities is 0 to 0xFFFF.
///
/// Do *not* use `std::u32::MAX` or similar for `duration_ms` if you want
/// the rumble effect to keep playing for a long time, as this results in
/// the effect ending immediately after starting due to an overflow.
/// Use some smaller, "huge enough" number instead.
pub fn set_rumble(&mut self,
low_frequency_rumble: u16,
high_frequency_rumble: u16,
duration_ms: u32)
-> Result<(), IntegerOrSdlError>
{
let result = unsafe {
sys::SDL_JoystickRumble(self.raw,
low_frequency_rumble,
high_frequency_rumble,
duration_ms)
};

if result != 0 {
Err(IntegerOrSdlError::SdlError(get_error()))
} else {
Ok(())
}
}
}

impl Drop for Joystick {
Expand Down

0 comments on commit b6fa720

Please sign in to comment.