Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add wrappers for SDL 2.0.9 rumble functions #824

Merged
merged 7 commits into from
Dec 12, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the changelog, technically, 0.32 is already released, so make a new category "v0.32.1 (unreleased)" and put those changes there instead. Otherwise, people will wonder why this rumble feature is not part of 0.32 on crates.io.

Other than than, looks good to me! I tested the update example locally on my computer with a Xbox 360 controller, works really well!

Copy link
Contributor Author

@Manorhos Manorhos Dec 12, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I wasn't so sure about that myself... What you proposed sounds good, I'm gonna do that.

Edit: Oh, and I'm glad it also works fine for you! The 2.0.9 rumble feature really is great, especially with the HIDAPI stuff they added.

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