run cargo fmt

This commit is contained in:
Guillaume Gomez
2020-12-08 17:06:23 +01:00
parent c4189933b6
commit 7fd7ee4447
74 changed files with 6227 additions and 4761 deletions

View File

@@ -1,4 +1,4 @@
fn main() {
#[cfg(any(target_os="openbsd", target_os="freebsd"))]
#[cfg(any(target_os = "openbsd", target_os = "freebsd"))]
println!(r"cargo:rustc-link-search=/usr/local/lib");
}

View File

@@ -3,22 +3,28 @@ use std::path::Path;
use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use sdl2::rect::Rect;
use sdl2::rect::Point;
use sdl2::rect::Rect;
use std::time::Duration;
fn main() -> Result<(), String> {
let sdl_context = sdl2::init()?;
let video_subsystem = sdl_context.video()?;
let window = video_subsystem.window("SDL2", 640, 480)
.position_centered().build().map_err(|e| e.to_string())?;
let window = video_subsystem
.window("SDL2", 640, 480)
.position_centered()
.build()
.map_err(|e| e.to_string())?;
let mut canvas = window.into_canvas()
.accelerated().build().map_err(|e| e.to_string())?;
let mut canvas = window
.into_canvas()
.accelerated()
.build()
.map_err(|e| e.to_string())?;
let texture_creator = canvas.texture_creator();
canvas.set_draw_color(sdl2::pixels::Color::RGBA(0,0,0,255));
canvas.set_draw_color(sdl2::pixels::Color::RGBA(0, 0, 0, 255));
let mut timer = sdl_context.timer()?;
@@ -27,34 +33,39 @@ fn main() -> Result<(), String> {
// animation sheet and extras are available from
// https://opengameart.org/content/a-platformer-in-the-forest
let temp_surface = sdl2::surface::Surface::load_bmp(Path::new("assets/characters.bmp"))?;
let texture = texture_creator.create_texture_from_surface(&temp_surface)
let texture = texture_creator
.create_texture_from_surface(&temp_surface)
.map_err(|e| e.to_string())?;
let frames_per_anim = 4;
let sprite_tile_size = (32,32);
let sprite_tile_size = (32, 32);
// Baby - walk animation
let mut source_rect_0 = Rect::new(0, 0, sprite_tile_size.0, sprite_tile_size.0);
let mut dest_rect_0 = Rect::new(0, 0, sprite_tile_size.0*4, sprite_tile_size.0*4);
dest_rect_0.center_on(Point::new(-64,120));
let mut dest_rect_0 = Rect::new(0, 0, sprite_tile_size.0 * 4, sprite_tile_size.0 * 4);
dest_rect_0.center_on(Point::new(-64, 120));
// King - walk animation
let mut source_rect_1 = Rect::new(0, 32, sprite_tile_size.0, sprite_tile_size.0);
let mut dest_rect_1 = Rect::new(0, 32, sprite_tile_size.0*4, sprite_tile_size.0*4);
dest_rect_1.center_on(Point::new(0,240));
let mut dest_rect_1 = Rect::new(0, 32, sprite_tile_size.0 * 4, sprite_tile_size.0 * 4);
dest_rect_1.center_on(Point::new(0, 240));
// Soldier - walk animation
let mut source_rect_2 = Rect::new(0, 64, sprite_tile_size.0, sprite_tile_size.0);
let mut dest_rect_2 = Rect::new(0, 64, sprite_tile_size.0*4, sprite_tile_size.0*4);
dest_rect_2.center_on(Point::new(440,360));
let mut dest_rect_2 = Rect::new(0, 64, sprite_tile_size.0 * 4, sprite_tile_size.0 * 4);
dest_rect_2.center_on(Point::new(440, 360));
let mut running = true;
while running {
for event in event_pump.poll_iter() {
match event {
Event::Quit {..} | Event::KeyDown {keycode: Some(Keycode::Escape), ..} => {
Event::Quit { .. }
| Event::KeyDown {
keycode: Some(Keycode::Escape),
..
} => {
running = false;
},
}
_ => {}
}
}
@@ -73,9 +84,33 @@ fn main() -> Result<(), String> {
canvas.clear();
// copy the frame to the canvas
canvas.copy_ex(&texture, Some(source_rect_0), Some(dest_rect_0), 0.0, None, false, false)?;
canvas.copy_ex(&texture, Some(source_rect_1), Some(dest_rect_1), 0.0, None, true, false)?;
canvas.copy_ex(&texture, Some(source_rect_2), Some(dest_rect_2), 0.0, None, false, false)?;
canvas.copy_ex(
&texture,
Some(source_rect_0),
Some(dest_rect_0),
0.0,
None,
false,
false,
)?;
canvas.copy_ex(
&texture,
Some(source_rect_1),
Some(dest_rect_1),
0.0,
None,
true,
false,
)?;
canvas.copy_ex(
&texture,
Some(source_rect_2),
Some(dest_rect_2),
0.0,
None,
false,
false,
)?;
canvas.present();
std::thread::sleep(Duration::from_millis(100));

View File

@@ -2,13 +2,12 @@ extern crate sdl2;
use sdl2::audio::{AudioCallback, AudioSpecDesired};
use sdl2::AudioSubsystem;
use std::time::Duration;
use std::sync::mpsc;
use std::i16;
use std::sync::mpsc;
use std::time::Duration;
const RECORDING_LENGTH_SECONDS: usize = 3;
struct Recording {
record_buffer: Vec<i16>,
pos: usize,
@@ -31,7 +30,8 @@ impl AudioCallback for Recording {
self.pos += 1;
if self.pos >= self.record_buffer.len() {
self.done = true;
self.done_sender.send(self.record_buffer.clone())
self.done_sender
.send(self.record_buffer.clone())
.expect("could not send record buffer");
break;
}
@@ -39,22 +39,36 @@ impl AudioCallback for Recording {
}
}
fn record(audio_subsystem: &AudioSubsystem, desired_spec: &AudioSpecDesired) -> Result<Vec<i16>, String> {
println!("Capturing {:} seconds... Please rock!", RECORDING_LENGTH_SECONDS);
fn record(
audio_subsystem: &AudioSubsystem,
desired_spec: &AudioSpecDesired,
) -> Result<Vec<i16>, String> {
println!(
"Capturing {:} seconds... Please rock!",
RECORDING_LENGTH_SECONDS
);
let (done_sender, done_receiver) = mpsc::channel();
let capture_device = audio_subsystem.open_capture(None, desired_spec, |spec| {
println!("Capture Spec = {:?}", spec);
Recording {
record_buffer: vec![0; spec.freq as usize * RECORDING_LENGTH_SECONDS * spec.channels as usize],
record_buffer: vec![
0;
spec.freq as usize
* RECORDING_LENGTH_SECONDS
* spec.channels as usize
],
pos: 0,
done_sender,
done: false
done: false,
}
})?;
println!("AudioDriver: {:?}", capture_device.subsystem().current_audio_driver());
println!(
"AudioDriver: {:?}",
capture_device.subsystem().current_audio_driver()
);
capture_device.resume();
// Wait until the recording is done.
@@ -69,7 +83,6 @@ fn record(audio_subsystem: &AudioSubsystem, desired_spec: &AudioSpecDesired) ->
Ok(recorded_vec)
}
/// Returns a percent value
fn calculate_average_volume(recorded_vec: &[i16]) -> f32 {
let sum: i64 = recorded_vec.iter().map(|&x| (x as i64).abs()).sum();
@@ -78,12 +91,14 @@ fn calculate_average_volume(recorded_vec: &[i16]) -> f32 {
/// Returns a percent value
fn calculate_max_volume(recorded_vec: &[i16]) -> f32 {
let max: i64 = recorded_vec.iter().map(|&x| (x as i64).abs()).max()
let max: i64 = recorded_vec
.iter()
.map(|&x| (x as i64).abs())
.max()
.expect("expected at least one value in recorded_vec");
(max as f32) / (i16::MAX as f32) * 100.0
}
struct SoundPlayback {
data: Vec<i16>,
pos: usize,
@@ -100,7 +115,11 @@ impl AudioCallback for SoundPlayback {
}
}
fn replay_recorded_vec(audio_subsystem: &AudioSubsystem, desired_spec: &AudioSpecDesired, recorded_vec: Vec<i16>) -> Result<(), String> {
fn replay_recorded_vec(
audio_subsystem: &AudioSubsystem,
desired_spec: &AudioSpecDesired,
recorded_vec: Vec<i16>,
) -> Result<(), String> {
println!("Playing...");
let playback_device = audio_subsystem.open_playback(None, desired_spec, |spec| {
@@ -120,7 +139,6 @@ fn replay_recorded_vec(audio_subsystem: &AudioSubsystem, desired_spec: &AudioSpe
Ok(())
}
fn main() -> Result<(), String> {
let sdl_context = sdl2::init()?;
let audio_subsystem = sdl_context.audio()?;
@@ -128,13 +146,19 @@ fn main() -> Result<(), String> {
let desired_spec = AudioSpecDesired {
freq: None,
channels: None,
samples: None
samples: None,
};
let recorded_vec = record(&audio_subsystem, &desired_spec)?;
println!("Average Volume of your Recording = {:?}%", calculate_average_volume(&recorded_vec));
println!("Max Volume of your Recording = {:?}%", calculate_max_volume(&recorded_vec));
println!(
"Average Volume of your Recording = {:?}%",
calculate_average_volume(&recorded_vec)
);
println!(
"Max Volume of your Recording = {:?}%",
calculate_max_volume(&recorded_vec)
);
replay_recorded_vec(&audio_subsystem, &desired_spec, recorded_vec)?;

View File

@@ -12,14 +12,11 @@ fn gen_wave(bytes_to_write: i32) -> Vec<i16> {
let mut result = Vec::new();
for x in 0..sample_count {
result.push(
if (x / period) % 2 == 0 {
tone_volume
}
else {
-tone_volume
}
);
result.push(if (x / period) % 2 == 0 {
tone_volume
} else {
-tone_volume
});
}
result
}
@@ -32,8 +29,7 @@ fn main() -> Result<(), String> {
freq: Some(48_000),
channels: Some(2),
// mono -
samples: Some(4)
// default sample size
samples: Some(4), // default sample size
};
let device = audio_subsystem.open_queue::<i16, _>(None, &desired_spec)?;

View File

@@ -6,7 +6,7 @@ use std::time::Duration;
struct SquareWave {
phase_inc: f32,
phase: f32,
volume: f32
volume: f32,
}
impl AudioCallback for SquareWave {
@@ -15,7 +15,11 @@ impl AudioCallback for SquareWave {
fn callback(&mut self, out: &mut [f32]) {
// Generate a square wave
for x in out.iter_mut() {
*x = if self.phase <= 0.5 { self.volume } else { -self.volume };
*x = if self.phase <= 0.5 {
self.volume
} else {
-self.volume
};
self.phase = (self.phase + self.phase_inc) % 1.0;
}
}
@@ -27,8 +31,8 @@ fn main() -> Result<(), String> {
let desired_spec = AudioSpecDesired {
freq: Some(44_100),
channels: Some(1), // mono
samples: None // default sample size
channels: Some(1), // mono
samples: None, // default sample size
};
let device = audio_subsystem.open_playback(None, &desired_spec, |spec| {
@@ -39,7 +43,7 @@ fn main() -> Result<(), String> {
SquareWave {
phase_inc: 440.0 / spec.freq as f32,
phase: 0.0,
volume: 0.25
volume: 0.25,
}
})?;
@@ -50,6 +54,6 @@ fn main() -> Result<(), String> {
std::thread::sleep(Duration::from_millis(2_000));
// Device is automatically closed when dropped
Ok(())
}

View File

@@ -1,9 +1,9 @@
extern crate sdl2;
use sdl2::audio::{AudioCallback, AudioSpecDesired,AudioSpecWAV,AudioCVT};
use std::time::Duration;
use sdl2::audio::{AudioCVT, AudioCallback, AudioSpecDesired, AudioSpecWAV};
use std::borrow::Cow;
use std::path::{PathBuf, Path};
use std::path::{Path, PathBuf};
use std::time::Duration;
// NOTE: You probably want to investigate the
// mixer feature for real use cases.
@@ -39,9 +39,9 @@ impl AudioCallback for Sound {
}
fn main() -> Result<(), String> {
let wav_file : Cow<'static, Path> = match std::env::args().nth(1) {
let wav_file: Cow<'static, Path> = match std::env::args().nth(1) {
None => Cow::from(Path::new("./assets/sine.wav")),
Some(s) => Cow::from(PathBuf::from(s))
Some(s) => Cow::from(PathBuf::from(s)),
};
let sdl_context = sdl2::init()?;
let audio_subsystem = sdl_context.audio()?;
@@ -49,17 +49,21 @@ fn main() -> Result<(), String> {
let desired_spec = AudioSpecDesired {
freq: Some(44_100),
channels: Some(1), // mono
samples: None // default
samples: None, // default
};
let device = audio_subsystem.open_playback(None, &desired_spec, |spec| {
let wav = AudioSpecWAV::load_wav(wav_file)
.expect("Could not load test WAV file");
let wav = AudioSpecWAV::load_wav(wav_file).expect("Could not load test WAV file");
let cvt = AudioCVT::new(
wav.format, wav.channels, wav.freq,
spec.format, spec.channels, spec.freq)
.expect("Could not convert WAV file");
wav.format,
wav.channels,
wav.freq,
spec.format,
spec.channels,
spec.freq,
)
.expect("Could not convert WAV file");
let data = cvt.convert(wav.buffer().to_vec());

View File

@@ -1,17 +1,17 @@
extern crate sdl2;
extern crate rand;
extern crate sdl2;
use sdl2::audio::{AudioCallback, AudioSpecDesired};
use std::time::Duration;
struct MyCallback {
volume: f32
volume: f32,
}
impl AudioCallback for MyCallback {
type Channel = f32;
fn callback(&mut self, out: &mut [f32]) {
use self::rand::{Rng, thread_rng};
use self::rand::{thread_rng, Rng};
let mut rng = thread_rng();
// Generate white noise
@@ -27,8 +27,8 @@ fn main() -> Result<(), String> {
let desired_spec = AudioSpecDesired {
freq: Some(44_100),
channels: Some(1), // mono
samples: None, // default sample size
channels: Some(1), // mono
samples: None, // default sample size
};
// None: use default device

View File

@@ -1,28 +1,33 @@
extern crate sdl2;
use std::env;
use std::path::Path;
use sdl2::event::Event;
use sdl2::image::{LoadSurface, InitFlag};
use sdl2::image::{InitFlag, LoadSurface};
use sdl2::keyboard::Keycode;
use sdl2::mouse::Cursor;
use sdl2::pixels::Color;
use sdl2::rect::Rect;
use sdl2::surface::Surface;
use std::env;
use std::path::Path;
pub fn run(png: &Path) -> Result<(), String> {
let sdl_context = sdl2::init()?;
let video_subsystem = sdl_context.video()?;
let _image_context = sdl2::image::init(InitFlag::PNG | InitFlag::JPG)?;
let window = video_subsystem.window("rust-sdl2 demo: Cursor", 800, 600)
.position_centered()
.build()
.map_err(|e| e.to_string())?;
let window = video_subsystem
.window("rust-sdl2 demo: Cursor", 800, 600)
.position_centered()
.build()
.map_err(|e| e.to_string())?;
let mut canvas = window.into_canvas().software().build().map_err(|e| e.to_string())?;
let mut canvas = window
.into_canvas()
.software()
.build()
.map_err(|e| e.to_string())?;
let surface = Surface::from_file(png)
.map_err(|err| format!("failed to load cursor image: {}", err))?;
let surface =
Surface::from_file(png).map_err(|err| format!("failed to load cursor image: {}", err))?;
let cursor = Cursor::from_surface(surface, 0, 0)
.map_err(|err| format!("failed to load cursor: {}", err))?;
cursor.set();
@@ -37,10 +42,12 @@ pub fn run(png: &Path) -> Result<(), String> {
'mainloop: loop {
for event in events.poll_iter() {
match event {
Event::Quit{..} |
Event::KeyDown {keycode: Option::Some(Keycode::Escape), ..} =>
break 'mainloop,
Event::MouseButtonDown {x, y, ..} => {
Event::Quit { .. }
| Event::KeyDown {
keycode: Option::Some(Keycode::Escape),
..
} => break 'mainloop,
Event::MouseButtonDown { x, y, .. } => {
canvas.fill_rect(Rect::new(x, y, 1, 1))?;
canvas.present();
}
@@ -52,7 +59,6 @@ pub fn run(png: &Path) -> Result<(), String> {
Ok(())
}
fn main() -> Result<(), String> {
let args: Vec<_> = env::args().collect();

View File

@@ -1,15 +1,16 @@
extern crate sdl2;
use sdl2::pixels::Color;
use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use sdl2::pixels::Color;
use std::time::Duration;
pub fn main() -> Result<(), String> {
let sdl_context = sdl2::init()?;
let video_subsystem = sdl_context.video()?;
let window = video_subsystem.window("rust-sdl2 demo: Video", 800, 600)
let window = video_subsystem
.window("rust-sdl2 demo: Video", 800, 600)
.position_centered()
.opengl()
.build()
@@ -25,13 +26,15 @@ pub fn main() -> Result<(), String> {
'running: loop {
for event in event_pump.poll_iter() {
match event {
Event::Quit {..} | Event::KeyDown { keycode: Some(Keycode::Escape), .. } => {
break 'running
},
Event::Quit { .. }
| Event::KeyDown {
keycode: Some(Keycode::Escape),
..
} => break 'running,
_ => {}
}
}
canvas.clear();
canvas.present();
::std::thread::sleep(Duration::new(0, 1_000_000_000u32 / 30));

View File

@@ -1,15 +1,16 @@
extern crate sdl2;
use sdl2::pixels::Color;
use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use sdl2::pixels::Color;
use std::time::Duration;
pub fn main() -> Result<(), String> {
let sdl_context = sdl2::init()?;
let video_subsystem = sdl_context.video()?;
let window = video_subsystem.window("rust-sdl2 demo: Events", 800, 600)
let window = video_subsystem
.window("rust-sdl2 demo: Events", 800, 600)
.position_centered()
.resizable()
.build()
@@ -21,17 +22,19 @@ pub fn main() -> Result<(), String> {
canvas.clear();
canvas.present();
let mut event_pump = sdl_context.event_pump()?;
println!("This example simply prints all events SDL knows about.");
'running: loop {
for event in event_pump.poll_iter() {
match event {
Event::Quit {..} | Event::KeyDown { keycode: Some(Keycode::Escape), .. } => {
break 'running
},
Event::Quit { .. }
| Event::KeyDown {
keycode: Some(Keycode::Escape),
..
} => break 'running,
// skip mouse motion intentionally because of the verbose it might cause.
Event::MouseMotion {..} => {},
Event::MouseMotion { .. } => {}
e => {
println!("{:?}", e);
}

View File

@@ -4,60 +4,79 @@ fn main() -> Result<(), String> {
let sdl_context = sdl2::init()?;
let game_controller_subsystem = sdl_context.game_controller()?;
let available = game_controller_subsystem.num_joysticks()
let available = game_controller_subsystem
.num_joysticks()
.map_err(|e| format!("can't enumerate joysticks: {}", e))?;
println!("{} joysticks available", available);
// Iterate over all available joysticks and look for game controllers.
let mut controller = (0..available).find_map(|id| {
if !game_controller_subsystem.is_game_controller(id) {
println!("{} is not a game controller", id);
return None;
}
println!("Attempting to open controller {}", id);
match game_controller_subsystem.open(id) {
Ok(c) => {
// We managed to find and open a game controller,
// exit the loop
println!("Success: opened \"{}\"", c.name());
Some(c)
},
Err(e) => {
println!("failed: {:?}", e);
None
let mut controller = (0..available)
.find_map(|id| {
if !game_controller_subsystem.is_game_controller(id) {
println!("{} is not a game controller", id);
return None;
}
}
}).expect("Couldn't open any controller");
println!("Attempting to open controller {}", id);
match game_controller_subsystem.open(id) {
Ok(c) => {
// We managed to find and open a game controller,
// exit the loop
println!("Success: opened \"{}\"", c.name());
Some(c)
}
Err(e) => {
println!("failed: {:?}", e);
None
}
}
})
.expect("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()?.wait_iter() {
use sdl2::event::Event;
use sdl2::controller::Axis;
use sdl2::event::Event;
match event {
Event::ControllerAxisMotion{ axis: Axis::TriggerLeft, value: val, .. } => {
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),
Err(e) => println!(
"Error setting rumble to ({}, {}): {:?}",
lo_freq, hi_freq, e
),
}
}
Event::ControllerAxisMotion{ axis: Axis::TriggerRight, value: val, .. } => {
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),
Err(e) => println!(
"Error setting rumble to ({}, {}): {:?}",
lo_freq, hi_freq, e
),
}
}
Event::ControllerAxisMotion{ axis, value: val, .. } => {
Event::ControllerAxisMotion {
axis, value: val, ..
} => {
// Axis motion is an absolute value in the range
// [-32768, 32767]. Let's simulate a very rough dead
// zone to ignore spurious events.
@@ -66,11 +85,9 @@ fn main() -> Result<(), String> {
println!("Axis {:?} moved to {}", axis, val);
}
}
Event::ControllerButtonDown{ button, .. } =>
println!("Button {:?} down", button),
Event::ControllerButtonUp{ button, .. } =>
println!("Button {:?} up", button),
Event::Quit{..} => break,
Event::ControllerButtonDown { button, .. } => println!("Button {:?} down", button),
Event::ControllerButtonUp { button, .. } => println!("Button {:?} up", button),
Event::Quit { .. } => break,
_ => (),
}
}

View File

@@ -1,22 +1,21 @@
extern crate sdl2;
#[cfg(feature = "unsafe_textures")]
use sdl2::rect::{Point, Rect};
#[cfg(feature = "unsafe_textures")]
use sdl2::pixels::Color;
use game_of_life::{PLAYGROUND_HEIGHT, PLAYGROUND_WIDTH, SQUARE_SIZE};
#[cfg(feature = "unsafe_textures")]
use sdl2::event::Event;
#[cfg(feature = "unsafe_textures")]
use sdl2::mouse::MouseButton;
#[cfg(feature = "unsafe_textures")]
use sdl2::keyboard::Keycode;
#[cfg(feature = "unsafe_textures")]
use sdl2::video::{Window};
use sdl2::mouse::MouseButton;
#[cfg(feature = "unsafe_textures")]
use sdl2::pixels::Color;
#[cfg(feature = "unsafe_textures")]
use sdl2::rect::{Point, Rect};
#[cfg(feature = "unsafe_textures")]
use sdl2::render::{Canvas, Texture};
#[cfg(feature = "unsafe_textures")]
use game_of_life::{SQUARE_SIZE, PLAYGROUND_WIDTH, PLAYGROUND_HEIGHT};
use sdl2::video::Window;
#[cfg(feature = "unsafe_textures")]
mod game_of_life {
@@ -31,7 +30,7 @@ mod game_of_life {
}
pub struct GameOfLife {
playground: [bool; (PLAYGROUND_WIDTH*PLAYGROUND_HEIGHT) as usize],
playground: [bool; (PLAYGROUND_WIDTH * PLAYGROUND_HEIGHT) as usize],
state: State,
}
@@ -40,13 +39,13 @@ mod game_of_life {
let mut playground = [false; (PLAYGROUND_WIDTH * PLAYGROUND_HEIGHT) as usize];
// let's make a nice default pattern !
for i in 1..(PLAYGROUND_HEIGHT-1) {
playground[(1 + i* PLAYGROUND_WIDTH) as usize] = true;
playground[((PLAYGROUND_WIDTH-2) + i* PLAYGROUND_WIDTH) as usize] = true;
for i in 1..(PLAYGROUND_HEIGHT - 1) {
playground[(1 + i * PLAYGROUND_WIDTH) as usize] = true;
playground[((PLAYGROUND_WIDTH - 2) + i * PLAYGROUND_WIDTH) as usize] = true;
}
for j in 2..(PLAYGROUND_WIDTH-2) {
for j in 2..(PLAYGROUND_WIDTH - 2) {
playground[(PLAYGROUND_WIDTH + j) as usize] = true;
playground[((PLAYGROUND_HEIGHT-2)*PLAYGROUND_WIDTH + j) as usize] = true;
playground[((PLAYGROUND_HEIGHT - 2) * PLAYGROUND_WIDTH + j) as usize] = true;
}
GameOfLife {
@@ -56,18 +55,16 @@ mod game_of_life {
}
pub fn get(&self, x: i32, y: i32) -> Option<bool> {
if x >= 0 && y >= 0 &&
(x as u32) < PLAYGROUND_WIDTH && (y as u32) < PLAYGROUND_HEIGHT {
Some(self.playground[(x as u32 + (y as u32)* PLAYGROUND_WIDTH) as usize])
if x >= 0 && y >= 0 && (x as u32) < PLAYGROUND_WIDTH && (y as u32) < PLAYGROUND_HEIGHT {
Some(self.playground[(x as u32 + (y as u32) * PLAYGROUND_WIDTH) as usize])
} else {
None
}
}
pub fn get_mut(&mut self, x: i32, y: i32) -> Option<&mut bool> {
if x >= 0 && y >= 0 &&
(x as u32) < PLAYGROUND_WIDTH && (y as u32) < PLAYGROUND_HEIGHT {
Some(&mut self.playground[(x as u32 + (y as u32)* PLAYGROUND_WIDTH) as usize])
if x >= 0 && y >= 0 && (x as u32) < PLAYGROUND_WIDTH && (y as u32) < PLAYGROUND_HEIGHT {
Some(&mut self.playground[(x as u32 + (y as u32) * PLAYGROUND_WIDTH) as usize])
} else {
None
}
@@ -90,12 +87,12 @@ mod game_of_life {
let u = u as u32;
let x = u % PLAYGROUND_WIDTH;
let y = u / PLAYGROUND_WIDTH;
let mut count : u32 = 0;
let mut count: u32 = 0;
for i in -1..2 {
for j in -1..2 {
if !(i == 0 && j == 0) {
let peek_x : i32 = (x as i32) + i;
let peek_y : i32 = (y as i32) + j;
let peek_x: i32 = (x as i32) + i;
let peek_y: i32 = (y as i32) + j;
if let Some(true) = self.get(peek_x, peek_y) {
count += 1;
}
@@ -114,8 +111,6 @@ mod game_of_life {
}
}
impl<'a> IntoIterator for &'a GameOfLife {
type Item = &'a bool;
type IntoIter = ::std::slice::Iter<'a, bool>;
@@ -131,74 +126,86 @@ fn dummy_texture<'a>(canvas: &mut Canvas<Window>) -> Result<(Texture, Texture),
Yellow,
White,
};
let mut square_texture1 = canvas.create_texture_target(None, SQUARE_SIZE, SQUARE_SIZE).map_err(|e| e.to_string())?;
let mut square_texture2 = canvas.create_texture_target(None, SQUARE_SIZE, SQUARE_SIZE).map_err(|e| e.to_string())?;
// let's change the textures we just created
let mut square_texture1 = canvas
.create_texture_target(None, SQUARE_SIZE, SQUARE_SIZE)
.map_err(|e| e.to_string())?;
let mut square_texture2 = canvas
.create_texture_target(None, SQUARE_SIZE, SQUARE_SIZE)
.map_err(|e| e.to_string())?;
// let's change the textures we just created
{
let textures = vec![
(&mut square_texture1, TextureColor::Yellow),
(&mut square_texture2, TextureColor::White)
(&mut square_texture2, TextureColor::White),
];
canvas.with_multiple_texture_canvas(textures.iter(), |texture_canvas, user_context| {
texture_canvas.set_draw_color(Color::RGB(0, 0, 0));
texture_canvas.clear();
match *user_context {
TextureColor::Yellow => {
for i in 0..SQUARE_SIZE {
for j in 0..SQUARE_SIZE {
if (i+j) % 4 == 0 {
texture_canvas.set_draw_color(Color::RGB(255, 255, 0));
texture_canvas.draw_point(Point::new(i as i32, j as i32))
.expect("could not draw point");
}
if (i+j*2) % 9 == 0 {
texture_canvas.set_draw_color(Color::RGB(200, 200, 0));
texture_canvas.draw_point(Point::new(i as i32, j as i32))
.expect("could not draw point");
canvas
.with_multiple_texture_canvas(textures.iter(), |texture_canvas, user_context| {
texture_canvas.set_draw_color(Color::RGB(0, 0, 0));
texture_canvas.clear();
match *user_context {
TextureColor::Yellow => {
for i in 0..SQUARE_SIZE {
for j in 0..SQUARE_SIZE {
if (i + j) % 4 == 0 {
texture_canvas.set_draw_color(Color::RGB(255, 255, 0));
texture_canvas
.draw_point(Point::new(i as i32, j as i32))
.expect("could not draw point");
}
if (i + j * 2) % 9 == 0 {
texture_canvas.set_draw_color(Color::RGB(200, 200, 0));
texture_canvas
.draw_point(Point::new(i as i32, j as i32))
.expect("could not draw point");
}
}
}
}
},
TextureColor::White => {
for i in 0..SQUARE_SIZE {
for j in 0..SQUARE_SIZE {
// drawing pixel by pixel isn't very effective, but we only do it once and store
// the texture afterwards so it's still alright!
if (i+j) % 7 == 0 {
// this doesn't mean anything, there was some trial and error to find
// something that wasn't too ugly
texture_canvas.set_draw_color(Color::RGB(192, 192, 192));
texture_canvas.draw_point(Point::new(i as i32, j as i32))
.expect("could not draw point");
}
if (i+j*2) % 5 == 0 {
texture_canvas.set_draw_color(Color::RGB(64, 64, 64));
texture_canvas.draw_point(Point::new(i as i32, j as i32))
.expect("could not draw point");
TextureColor::White => {
for i in 0..SQUARE_SIZE {
for j in 0..SQUARE_SIZE {
// drawing pixel by pixel isn't very effective, but we only do it once and store
// the texture afterwards so it's still alright!
if (i + j) % 7 == 0 {
// this doesn't mean anything, there was some trial and error to find
// something that wasn't too ugly
texture_canvas.set_draw_color(Color::RGB(192, 192, 192));
texture_canvas
.draw_point(Point::new(i as i32, j as i32))
.expect("could not draw point");
}
if (i + j * 2) % 5 == 0 {
texture_canvas.set_draw_color(Color::RGB(64, 64, 64));
texture_canvas
.draw_point(Point::new(i as i32, j as i32))
.expect("could not draw point");
}
}
}
}
}
};
for i in 0..SQUARE_SIZE {
for j in 0..SQUARE_SIZE {
// drawing pixel by pixel isn't very effective, but we only do it once and store
// the texture afterwards so it's still alright!
if (i+j) % 7 == 0 {
// this doesn't mean anything, there was some trial and serror to find
// something that wasn't too ugly
texture_canvas.set_draw_color(Color::RGB(192, 192, 192));
texture_canvas.draw_point(Point::new(i as i32, j as i32))
.expect("could not draw point");
}
if (i+j*2) % 5 == 0 {
texture_canvas.set_draw_color(Color::RGB(64, 64, 64));
texture_canvas.draw_point(Point::new(i as i32, j as i32))
.expect("could not draw point");
};
for i in 0..SQUARE_SIZE {
for j in 0..SQUARE_SIZE {
// drawing pixel by pixel isn't very effective, but we only do it once and store
// the texture afterwards so it's still alright!
if (i + j) % 7 == 0 {
// this doesn't mean anything, there was some trial and serror to find
// something that wasn't too ugly
texture_canvas.set_draw_color(Color::RGB(192, 192, 192));
texture_canvas
.draw_point(Point::new(i as i32, j as i32))
.expect("could not draw point");
}
if (i + j * 2) % 5 == 0 {
texture_canvas.set_draw_color(Color::RGB(64, 64, 64));
texture_canvas
.draw_point(Point::new(i as i32, j as i32))
.expect("could not draw point");
}
}
}
}
}).map_err(|e| e.to_string())?;
})
.map_err(|e| e.to_string())?;
}
Ok((square_texture1, square_texture2))
}
@@ -213,19 +220,23 @@ pub fn main() -> Result<(), String> {
// fullscreen, ... but you cannot change its content without using a Canvas or using the
// `surface()` method.
let window = video_subsystem
.window("rust-sdl2 demo: Game of Life",
SQUARE_SIZE*PLAYGROUND_WIDTH,
SQUARE_SIZE*PLAYGROUND_HEIGHT)
.window(
"rust-sdl2 demo: Game of Life",
SQUARE_SIZE * PLAYGROUND_WIDTH,
SQUARE_SIZE * PLAYGROUND_HEIGHT,
)
.position_centered()
.build()
.map_err(|e| e.to_string())?;
// the canvas allows us to both manipulate the property of the window and to change its content
// via hardware or software rendering. See CanvasBuilder for more info.
let mut canvas = window.into_canvas()
let mut canvas = window
.into_canvas()
.target_texture()
.present_vsync()
.build().map_err(|e| e.to_string())?;
.build()
.map_err(|e| e.to_string())?;
println!("Using SDL_Renderer \"{}\"", canvas.info().name);
canvas.set_draw_color(Color::RGB(0, 0, 0));
@@ -241,25 +252,38 @@ pub fn main() -> Result<(), String> {
let mut game = game_of_life::GameOfLife::new();
let mut event_pump = sdl_context.event_pump()?;
let mut frame : u32 = 0;
let mut frame: u32 = 0;
'running: loop {
// get the inputs here
for event in event_pump.poll_iter() {
match event {
Event::Quit {..} | Event::KeyDown { keycode: Some(Keycode::Escape), .. } => {
break 'running
},
Event::KeyDown { keycode: Some(Keycode::Space), repeat: false, .. } => {
Event::Quit { .. }
| Event::KeyDown {
keycode: Some(Keycode::Escape),
..
} => break 'running,
Event::KeyDown {
keycode: Some(Keycode::Space),
repeat: false,
..
} => {
game.toggle_state();
},
Event::MouseButtonDown { x, y, mouse_btn: MouseButton::Left, .. } => {
}
Event::MouseButtonDown {
x,
y,
mouse_btn: MouseButton::Left,
..
} => {
let x = (x as u32) / SQUARE_SIZE;
let y = (y as u32) / SQUARE_SIZE;
match game.get_mut(x as i32, y as i32) {
Some(square) => {*square = !(*square);},
Some(square) => {
*square = !(*square);
}
None => unreachable!(),
};
},
}
_ => {}
}
}
@@ -280,12 +304,16 @@ pub fn main() -> Result<(), String> {
&square_texture2
};
if *unit {
canvas.copy(&square_texture,
None,
Rect::new(((i % PLAYGROUND_WIDTH) * SQUARE_SIZE) as i32,
((i / PLAYGROUND_WIDTH) * SQUARE_SIZE) as i32,
SQUARE_SIZE,
SQUARE_SIZE))?;
canvas.copy(
&square_texture,
None,
Rect::new(
((i % PLAYGROUND_WIDTH) * SQUARE_SIZE) as i32,
((i / PLAYGROUND_WIDTH) * SQUARE_SIZE) as i32,
SQUARE_SIZE,
SQUARE_SIZE,
),
)?;
}
}
canvas.present();
@@ -298,4 +326,4 @@ pub fn main() -> Result<(), String> {
}
#[cfg(not(feature = "unsafe_textures"))]
pub fn main(){}
pub fn main() {}

View File

@@ -1,13 +1,13 @@
extern crate sdl2;
use sdl2::rect::{Point, Rect};
use sdl2::pixels::Color;
use crate::game_of_life::{PLAYGROUND_HEIGHT, PLAYGROUND_WIDTH, SQUARE_SIZE};
use sdl2::event::Event;
use sdl2::mouse::MouseButton;
use sdl2::keyboard::Keycode;
use sdl2::video::{Window, WindowContext};
use sdl2::mouse::MouseButton;
use sdl2::pixels::Color;
use sdl2::rect::{Point, Rect};
use sdl2::render::{Canvas, Texture, TextureCreator};
use crate::game_of_life::{SQUARE_SIZE, PLAYGROUND_WIDTH, PLAYGROUND_HEIGHT};
use sdl2::video::{Window, WindowContext};
mod game_of_life {
pub const SQUARE_SIZE: u32 = 16;
@@ -21,7 +21,7 @@ mod game_of_life {
}
pub struct GameOfLife {
playground: [bool; (PLAYGROUND_WIDTH*PLAYGROUND_HEIGHT) as usize],
playground: [bool; (PLAYGROUND_WIDTH * PLAYGROUND_HEIGHT) as usize],
state: State,
}
@@ -30,13 +30,13 @@ mod game_of_life {
let mut playground = [false; (PLAYGROUND_WIDTH * PLAYGROUND_HEIGHT) as usize];
// let's make a nice default pattern !
for i in 1..(PLAYGROUND_HEIGHT-1) {
playground[(1 + i* PLAYGROUND_WIDTH) as usize] = true;
playground[((PLAYGROUND_WIDTH-2) + i* PLAYGROUND_WIDTH) as usize] = true;
for i in 1..(PLAYGROUND_HEIGHT - 1) {
playground[(1 + i * PLAYGROUND_WIDTH) as usize] = true;
playground[((PLAYGROUND_WIDTH - 2) + i * PLAYGROUND_WIDTH) as usize] = true;
}
for j in 2..(PLAYGROUND_WIDTH-2) {
for j in 2..(PLAYGROUND_WIDTH - 2) {
playground[(PLAYGROUND_WIDTH + j) as usize] = true;
playground[((PLAYGROUND_HEIGHT-2)*PLAYGROUND_WIDTH + j) as usize] = true;
playground[((PLAYGROUND_HEIGHT - 2) * PLAYGROUND_WIDTH + j) as usize] = true;
}
GameOfLife {
@@ -46,18 +46,16 @@ mod game_of_life {
}
pub fn get(&self, x: i32, y: i32) -> Option<bool> {
if x >= 0 && y >= 0 &&
(x as u32) < PLAYGROUND_WIDTH && (y as u32) < PLAYGROUND_HEIGHT {
Some(self.playground[(x as u32 + (y as u32)* PLAYGROUND_WIDTH) as usize])
if x >= 0 && y >= 0 && (x as u32) < PLAYGROUND_WIDTH && (y as u32) < PLAYGROUND_HEIGHT {
Some(self.playground[(x as u32 + (y as u32) * PLAYGROUND_WIDTH) as usize])
} else {
None
}
}
pub fn get_mut(&mut self, x: i32, y: i32) -> Option<&mut bool> {
if x >= 0 && y >= 0 &&
(x as u32) < PLAYGROUND_WIDTH && (y as u32) < PLAYGROUND_HEIGHT {
Some(&mut self.playground[(x as u32 + (y as u32)* PLAYGROUND_WIDTH) as usize])
if x >= 0 && y >= 0 && (x as u32) < PLAYGROUND_WIDTH && (y as u32) < PLAYGROUND_HEIGHT {
Some(&mut self.playground[(x as u32 + (y as u32) * PLAYGROUND_WIDTH) as usize])
} else {
None
}
@@ -80,12 +78,12 @@ mod game_of_life {
let u = u as u32;
let x = u % PLAYGROUND_WIDTH;
let y = u / PLAYGROUND_WIDTH;
let mut count : u32 = 0;
let mut count: u32 = 0;
for i in -1..2 {
for j in -1..2 {
if !(i == 0 && j == 0) {
let peek_x : i32 = (x as i32) + i;
let peek_y : i32 = (y as i32) + j;
let peek_x: i32 = (x as i32) + i;
let peek_y: i32 = (y as i32) + j;
if let Some(true) = self.get(peek_x, peek_y) {
count += 1;
}
@@ -104,8 +102,6 @@ mod game_of_life {
}
}
impl<'a> IntoIterator for &'a GameOfLife {
type Item = &'a bool;
type IntoIter = ::std::slice::Iter<'a, bool>;
@@ -115,79 +111,94 @@ mod game_of_life {
}
}
fn dummy_texture<'a>(canvas: &mut Canvas<Window>, texture_creator: &'a TextureCreator<WindowContext>) -> Result<(Texture<'a>, Texture<'a>), String> {
fn dummy_texture<'a>(
canvas: &mut Canvas<Window>,
texture_creator: &'a TextureCreator<WindowContext>,
) -> Result<(Texture<'a>, Texture<'a>), String> {
enum TextureColor {
Yellow,
White,
};
let mut square_texture1 = texture_creator.create_texture_target(None, SQUARE_SIZE, SQUARE_SIZE).map_err(|e| e.to_string())?;
let mut square_texture2 = texture_creator.create_texture_target(None, SQUARE_SIZE, SQUARE_SIZE).map_err(|e| e.to_string())?;
// let's change the textures we just created
let mut square_texture1 = texture_creator
.create_texture_target(None, SQUARE_SIZE, SQUARE_SIZE)
.map_err(|e| e.to_string())?;
let mut square_texture2 = texture_creator
.create_texture_target(None, SQUARE_SIZE, SQUARE_SIZE)
.map_err(|e| e.to_string())?;
// let's change the textures we just created
{
let textures = vec![
(&mut square_texture1, TextureColor::Yellow),
(&mut square_texture2, TextureColor::White)
(&mut square_texture2, TextureColor::White),
];
canvas.with_multiple_texture_canvas(textures.iter(), |texture_canvas, user_context| {
texture_canvas.set_draw_color(Color::RGB(0, 0, 0));
texture_canvas.clear();
match *user_context {
TextureColor::Yellow => {
for i in 0..SQUARE_SIZE {
for j in 0..SQUARE_SIZE {
if (i+j) % 4 == 0 {
texture_canvas.set_draw_color(Color::RGB(255, 255, 0));
texture_canvas.draw_point(Point::new(i as i32, j as i32))
.expect("could not draw point");
}
if (i+j*2) % 9 == 0 {
texture_canvas.set_draw_color(Color::RGB(200, 200, 0));
texture_canvas.draw_point(Point::new(i as i32, j as i32))
.expect("could not draw point");
canvas
.with_multiple_texture_canvas(textures.iter(), |texture_canvas, user_context| {
texture_canvas.set_draw_color(Color::RGB(0, 0, 0));
texture_canvas.clear();
match *user_context {
TextureColor::Yellow => {
for i in 0..SQUARE_SIZE {
for j in 0..SQUARE_SIZE {
if (i + j) % 4 == 0 {
texture_canvas.set_draw_color(Color::RGB(255, 255, 0));
texture_canvas
.draw_point(Point::new(i as i32, j as i32))
.expect("could not draw point");
}
if (i + j * 2) % 9 == 0 {
texture_canvas.set_draw_color(Color::RGB(200, 200, 0));
texture_canvas
.draw_point(Point::new(i as i32, j as i32))
.expect("could not draw point");
}
}
}
}
},
TextureColor::White => {
for i in 0..SQUARE_SIZE {
for j in 0..SQUARE_SIZE {
// drawing pixel by pixel isn't very effective, but we only do it once and store
// the texture afterwards so it's still alright!
if (i+j) % 7 == 0 {
// this doesn't mean anything, there was some trial and error to find
// something that wasn't too ugly
texture_canvas.set_draw_color(Color::RGB(192, 192, 192));
texture_canvas.draw_point(Point::new(i as i32, j as i32))
.expect("could not draw point");
}
if (i+j*2) % 5 == 0 {
texture_canvas.set_draw_color(Color::RGB(64, 64, 64));
texture_canvas.draw_point(Point::new(i as i32, j as i32))
.expect("could not draw point");
TextureColor::White => {
for i in 0..SQUARE_SIZE {
for j in 0..SQUARE_SIZE {
// drawing pixel by pixel isn't very effective, but we only do it once and store
// the texture afterwards so it's still alright!
if (i + j) % 7 == 0 {
// this doesn't mean anything, there was some trial and error to find
// something that wasn't too ugly
texture_canvas.set_draw_color(Color::RGB(192, 192, 192));
texture_canvas
.draw_point(Point::new(i as i32, j as i32))
.expect("could not draw point");
}
if (i + j * 2) % 5 == 0 {
texture_canvas.set_draw_color(Color::RGB(64, 64, 64));
texture_canvas
.draw_point(Point::new(i as i32, j as i32))
.expect("could not draw point");
}
}
}
}
}
};
for i in 0..SQUARE_SIZE {
for j in 0..SQUARE_SIZE {
// drawing pixel by pixel isn't very effective, but we only do it once and store
// the texture afterwards so it's still alright!
if (i+j) % 7 == 0 {
// this doesn't mean anything, there was some trial and serror to find
// something that wasn't too ugly
texture_canvas.set_draw_color(Color::RGB(192, 192, 192));
texture_canvas.draw_point(Point::new(i as i32, j as i32))
.expect("could not draw point");
}
if (i+j*2) % 5 == 0 {
texture_canvas.set_draw_color(Color::RGB(64, 64, 64));
texture_canvas.draw_point(Point::new(i as i32, j as i32))
.expect("could not draw point");
};
for i in 0..SQUARE_SIZE {
for j in 0..SQUARE_SIZE {
// drawing pixel by pixel isn't very effective, but we only do it once and store
// the texture afterwards so it's still alright!
if (i + j) % 7 == 0 {
// this doesn't mean anything, there was some trial and serror to find
// something that wasn't too ugly
texture_canvas.set_draw_color(Color::RGB(192, 192, 192));
texture_canvas
.draw_point(Point::new(i as i32, j as i32))
.expect("could not draw point");
}
if (i + j * 2) % 5 == 0 {
texture_canvas.set_draw_color(Color::RGB(64, 64, 64));
texture_canvas
.draw_point(Point::new(i as i32, j as i32))
.expect("could not draw point");
}
}
}
}
}).map_err(|e| e.to_string())?;
})
.map_err(|e| e.to_string())?;
}
Ok((square_texture1, square_texture2))
}
@@ -201,16 +212,19 @@ pub fn main() -> Result<(), String> {
// fullscreen, ... but you cannot change its content without using a Canvas or using the
// `surface()` method.
let window = video_subsystem
.window("rust-sdl2 demo: Game of Life",
SQUARE_SIZE*PLAYGROUND_WIDTH,
SQUARE_SIZE*PLAYGROUND_HEIGHT)
.window(
"rust-sdl2 demo: Game of Life",
SQUARE_SIZE * PLAYGROUND_WIDTH,
SQUARE_SIZE * PLAYGROUND_HEIGHT,
)
.position_centered()
.build()
.map_err(|e| e.to_string())?;
// the canvas allows us to both manipulate the property of the window and to change its content
// via hardware or software rendering. See CanvasBuilder for more info.
let mut canvas = window.into_canvas()
let mut canvas = window
.into_canvas()
.target_texture()
.present_vsync()
.build()
@@ -227,32 +241,45 @@ pub fn main() -> Result<(), String> {
// this struct manages textures. For lifetime reasons, the canvas cannot directly create
// textures, you have to create a `TextureCreator` instead.
let texture_creator : TextureCreator<_> = canvas.texture_creator();
let texture_creator: TextureCreator<_> = canvas.texture_creator();
// Create a "target" texture so that we can use our Renderer with it later
let (square_texture1, square_texture2) = dummy_texture(&mut canvas, &texture_creator)?;
let mut game = game_of_life::GameOfLife::new();
let mut event_pump = sdl_context.event_pump()?;
let mut frame : u32 = 0;
let mut frame: u32 = 0;
'running: loop {
// get the inputs here
for event in event_pump.poll_iter() {
match event {
Event::Quit {..} | Event::KeyDown { keycode: Some(Keycode::Escape), .. } => {
break 'running
},
Event::KeyDown { keycode: Some(Keycode::Space), repeat: false, .. } => {
Event::Quit { .. }
| Event::KeyDown {
keycode: Some(Keycode::Escape),
..
} => break 'running,
Event::KeyDown {
keycode: Some(Keycode::Space),
repeat: false,
..
} => {
game.toggle_state();
},
Event::MouseButtonDown { x, y, mouse_btn: MouseButton::Left, .. } => {
}
Event::MouseButtonDown {
x,
y,
mouse_btn: MouseButton::Left,
..
} => {
let x = (x as u32) / SQUARE_SIZE;
let y = (y as u32) / SQUARE_SIZE;
match game.get_mut(x as i32, y as i32) {
Some(square) => {*square = !(*square);},
Some(square) => {
*square = !(*square);
}
None => unreachable!(),
};
},
}
_ => {}
}
}
@@ -273,12 +300,16 @@ pub fn main() -> Result<(), String> {
&square_texture2
};
if *unit {
canvas.copy(square_texture,
None,
Rect::new(((i % PLAYGROUND_WIDTH) * SQUARE_SIZE) as i32,
((i / PLAYGROUND_WIDTH) * SQUARE_SIZE) as i32,
SQUARE_SIZE,
SQUARE_SIZE))?;
canvas.copy(
square_texture,
None,
Rect::new(
((i % PLAYGROUND_WIDTH) * SQUARE_SIZE) as i32,
((i / PLAYGROUND_WIDTH) * SQUARE_SIZE) as i32,
SQUARE_SIZE,
SQUARE_SIZE,
),
)?;
}
}
canvas.present();

View File

@@ -1,8 +1,8 @@
extern crate sdl2;
use sdl2::event::Event;
use sdl2::pixels;
use sdl2::keyboard::Keycode;
use sdl2::pixels;
use sdl2::gfx::primitives::DrawRenderer;
@@ -12,7 +12,12 @@ const SCREEN_HEIGHT: u32 = 600;
fn main() -> Result<(), String> {
let sdl_context = sdl2::init()?;
let video_subsys = sdl_context.video()?;
let window = video_subsys.window("rust-sdl2_gfx: draw line & FPSManager", SCREEN_WIDTH, SCREEN_HEIGHT)
let window = video_subsys
.window(
"rust-sdl2_gfx: draw line & FPSManager",
SCREEN_WIDTH,
SCREEN_HEIGHT,
)
.position_centered()
.opengl()
.build()
@@ -31,14 +36,15 @@ fn main() -> Result<(), String> {
'main: loop {
for event in events.poll_iter() {
match event {
Event::Quit { .. } => break 'main,
Event::Quit {..} => break 'main,
Event::KeyDown {keycode: Some(keycode), ..} => {
Event::KeyDown {
keycode: Some(keycode),
..
} => {
if keycode == Keycode::Escape {
break 'main
break 'main;
} else if keycode == Keycode::Space {
println!("space down");
for i in 0..400 {
@@ -48,7 +54,7 @@ fn main() -> Result<(), String> {
}
}
Event::MouseButtonDown {x, y, ..} => {
Event::MouseButtonDown { x, y, .. } => {
let color = pixels::Color::RGB(x as u8, y as u8, 255);
let _ = canvas.line(lastx, lasty, x as i16, y as i16, color);
lastx = x as i16;

View File

@@ -5,31 +5,39 @@ fn main() -> Result<(), String> {
let joystick_subsystem = sdl_context.joystick()?;
let haptic_subsystem = sdl_context.haptic()?;
let available = joystick_subsystem.num_joysticks()
let available = joystick_subsystem
.num_joysticks()
.map_err(|e| format!("can't enumerate joysticks: {}", e))?;
println!("{} joysticks available", available);
// Iterate over all available joysticks and stop once we manage to open one.
let joystick_index = (0..available).find_map(|id| match joystick_subsystem.open(id) {
Ok(c) => {
println!("Success: opened \"{}\"", c.name());
Some(id)
},
Err(e) => {
println!("failed: {:?}", e);
None
},
}).expect("Couldn't open any joystick");
let joystick_index = (0..available)
.find_map(|id| match joystick_subsystem.open(id) {
Ok(c) => {
println!("Success: opened \"{}\"", c.name());
Some(id)
}
Err(e) => {
println!("failed: {:?}", e);
None
}
})
.expect("Couldn't open any joystick");
let mut haptic = haptic_subsystem.open_from_joystick_id(joystick_index)
let mut haptic = haptic_subsystem
.open_from_joystick_id(joystick_index)
.map_err(|e| e.to_string())?;
for event in sdl_context.event_pump()?.wait_iter() {
use sdl2::event::Event;
match event {
Event::JoyAxisMotion{ axis_idx, value: val, .. } => {
Event::JoyAxisMotion {
axis_idx,
value: val,
..
} => {
// Axis motion is an absolute value in the range
// [-32768, 32767]. Let's simulate a very rough dead
// zone to ignore spurious events.
@@ -38,15 +46,15 @@ fn main() -> Result<(), String> {
println!("Axis {} moved to {}", axis_idx, val);
}
}
Event::JoyButtonDown{ button_idx, .. } =>{
Event::JoyButtonDown { button_idx, .. } => {
println!("Button {} down", button_idx);
haptic.rumble_play(0.5, 500);
},
Event::JoyButtonUp{ button_idx, .. } =>
println!("Button {} up", button_idx),
Event::JoyHatMotion{ hat_idx, state, .. } =>
println!("Hat {} moved to {:?}", hat_idx, state),
Event::Quit{..} => break,
}
Event::JoyButtonUp { button_idx, .. } => println!("Button {} up", button_idx),
Event::JoyHatMotion { hat_idx, state, .. } => {
println!("Hat {} moved to {:?}", hat_idx, state)
}
Event::Quit { .. } => break,
_ => (),
}
}

View File

@@ -1,21 +1,26 @@
extern crate sdl2;
use sdl2::event::Event;
use sdl2::image::{InitFlag, LoadTexture};
use sdl2::keyboard::Keycode;
use std::env;
use std::path::Path;
use sdl2::image::{LoadTexture, InitFlag};
use sdl2::event::Event;
use sdl2::keyboard::Keycode;
pub fn run(png: &Path) -> Result<(), String> {
let sdl_context = sdl2::init()?;
let video_subsystem = sdl_context.video()?;
let _image_context = sdl2::image::init(InitFlag::PNG | InitFlag::JPG)?;
let window = video_subsystem.window("rust-sdl2 demo: Video", 800, 600)
.position_centered()
.build()
.map_err(|e| e.to_string())?;
let window = video_subsystem
.window("rust-sdl2 demo: Video", 800, 600)
.position_centered()
.build()
.map_err(|e| e.to_string())?;
let mut canvas = window.into_canvas().software().build().map_err(|e| e.to_string())?;
let mut canvas = window
.into_canvas()
.software()
.build()
.map_err(|e| e.to_string())?;
let texture_creator = canvas.texture_creator();
let texture = texture_creator.load_texture(png)?;
@@ -25,9 +30,11 @@ pub fn run(png: &Path) -> Result<(), String> {
'mainloop: loop {
for event in sdl_context.event_pump()?.poll_iter() {
match event {
Event::Quit{..} |
Event::KeyDown {keycode: Option::Some(Keycode::Escape), ..} =>
break 'mainloop,
Event::Quit { .. }
| Event::KeyDown {
keycode: Option::Some(Keycode::Escape),
..
} => break 'mainloop,
_ => {}
}
}

View File

@@ -4,26 +4,32 @@ fn main() -> Result<(), String> {
let sdl_context = sdl2::init()?;
let joystick_subsystem = sdl_context.joystick()?;
let available = joystick_subsystem.num_joysticks()
let available = joystick_subsystem
.num_joysticks()
.map_err(|e| format!("can't enumerate joysticks: {}", e))?;
println!("{} joysticks available", available);
// Iterate over all available joysticks and stop once we manage to open one.
let mut joystick = (0..available).find_map(|id| match joystick_subsystem.open(id) {
Ok(c) => {
println!("Success: opened \"{}\"", c.name());
Some(c)
},
Err(e) => {
println!("failed: {:?}", e);
None
},
}).expect("Couldn't open any joystick");
let mut joystick = (0..available)
.find_map(|id| match joystick_subsystem.open(id) {
Ok(c) => {
println!("Success: opened \"{}\"", c.name());
Some(c)
}
Err(e) => {
println!("failed: {:?}", e);
None
}
})
.expect("Couldn't open any joystick");
// Print the joystick's power level
println!("\"{}\" power level: {:?}", joystick.name(), joystick.power_level()
.map_err(|e| e.to_string())?);
println!(
"\"{}\" power level: {:?}",
joystick.name(),
joystick.power_level().map_err(|e| e.to_string())?
);
let (mut lo_freq, mut hi_freq) = (0, 0);
@@ -31,7 +37,11 @@ fn main() -> Result<(), String> {
use sdl2::event::Event;
match event {
Event::JoyAxisMotion{ axis_idx, value: val, .. } => {
Event::JoyAxisMotion {
axis_idx,
value: val,
..
} => {
// Axis motion is an absolute value in the range
// [-32768, 32767]. Let's simulate a very rough dead
// zone to ignore spurious events.
@@ -40,7 +50,7 @@ fn main() -> Result<(), String> {
println!("Axis {} moved to {}", axis_idx, val);
}
}
Event::JoyButtonDown{ button_idx, .. } => {
Event::JoyButtonDown { button_idx, .. } => {
println!("Button {} down", button_idx);
if button_idx == 0 {
lo_freq = 65535;
@@ -50,11 +60,14 @@ fn main() -> Result<(), String> {
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),
Err(e) => println!(
"Error setting rumble to ({}, {}): {:?}",
lo_freq, hi_freq, e
),
}
}
}
Event::JoyButtonUp{ button_idx, .. } => {
Event::JoyButtonUp { button_idx, .. } => {
println!("Button {} up", button_idx);
if button_idx == 0 {
lo_freq = 0;
@@ -64,13 +77,17 @@ fn main() -> Result<(), String> {
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),
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,
Event::JoyHatMotion { hat_idx, state, .. } => {
println!("Hat {} moved to {:?}", hat_idx, state)
}
Event::Quit { .. } => break,
_ => (),
}
}

View File

@@ -9,7 +9,8 @@ pub fn main() -> Result<(), String> {
let sdl_context = sdl2::init()?;
let video_subsystem = sdl_context.video()?;
let _window = video_subsystem.window("Keyboard", 800, 600)
let _window = video_subsystem
.window("Keyboard", 800, 600)
.position_centered()
.build()
.map_err(|e| e.to_string())?;
@@ -20,13 +21,17 @@ pub fn main() -> Result<(), String> {
'running: loop {
for event in events.poll_iter() {
if let Event::Quit {..} = event {
if let Event::Quit { .. } = event {
break 'running;
};
}
// Create a set of pressed Keys.
let keys = events.keyboard_state().pressed_scancodes().filter_map(Keycode::from_scancode).collect();
let keys = events
.keyboard_state()
.pressed_scancodes()
.filter_map(Keycode::from_scancode)
.collect();
// Get the difference between the new and old sets.
let new_keys = &keys - &prev_keys;

View File

@@ -1,15 +1,16 @@
extern crate sdl2;
use sdl2::pixels::Color;
use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use ::sdl2::messagebox::*;
use sdl2::messagebox::*;
use sdl2::pixels::Color;
pub fn main() -> Result<(), String> {
let sdl_context = sdl2::init()?;
let video_subsystem = sdl_context.video()?;
let window = video_subsystem.window("rust-sdl2 demo: Video", 800, 600)
let window = video_subsystem
.window("rust-sdl2 demo: Video", 800, 600)
.position_centered()
.opengl()
.build()
@@ -25,43 +26,51 @@ pub fn main() -> Result<(), String> {
'running: loop {
for event in event_pump.poll_iter() {
match event {
Event::Quit {..} | Event::KeyDown { keycode: Some(Keycode::Escape), .. } => {
show_simple_message_box(MessageBoxFlag::ERROR,
Event::Quit { .. }
| Event::KeyDown {
keycode: Some(Keycode::Escape),
..
} => {
show_simple_message_box(
MessageBoxFlag::ERROR,
"Some title",
"Some information inside the window",
canvas.window()
).map_err(|e| e.to_string())?;
break 'running
},
canvas.window(),
)
.map_err(|e| e.to_string())?;
break 'running;
}
_ => {}
}
}
// The rest of the game loop goes here...
}
let buttons : Vec<_> = vec![
let buttons: Vec<_> = vec![
ButtonData {
flags:MessageBoxButtonFlag::RETURNKEY_DEFAULT,
button_id:1,
text:"Ok"
flags: MessageBoxButtonFlag::RETURNKEY_DEFAULT,
button_id: 1,
text: "Ok",
},
ButtonData {
flags:MessageBoxButtonFlag::NOTHING,
button_id:2,
text:"No"
flags: MessageBoxButtonFlag::NOTHING,
button_id: 2,
text: "No",
},
ButtonData {
flags:MessageBoxButtonFlag::ESCAPEKEY_DEFAULT,
button_id:3,
text:"Cancel"
flags: MessageBoxButtonFlag::ESCAPEKEY_DEFAULT,
button_id: 3,
text: "Cancel",
},
];
let res = show_message_box(MessageBoxFlag::WARNING,
buttons.as_slice(),
"Some warning",
"You forget to do something, do it anyway ?",
None,
None);
println!("{:?}",res);
let res = show_message_box(
MessageBoxFlag::WARNING,
buttons.as_slice(),
"Some warning",
"You forget to do something, do it anyway ?",
None,
None,
);
println!("{:?}", res);
Ok(())
}

View File

@@ -1,10 +1,9 @@
/// Demonstrates the simultaneous mixing of music and sound effects.
extern crate sdl2;
use sdl2::mixer::{InitFlag, AUDIO_S16LSB, DEFAULT_CHANNELS};
use std::env;
use std::path::Path;
use sdl2::mixer::{InitFlag, DEFAULT_CHANNELS, AUDIO_S16LSB};
fn main() -> Result<(), String> {
let args: Vec<_> = env::args().collect();
@@ -31,9 +30,8 @@ fn demo(music_file: &Path, sound_file: Option<&Path>) -> Result<(), String> {
let channels = DEFAULT_CHANNELS; // Stereo
let chunk_size = 1_024;
sdl2::mixer::open_audio(frequency, format, channels, chunk_size)?;
let _mixer_context = sdl2::mixer::init(
InitFlag::MP3 | InitFlag::FLAC | InitFlag::MOD | InitFlag::OGG
)?;
let _mixer_context =
sdl2::mixer::init(InitFlag::MP3 | InitFlag::FLAC | InitFlag::MOD | InitFlag::OGG)?;
// Number of mixing channels available for sound effect `Chunk`s to play
// simultaneously.
@@ -106,8 +104,10 @@ fn demo(music_file: &Path, sound_file: Option<&Path>) -> Result<(), String> {
timer.delay(5_000);
println!("fading in from pos ... {:?}",
music.fade_in_from_pos(1, 10_000, 100.0));
println!(
"fading in from pos ... {:?}",
music.fade_in_from_pos(1, 10_000, 100.0)
);
timer.delay(5_000);
sdl2::mixer::Music::halt();

View File

@@ -9,7 +9,8 @@ pub fn main() -> Result<(), String> {
let sdl_context = sdl2::init()?;
let video_subsystem = sdl_context.video()?;
let _window = video_subsystem.window("Mouse", 800, 600)
let _window = video_subsystem
.window("Mouse", 800, 600)
.position_centered()
.build()
.map_err(|e| e.to_string())?;
@@ -21,8 +22,11 @@ pub fn main() -> Result<(), String> {
'running: loop {
for event in events.poll_iter() {
match event {
Event::KeyDown { keycode: Some(Keycode::Escape), .. } |
Event::Quit { .. } => break 'running,
Event::KeyDown {
keycode: Some(Keycode::Escape),
..
}
| Event::Quit { .. } => break 'running,
_ => {}
}
}
@@ -38,7 +42,13 @@ pub fn main() -> Result<(), String> {
let old_buttons = &prev_buttons - &buttons;
if !new_buttons.is_empty() || !old_buttons.is_empty() {
println!("X = {:?}, Y = {:?} : {:?} -> {:?}", state.x(), state.y(), new_buttons, old_buttons);
println!(
"X = {:?}, Y = {:?} : {:?} -> {:?}",
state.x(),
state.y(),
new_buttons,
old_buttons
);
}
prev_buttons = buttons;

View File

@@ -1,14 +1,14 @@
extern crate sdl2;
use sdl2::pixels::Color;
use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use sdl2::video::Window;
use sdl2::pixels::Color;
use sdl2::rect::Rect;
use sdl2::video::Window;
use std::time::Duration;
const WINDOW_WIDTH : u32 = 800;
const WINDOW_HEIGHT : u32 = 600;
const WINDOW_WIDTH: u32 = 800;
const WINDOW_HEIGHT: u32 = 600;
#[derive(Clone, Copy)]
enum Gradient {
@@ -16,13 +16,17 @@ enum Gradient {
Cyan,
Green,
Blue,
White
White,
}
fn set_window_gradient(window: &mut Window, event_pump: &sdl2::EventPump, gradient: Gradient) -> Result<(), String> {
fn set_window_gradient(
window: &mut Window,
event_pump: &sdl2::EventPump,
gradient: Gradient,
) -> Result<(), String> {
let mut surface = window.surface(event_pump)?;
for i in 0 .. (WINDOW_WIDTH / 4) {
let c : u8 = 255 - (i as u8);
for i in 0..(WINDOW_WIDTH / 4) {
let c: u8 = 255 - (i as u8);
let i = i as i32;
let color = match gradient {
Gradient::Red => Color::RGB(c, 0, 0),
@@ -31,7 +35,7 @@ fn set_window_gradient(window: &mut Window, event_pump: &sdl2::EventPump, gradie
Gradient::Blue => Color::RGB(0, 0, c),
Gradient::White => Color::RGB(c, c, c),
};
surface.fill_rect(Rect::new(i*4, 0, 4, WINDOW_HEIGHT), color)?;
surface.fill_rect(Rect::new(i * 4, 0, 4, WINDOW_HEIGHT), color)?;
}
surface.finish()
}
@@ -51,7 +55,8 @@ pub fn main() -> Result<(), String> {
let sdl_context = sdl2::init()?;
let video_subsystem = sdl_context.video()?;
let mut window = video_subsystem.window("rust-sdl2 demo: No Renderer", WINDOW_WIDTH, WINDOW_HEIGHT)
let mut window = video_subsystem
.window("rust-sdl2 demo: No Renderer", WINDOW_WIDTH, WINDOW_HEIGHT)
.position_centered()
.build()
.map_err(|e| e.to_string())?;
@@ -59,15 +64,17 @@ pub fn main() -> Result<(), String> {
let mut current_gradient = Gradient::Red;
set_window_gradient(&mut window, &event_pump, current_gradient)?;
'running: loop {
let mut keypress : bool = false;
let mut keypress: bool = false;
for event in event_pump.poll_iter() {
match event {
Event::Quit {..} | Event::KeyDown { keycode: Some(Keycode::Escape), .. } => {
break 'running
},
Event::Quit { .. }
| Event::KeyDown {
keycode: Some(Keycode::Escape),
..
} => break 'running,
Event::KeyDown { repeat: false, .. } => {
keypress = true;
},
}
_ => {}
}
}

View File

@@ -1,10 +1,9 @@
extern crate futures;
/// Minimal example for getting sdl2 and wgpu working together with raw-window-handle.
extern crate glsl_to_spirv;
extern crate libc;
extern crate sdl2;
extern crate wgpu;
extern crate futures;
use futures::executor::block_on;
@@ -41,14 +40,12 @@ fn main() -> Result<(), String> {
None => return Err(String::from("No adapter found")),
};
let (device, queue) = block_on(adapter.request_device(
&wgpu::DeviceDescriptor {
extensions: wgpu::Extensions {
anisotropic_filtering: false,
},
limits: wgpu::Limits::default(),
}
));
let (device, queue) = block_on(adapter.request_device(&wgpu::DeviceDescriptor {
extensions: wgpu::Extensions {
anisotropic_filtering: false,
},
limits: wgpu::Limits::default(),
}));
let vs = include_str!("shader.vert");
let vs_spirv = &load_glsl(vs, glsl_to_spirv::ShaderType::Vertex)?;
@@ -143,10 +140,9 @@ fn main() -> Result<(), String> {
Ok(a) => a,
Err(_) => return Err(String::from("Timeout getting next texture")),
};
let mut encoder =
device.create_command_encoder(&wgpu::CommandEncoderDescriptor {
label: Some("command_encoder")
});
let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor {
label: Some("command_encoder"),
});
{
let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
@@ -161,7 +157,7 @@ fn main() -> Result<(), String> {
});
rpass.set_pipeline(&render_pipeline);
rpass.set_bind_group(0, &bind_group, &[]);
rpass.draw(0 .. 3, 0 .. 1);
rpass.draw(0..3, 0..1);
}
queue.submit(&[encoder.finish()]);

View File

@@ -1,15 +1,16 @@
extern crate sdl2;
use sdl2::event::Event;
use sdl2::mouse::MouseButton;
use sdl2::keyboard::Keycode;
use sdl2::mouse::MouseButton;
use std::time::Duration;
pub fn main() -> Result<(), String> {
let sdl_context = sdl2::init()?;
let video_subsystem = sdl_context.video()?;
let _window = video_subsystem.window("Mouse", 800, 600)
let _window = video_subsystem
.window("Mouse", 800, 600)
.position_centered()
.build()
.map_err(|e| e.to_string())?;
@@ -20,15 +21,21 @@ pub fn main() -> Result<(), String> {
'running: loop {
for event in events.poll_iter() {
match event {
Event::KeyDown { keycode: Some(Keycode::Escape), .. } |
Event::Quit { .. } => break 'running,
Event::KeyDown {
keycode: Some(Keycode::Escape),
..
}
| Event::Quit { .. } => break 'running,
_ => {}
}
}
// get a mouse state using mouse_state() so as not to call
// relative_mouse_state() twice and get a false position reading
if events.mouse_state().is_mouse_button_pressed(MouseButton::Left) {
if events
.mouse_state()
.is_mouse_button_pressed(MouseButton::Left)
{
state = events.relative_mouse_state();
println!("Relative - X = {:?}, Y = {:?}", state.x(), state.y());
}

View File

@@ -13,9 +13,14 @@ fn main() -> Result<(), String> {
.position_centered()
.build()
.map_err(|e| e.to_string())?;
let mut canvas = window.into_canvas().software().build().map_err(|e| e.to_string())?;
let mut canvas = window
.into_canvas()
.software()
.build()
.map_err(|e| e.to_string())?;
let creator = canvas.texture_creator();
let mut texture = creator.create_texture_target(PixelFormatEnum::RGBA8888, 400, 300)
let mut texture = creator
.create_texture_target(PixelFormatEnum::RGBA8888, 400, 300)
.map_err(|e| e.to_string())?;
let mut angle = 0.0;
@@ -23,27 +28,35 @@ fn main() -> Result<(), String> {
'mainloop: loop {
for event in sdl_context.event_pump()?.poll_iter() {
match event {
Event::KeyDown { keycode: Some(Keycode::Escape), .. } |
Event::Quit { .. } => break 'mainloop,
Event::KeyDown {
keycode: Some(Keycode::Escape),
..
}
| Event::Quit { .. } => break 'mainloop,
_ => {}
}
}
angle = (angle + 0.5) % 360.;
canvas.with_texture_canvas(&mut texture, |texture_canvas| {
texture_canvas.clear();
texture_canvas.set_draw_color(Color::RGBA(255, 0, 0, 255));
texture_canvas.fill_rect(Rect::new(0, 0, 400, 300)).expect("could not fill rect");
}).map_err(|e| e.to_string())?;
canvas
.with_texture_canvas(&mut texture, |texture_canvas| {
texture_canvas.clear();
texture_canvas.set_draw_color(Color::RGBA(255, 0, 0, 255));
texture_canvas
.fill_rect(Rect::new(0, 0, 400, 300))
.expect("could not fill rect");
})
.map_err(|e| e.to_string())?;
canvas.set_draw_color(Color::RGBA(0, 0, 0, 255));
let dst = Some(Rect::new(0, 0, 400, 300));
canvas.clear();
canvas.copy_ex(&texture,
canvas.copy_ex(
&texture,
None,
dst,
angle,
Some(Point::new(400, 300)),
false,
false
false,
)?;
canvas.present();
}

View File

@@ -1,15 +1,16 @@
extern crate sdl2;
use sdl2::pixels::PixelFormatEnum;
use sdl2::rect::Rect;
use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use sdl2::pixels::PixelFormatEnum;
use sdl2::rect::Rect;
pub fn main() -> Result<(), String> {
let sdl_context = sdl2::init()?;
let video_subsystem = sdl_context.video()?;
let window = video_subsystem.window("rust-sdl2 demo: Video", 800, 600)
let window = video_subsystem
.window("rust-sdl2 demo: Video", 800, 600)
.position_centered()
.opengl()
.build()
@@ -18,13 +19,14 @@ pub fn main() -> Result<(), String> {
let mut canvas = window.into_canvas().build().map_err(|e| e.to_string())?;
let texture_creator = canvas.texture_creator();
let mut texture = texture_creator.create_texture_streaming(PixelFormatEnum::RGB24, 256, 256)
let mut texture = texture_creator
.create_texture_streaming(PixelFormatEnum::RGB24, 256, 256)
.map_err(|e| e.to_string())?;
// Create a red-green gradient
texture.with_lock(None, |buffer: &mut [u8], pitch: usize| {
for y in 0..256 {
for x in 0..256 {
let offset = y*pitch + x*3;
let offset = y * pitch + x * 3;
buffer[offset] = x as u8;
buffer[offset + 1] = y as u8;
buffer[offset + 2] = 0;
@@ -34,8 +36,15 @@ pub fn main() -> Result<(), String> {
canvas.clear();
canvas.copy(&texture, None, Some(Rect::new(100, 100, 256, 256)))?;
canvas.copy_ex(&texture, None,
Some(Rect::new(450, 100, 256, 256)), 30.0, None, false, false)?;
canvas.copy_ex(
&texture,
None,
Some(Rect::new(450, 100, 256, 256)),
30.0,
None,
false,
false,
)?;
canvas.present();
let mut event_pump = sdl_context.event_pump()?;
@@ -43,10 +52,11 @@ pub fn main() -> Result<(), String> {
'running: loop {
for event in event_pump.poll_iter() {
match event {
Event::Quit {..}
| Event::KeyDown { keycode: Some(Keycode::Escape), .. } => {
break 'running
},
Event::Quit { .. }
| Event::KeyDown {
keycode: Some(Keycode::Escape),
..
} => break 'running,
_ => {}
}
}

View File

@@ -1,15 +1,16 @@
extern crate sdl2;
use sdl2::pixels::PixelFormatEnum;
use sdl2::rect::Rect;
use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use sdl2::pixels::PixelFormatEnum;
use sdl2::rect::Rect;
pub fn main() -> Result<(), String> {
let sdl_context = sdl2::init()?;
let video_subsystem = sdl_context.video()?;
let window = video_subsystem.window("rust-sdl2 demo: Video", 800, 600)
let window = video_subsystem
.window("rust-sdl2 demo: Video", 800, 600)
.position_centered()
.opengl()
.build()
@@ -18,7 +19,8 @@ pub fn main() -> Result<(), String> {
let mut canvas = window.into_canvas().build().map_err(|e| e.to_string())?;
let texture_creator = canvas.texture_creator();
let mut texture = texture_creator.create_texture_streaming(PixelFormatEnum::IYUV, 256, 256)
let mut texture = texture_creator
.create_texture_streaming(PixelFormatEnum::IYUV, 256, 256)
.map_err(|e| e.to_string())?;
// Create a U-V gradient
texture.with_lock(None, |buffer: &mut [u8], pitch: usize| {
@@ -31,20 +33,20 @@ pub fn main() -> Result<(), String> {
// Set Y (constant)
for y in 0..h {
for x in 0..w {
let offset = y*pitch + x;
let offset = y * pitch + x;
buffer[offset] = 128;
}
}
let y_size = pitch*h;
let y_size = pitch * h;
// Set U and V (X and Y)
for y in 0..h/2 {
for x in 0..w/2 {
let u_offset = y_size + y*pitch/2 + x;
let v_offset = y_size + (pitch/2 * h/2) + y*pitch/2 + x;
buffer[u_offset] = (x*2) as u8;
buffer[v_offset] = (y*2) as u8;
for y in 0..h / 2 {
for x in 0..w / 2 {
let u_offset = y_size + y * pitch / 2 + x;
let v_offset = y_size + (pitch / 2 * h / 2) + y * pitch / 2 + x;
buffer[u_offset] = (x * 2) as u8;
buffer[v_offset] = (y * 2) as u8;
}
}
})?;
@@ -58,9 +60,11 @@ pub fn main() -> Result<(), String> {
'running: loop {
for event in event_pump.poll_iter() {
match event {
Event::Quit {..} | Event::KeyDown { keycode: Some(Keycode::Escape), .. } => {
break 'running
},
Event::Quit { .. }
| Event::KeyDown {
keycode: Some(Keycode::Escape),
..
} => break 'running,
_ => {}
}
}

View File

@@ -1,15 +1,15 @@
extern crate sdl2;
use sdl2::event::Event;
use sdl2::image::{LoadTexture, InitFlag};
use sdl2::image::{InitFlag, LoadTexture};
use sdl2::keyboard::Keycode;
use sdl2::pixels::Color;
use sdl2::render::{TextureCreator, Texture};
use sdl2::render::{Texture, TextureCreator};
use sdl2::ttf::{Font, Sdl2TtfContext};
use std::env;
use std::borrow::Borrow;
use std::collections::HashMap;
use std::env;
use std::hash::Hash;
use std::rc::Rc;
@@ -31,7 +31,11 @@ fn main() -> Result<(), String> {
.position_centered()
.build()
.map_err(|e| e.to_string())?;
let mut canvas = window.into_canvas().software().build().map_err(|e| e.to_string())?;
let mut canvas = window
.into_canvas()
.software()
.build()
.map_err(|e| e.to_string())?;
let texture_creator = canvas.texture_creator();
let mut texture_manager = TextureManager::new(&texture_creator);
let mut font_manager = FontManager::new(&font_context);
@@ -43,8 +47,11 @@ fn main() -> Result<(), String> {
'mainloop: loop {
for event in sdl_context.event_pump()?.poll_iter() {
match event {
Event::KeyDown { keycode: Some(Keycode::Escape), .. } |
Event::Quit { .. } => break 'mainloop,
Event::KeyDown {
keycode: Some(Keycode::Escape),
..
}
| Event::Quit { .. } => break 'mainloop,
_ => {}
}
}
@@ -54,10 +61,13 @@ fn main() -> Result<(), String> {
// not recommended to create a texture from the font each iteration
// but it is the simplest thing to do for this example
let surface = font.render("Hello Rust!")
.blended(Color::RGBA(255, 0, 0, 255)).map_err(|e| e.to_string())?;
let surface = font
.render("Hello Rust!")
.blended(Color::RGBA(255, 0, 0, 255))
.map_err(|e| e.to_string())?;
let font_texture = texture_creator
.create_texture_from_surface(&surface).map_err(|e| e.to_string())?;
.create_texture_from_surface(&surface)
.map_err(|e| e.to_string())?;
//draw all
canvas.clear();
@@ -75,16 +85,18 @@ type FontManager<'l> = ResourceManager<'l, FontDetails, Font<'l, 'static>, Sdl2T
// Generic struct to cache any resource loaded by a ResourceLoader
pub struct ResourceManager<'l, K, R, L>
where K: Hash + Eq,
L: 'l + ResourceLoader<'l, R>
where
K: Hash + Eq,
L: 'l + ResourceLoader<'l, R>,
{
loader: &'l L,
cache: HashMap<K, Rc<R>>,
}
impl<'l, K, R, L> ResourceManager<'l, K, R, L>
where K: Hash + Eq,
L: ResourceLoader<'l, R>
where
K: Hash + Eq,
L: ResourceLoader<'l, R>,
{
pub fn new(loader: &'l L) -> Self {
ResourceManager {
@@ -96,19 +108,19 @@ impl<'l, K, R, L> ResourceManager<'l, K, R, L>
// Generics magic to allow a HashMap to use String as a key
// while allowing it to use &str for gets
pub fn load<D>(&mut self, details: &D) -> Result<Rc<R>, String>
where L: ResourceLoader<'l, R, Args = D>,
D: Eq + Hash + ?Sized,
K: Borrow<D> + for<'a> From<&'a D>
where
L: ResourceLoader<'l, R, Args = D>,
D: Eq + Hash + ?Sized,
K: Borrow<D> + for<'a> From<&'a D>,
{
self.cache
.get(details)
.cloned()
.map_or_else(|| {
let resource = Rc::new(self.loader.load(details)?);
self.cache.insert(details.into(), resource.clone());
Ok(resource)
},
Ok)
self.cache.get(details).cloned().map_or_else(
|| {
let resource = Rc::new(self.loader.load(details)?);
self.cache.insert(details.into(), resource.clone());
Ok(resource)
},
Ok,
)
}
}

View File

@@ -5,12 +5,12 @@ use std::path::Path;
use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use sdl2::pixels::Color;
use sdl2::rect::Rect;
use sdl2::render::TextureQuery;
use sdl2::pixels::Color;
static SCREEN_WIDTH : u32 = 800;
static SCREEN_HEIGHT : u32 = 600;
static SCREEN_WIDTH: u32 = 800;
static SCREEN_HEIGHT: u32 = 600;
// handle the annoying Rect i32
macro_rules! rect(
@@ -48,7 +48,8 @@ fn run(font_path: &Path) -> Result<(), String> {
let video_subsys = sdl_context.video()?;
let ttf_context = sdl2::ttf::init().map_err(|e| e.to_string())?;
let window = video_subsys.window("SDL2_TTF Example", SCREEN_WIDTH, SCREEN_HEIGHT)
let window = video_subsys
.window("SDL2_TTF Example", SCREEN_WIDTH, SCREEN_HEIGHT)
.position_centered()
.opengl()
.build()
@@ -62,9 +63,12 @@ fn run(font_path: &Path) -> Result<(), String> {
font.set_style(sdl2::ttf::FontStyle::BOLD);
// render a surface, and convert it to a texture bound to the canvas
let surface = font.render("Hello Rust!")
.blended(Color::RGBA(255, 0, 0, 255)).map_err(|e| e.to_string())?;
let texture = texture_creator.create_texture_from_surface(&surface)
let surface = font
.render("Hello Rust!")
.blended(Color::RGBA(255, 0, 0, 255))
.map_err(|e| e.to_string())?;
let texture = texture_creator
.create_texture_from_surface(&surface)
.map_err(|e| e.to_string())?;
canvas.set_draw_color(Color::RGBA(195, 217, 255, 255));
@@ -74,7 +78,12 @@ fn run(font_path: &Path) -> Result<(), String> {
// If the example text is too big for the screen, downscale it (and center irregardless)
let padding = 64;
let target = get_centered_rect(width, height, SCREEN_WIDTH - padding, SCREEN_HEIGHT - padding);
let target = get_centered_rect(
width,
height,
SCREEN_WIDTH - padding,
SCREEN_HEIGHT - padding,
);
canvas.copy(&texture, None, Some(target))?;
canvas.present();
@@ -82,8 +91,11 @@ fn run(font_path: &Path) -> Result<(), String> {
'mainloop: loop {
for event in sdl_context.event_pump()?.poll_iter() {
match event {
Event::KeyDown {keycode: Some(Keycode::Escape), ..} |
Event::Quit {..} => break 'mainloop,
Event::KeyDown {
keycode: Some(Keycode::Escape),
..
}
| Event::Quit { .. } => break 'mainloop,
_ => {}
}
}

View File

@@ -1,8 +1,8 @@
extern crate sdl2;
use sdl2::pixels::Color;
use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use sdl2::pixels::Color;
pub fn main() -> Result<(), String> {
let sdl_context = sdl2::init()?;
@@ -14,7 +14,11 @@ pub fn main() -> Result<(), String> {
.build()
.map_err(|e| e.to_string())?;
let mut canvas = window.into_canvas().present_vsync().build().map_err(|e| e.to_string())?;
let mut canvas = window
.into_canvas()
.present_vsync()
.build()
.map_err(|e| e.to_string())?;
let mut tick = 0;
@@ -23,8 +27,11 @@ pub fn main() -> Result<(), String> {
'running: loop {
for event in event_pump.poll_iter() {
match event {
Event::Quit { .. } |
Event::KeyDown { keycode: Some(Keycode::Escape), .. } => break 'running,
Event::Quit { .. }
| Event::KeyDown {
keycode: Some(Keycode::Escape),
..
} => break 'running,
_ => {}
}
}
@@ -35,12 +42,10 @@ pub fn main() -> Result<(), String> {
let position = window.position();
let size = window.size();
let title = format!("Window - pos({}x{}), size({}x{}): {}",
position.0,
position.1,
size.0,
size.1,
tick);
let title = format!(
"Window - pos({}x{}), size({}x{}): {}",
position.0, position.1, size.0, size.1, tick
);
window.set_title(&title).map_err(|e| e.to_string())?;
tick += 1;

View File

@@ -1,23 +1,23 @@
#![allow(unused_imports, dead_code, unused_variables)]
#[cfg(feature = "pkg-config")]
extern crate pkg_config;
#[cfg(feature = "bindgen")]
extern crate bindgen;
#[cfg(feature="bundled")]
#[cfg(feature = "bundled")]
extern crate cmake;
#[cfg(feature="bundled")]
extern crate tar;
#[cfg(feature="bundled")]
#[cfg(feature = "bundled")]
extern crate flate2;
#[cfg(feature="bundled")]
#[cfg(feature = "pkg-config")]
extern crate pkg_config;
#[cfg(feature = "bundled")]
extern crate tar;
#[cfg(feature = "bundled")]
extern crate unidiff;
#[macro_use]
extern crate cfg_if;
use std::path::{Path, PathBuf};
use std::{io, fs, env};
use std::{env, fs, io};
// corresponds to the headers that we have in sdl2-sys/SDL2-{version}
const SDL2_HEADERS_BUNDLED_VERSION: &str = "2.0.12";
@@ -28,11 +28,19 @@ const LASTEST_SDL2_VERSION: &str = "2.0.12";
#[cfg(feature = "bindgen")]
macro_rules! add_msvc_includes_to_bindings {
($bindings:expr) => {
$bindings = $bindings.clang_arg(format!("-IC:/Program Files (x86)/Windows Kits/8.1/Include/shared"));
$bindings = $bindings.clang_arg(format!(
"-IC:/Program Files (x86)/Windows Kits/8.1/Include/shared"
));
$bindings = $bindings.clang_arg(format!("-IC:/Program Files/LLVM/lib/clang/5.0.0/include"));
$bindings = $bindings.clang_arg(format!("-IC:/Program Files (x86)/Windows Kits/10/Include/10.0.10240.0/ucrt"));
$bindings = $bindings.clang_arg(format!("-IC:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/include"));
$bindings = $bindings.clang_arg(format!("-IC:/Program Files (x86)/Windows Kits/8.1/Include/um"));
$bindings = $bindings.clang_arg(format!(
"-IC:/Program Files (x86)/Windows Kits/10/Include/10.0.10240.0/ucrt"
));
$bindings = $bindings.clang_arg(format!(
"-IC:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/include"
));
$bindings = $bindings.clang_arg(format!(
"-IC:/Program Files (x86)/Windows Kits/8.1/Include/um"
));
};
}
@@ -62,14 +70,23 @@ fn run_command(cmd: &str, args: &[&str]) {
#[cfg(feature = "bundled")]
fn download_to(url: &str, dest: &str) {
if cfg!(windows) {
run_command("powershell", &[
"-NoProfile", "-NonInteractive",
"-Command", &format!("& {{
run_command(
"powershell",
&[
"-NoProfile",
"-NonInteractive",
"-Command",
&format!(
"& {{
$client = New-Object System.Net.WebClient
$client.DownloadFile(\"{0}\", \"{1}\")
if (!$?) {{ Exit 1 }}
}}", url, dest).as_str()
]);
}}",
url, dest
)
.as_str(),
],
);
} else {
run_command("curl", &[url, "-o", dest]);
}
@@ -79,12 +96,17 @@ fn download_to(url: &str, dest: &str) {
fn pkg_config_print(statik: bool, lib_name: &str) {
pkg_config::Config::new()
.statik(statik)
.probe(lib_name).unwrap();
.probe(lib_name)
.unwrap();
}
#[cfg(feature = "use-pkgconfig")]
fn get_pkg_config() {
let statik: bool = if cfg!(feature = "static-link") { true } else { false };
let statik: bool = if cfg!(feature = "static-link") {
true
} else {
false
};
pkg_config_print(statik, "sdl2");
if cfg!(feature = "image") {
@@ -122,21 +144,19 @@ fn get_vcpkg_config() {
#[cfg(feature = "bundled")]
fn download_sdl2() -> PathBuf {
let out_dir = env::var("OUT_DIR").unwrap();
let sdl2_archive_name = format!("SDL2-{}.tar.gz", LASTEST_SDL2_VERSION);
let sdl2_archive_url = format!("https://libsdl.org/release/{}", sdl2_archive_name);
let sdl2_archive_path = Path::new(&out_dir).join(sdl2_archive_name);
let sdl2_build_path = Path::new(&out_dir).join(format!("SDL2-{}", LASTEST_SDL2_VERSION));
// avoid re-downloading the archive if it already exists
// avoid re-downloading the archive if it already exists
if !sdl2_archive_path.exists() {
download_to(&sdl2_archive_url, sdl2_archive_path.to_str().unwrap());
}
let reader = flate2::read::GzDecoder::new(
fs::File::open(&sdl2_archive_path).unwrap()
);
let reader = flate2::read::GzDecoder::new(fs::File::open(&sdl2_archive_path).unwrap());
let mut ar = tar::Archive::new(reader);
ar.unpack(&out_dir).unwrap();
@@ -153,15 +173,22 @@ fn patch_sdl2(sdl2_source_path: &Path) {
// https://bugzilla.libsdl.org/show_bug.cgi?id=5105
// Expected to be fixed in 2.0.14
("SDL2-2.0.12-sndio-shared-linux.patch", include_str!("patches/SDL2-2.0.12-sndio-shared-linux.patch")),
(
"SDL2-2.0.12-sndio-shared-linux.patch",
include_str!("patches/SDL2-2.0.12-sndio-shared-linux.patch"),
),
// https://bugzilla.libsdl.org/show_bug.cgi?id=3421
// Expected to be fixed in 2.0.14
("SDL2-2.0.12-SDL_DISABLE_WINDOWS_IME.patch", include_str!("patches/SDL2-2.0.12-SDL_DISABLE_WINDOWS_IME.patch")),
(
"SDL2-2.0.12-SDL_DISABLE_WINDOWS_IME.patch",
include_str!("patches/SDL2-2.0.12-SDL_DISABLE_WINDOWS_IME.patch"),
),
// https://bugzilla.libsdl.org/show_bug.cgi?id=4988
// Expected to be fixed in 2.0.14
("SDL2-2.0.12-metal-detection-macos-ios.patch", include_str!("patches/SDL2-2.0.12-metal-detection-macos-ios.patch"))
(
"SDL2-2.0.12-metal-detection-macos-ios.patch",
include_str!("patches/SDL2-2.0.12-metal-detection-macos-ios.patch"),
),
];
let sdl_version = format!("SDL2-{}", LASTEST_SDL2_VERSION);
@@ -180,20 +207,20 @@ fn patch_sdl2(sdl2_source_path: &Path) {
// TOOD: This code is untested (save for the immediate application), and
// probably belongs in the unidiff (or similar) package.
for modified_file in patch_set.modified_files() {
use std::io::{Write, BufRead};
use std::io::{BufRead, Write};
let file_path = sdl2_source_path.join(modified_file.path());
let old_path = sdl2_source_path.join(format!("{}_old", modified_file.path()));
fs::rename(&file_path, &old_path)
.expect(&format!(
"Rename of {} to {} failed",
file_path.to_string_lossy(),
old_path.to_string_lossy()));
fs::rename(&file_path, &old_path).expect(&format!(
"Rename of {} to {} failed",
file_path.to_string_lossy(),
old_path.to_string_lossy()
));
let dst_file = fs::File::create(file_path).unwrap();
let mut dst_buf = io::BufWriter::new(dst_file);
let old_file = fs::File::open(old_path).unwrap();
let mut old_buf = io::BufReader::new(old_file);
let dst_file = fs::File::create(file_path).unwrap();
let mut dst_buf = io::BufWriter::new(dst_file);
let old_file = fs::File::open(old_path).unwrap();
let mut old_buf = io::BufReader::new(old_file);
let mut cursor = 0;
for (i, hunk) in modified_file.into_iter().enumerate() {
@@ -213,7 +240,10 @@ fn patch_sdl2(sdl2_source_path: &Path) {
old_buf.read_line(&mut actual_line).unwrap();
actual_line.pop(); // Remove the trailing newline.
if expected_line.value.trim_end() != actual_line {
panic!("Can't apply patch; mismatch between expected and actual in hunk {}", i);
panic!(
"Can't apply patch; mismatch between expected and actual in hunk {}",
i
);
}
}
cursor += hunk.source_length;
@@ -237,11 +267,11 @@ fn patch_sdl2(sdl2_source_path: &Path) {
// defined here. Hopefully this gets moved somewhere else before it
// bites someone.
for removed_file in patch_set.removed_files() {
fs::remove_file(sdl2_source_path.join(removed_file.path()))
.expect(
&format!("Failed to remove file {} from {}",
removed_file.path(),
sdl2_source_path.to_string_lossy()));
fs::remove_file(sdl2_source_path.join(removed_file.path())).expect(&format!(
"Failed to remove file {} from {}",
removed_file.path(),
sdl2_source_path.to_string_lossy()
));
}
// For every new file, copy the entire contents of the patched file into
// a newly created <file_name>.
@@ -256,10 +286,10 @@ fn patch_sdl2(sdl2_source_path: &Path) {
// ever have more than one hunk.
assert!(added_file.len() == 1);
let file_path = sdl2_source_path.join(added_file.path());
let dst_file = fs::File::create(&file_path)
.expect(&format!(
"Failed to create file {}",
file_path.to_string_lossy()));
let dst_file = fs::File::create(&file_path).expect(&format!(
"Failed to create file {}",
file_path.to_string_lossy()
));
let mut dst_buf = io::BufWriter::new(&dst_file);
for line in added_file.into_iter().nth(0).unwrap().target_lines() {
@@ -270,7 +300,7 @@ fn patch_sdl2(sdl2_source_path: &Path) {
}
}
// compile a shared or static lib depending on the feature
// compile a shared or static lib depending on the feature
#[cfg(feature = "bundled")]
fn compile_sdl2(sdl2_build_path: &Path, target_os: &str) -> PathBuf {
let mut cfg = cmake::Config::new(sdl2_build_path);
@@ -279,7 +309,10 @@ fn compile_sdl2(sdl2_build_path: &Path, target_os: &str) -> PathBuf {
#[cfg(target_os = "linux")]
{
use version_compare::Version;
if let Ok(version) = std::process::Command::new("cc").arg("-dumpversion").output() {
if let Ok(version) = std::process::Command::new("cc")
.arg("-dumpversion")
.output()
{
let local_ver = Version::from(std::str::from_utf8(&version.stdout).unwrap()).unwrap();
let affected_ver = Version::from("10").unwrap();
@@ -306,46 +339,56 @@ fn compile_sdl2(sdl2_build_path: &Path, target_os: &str) -> PathBuf {
#[cfg(not(feature = "bundled"))]
fn compute_include_paths() -> Vec<String> {
let mut include_paths: Vec<String> = vec!();
let mut include_paths: Vec<String> = vec![];
if let Ok(include_path) = env::var("SDL2_INCLUDE_PATH") {
include_paths.push(format!("{}", include_path));
};
#[cfg(feature = "pkg-config")] {
#[cfg(feature = "pkg-config")]
{
// don't print the "cargo:xxx" directives, we're just trying to get the include paths here
let pkg_config_library = pkg_config::Config::new().print_system_libs(false).probe("sdl2").unwrap();
let pkg_config_library = pkg_config::Config::new()
.print_system_libs(false)
.probe("sdl2")
.unwrap();
for path in pkg_config_library.include_paths {
include_paths.push(format!("{}", path.display()));
};
}
}
#[cfg(feature = "vcpkg")] {
#[cfg(feature = "vcpkg")]
{
// don't print the "cargo:xxx" directives, we're just trying to get the include paths here
let vcpkg_library = vcpkg::Config::new().cargo_metadata(false).probe("sdl2").unwrap();
let vcpkg_library = vcpkg::Config::new()
.cargo_metadata(false)
.probe("sdl2")
.unwrap();
for path in vcpkg_library.include_paths {
include_paths.push(format!("{}", path.display()));
};
}
}
include_paths
}
fn link_sdl2(target_os: &str) {
#[cfg(all(feature = "use-pkgconfig", not(feature = "bundled")))] {
#[cfg(all(feature = "use-pkgconfig", not(feature = "bundled")))]
{
// prints the appropriate linking parameters when using pkg-config
// useless when using "bundled"
get_pkg_config();
}
#[cfg(all(feature = "use-vcpkg", not(feature = "bundled")))] {
}
#[cfg(all(feature = "use-vcpkg", not(feature = "bundled")))]
{
// prints the appropriate linking parameters when using pkg-config
// useless when using "bundled"
get_vcpkg_config();
}
#[cfg(not(feature = "static-link"))] {
#[cfg(not(feature = "static-link"))]
{
if target_os == "ios" {
// iOS requires additional linking to function properly
println!("cargo:rustc-flags=-l framework=AVFoundation");
@@ -362,7 +405,7 @@ fn link_sdl2(target_os: &str) {
// pkg-config automatically prints this output when probing,
// however pkg_config isn't used with the feature "bundled"
if cfg!(feature = "bundled") || cfg!(not(feature = "use-pkgconfig")) {
if cfg!(feature = "bundled") || cfg!(not(feature = "use-pkgconfig")) {
if cfg!(feature = "use_mac_framework") && target_os == "darwin" {
println!("cargo:rustc-flags=-l framework=SDL2");
} else if target_os != "emscripten" {
@@ -371,8 +414,11 @@ fn link_sdl2(target_os: &str) {
}
}
#[cfg(feature = "static-link")] {
if cfg!(feature = "bundled") || (cfg!(feature = "use-pkgconfig") == false && cfg!(feature = "use-vcpkg") == false) {
#[cfg(feature = "static-link")]
{
if cfg!(feature = "bundled")
|| (cfg!(feature = "use-pkgconfig") == false && cfg!(feature = "use-vcpkg") == false)
{
println!("cargo:rustc-link-lib=static=SDL2main");
println!("cargo:rustc-link-lib=static=SDL2");
}
@@ -412,14 +458,18 @@ fn link_sdl2(target_os: &str) {
// ':filename' syntax is used for renaming of libraries, which basically
// leaves it up to the user to make a symlink to the shared object so
// -lSDL2_mixer can find it.
#[cfg(all(not(feature = "use-pkgconfig"), not(feature = "static-link")))] {
#[cfg(all(not(feature = "use-pkgconfig"), not(feature = "static-link")))]
{
if cfg!(feature = "mixer") {
if target_os.contains("linux") || target_os.contains("freebsd") || target_os.contains("openbsd") {
if target_os.contains("linux")
|| target_os.contains("freebsd")
|| target_os.contains("openbsd")
{
println!("cargo:rustc-flags=-l SDL2_mixer");
} else if target_os.contains("windows") {
println!("cargo:rustc-flags=-l SDL2_mixer");
} else if target_os.contains("darwin") {
if cfg!(any(mac_framework, feature="use_mac_framework")) {
if cfg!(any(mac_framework, feature = "use_mac_framework")) {
println!("cargo:rustc-flags=-l framework=SDL2_mixer");
} else {
println!("cargo:rustc-flags=-l SDL2_mixer");
@@ -427,12 +477,15 @@ fn link_sdl2(target_os: &str) {
}
}
if cfg!(feature = "image") {
if target_os.contains("linux") || target_os.contains("freebsd") || target_os.contains("openbsd") {
if target_os.contains("linux")
|| target_os.contains("freebsd")
|| target_os.contains("openbsd")
{
println!("cargo:rustc-flags=-l SDL2_image");
} else if target_os.contains("windows") {
println!("cargo:rustc-flags=-l SDL2_image");
} else if target_os.contains("darwin") {
if cfg!(any(mac_framework, feature="use_mac_framework")) {
if cfg!(any(mac_framework, feature = "use_mac_framework")) {
println!("cargo:rustc-flags=-l framework=SDL2_image");
} else {
println!("cargo:rustc-flags=-l SDL2_image");
@@ -440,12 +493,15 @@ fn link_sdl2(target_os: &str) {
}
}
if cfg!(feature = "ttf") {
if target_os.contains("linux") || target_os.contains("freebsd") || target_os.contains("openbsd") {
if target_os.contains("linux")
|| target_os.contains("freebsd")
|| target_os.contains("openbsd")
{
println!("cargo:rustc-flags=-l SDL2_ttf");
} else if target_os.contains("windows") {
println!("cargo:rustc-flags=-l SDL2_ttf");
} else if target_os.contains("darwin") {
if cfg!(any(mac_framework, feature="use_mac_framework")) {
if cfg!(any(mac_framework, feature = "use_mac_framework")) {
println!("cargo:rustc-flags=-l framework=SDL2_ttf");
} else {
println!("cargo:rustc-flags=-l SDL2_ttf");
@@ -453,12 +509,15 @@ fn link_sdl2(target_os: &str) {
}
}
if cfg!(feature = "gfx") {
if target_os.contains("linux") || target_os.contains("freebsd") || target_os.contains("openbsd") {
if target_os.contains("linux")
|| target_os.contains("freebsd")
|| target_os.contains("openbsd")
{
println!("cargo:rustc-flags=-l SDL2_gfx");
} else if target_os.contains("windows") {
println!("cargo:rustc-flags=-l SDL2_gfx");
} else if target_os.contains("darwin") {
if cfg!(any(mac_framework, feature="use_mac_framework")) {
if cfg!(any(mac_framework, feature = "use_mac_framework")) {
println!("cargo:rustc-flags=-l framework=SDL2_gfx");
} else {
println!("cargo:rustc-flags=-l SDL2_gfx");
@@ -505,10 +564,11 @@ fn copy_dynamic_libraries(sdl2_compiled_path: &PathBuf, target_os: &str) {
let src_dll_path = sdl2_bin_path.join(sdl2_dll_name);
let dst_dll_path = target_path.join(sdl2_dll_name);
fs::copy(&src_dll_path, &dst_dll_path)
.expect(&format!("Failed to copy SDL2 dynamic library from {} to {}",
src_dll_path.to_string_lossy(),
dst_dll_path.to_string_lossy()));
fs::copy(&src_dll_path, &dst_dll_path).expect(&format!(
"Failed to copy SDL2 dynamic library from {} to {}",
src_dll_path.to_string_lossy(),
dst_dll_path.to_string_lossy()
));
}
}
@@ -518,7 +578,8 @@ fn main() {
let target_os = get_os_from_triple(target.as_str()).unwrap();
let sdl2_compiled_path: PathBuf;
#[cfg(feature = "bundled")] {
#[cfg(feature = "bundled")]
{
let sdl2_source_path = download_sdl2();
patch_sdl2(sdl2_source_path.as_path());
sdl2_compiled_path = compile_sdl2(sdl2_source_path.as_path(), target_os);
@@ -526,31 +587,39 @@ fn main() {
let sdl2_downloaded_include_path = sdl2_source_path.join("include");
let sdl2_compiled_lib_path = sdl2_compiled_path.join("lib");
println!("cargo:rustc-link-search={}", sdl2_compiled_lib_path.display());
#[cfg(feature = "bindgen")] {
let include_paths = vec!(String::from(sdl2_downloaded_include_path.to_str().unwrap()));
println!(
"cargo:rustc-link-search={}",
sdl2_compiled_lib_path.display()
);
#[cfg(feature = "bindgen")]
{
let include_paths = vec![String::from(sdl2_downloaded_include_path.to_str().unwrap())];
println!("cargo:include={}", include_paths.join(":"));
generate_bindings(target.as_str(), host.as_str(), include_paths.as_slice())
}
#[cfg(not(feature = "bindgen"))] {
#[cfg(not(feature = "bindgen"))]
{
println!("cargo:include={}", sdl2_downloaded_include_path.display());
}
};
#[cfg(all(not(feature = "bundled"), feature = "bindgen"))] {
#[cfg(all(not(feature = "bundled"), feature = "bindgen"))]
{
let include_paths: Vec<String> = compute_include_paths();
generate_bindings(target.as_str(), host.as_str(), include_paths.as_slice())
}
#[cfg(not(feature = "bindgen"))] {
#[cfg(not(feature = "bindgen"))]
{
copy_pregenerated_bindings();
println!("cargo:include={}", get_bundled_header_path().display());
}
link_sdl2(target_os);
#[cfg(all(feature = "bundled", not(feature = "static-link")))] {
#[cfg(all(feature = "bundled", not(feature = "static-link")))]
{
copy_dynamic_libraries(&sdl2_compiled_path, target_os);
}
}
@@ -559,34 +628,58 @@ fn main() {
fn copy_pregenerated_bindings() {
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
let crate_path = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
fs::copy(crate_path.join("sdl_bindings.rs"), out_path.join("sdl_bindings.rs"))
.expect("Couldn't find pregenerated bindings!");
fs::copy(
crate_path.join("sdl_bindings.rs"),
out_path.join("sdl_bindings.rs"),
)
.expect("Couldn't find pregenerated bindings!");
if cfg!(feature = "image") {
fs::copy(crate_path.join("sdl_image_bindings.rs"), out_path.join("sdl_image_bindings.rs"))
.expect("Couldn't find pregenerated SDL_image bindings!");
fs::copy(
crate_path.join("sdl_image_bindings.rs"),
out_path.join("sdl_image_bindings.rs"),
)
.expect("Couldn't find pregenerated SDL_image bindings!");
}
if cfg!(feature = "ttf") {
fs::copy(crate_path.join("sdl_ttf_bindings.rs"), out_path.join("sdl_ttf_bindings.rs"))
.expect("Couldn't find pregenerated SDL_ttf bindings!");
fs::copy(
crate_path.join("sdl_ttf_bindings.rs"),
out_path.join("sdl_ttf_bindings.rs"),
)
.expect("Couldn't find pregenerated SDL_ttf bindings!");
}
if cfg!(feature = "mixer") {
fs::copy(crate_path.join("sdl_mixer_bindings.rs"), out_path.join("sdl_mixer_bindings.rs"))
.expect("Couldn't find pregenerated SDL_mixer bindings!");
fs::copy(
crate_path.join("sdl_mixer_bindings.rs"),
out_path.join("sdl_mixer_bindings.rs"),
)
.expect("Couldn't find pregenerated SDL_mixer bindings!");
}
if cfg!(feature = "gfx") {
fs::copy(crate_path.join("sdl_gfx_framerate_bindings.rs"), out_path.join("sdl_gfx_framerate_bindings.rs"))
.expect("Couldn't find pregenerated SDL_gfx framerate bindings!");
fs::copy(
crate_path.join("sdl_gfx_framerate_bindings.rs"),
out_path.join("sdl_gfx_framerate_bindings.rs"),
)
.expect("Couldn't find pregenerated SDL_gfx framerate bindings!");
fs::copy(crate_path.join("sdl_gfx_primitives_bindings.rs"), out_path.join("sdl_gfx_primitives_bindings.rs"))
.expect("Couldn't find pregenerated SDL_gfx primitives bindings!");
fs::copy(
crate_path.join("sdl_gfx_primitives_bindings.rs"),
out_path.join("sdl_gfx_primitives_bindings.rs"),
)
.expect("Couldn't find pregenerated SDL_gfx primitives bindings!");
fs::copy(crate_path.join("sdl_gfx_imagefilter_bindings.rs"), out_path.join("sdl_gfx_imagefilter_bindings.rs"))
.expect("Couldn't find pregenerated SDL_gfx imagefilter bindings!");
fs::copy(
crate_path.join("sdl_gfx_imagefilter_bindings.rs"),
out_path.join("sdl_gfx_imagefilter_bindings.rs"),
)
.expect("Couldn't find pregenerated SDL_gfx imagefilter bindings!");
fs::copy(crate_path.join("sdl_gfx_rotozoom_bindings.rs"), out_path.join("sdl_gfx_rotozoom_bindings.rs"))
.expect("Couldn't find pregenerated SDL_gfx rotozoom bindings!");
fs::copy(
crate_path.join("sdl_gfx_rotozoom_bindings.rs"),
out_path.join("sdl_gfx_rotozoom_bindings.rs"),
)
.expect("Couldn't find pregenerated SDL_gfx rotozoom bindings!");
}
}
@@ -598,7 +691,9 @@ fn generate_bindings(target: &str, host: &str, headers_paths: &[String]) {
let mut bindings = bindgen::Builder::default()
// enable no_std-friendly output by only using core definitions
.use_core()
.default_enum_style(bindgen::EnumVariation::Rust { non_exhaustive: false })
.default_enum_style(bindgen::EnumVariation::Rust {
non_exhaustive: false,
})
.ctypes_prefix("libc");
let mut image_bindings = bindgen::Builder::default()
@@ -616,16 +711,12 @@ fn generate_bindings(target: &str, host: &str, headers_paths: &[String]) {
.raw_line("use crate::*;")
.ctypes_prefix("libc");
let mut gfx_framerate_bindings = bindgen::Builder::default()
.use_core()
.ctypes_prefix("libc");
let mut gfx_framerate_bindings = bindgen::Builder::default().use_core().ctypes_prefix("libc");
let mut gfx_primitives_bindings = bindgen::Builder::default()
.use_core()
.raw_line("use crate::*;")
.ctypes_prefix("libc");
let mut gfx_imagefilter_bindings = bindgen::Builder::default()
.use_core()
.ctypes_prefix("libc");
let mut gfx_imagefilter_bindings = bindgen::Builder::default().use_core().ctypes_prefix("libc");
let mut gfx_rotozoom_bindings = bindgen::Builder::default()
.use_core()
.raw_line("use crate::*;")
@@ -682,10 +773,14 @@ fn generate_bindings(target: &str, host: &str, headers_paths: &[String]) {
mixer_bindings = mixer_bindings.clang_arg(format!("-I{}", include_path.display()));
}
if cfg!(feature = "gfx") {
gfx_framerate_bindings = gfx_framerate_bindings.clang_arg(format!("-I{}", include_path.display()));
gfx_primitives_bindings = gfx_primitives_bindings.clang_arg(format!("-I{}", include_path.display()));
gfx_imagefilter_bindings = gfx_imagefilter_bindings.clang_arg(format!("-I{}", include_path.display()));
gfx_rotozoom_bindings = gfx_rotozoom_bindings.clang_arg(format!("-I{}", include_path.display()));
gfx_framerate_bindings =
gfx_framerate_bindings.clang_arg(format!("-I{}", include_path.display()));
gfx_primitives_bindings =
gfx_primitives_bindings.clang_arg(format!("-I{}", include_path.display()));
gfx_imagefilter_bindings =
gfx_imagefilter_bindings.clang_arg(format!("-I{}", include_path.display()));
gfx_rotozoom_bindings =
gfx_rotozoom_bindings.clang_arg(format!("-I{}", include_path.display()));
}
} else {
// if paths are included, use them for bindgen. Bindgen should use the first one.
@@ -702,16 +797,19 @@ fn generate_bindings(target: &str, host: &str, headers_paths: &[String]) {
mixer_bindings = mixer_bindings.clang_arg(format!("-I{}", headers_path));
}
if cfg!(feature = "gfx") {
gfx_framerate_bindings = gfx_framerate_bindings.clang_arg(format!("-I{}", headers_path));
gfx_primitives_bindings = gfx_primitives_bindings.clang_arg(format!("-I{}", headers_path));
gfx_imagefilter_bindings = gfx_imagefilter_bindings.clang_arg(format!("-I{}", headers_path));
gfx_rotozoom_bindings = gfx_rotozoom_bindings.clang_arg(format!("-I{}", headers_path));
gfx_framerate_bindings =
gfx_framerate_bindings.clang_arg(format!("-I{}", headers_path));
gfx_primitives_bindings =
gfx_primitives_bindings.clang_arg(format!("-I{}", headers_path));
gfx_imagefilter_bindings =
gfx_imagefilter_bindings.clang_arg(format!("-I{}", headers_path));
gfx_rotozoom_bindings =
gfx_rotozoom_bindings.clang_arg(format!("-I{}", headers_path));
}
}
}
if target_os == "windows-msvc" {
add_msvc_includes_to_bindings!(bindings);
if cfg!(feature = "image") {
add_msvc_includes_to_bindings!(image_bindings);
@@ -750,9 +848,11 @@ fn generate_bindings(target: &str, host: &str, headers_paths: &[String]) {
gfx_framerate_bindings = gfx_framerate_bindings.clang_arg("-DSDL_VIDEO_DRIVER_X11");
gfx_framerate_bindings = gfx_framerate_bindings.clang_arg("-DSDL_VIDEO_DRIVER_WAYLAND");
gfx_primitives_bindings = gfx_primitives_bindings.clang_arg("-DSDL_VIDEO_DRIVER_X11");
gfx_primitives_bindings = gfx_primitives_bindings.clang_arg("-DSDL_VIDEO_DRIVER_WAYLAND");
gfx_primitives_bindings =
gfx_primitives_bindings.clang_arg("-DSDL_VIDEO_DRIVER_WAYLAND");
gfx_imagefilter_bindings = gfx_imagefilter_bindings.clang_arg("-DSDL_VIDEO_DRIVER_X11");
gfx_imagefilter_bindings = gfx_imagefilter_bindings.clang_arg("-DSDL_VIDEO_DRIVER_WAYLAND");
gfx_imagefilter_bindings =
gfx_imagefilter_bindings.clang_arg("-DSDL_VIDEO_DRIVER_WAYLAND");
gfx_rotozoom_bindings = gfx_rotozoom_bindings.clang_arg("-DSDL_VIDEO_DRIVER_X11");
gfx_rotozoom_bindings = gfx_rotozoom_bindings.clang_arg("-DSDL_VIDEO_DRIVER_WAYLAND");
}
@@ -946,7 +1046,6 @@ fn generate_bindings(target: &str, host: &str, headers_paths: &[String]) {
}
}
fn get_os_from_triple(triple: &str) -> Option<&str>
{
fn get_os_from_triple(triple: &str) -> Option<&str> {
triple.splitn(3, "-").nth(2)
}

View File

@@ -1,7 +1,7 @@
#![no_std]
use sdl2_sys::*;
use core::ptr::null_mut;
use sdl2_sys::*;
fn main() {
unsafe {
@@ -16,7 +16,7 @@ fn main() {
SDL_WINDOWPOS_UNDEFINED_MASK as i32,
640,
480,
SDL_WindowFlags::SDL_WINDOW_SHOWN as u32
SDL_WindowFlags::SDL_WINDOW_SHOWN as u32,
);
if _window == null_mut() {
@@ -24,7 +24,11 @@ fn main() {
}
_surface = SDL_GetWindowSurface(_window);
SDL_FillRect(_surface, null_mut(), SDL_MapRGB((*_surface).format, 0xFF, 0xFF, 0x00));
SDL_FillRect(
_surface,
null_mut(),
SDL_MapRGB((*_surface).format, 0xFF, 0xFF, 0x00),
);
SDL_UpdateWindowSurface(_window);
SDL_Delay(5000);
SDL_DestroyWindow(_window);

View File

@@ -1,4 +1,4 @@
pub mod primitives;
pub mod framerate;
pub mod imagefilter;
pub mod primitives;
pub mod rotozoom;

View File

@@ -1,13 +1,12 @@
//!
//! This crate was mainly generated by [`bindgen`](https://crates.io/crates/bindgen). It should be enough in most cases,
//! but if you ever find discrepancies between what bindgen generated and your OS, you can always
//! but if you ever find discrepancies between what bindgen generated and your OS, you can always
//! [generate your own `sdl2-sys`](https://github.com/rust-sdl2/rust-sdl2#generating-sdl2-sys-with-bindgen).
//!
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
// suppress warnings about u128 (that we don't even use ourselves anyway)
#![allow(improper_ctypes)]
#![no_std]

View File

@@ -52,18 +52,18 @@
//! std::thread::sleep(Duration::from_millis(2000));
//! ```
use std::ffi::{CStr, CString};
use libc::{c_char, c_int, c_void};
use std::convert::TryFrom;
use libc::{c_int, c_void, c_char};
use std::ops::{Deref, DerefMut};
use std::path::Path;
use std::ffi::{CStr, CString};
use std::marker::PhantomData;
use std::mem;
use std::ops::{Deref, DerefMut};
use std::path::Path;
use std::ptr;
use crate::AudioSubsystem;
use crate::get_error;
use crate::rwops::RWops;
use crate::AudioSubsystem;
use crate::sys;
use crate::sys::SDL_AudioStatus;
@@ -75,8 +75,16 @@ impl AudioSubsystem {
/// its data buffer) you're likely to be interested in the
/// [AudioDevice.lock method](audio/struct.AudioDevice.html#method.lock).
#[inline]
pub fn open_playback<'a, CB, F, D>(&self, device: D, spec: &AudioSpecDesired, get_callback: F) -> Result<AudioDevice <CB>, String>
where CB: AudioCallback, F: FnOnce(AudioSpec) -> CB, D: Into<Option<&'a str>>,
pub fn open_playback<'a, CB, F, D>(
&self,
device: D,
spec: &AudioSpecDesired,
get_callback: F,
) -> Result<AudioDevice<CB>, String>
where
CB: AudioCallback,
F: FnOnce(AudioSpec) -> CB,
D: Into<Option<&'a str>>,
{
AudioDevice::open_playback(self, device, spec, get_callback)
}
@@ -87,16 +95,30 @@ impl AudioSubsystem {
/// If you want to modify the callback-owned data at a later point (for example to update
/// its data buffer) you're likely to be interested in the
/// [AudioDevice.lock method](audio/struct.AudioDevice.html#method.lock).
pub fn open_capture<'a, CB, F, D>(&self, device: D, spec: &AudioSpecDesired, get_callback: F) -> Result<AudioDevice <CB>, String>
where CB: AudioCallback, F: FnOnce(AudioSpec) -> CB, D: Into<Option<&'a str>>,
pub fn open_capture<'a, CB, F, D>(
&self,
device: D,
spec: &AudioSpecDesired,
get_callback: F,
) -> Result<AudioDevice<CB>, String>
where
CB: AudioCallback,
F: FnOnce(AudioSpec) -> CB,
D: Into<Option<&'a str>>,
{
AudioDevice::open_capture(self, device, spec, get_callback)
}
/// Opens a new audio device which uses queueing rather than older callback method.
#[inline]
pub fn open_queue<'a, Channel, D>(&self, device: D, spec: &AudioSpecDesired) -> Result<AudioQueue<Channel>, String>
where Channel: AudioFormatNum, D: Into<Option<&'a str>>,
pub fn open_queue<'a, Channel, D>(
&self,
device: D,
spec: &AudioSpecDesired,
) -> Result<AudioQueue<Channel>, String>
where
Channel: AudioFormatNum,
D: Into<Option<&'a str>>,
{
AudioQueue::open_queue(self, device, spec)
}
@@ -158,7 +180,7 @@ pub enum AudioFormat {
/// 32-bit floating point samples, little-endian
F32LSB = sys::AUDIO_F32LSB as i32,
/// 32-bit floating point samples, big-endian
F32MSB = sys::AUDIO_F32MSB as i32
F32MSB = sys::AUDIO_F32MSB as i32,
}
impl AudioFormat {
@@ -175,7 +197,7 @@ impl AudioFormat {
sys::AUDIO_S32MSB => Some(S32MSB),
sys::AUDIO_F32LSB => Some(F32LSB),
sys::AUDIO_F32MSB => Some(F32MSB),
_ => None
_ => None,
}
}
@@ -188,25 +210,49 @@ impl AudioFormat {
#[cfg(target_endian = "little")]
impl AudioFormat {
/// Unsigned 16-bit samples, native endian
#[inline] pub const fn u16_sys() -> AudioFormat { AudioFormat::U16LSB }
#[inline]
pub const fn u16_sys() -> AudioFormat {
AudioFormat::U16LSB
}
/// Signed 16-bit samples, native endian
#[inline] pub const fn s16_sys() -> AudioFormat { AudioFormat::S16LSB }
#[inline]
pub const fn s16_sys() -> AudioFormat {
AudioFormat::S16LSB
}
/// Signed 32-bit samples, native endian
#[inline] pub const fn s32_sys() -> AudioFormat { AudioFormat::S32LSB }
#[inline]
pub const fn s32_sys() -> AudioFormat {
AudioFormat::S32LSB
}
/// 32-bit floating point samples, native endian
#[inline] pub const fn f32_sys() -> AudioFormat { AudioFormat::F32LSB }
#[inline]
pub const fn f32_sys() -> AudioFormat {
AudioFormat::F32LSB
}
}
#[cfg(target_endian = "big")]
impl AudioFormat {
/// Unsigned 16-bit samples, native endian
#[inline] pub const fn u16_sys() -> AudioFormat { AudioFormat::U16MSB }
#[inline]
pub const fn u16_sys() -> AudioFormat {
AudioFormat::U16MSB
}
/// Signed 16-bit samples, native endian
#[inline] pub const fn s16_sys() -> AudioFormat { AudioFormat::S16MSB }
#[inline]
pub const fn s16_sys() -> AudioFormat {
AudioFormat::S16MSB
}
/// Signed 32-bit samples, native endian
#[inline] pub const fn s32_sys() -> AudioFormat { AudioFormat::S32MSB }
#[inline]
pub const fn s32_sys() -> AudioFormat {
AudioFormat::S32MSB
}
/// 32-bit floating point samples, native endian
#[inline] pub const fn f32_sys() -> AudioFormat { AudioFormat::F32MSB }
#[inline]
pub const fn f32_sys() -> AudioFormat {
AudioFormat::F32MSB
}
}
#[repr(i32)]
@@ -214,7 +260,7 @@ impl AudioFormat {
pub enum AudioStatus {
Stopped = SDL_AudioStatus::SDL_AUDIO_STOPPED as i32,
Playing = SDL_AudioStatus::SDL_AUDIO_PLAYING as i32,
Paused = SDL_AudioStatus::SDL_AUDIO_PAUSED as i32,
Paused = SDL_AudioStatus::SDL_AUDIO_PAUSED as i32,
}
impl TryFrom<u32> for AudioStatus {
@@ -227,7 +273,7 @@ impl TryFrom<u32> for AudioStatus {
Ok(match unsafe { mem::transmute(n) } {
SDL_AUDIO_STOPPED => Stopped,
SDL_AUDIO_PLAYING => Playing,
SDL_AUDIO_PAUSED => Paused,
SDL_AUDIO_PAUSED => Paused,
})
}
}
@@ -236,7 +282,7 @@ impl TryFrom<u32> for AudioStatus {
#[derive(Copy, Clone)]
pub struct DriverIterator {
length: i32,
index: i32
index: i32,
}
impl Iterator for DriverIterator {
@@ -264,7 +310,7 @@ impl Iterator for DriverIterator {
}
}
impl ExactSizeIterator for DriverIterator { }
impl ExactSizeIterator for DriverIterator {}
/// Gets an iterator of all audio drivers compiled into the SDL2 library.
#[doc(alias = "SDL_GetAudioDriver")]
@@ -276,7 +322,7 @@ pub fn drivers() -> DriverIterator {
// SDL_GetNumAudioDrivers can never return a negative value.
DriverIterator {
length: unsafe { sys::SDL_GetNumAudioDrivers() },
index: 0
index: 0,
}
}
@@ -285,7 +331,7 @@ pub struct AudioSpecWAV {
pub format: AudioFormat,
pub channels: u8,
audio_buf: *mut u8,
audio_len: u32
audio_len: u32,
}
impl AudioSpecWAV {
@@ -305,7 +351,13 @@ impl AudioSpecWAV {
let mut audio_buf: *mut u8 = null_mut();
let mut audio_len: u32 = 0;
unsafe {
let ret = sys::SDL_LoadWAV_RW(src.raw(), 0, desired.as_mut_ptr(), &mut audio_buf, &mut audio_len);
let ret = sys::SDL_LoadWAV_RW(
src.raw(),
0,
desired.as_mut_ptr(),
&mut audio_buf,
&mut audio_len,
);
if ret.is_null() {
Err(get_error())
} else {
@@ -315,7 +367,7 @@ impl AudioSpecWAV {
format: AudioFormat::from_ll(desired.format).unwrap(),
channels: desired.channels,
audio_buf,
audio_len
audio_len,
})
}
}
@@ -334,12 +386,15 @@ impl AudioSpecWAV {
impl Drop for AudioSpecWAV {
#[doc(alias = "SDL_FreeWAV")]
fn drop(&mut self) {
unsafe { sys::SDL_FreeWAV(self.audio_buf); }
unsafe {
sys::SDL_FreeWAV(self.audio_buf);
}
}
}
pub trait AudioCallback: Send
where Self::Channel: AudioFormatNum + 'static
where
Self::Channel: AudioFormatNum + 'static,
{
type Channel;
@@ -376,44 +431,59 @@ pub trait AudioFormatNum {
/// `AUDIO_S8`
impl AudioFormatNum for i8 {
fn audio_format() -> AudioFormat { AudioFormat::S8 }
fn audio_format() -> AudioFormat {
AudioFormat::S8
}
const SILENCE: i8 = 0;
}
/// `AUDIO_U8`
impl AudioFormatNum for u8 {
fn audio_format() -> AudioFormat { AudioFormat::U8 }
fn audio_format() -> AudioFormat {
AudioFormat::U8
}
const SILENCE: u8 = 0x80;
}
/// `AUDIO_S16`
impl AudioFormatNum for i16 {
fn audio_format() -> AudioFormat { AudioFormat::s16_sys() }
fn audio_format() -> AudioFormat {
AudioFormat::s16_sys()
}
const SILENCE: i16 = 0;
}
/// `AUDIO_U16`
impl AudioFormatNum for u16 {
fn audio_format() -> AudioFormat { AudioFormat::u16_sys() }
fn audio_format() -> AudioFormat {
AudioFormat::u16_sys()
}
const SILENCE: u16 = 0x8000;
}
/// `AUDIO_S32`
impl AudioFormatNum for i32 {
fn audio_format() -> AudioFormat { AudioFormat::s32_sys() }
fn audio_format() -> AudioFormat {
AudioFormat::s32_sys()
}
const SILENCE: i32 = 0;
}
/// `AUDIO_F32`
impl AudioFormatNum for f32 {
fn audio_format() -> AudioFormat { AudioFormat::f32_sys() }
fn audio_format() -> AudioFormat {
AudioFormat::f32_sys()
}
const SILENCE: f32 = 0.0;
}
extern "C" fn audio_callback_marshall<CB: AudioCallback>
(userdata: *mut c_void, stream: *mut u8, len: c_int) {
use std::slice::from_raw_parts_mut;
extern "C" fn audio_callback_marshall<CB: AudioCallback>(
userdata: *mut c_void,
stream: *mut u8,
len: c_int,
) {
use std::mem::size_of;
use std::slice::from_raw_parts_mut;
unsafe {
let cb_userdata: &mut Option<CB> = &mut *(userdata as *mut _);
let buf: &mut [CB::Channel] = from_raw_parts_mut(
stream as *mut CB::Channel,
len as usize / size_of::<CB::Channel>()
len as usize / size_of::<CB::Channel>(),
);
if let Some(cb) = cb_userdata {
@@ -433,21 +503,31 @@ pub struct AudioSpecDesired {
}
impl AudioSpecDesired {
fn convert_to_ll<CB, F, C, S>(freq: F, channels: C, samples: S, userdata: *mut Option<CB>) -> sys::SDL_AudioSpec
fn convert_to_ll<CB, F, C, S>(
freq: F,
channels: C,
samples: S,
userdata: *mut Option<CB>,
) -> sys::SDL_AudioSpec
where
CB: AudioCallback,
F: Into<Option<i32>>,
C: Into<Option<u8>>,
S: Into<Option<u16>>,
{
let freq = freq.into();
let channels = channels.into();
let samples = samples.into();
if let Some(freq) = freq { assert!(freq > 0); }
if let Some(channels) = channels { assert!(channels > 0); }
if let Some(samples) = samples { assert!(samples > 0); }
if let Some(freq) = freq {
assert!(freq > 0);
}
if let Some(channels) = channels {
assert!(channels > 0);
}
if let Some(samples) = samples {
assert!(samples > 0);
}
// A value of 0 means "fallback" or "default".
@@ -459,11 +539,10 @@ impl AudioSpecDesired {
samples: samples.unwrap_or(0),
padding: 0,
size: 0,
callback: Some(audio_callback_marshall::<CB>
as extern "C" fn
(arg1: *mut c_void,
arg2: *mut u8,
arg3: c_int)),
callback: Some(
audio_callback_marshall::<CB>
as extern "C" fn(arg1: *mut c_void, arg2: *mut u8, arg3: c_int),
),
userdata: userdata as *mut _,
}
}
@@ -473,15 +552,21 @@ impl AudioSpecDesired {
Channel: AudioFormatNum,
F: Into<Option<i32>>,
C: Into<Option<u8>>,
S: Into<Option<u16>>
S: Into<Option<u16>>,
{
let freq = freq.into();
let channels = channels.into();
let samples = samples.into();
if let Some(freq) = freq { assert!(freq > 0); }
if let Some(channels) = channels { assert!(channels > 0); }
if let Some(samples) = samples { assert!(samples > 0); }
if let Some(freq) = freq {
assert!(freq > 0);
}
if let Some(channels) = channels {
assert!(channels > 0);
}
if let Some(samples) = samples {
assert!(samples > 0);
}
// A value of 0 means "fallback" or "default".
@@ -511,7 +596,7 @@ pub struct AudioSpec {
/// trait.AudioFormatNum.html#associatedconstant.SILENCE) more useful.
pub silence: u8,
pub samples: u16,
pub size: u32
pub size: u32,
}
impl AudioSpec {
@@ -522,19 +607,19 @@ impl AudioSpec {
channels: spec.channels,
silence: spec.silence,
samples: spec.samples,
size: spec.size
size: spec.size,
}
}
}
enum AudioDeviceID {
PlaybackDevice(sys::SDL_AudioDeviceID)
PlaybackDevice(sys::SDL_AudioDeviceID),
}
impl AudioDeviceID {
fn id(&self) -> sys::SDL_AudioDeviceID {
match *self {
AudioDeviceID::PlaybackDevice(id) => id
AudioDeviceID::PlaybackDevice(id) => id,
}
}
}
@@ -558,16 +643,25 @@ pub struct AudioQueue<Channel: AudioFormatNum> {
impl<'a, Channel: AudioFormatNum> AudioQueue<Channel> {
/// Opens a new audio device given the desired parameters and callback.
#[doc(alias = "SDL_OpenAudioDevice")]
pub fn open_queue<D: Into<Option<&'a str>>>(a: &AudioSubsystem, device: D, spec: &AudioSpecDesired) -> Result<AudioQueue<Channel>, String> {
pub fn open_queue<D: Into<Option<&'a str>>>(
a: &AudioSubsystem,
device: D,
spec: &AudioSpecDesired,
) -> Result<AudioQueue<Channel>, String> {
use std::mem::MaybeUninit;
let desired = AudioSpecDesired::convert_queue_to_ll::<Channel, Option<i32>, Option<u8>, Option<u16>>(spec.freq, spec.channels, spec.samples);
let desired = AudioSpecDesired::convert_queue_to_ll::<
Channel,
Option<i32>,
Option<u8>,
Option<u16>,
>(spec.freq, spec.channels, spec.samples);
let mut obtained = MaybeUninit::uninit();
unsafe {
let device = match device.into() {
Some(device) => Some(CString::new(device).unwrap()),
None => None
None => None,
};
// Warning: map_or consumes its argument; `device.map_or()` would therefore consume the
// CString and drop it, making device_ptr a dangling pointer! To avoid that we downgrade
@@ -576,13 +670,14 @@ impl<'a, Channel: AudioFormatNum> AudioQueue<Channel> {
let iscapture_flag = 0;
let device_id = sys::SDL_OpenAudioDevice(
device_ptr as *const c_char, iscapture_flag, &desired,
obtained.as_mut_ptr(), 0
device_ptr as *const c_char,
iscapture_flag,
&desired,
obtained.as_mut_ptr(),
0,
);
match device_id {
0 => {
Err(get_error())
},
0 => Err(get_error()),
id => {
let obtained = obtained.assume_init();
let device_id = AudioDeviceID::PlaybackDevice(id);
@@ -601,10 +696,14 @@ impl<'a, Channel: AudioFormatNum> AudioQueue<Channel> {
#[inline]
#[doc(alias = "SDL_GetAudioDeviceStatus")]
pub fn subsystem(&self) -> &AudioSubsystem { &self.subsystem }
pub fn subsystem(&self) -> &AudioSubsystem {
&self.subsystem
}
#[inline]
pub fn spec(&self) -> &AudioSpec { &self.spec }
pub fn spec(&self) -> &AudioSpec {
&self.spec
}
pub fn status(&self) -> AudioStatus {
unsafe {
@@ -628,19 +727,27 @@ impl<'a, Channel: AudioFormatNum> AudioQueue<Channel> {
/// Adds data to the audio queue.
#[doc(alias = "SDL_QueueAudio")]
pub fn queue(&self, data: &[Channel]) -> bool {
let result = unsafe {sys::SDL_QueueAudio(self.device_id.id(), data.as_ptr() as *const c_void, (data.len() * mem::size_of::<Channel>()) as u32)};
let result = unsafe {
sys::SDL_QueueAudio(
self.device_id.id(),
data.as_ptr() as *const c_void,
(data.len() * mem::size_of::<Channel>()) as u32,
)
};
result == 0
}
#[doc(alias = "SDL_GetQueuedAudioSize")]
pub fn size(&self) -> u32 {
unsafe {sys::SDL_GetQueuedAudioSize(self.device_id.id())}
unsafe { sys::SDL_GetQueuedAudioSize(self.device_id.id()) }
}
/// Clears all data from the current audio queue.
#[doc(alias = "SDL_ClearQueuedAudio")]
pub fn clear(&self) {
unsafe {sys::SDL_ClearQueuedAudio(self.device_id.id());}
unsafe {
sys::SDL_ClearQueuedAudio(self.device_id.id());
}
}
}
@@ -650,13 +757,19 @@ pub struct AudioDevice<CB: AudioCallback> {
device_id: AudioDeviceID,
spec: AudioSpec,
/// Store the callback to keep it alive for the entire duration of `AudioDevice`.
userdata: Box<Option<CB>>
userdata: Box<Option<CB>>,
}
impl<CB: AudioCallback> AudioDevice<CB> {
/// Opens a new audio device for playback or capture (given the desired parameters and callback).
#[doc(alias = "SDL_OpenAudioDevice")]
fn open<'a, F, D>(a: &AudioSubsystem, device: D, spec: &AudioSpecDesired, get_callback: F, capture: bool) -> Result<AudioDevice <CB>, String>
fn open<'a, F, D>(
a: &AudioSubsystem,
device: D,
spec: &AudioSpecDesired,
get_callback: F,
capture: bool,
) -> Result<AudioDevice<CB>, String>
where
F: FnOnce(AudioSpec) -> CB,
D: Into<Option<&'a str>>,
@@ -664,13 +777,14 @@ impl<CB: AudioCallback> AudioDevice<CB> {
use std::mem::MaybeUninit;
let mut userdata: Box<Option<CB>> = Box::new(None);
let desired = AudioSpecDesired::convert_to_ll(spec.freq, spec.channels, spec.samples, &mut *userdata);
let desired =
AudioSpecDesired::convert_to_ll(spec.freq, spec.channels, spec.samples, &mut *userdata);
let mut obtained = MaybeUninit::uninit();
unsafe {
let device = match device.into() {
Some(device) => Some(CString::new(device).unwrap()),
None => None
None => None,
};
// Warning: map_or consumes its argument; `device.map_or()` would therefore consume the
// CString and drop it, making device_ptr a dangling pointer! To avoid that we downgrade
@@ -679,13 +793,14 @@ impl<CB: AudioCallback> AudioDevice<CB> {
let iscapture_flag = if capture { 1 } else { 0 };
let device_id = sys::SDL_OpenAudioDevice(
device_ptr as *const c_char, iscapture_flag, &desired,
obtained.as_mut_ptr(), 0
device_ptr as *const c_char,
iscapture_flag,
&desired,
obtained.as_mut_ptr(),
0,
);
match device_id {
0 => {
Err(get_error())
},
0 => Err(get_error()),
id => {
let obtained = obtained.assume_init();
let device_id = AudioDeviceID::PlaybackDevice(id);
@@ -708,10 +823,15 @@ impl<CB: AudioCallback> AudioDevice<CB> {
///
/// If you want to modify the callback-owned data at a later point (for example to update
/// its data buffer) you're likely to be interested in the [lock method](#method.lock).
pub fn open_playback<'a, F, D>(a: &AudioSubsystem, device: D, spec: &AudioSpecDesired, get_callback: F) -> Result<AudioDevice <CB>, String>
where
F: FnOnce(AudioSpec) -> CB,
D: Into<Option<&'a str>>,
pub fn open_playback<'a, F, D>(
a: &AudioSubsystem,
device: D,
spec: &AudioSpecDesired,
get_callback: F,
) -> Result<AudioDevice<CB>, String>
where
F: FnOnce(AudioSpec) -> CB,
D: Into<Option<&'a str>>,
{
AudioDevice::open(a, device, spec, get_callback, false)
}
@@ -721,20 +841,29 @@ impl<CB: AudioCallback> AudioDevice<CB> {
///
/// If you want to modify the callback-owned data at a later point (for example to update
/// its data buffer) you're likely to be interested in the [lock method](#method.lock).
pub fn open_capture<'a, F, D>(a: &AudioSubsystem, device: D, spec: &AudioSpecDesired, get_callback: F) -> Result<AudioDevice <CB>, String>
where
F: FnOnce(AudioSpec) -> CB,
D: Into<Option<&'a str>>,
pub fn open_capture<'a, F, D>(
a: &AudioSubsystem,
device: D,
spec: &AudioSpecDesired,
get_callback: F,
) -> Result<AudioDevice<CB>, String>
where
F: FnOnce(AudioSpec) -> CB,
D: Into<Option<&'a str>>,
{
AudioDevice::open(a, device, spec, get_callback, true)
}
#[inline]
#[doc(alias = "SDL_GetAudioDeviceStatus")]
pub fn subsystem(&self) -> &AudioSubsystem { &self.subsystem }
pub fn subsystem(&self) -> &AudioSubsystem {
&self.subsystem
}
#[inline]
pub fn spec(&self) -> &AudioSpec { &self.spec }
pub fn spec(&self) -> &AudioSpec {
&self.spec
}
pub fn status(&self) -> AudioStatus {
unsafe {
@@ -764,8 +893,8 @@ impl<CB: AudioCallback> AudioDevice<CB> {
pub fn lock(&mut self) -> AudioDeviceLockGuard<CB> {
unsafe { sys::SDL_LockAudioDevice(self.device_id.id()) };
AudioDeviceLockGuard {
device: self,
_nosend: PhantomData
device: self,
_nosend: PhantomData,
}
}
@@ -780,19 +909,27 @@ impl<CB: AudioCallback> AudioDevice<CB> {
}
/// Similar to `std::sync::MutexGuard`, but for use with `AudioDevice::lock()`.
pub struct AudioDeviceLockGuard<'a, CB> where CB: AudioCallback, CB: 'a {
pub struct AudioDeviceLockGuard<'a, CB>
where
CB: AudioCallback,
CB: 'a,
{
device: &'a mut AudioDevice<CB>,
_nosend: PhantomData<*mut ()>
_nosend: PhantomData<*mut ()>,
}
impl<'a, CB: AudioCallback> Deref for AudioDeviceLockGuard<'a, CB> {
type Target = CB;
#[doc(alias = "SDL_UnlockAudioDevice")]
fn deref(&self) -> &CB { (*self.device.userdata).as_ref().expect("Missing callback") }
fn deref(&self) -> &CB {
(*self.device.userdata).as_ref().expect("Missing callback")
}
}
impl<'a, CB: AudioCallback> DerefMut for AudioDeviceLockGuard<'a, CB> {
fn deref_mut(&mut self) -> &mut CB { (*self.device.userdata).as_mut().expect("Missing callback") }
fn deref_mut(&mut self) -> &mut CB {
(*self.device.userdata).as_mut().expect("Missing callback")
}
}
impl<'a, CB: AudioCallback> Drop for AudioDeviceLockGuard<'a, CB> {
@@ -803,22 +940,33 @@ impl<'a, CB: AudioCallback> Drop for AudioDeviceLockGuard<'a, CB> {
#[derive(Copy, Clone)]
pub struct AudioCVT {
raw: sys::SDL_AudioCVT
raw: sys::SDL_AudioCVT,
}
impl AudioCVT {
#[doc(alias = "SDL_BuildAudioCVT")]
pub fn new(src_format: AudioFormat, src_channels: u8, src_rate: i32,
dst_format: AudioFormat, dst_channels: u8, dst_rate: i32) -> Result<AudioCVT, String>
{
pub fn new(
src_format: AudioFormat,
src_channels: u8,
src_rate: i32,
dst_format: AudioFormat,
dst_channels: u8,
dst_rate: i32,
) -> Result<AudioCVT, String> {
use std::mem::MaybeUninit;
let mut raw: MaybeUninit<sys::SDL_AudioCVT> = mem::MaybeUninit::uninit();
unsafe {
let ret = sys::SDL_BuildAudioCVT(raw.as_mut_ptr(),
src_format.to_ll(), src_channels, src_rate as c_int,
dst_format.to_ll(), dst_channels, dst_rate as c_int);
let ret = sys::SDL_BuildAudioCVT(
raw.as_mut_ptr(),
src_format.to_ll(),
src_channels,
src_rate as c_int,
dst_format.to_ll(),
dst_channels,
dst_rate as c_int,
);
if ret == 1 || ret == 0 {
let raw = raw.assume_init();
Ok(AudioCVT { raw })
@@ -852,7 +1000,9 @@ impl AudioCVT {
let ret = sys::SDL_ConvertAudio(&mut raw);
// There's no reason for SDL_ConvertAudio to fail.
// The only time it can fail is if buf is NULL, which it never is.
if ret != 0 { panic!(get_error()) }
if ret != 0 {
panic!(get_error())
}
// return original buffer back to caller
debug_assert!(raw.len_cvt > 0);
@@ -869,16 +1019,19 @@ impl AudioCVT {
/// Checks if any conversion is needed. i.e. if the buffer that goes
/// into `convert()` is unchanged from the result.
pub fn is_conversion_needed(&self) -> bool { self.raw.needed != 0 }
pub fn is_conversion_needed(&self) -> bool {
self.raw.needed != 0
}
/// Gets the buffer capacity that can contain both the original and
/// converted data.
pub fn capacity(&self, src_len: usize) -> usize {
src_len.checked_mul(self.raw.len_mult as usize).expect("Integer overflow")
src_len
.checked_mul(self.raw.len_mult as usize)
.expect("Integer overflow")
}
}
#[cfg(test)]
mod test {
use super::{AudioCVT, AudioFormat};
@@ -897,10 +1050,17 @@ mod test {
assert!(cvt.is_conversion_needed());
// since we're going from mono to stereo, our capacity must be at least twice the original (255) vec size
assert!(cvt.capacity(255) >= 255*2, "capacity must be able to hold the converted audio sample");
assert!(
cvt.capacity(255) >= 255 * 2,
"capacity must be able to hold the converted audio sample"
);
let new_buffer = cvt.convert(buffer);
assert_eq!(new_buffer.len(), new_buffer_expected.len(), "capacity must be exactly equal to twice the original vec size");
assert_eq!(
new_buffer.len(),
new_buffer_expected.len(),
"capacity must be exactly equal to twice the original vec size"
);
// // this has been commented, see https://discourse.libsdl.org/t/change-of-behavior-in-audiocvt-sdl-convertaudio-from-2-0-5-to-2-0-6/24682
// // to maybe re-enable it someday

View File

@@ -1,7 +1,7 @@
use std::ffi::{CString, CStr};
use libc::c_void;
use libc::c_char;
use crate::get_error;
use libc::c_char;
use libc::c_void;
use std::ffi::{CStr, CString};
use crate::sys;
@@ -16,14 +16,14 @@ use crate::sys;
/// video_subsystem.clipboard().set_clipboard_text("Hello World!").unwrap();
/// ```
pub struct ClipboardUtil {
_subsystem: crate::VideoSubsystem
_subsystem: crate::VideoSubsystem,
}
impl crate::VideoSubsystem {
#[inline]
pub fn clipboard(&self) -> ClipboardUtil {
ClipboardUtil {
_subsystem: self.clone()
_subsystem: self.clone(),
}
}
}

View File

@@ -6,11 +6,10 @@ use std::fmt;
#[derive(Debug, Clone, PartialEq)]
pub enum IntegerOrSdlError {
IntegerOverflows(&'static str, u32),
SdlError(String)
SdlError(String),
}
/// Validates and converts the given u32 to a positive C integer.
pub fn validate_int(value: u32, name: &'static str)
-> Result<::libc::c_int, IntegerOrSdlError> {
pub fn validate_int(value: u32, name: &'static str) -> Result<::libc::c_int, IntegerOrSdlError> {
use self::IntegerOrSdlError::*;
// Many SDL functions will accept `int` values, even if it doesn't make sense
// for the values to be negative.

View File

@@ -1,15 +1,15 @@
use crate::rwops::RWops;
use libc::c_char;
use std::error;
use std::ffi::{CString, CStr, NulError};
use std::ffi::{CStr, CString, NulError};
use std::fmt;
use std::io;
use std::path::Path;
use crate::rwops::RWops;
use crate::GameControllerSubsystem;
use crate::common::{validate_int, IntegerOrSdlError};
use crate::get_error;
use crate::joystick;
use crate::common::{validate_int, IntegerOrSdlError};
use crate::GameControllerSubsystem;
use std::mem::transmute;
use crate::sys;
@@ -66,8 +66,10 @@ impl GameControllerSubsystem {
#[doc(alias = "SDL_IsGameController")]
pub fn is_game_controller(&self, joystick_index: u32) -> bool {
match validate_int(joystick_index, "joystick_index") {
Ok(joystick_index) => unsafe { sys::SDL_IsGameController(joystick_index) != sys::SDL_bool::SDL_FALSE },
Err(_) => false
Ok(joystick_index) => unsafe {
sys::SDL_IsGameController(joystick_index) != sys::SDL_bool::SDL_FALSE
},
Err(_) => false,
}
}
@@ -85,7 +87,7 @@ impl GameControllerSubsystem {
} else {
Ok(GameController {
subsystem: self.clone(),
raw: controller
raw: controller,
})
}
}
@@ -101,7 +103,10 @@ impl GameControllerSubsystem {
Err(SdlError(get_error()))
} else {
Ok(unsafe {
CStr::from_ptr(c_str as *const _).to_str().unwrap().to_owned()
CStr::from_ptr(c_str as *const _)
.to_str()
.unwrap()
.to_owned()
})
}
}
@@ -116,21 +121,22 @@ impl GameControllerSubsystem {
/// Return `true` if controller events are processed.
#[doc(alias = "SDL_GameControllerEventState")]
pub fn event_state(&self) -> bool {
unsafe { sys::SDL_GameControllerEventState(sys::SDL_QUERY as i32)
== sys::SDL_ENABLE as i32 }
unsafe {
sys::SDL_GameControllerEventState(sys::SDL_QUERY as i32) == sys::SDL_ENABLE as i32
}
}
/// Add a new controller input mapping from a mapping string.
#[doc(alias = "SDL_GameControllerAddMapping")]
pub fn add_mapping(&self, mapping: &str)
-> Result<MappingStatus, AddMappingError> {
pub fn add_mapping(&self, mapping: &str) -> Result<MappingStatus, AddMappingError> {
use self::AddMappingError::*;
let mapping = match CString::new(mapping) {
Ok(s) => s,
Err(err) => return Err(InvalidMapping(err)),
};
let result = unsafe { sys::SDL_GameControllerAddMapping(mapping.as_ptr() as *const c_char) };
let result =
unsafe { sys::SDL_GameControllerAddMapping(mapping.as_ptr() as *const c_char) };
match result {
1 => Ok(MappingStatus::Added),
@@ -189,11 +195,11 @@ impl GameControllerSubsystem {
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
#[repr(i32)]
pub enum Axis {
LeftX = sys::SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_LEFTX as i32,
LeftY = sys::SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_LEFTY as i32,
RightX = sys::SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_RIGHTX as i32,
RightY = sys::SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_RIGHTY as i32,
TriggerLeft = sys::SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_TRIGGERLEFT as i32,
LeftX = sys::SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_LEFTX as i32,
LeftY = sys::SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_LEFTY as i32,
RightX = sys::SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_RIGHTX as i32,
RightY = sys::SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_RIGHTY as i32,
TriggerLeft = sys::SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_TRIGGERLEFT as i32,
TriggerRight = sys::SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_TRIGGERRIGHT as i32,
}
@@ -203,9 +209,11 @@ impl Axis {
#[doc(alias = "SDL_GameControllerGetAxisFromString")]
pub fn from_string(axis: &str) -> Option<Axis> {
let id = match CString::new(axis) {
Ok(axis) => unsafe { sys::SDL_GameControllerGetAxisFromString(axis.as_ptr() as *const c_char) },
Ok(axis) => unsafe {
sys::SDL_GameControllerGetAxisFromString(axis.as_ptr() as *const c_char)
},
// string contains a nul byte - it won't match anything.
Err(_) => sys::SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_INVALID
Err(_) => sys::SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_INVALID,
};
Axis::from_ll(id)
@@ -216,7 +224,9 @@ impl Axis {
#[doc(alias = "SDL_GameControllerGetStringForAxis")]
pub fn string(self) -> String {
let axis: sys::SDL_GameControllerAxis;
unsafe { axis = transmute(self); }
unsafe {
axis = transmute(self);
}
let string = unsafe { sys::SDL_GameControllerGetStringForAxis(axis) };
@@ -225,14 +235,14 @@ impl Axis {
pub fn from_ll(bitflags: sys::SDL_GameControllerAxis) -> Option<Axis> {
Some(match bitflags {
sys::SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_INVALID => return None,
sys::SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_LEFTX => Axis::LeftX,
sys::SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_LEFTY => Axis::LeftY,
sys::SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_RIGHTX => Axis::RightX,
sys::SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_RIGHTY => Axis::RightY,
sys::SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_TRIGGERLEFT => Axis::TriggerLeft,
sys::SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_INVALID => return None,
sys::SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_LEFTX => Axis::LeftX,
sys::SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_LEFTY => Axis::LeftY,
sys::SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_RIGHTX => Axis::RightX,
sys::SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_RIGHTY => Axis::RightY,
sys::SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_TRIGGERLEFT => Axis::TriggerLeft,
sys::SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_TRIGGERRIGHT => Axis::TriggerRight,
_ => panic!("unhandled controller axis")
_ => panic!("unhandled controller axis"),
})
}
@@ -251,21 +261,21 @@ impl Axis {
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
#[repr(i32)]
pub enum Button {
A = sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_A as i32,
B = sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_B as i32,
X = sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_X as i32,
Y = sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_Y as i32,
Back = sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_BACK as i32,
Guide = sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_GUIDE as i32,
Start = sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_START as i32,
LeftStick = sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_LEFTSTICK as i32,
RightStick = sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_RIGHTSTICK as i32,
LeftShoulder = sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_LEFTSHOULDER as i32,
A = sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_A as i32,
B = sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_B as i32,
X = sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_X as i32,
Y = sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_Y as i32,
Back = sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_BACK as i32,
Guide = sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_GUIDE as i32,
Start = sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_START as i32,
LeftStick = sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_LEFTSTICK as i32,
RightStick = sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_RIGHTSTICK as i32,
LeftShoulder = sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_LEFTSHOULDER as i32,
RightShoulder = sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_RIGHTSHOULDER as i32,
DPadUp = sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_UP as i32,
DPadDown = sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_DOWN as i32,
DPadLeft = sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_LEFT as i32,
DPadRight = sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_RIGHT as i32,
DPadUp = sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_UP as i32,
DPadDown = sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_DOWN as i32,
DPadLeft = sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_LEFT as i32,
DPadRight = sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_RIGHT as i32,
}
impl Button {
@@ -274,9 +284,11 @@ impl Button {
#[doc(alias = "SDL_GameControllerGetButtonFromString")]
pub fn from_string(button: &str) -> Option<Button> {
let id = match CString::new(button) {
Ok(button) => unsafe { sys::SDL_GameControllerGetButtonFromString(button.as_ptr() as *const c_char) },
Ok(button) => unsafe {
sys::SDL_GameControllerGetButtonFromString(button.as_ptr() as *const c_char)
},
// string contains a nul byte - it won't match anything.
Err(_) => sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_INVALID
Err(_) => sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_INVALID,
};
Button::from_ll(id)
@@ -287,7 +299,9 @@ impl Button {
#[doc(alias = "SDL_GameControllerGetStringForButton")]
pub fn string(self) -> String {
let button: sys::SDL_GameControllerButton;
unsafe { button = transmute(self); }
unsafe {
button = transmute(self);
}
let string = unsafe { sys::SDL_GameControllerGetStringForButton(button) };
@@ -296,43 +310,51 @@ impl Button {
pub fn from_ll(bitflags: sys::SDL_GameControllerButton) -> Option<Button> {
Some(match bitflags {
sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_INVALID => return None,
sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_A => Button::A,
sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_B => Button::B,
sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_X => Button::X,
sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_Y => Button::Y,
sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_BACK => Button::Back,
sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_GUIDE => Button::Guide,
sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_START => Button::Start,
sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_LEFTSTICK => Button::LeftStick,
sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_RIGHTSTICK => Button::RightStick,
sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_LEFTSHOULDER => Button::LeftShoulder,
sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_RIGHTSHOULDER => Button::RightShoulder,
sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_UP => Button::DPadUp,
sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_DOWN => Button::DPadDown,
sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_LEFT => Button::DPadLeft,
sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_RIGHT => Button::DPadRight,
_ => panic!("unhandled controller button")
sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_INVALID => return None,
sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_A => Button::A,
sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_B => Button::B,
sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_X => Button::X,
sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_Y => Button::Y,
sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_BACK => Button::Back,
sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_GUIDE => Button::Guide,
sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_START => Button::Start,
sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_LEFTSTICK => Button::LeftStick,
sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_RIGHTSTICK => Button::RightStick,
sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_LEFTSHOULDER => {
Button::LeftShoulder
}
sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_RIGHTSHOULDER => {
Button::RightShoulder
}
sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_UP => Button::DPadUp,
sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_DOWN => Button::DPadDown,
sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_LEFT => Button::DPadLeft,
sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_RIGHT => Button::DPadRight,
_ => panic!("unhandled controller button"),
})
}
pub fn to_ll(self) -> sys::SDL_GameControllerButton {
match self {
Button::A => sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_A,
Button::B => sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_B,
Button::X => sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_X,
Button::Y => sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_Y,
Button::Back => sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_BACK,
Button::Guide => sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_GUIDE,
Button::Start => sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_START,
Button::LeftStick => sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_LEFTSTICK,
Button::RightStick => sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_RIGHTSTICK,
Button::LeftShoulder => sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_LEFTSHOULDER,
Button::RightShoulder => sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_RIGHTSHOULDER,
Button::DPadUp => sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_UP,
Button::DPadDown => sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_DOWN,
Button::DPadLeft => sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_LEFT,
Button::DPadRight => sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_RIGHT,
Button::A => sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_A,
Button::B => sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_B,
Button::X => sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_X,
Button::Y => sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_Y,
Button::Back => sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_BACK,
Button::Guide => sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_GUIDE,
Button::Start => sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_START,
Button::LeftStick => sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_LEFTSTICK,
Button::RightStick => sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_RIGHTSTICK,
Button::LeftShoulder => {
sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_LEFTSHOULDER
}
Button::RightShoulder => {
sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_RIGHTSHOULDER
}
Button::DPadUp => sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_UP,
Button::DPadDown => sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_DOWN,
Button::DPadLeft => sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_LEFT,
Button::DPadRight => sys::SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_RIGHT,
}
}
}
@@ -340,19 +362,21 @@ impl Button {
/// Possible return values for `add_mapping`
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum MappingStatus {
Added = 1,
Added = 1,
Updated = 0,
}
/// Wrapper around the `SDL_GameController` object
pub struct GameController {
subsystem: GameControllerSubsystem,
raw: *mut sys::SDL_GameController
raw: *mut sys::SDL_GameController,
}
impl GameController {
#[inline]
pub fn subsystem(&self) -> &GameControllerSubsystem { &self.subsystem }
pub fn subsystem(&self) -> &GameControllerSubsystem {
&self.subsystem
}
/// Return the name of the controller or an empty string if no
/// name is found.
@@ -383,8 +407,8 @@ impl GameController {
#[doc(alias = "SDL_GameControllerGetJoystick")]
pub fn instance_id(&self) -> u32 {
let result = unsafe {
let joystick = sys::SDL_GameControllerGetJoystick(self.raw);
sys::SDL_JoystickInstanceID(joystick)
let joystick = sys::SDL_GameControllerGetJoystick(self.raw);
sys::SDL_JoystickInstanceID(joystick)
};
if result < 0 {
@@ -404,7 +428,9 @@ impl GameController {
// There should be no apparent reason for this to change in the future.
let raw_axis: sys::SDL_GameControllerAxis;
unsafe { raw_axis = transmute(axis); }
unsafe {
raw_axis = transmute(axis);
}
unsafe { sys::SDL_GameControllerGetAxis(self.raw, raw_axis) }
}
@@ -418,7 +444,9 @@ impl GameController {
// There should be no apparent reason for this to change in the future.
let raw_button: sys::SDL_GameControllerButton;
unsafe { raw_button = transmute(button); }
unsafe {
raw_button = transmute(button);
}
unsafe { sys::SDL_GameControllerGetButton(self.raw, raw_button) != 0 }
}
@@ -435,17 +463,19 @@ impl GameController {
/// the effect ending immediately after starting due to an overflow.
/// Use some smaller, "huge enough" number instead.
#[doc(alias = "SDL_GameControllerRumble")]
pub fn set_rumble(&mut self,
low_frequency_rumble: u16,
high_frequency_rumble: u16,
duration_ms: u32)
-> Result<(), IntegerOrSdlError>
{
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)
sys::SDL_GameControllerRumble(
self.raw,
low_frequency_rumble,
high_frequency_rumble,
duration_ms,
)
};
if result != 0 {
@@ -470,7 +500,10 @@ fn c_str_to_string(c_str: *const c_char) -> String {
String::new()
} else {
unsafe {
CStr::from_ptr(c_str as *const _).to_str().unwrap().to_owned()
CStr::from_ptr(c_str as *const _)
.to_str()
.unwrap()
.to_owned()
}
}
}
@@ -482,7 +515,10 @@ fn c_str_to_string_or_err(c_str: *const c_char) -> Result<String, String> {
Err(get_error())
} else {
Ok(unsafe {
CStr::from_ptr(c_str as *const _).to_str().unwrap().to_owned()
CStr::from_ptr(c_str as *const _)
.to_str()
.unwrap()
.to_owned()
})
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +1,9 @@
use crate::get_error;
use libc::c_char;
use libc::c_void;
use std::error;
use std::ffi::{CStr, CString, NulError};
use std::fmt;
use libc::c_void;
use crate::get_error;
use libc::c_char;
use crate::sys;
@@ -37,7 +37,7 @@ impl fmt::Display for PrefPathError {
match *self {
InvalidOrganizationName(ref e) => write!(f, "Invalid organization name: {}", e),
InvalidApplicationName(ref e) => write!(f, "Invalid application name: {}", e),
SdlError(ref e) => write!(f, "SDL error: {}", e)
SdlError(ref e) => write!(f, "SDL error: {}", e),
}
}
}
@@ -58,8 +58,7 @@ impl error::Error for PrefPathError {
/// Return the preferred directory for the application to write files on this
/// system, based on the given organization and application name.
#[doc(alias = "SDL_GetPrefPath")]
pub fn pref_path(org_name: &str, app_name: &str)
-> Result<String, PrefPathError> {
pub fn pref_path(org_name: &str, app_name: &str) -> Result<String, PrefPathError> {
use self::PrefPathError::*;
let result = unsafe {
let org = match CString::new(org_name) {
@@ -67,10 +66,11 @@ pub fn pref_path(org_name: &str, app_name: &str)
Err(err) => return Err(InvalidOrganizationName(err)),
};
let app = match CString::new(app_name) {
Ok(s) =>s,
Ok(s) => s,
Err(err) => return Err(InvalidApplicationName(err)),
};
let buf = sys::SDL_GetPrefPath(org.as_ptr() as *const c_char, app.as_ptr() as *const c_char);
let buf =
sys::SDL_GetPrefPath(org.as_ptr() as *const c_char, app.as_ptr() as *const c_char);
CStr::from_ptr(buf as *const _).to_str().unwrap().to_owned()
};

View File

@@ -1,9 +1,9 @@
//! Framerate control
use get_error;
use libc;
use libc::{c_void, size_t};
use std::mem;
use ::get_error;
use sys::gfx;
/// Structure holding the state and timing information of the framerate controller.
@@ -27,7 +27,7 @@ impl FPSManager {
let ret = unsafe { gfx::framerate::SDL_setFramerate(self.raw, rate as u32) };
match ret {
0 => Ok(()),
_ => Err(get_error())
_ => Err(get_error()),
}
}

View File

@@ -1,9 +1,9 @@
//! MMX image filters
use std::mem;
use libc::{self,size_t, c_void, c_uint, c_int};
use ::get_error;
use c_vec::CVec;
use get_error;
use libc::{self, c_int, c_uint, c_void, size_t};
use std::mem;
use sys::gfx::imagefilter;
/// MMX detection routine (with override flag).
@@ -25,9 +25,7 @@ pub fn mmx_on() {
fn cvec_with_size(sz: usize) -> CVec<u8> {
unsafe {
let p = libc::malloc(sz as size_t) as *mut u8;
CVec::new_with_dtor(p, sz, move |p| {
libc::free(p as *mut c_void)
})
CVec::new_with_dtor(p, sz, move |p| libc::free(p as *mut c_void))
}
}
@@ -36,12 +34,19 @@ pub fn add(src1: CVec<u8>, src2: CVec<u8>) -> Result<CVec<u8>, String> {
assert_eq!(src1.len(), src2.len());
let size = src1.len();
let dest = cvec_with_size(size);
let ret = unsafe { imagefilter::SDL_imageFilterAdd(mem::transmute(src1.get(0)),
mem::transmute(src2.get(0)),
mem::transmute(dest.get(0)),
size as c_uint) };
if ret == 0 { Ok(dest) }
else { Err(get_error()) }
let ret = unsafe {
imagefilter::SDL_imageFilterAdd(
mem::transmute(src1.get(0)),
mem::transmute(src2.get(0)),
mem::transmute(dest.get(0)),
size as c_uint,
)
};
if ret == 0 {
Ok(dest)
} else {
Err(get_error())
}
}
/// Filter using Mean: D = S1/2 + S2/2.
@@ -49,12 +54,19 @@ pub fn mean(src1: CVec<u8>, src2: CVec<u8>) -> Result<CVec<u8>, String> {
assert_eq!(src1.len(), src2.len());
let size = src1.len();
let dest = cvec_with_size(size);
let ret = unsafe { imagefilter::SDL_imageFilterMean(mem::transmute(src1.get(0)),
mem::transmute(src2.get(0)),
mem::transmute(dest.get(0)),
size as c_uint) };
if ret == 0 { Ok(dest) }
else { Err(get_error()) }
let ret = unsafe {
imagefilter::SDL_imageFilterMean(
mem::transmute(src1.get(0)),
mem::transmute(src2.get(0)),
mem::transmute(dest.get(0)),
size as c_uint,
)
};
if ret == 0 {
Ok(dest)
} else {
Err(get_error())
}
}
/// Filter using Sub: D = saturation0(S1 - S2).
@@ -62,12 +74,19 @@ pub fn sub(src1: CVec<u8>, src2: CVec<u8>) -> Result<CVec<u8>, String> {
assert_eq!(src1.len(), src2.len());
let size = src1.len();
let dest = cvec_with_size(size);
let ret = unsafe { imagefilter::SDL_imageFilterSub(mem::transmute(src1.get(0)),
mem::transmute(src2.get(0)),
mem::transmute(dest.get(0)),
size as c_uint) };
if ret == 0 { Ok(dest) }
else { Err(get_error()) }
let ret = unsafe {
imagefilter::SDL_imageFilterSub(
mem::transmute(src1.get(0)),
mem::transmute(src2.get(0)),
mem::transmute(dest.get(0)),
size as c_uint,
)
};
if ret == 0 {
Ok(dest)
} else {
Err(get_error())
}
}
/// Filter using `AbsDiff`: D = | S1 - S2 |.
@@ -75,12 +94,19 @@ pub fn abs_diff(src1: CVec<u8>, src2: CVec<u8>) -> Result<CVec<u8>, String> {
assert_eq!(src1.len(), src2.len());
let size = src1.len();
let dest = cvec_with_size(size);
let ret = unsafe { imagefilter::SDL_imageFilterAbsDiff(mem::transmute(src1.get(0)),
mem::transmute(src2.get(0)),
mem::transmute(dest.get(0)),
size as c_uint) };
if ret == 0 { Ok(dest) }
else { Err(get_error()) }
let ret = unsafe {
imagefilter::SDL_imageFilterAbsDiff(
mem::transmute(src1.get(0)),
mem::transmute(src2.get(0)),
mem::transmute(dest.get(0)),
size as c_uint,
)
};
if ret == 0 {
Ok(dest)
} else {
Err(get_error())
}
}
/// Filter using Mult: D = saturation255(S1 * S2).
@@ -88,12 +114,19 @@ pub fn mult(src1: CVec<u8>, src2: CVec<u8>) -> Result<CVec<u8>, String> {
assert_eq!(src1.len(), src2.len());
let size = src1.len();
let dest = cvec_with_size(size);
let ret = unsafe { imagefilter::SDL_imageFilterMult(mem::transmute(src1.get(0)),
mem::transmute(src2.get(0)),
mem::transmute(dest.get(0)),
size as c_uint) };
if ret == 0 { Ok(dest) }
else { Err(get_error()) }
let ret = unsafe {
imagefilter::SDL_imageFilterMult(
mem::transmute(src1.get(0)),
mem::transmute(src2.get(0)),
mem::transmute(dest.get(0)),
size as c_uint,
)
};
if ret == 0 {
Ok(dest)
} else {
Err(get_error())
}
}
/// Filter using `MultNor`: D = S1 * S2.
@@ -101,12 +134,19 @@ pub fn mult_nor(src1: CVec<u8>, src2: CVec<u8>) -> Result<CVec<u8>, String> {
assert_eq!(src1.len(), src2.len());
let size = src1.len();
let dest = cvec_with_size(size);
let ret = unsafe { imagefilter::SDL_imageFilterMultNor(mem::transmute(src1.get(0)),
mem::transmute(src2.get(0)),
mem::transmute(dest.get(0)),
size as c_uint) };
if ret == 0 { Ok(dest) }
else { Err(get_error()) }
let ret = unsafe {
imagefilter::SDL_imageFilterMultNor(
mem::transmute(src1.get(0)),
mem::transmute(src2.get(0)),
mem::transmute(dest.get(0)),
size as c_uint,
)
};
if ret == 0 {
Ok(dest)
} else {
Err(get_error())
}
}
/// Filter using `MultDivby2`: D = saturation255(S1/2 * S2).
@@ -114,12 +154,19 @@ pub fn mult_div_by2(src1: CVec<u8>, src2: CVec<u8>) -> Result<CVec<u8>, String>
assert_eq!(src1.len(), src2.len());
let size = src1.len();
let dest = cvec_with_size(size);
let ret = unsafe { imagefilter::SDL_imageFilterMultDivby2(mem::transmute(src1.get(0)),
mem::transmute(src2.get(0)),
mem::transmute(dest.get(0)),
size as c_uint) };
if ret == 0 { Ok(dest) }
else { Err(get_error()) }
let ret = unsafe {
imagefilter::SDL_imageFilterMultDivby2(
mem::transmute(src1.get(0)),
mem::transmute(src2.get(0)),
mem::transmute(dest.get(0)),
size as c_uint,
)
};
if ret == 0 {
Ok(dest)
} else {
Err(get_error())
}
}
/// Filter using `MultDivby4`: D = saturation255(S1/2 * S2/2).
@@ -127,12 +174,19 @@ pub fn mult_div_by4(src1: CVec<u8>, src2: CVec<u8>) -> Result<CVec<u8>, String>
assert_eq!(src1.len(), src2.len());
let size = src1.len();
let dest = cvec_with_size(size);
let ret = unsafe { imagefilter::SDL_imageFilterMultDivby4(mem::transmute(src1.get(0)),
mem::transmute(src2.get(0)),
mem::transmute(dest.get(0)),
size as c_uint) };
if ret == 0 { Ok(dest) }
else { Err(get_error()) }
let ret = unsafe {
imagefilter::SDL_imageFilterMultDivby4(
mem::transmute(src1.get(0)),
mem::transmute(src2.get(0)),
mem::transmute(dest.get(0)),
size as c_uint,
)
};
if ret == 0 {
Ok(dest)
} else {
Err(get_error())
}
}
/// Filter using `BitAnd`: D = S1 & S2.
@@ -140,12 +194,19 @@ pub fn bit_and(src1: CVec<u8>, src2: CVec<u8>) -> Result<CVec<u8>, String> {
assert_eq!(src1.len(), src2.len());
let size = src1.len();
let dest = cvec_with_size(size);
let ret = unsafe { imagefilter::SDL_imageFilterBitAnd(mem::transmute(src1.get(0)),
mem::transmute(src2.get(0)),
mem::transmute(dest.get(0)),
size as c_uint) };
if ret == 0 { Ok(dest) }
else { Err(get_error()) }
let ret = unsafe {
imagefilter::SDL_imageFilterBitAnd(
mem::transmute(src1.get(0)),
mem::transmute(src2.get(0)),
mem::transmute(dest.get(0)),
size as c_uint,
)
};
if ret == 0 {
Ok(dest)
} else {
Err(get_error())
}
}
/// Filter using `BitOr`: D = S1 | S2.
@@ -153,12 +214,19 @@ pub fn bit_or(src1: CVec<u8>, src2: CVec<u8>) -> Result<CVec<u8>, String> {
assert_eq!(src1.len(), src2.len());
let size = src1.len();
let dest = cvec_with_size(size);
let ret = unsafe { imagefilter::SDL_imageFilterBitOr(mem::transmute(src1.get(0)),
mem::transmute(src2.get(0)),
mem::transmute(dest.get(0)),
size as c_uint) };
if ret == 0 { Ok(dest) }
else { Err(get_error()) }
let ret = unsafe {
imagefilter::SDL_imageFilterBitOr(
mem::transmute(src1.get(0)),
mem::transmute(src2.get(0)),
mem::transmute(dest.get(0)),
size as c_uint,
)
};
if ret == 0 {
Ok(dest)
} else {
Err(get_error())
}
}
/// Filter using Div: D = S1 / S2.
@@ -166,188 +234,331 @@ pub fn div(src1: CVec<u8>, src2: CVec<u8>) -> Result<CVec<u8>, String> {
assert_eq!(src1.len(), src2.len());
let size = src1.len();
let dest = cvec_with_size(size);
let ret = unsafe { imagefilter::SDL_imageFilterDiv(mem::transmute(src1.get(0)),
mem::transmute(src2.get(0)),
mem::transmute(dest.get(0)),
size as c_uint) };
if ret == 0 { Ok(dest) }
else { Err(get_error()) }
let ret = unsafe {
imagefilter::SDL_imageFilterDiv(
mem::transmute(src1.get(0)),
mem::transmute(src2.get(0)),
mem::transmute(dest.get(0)),
size as c_uint,
)
};
if ret == 0 {
Ok(dest)
} else {
Err(get_error())
}
}
/// Filter using `BitNegation`: D = !S.
pub fn bit_negation(src1: CVec<u8>) -> Result<CVec<u8>, String> {
let size = src1.len();
let dest = cvec_with_size(size);
let ret = unsafe { imagefilter::SDL_imageFilterBitNegation(mem::transmute(src1.get(0)),
mem::transmute(dest.get(0)),
size as c_uint) };
if ret == 0 { Ok(dest) }
else { Err(get_error()) }
let ret = unsafe {
imagefilter::SDL_imageFilterBitNegation(
mem::transmute(src1.get(0)),
mem::transmute(dest.get(0)),
size as c_uint,
)
};
if ret == 0 {
Ok(dest)
} else {
Err(get_error())
}
}
/// Filter using `AddByte`: D = saturation255(S + C).
pub fn add_byte(src1: CVec<u8>, c: u8) -> Result<CVec<u8>, String> {
let size = src1.len();
let dest = cvec_with_size(size);
let ret = unsafe { imagefilter::SDL_imageFilterAddByte(mem::transmute(src1.get(0)),
mem::transmute(dest.get(0)),
size as c_uint, c) };
if ret == 0 { Ok(dest) }
else { Err(get_error()) }
let ret = unsafe {
imagefilter::SDL_imageFilterAddByte(
mem::transmute(src1.get(0)),
mem::transmute(dest.get(0)),
size as c_uint,
c,
)
};
if ret == 0 {
Ok(dest)
} else {
Err(get_error())
}
}
/// Filter using `AddUint`: D = saturation255((S[i] + Cs[i % 4]), Cs=Swap32((uint)C).
pub fn add_uint(src1: CVec<u8>, c: u32) -> Result<CVec<u8>, String> {
let size = src1.len();
let dest = cvec_with_size(size);
let ret = unsafe { imagefilter::SDL_imageFilterAddUint(mem::transmute(src1.get(0)),
mem::transmute(dest.get(0)),
size as c_uint, c) };
if ret == 0 { Ok(dest) }
else { Err(get_error()) }
let ret = unsafe {
imagefilter::SDL_imageFilterAddUint(
mem::transmute(src1.get(0)),
mem::transmute(dest.get(0)),
size as c_uint,
c,
)
};
if ret == 0 {
Ok(dest)
} else {
Err(get_error())
}
}
/// Filter using `AddByteToHalf`: D = saturation255(S/2 + C).
pub fn add_byte_to_half(src1: CVec<u8>, c: u8) -> Result<CVec<u8>, String> {
let size = src1.len();
let dest = cvec_with_size(size);
let ret = unsafe { imagefilter::SDL_imageFilterAddByteToHalf(mem::transmute(src1.get(0)),
mem::transmute(dest.get(0)),
size as c_uint, c) };
if ret == 0 { Ok(dest) }
else { Err(get_error()) }
let ret = unsafe {
imagefilter::SDL_imageFilterAddByteToHalf(
mem::transmute(src1.get(0)),
mem::transmute(dest.get(0)),
size as c_uint,
c,
)
};
if ret == 0 {
Ok(dest)
} else {
Err(get_error())
}
}
/// Filter using `SubByte`: D = saturation0(S - C).
pub fn sub_byte(src1: CVec<u8>, c: u8) -> Result<CVec<u8>, String> {
let size = src1.len();
let dest = cvec_with_size(size);
let ret = unsafe { imagefilter::SDL_imageFilterSubByte(mem::transmute(src1.get(0)),
mem::transmute(dest.get(0)),
size as c_uint, c) };
if ret == 0 { Ok(dest) }
else { Err(get_error()) }
let ret = unsafe {
imagefilter::SDL_imageFilterSubByte(
mem::transmute(src1.get(0)),
mem::transmute(dest.get(0)),
size as c_uint,
c,
)
};
if ret == 0 {
Ok(dest)
} else {
Err(get_error())
}
}
/// Filter using `SubUint`: D = saturation0(S[i] - Cs[i % 4]), Cs=Swap32((uint)C).
pub fn sub_uint(src1: CVec<u8>, c: u32) -> Result<CVec<u8>, String> {
let size = src1.len();
let dest = cvec_with_size(size);
let ret = unsafe { imagefilter::SDL_imageFilterSubUint(mem::transmute(src1.get(0)),
mem::transmute(dest.get(0)),
size as c_uint, c) };
if ret == 0 { Ok(dest) }
else { Err(get_error()) }
let ret = unsafe {
imagefilter::SDL_imageFilterSubUint(
mem::transmute(src1.get(0)),
mem::transmute(dest.get(0)),
size as c_uint,
c,
)
};
if ret == 0 {
Ok(dest)
} else {
Err(get_error())
}
}
/// Filter using `ShiftRight`: D = saturation0(S >> N).
pub fn shift_right(src1: CVec<u8>, n: u8) -> Result<CVec<u8>, String> {
let size = src1.len();
let dest = cvec_with_size(size);
let ret = unsafe { imagefilter::SDL_imageFilterShiftRight(mem::transmute(src1.get(0)),
mem::transmute(dest.get(0)),
size as c_uint, n) };
if ret == 0 { Ok(dest) }
else { Err(get_error()) }
let ret = unsafe {
imagefilter::SDL_imageFilterShiftRight(
mem::transmute(src1.get(0)),
mem::transmute(dest.get(0)),
size as c_uint,
n,
)
};
if ret == 0 {
Ok(dest)
} else {
Err(get_error())
}
}
/// Filter using `ShiftRightUint`: D = saturation0((uint)S[i] >> N).
pub fn shift_right_uint(src1: CVec<u8>, n: u8) -> Result<CVec<u8>, String> {
let size = src1.len();
let dest = cvec_with_size(size);
let ret = unsafe { imagefilter::SDL_imageFilterShiftRightUint(mem::transmute(src1.get(0)),
mem::transmute(dest.get(0)),
size as c_uint, n) };
if ret == 0 { Ok(dest) }
else { Err(get_error()) }
let ret = unsafe {
imagefilter::SDL_imageFilterShiftRightUint(
mem::transmute(src1.get(0)),
mem::transmute(dest.get(0)),
size as c_uint,
n,
)
};
if ret == 0 {
Ok(dest)
} else {
Err(get_error())
}
}
/// Filter using `MultByByte`: D = saturation255(S * C).
pub fn mult_by_byte(src1: CVec<u8>, c: u8) -> Result<CVec<u8>, String> {
let size = src1.len();
let dest = cvec_with_size(size);
let ret = unsafe { imagefilter::SDL_imageFilterMultByByte(mem::transmute(src1.get(0)),
mem::transmute(dest.get(0)),
size as c_uint, c) };
if ret == 0 { Ok(dest) }
else { Err(get_error()) }
let ret = unsafe {
imagefilter::SDL_imageFilterMultByByte(
mem::transmute(src1.get(0)),
mem::transmute(dest.get(0)),
size as c_uint,
c,
)
};
if ret == 0 {
Ok(dest)
} else {
Err(get_error())
}
}
/// Filter using `ShiftRightAndMultByByte`: D = saturation255((S >> N) * C).
pub fn shift_right_and_mult_by_byte(src1: CVec<u8>, n: u8, c: u8) -> Result<CVec<u8>, String> {
let size = src1.len();
let dest = cvec_with_size(size);
let ret = unsafe { imagefilter::SDL_imageFilterShiftRightAndMultByByte(mem::transmute(src1.get(0)),
mem::transmute(dest.get(0)),
size as c_uint, n, c) };
if ret == 0 { Ok(dest) }
else { Err(get_error()) }
let ret = unsafe {
imagefilter::SDL_imageFilterShiftRightAndMultByByte(
mem::transmute(src1.get(0)),
mem::transmute(dest.get(0)),
size as c_uint,
n,
c,
)
};
if ret == 0 {
Ok(dest)
} else {
Err(get_error())
}
}
/// Filter using `ShiftLeftByte`: D = (S << N).
pub fn shift_left_byte(src1: CVec<u8>, n: u8) -> Result<CVec<u8>, String> {
let size = src1.len();
let dest = cvec_with_size(size);
let ret = unsafe { imagefilter::SDL_imageFilterShiftLeftByte(mem::transmute(src1.get(0)),
mem::transmute(dest.get(0)),
size as c_uint, n) };
if ret == 0 { Ok(dest) }
else { Err(get_error()) }
let ret = unsafe {
imagefilter::SDL_imageFilterShiftLeftByte(
mem::transmute(src1.get(0)),
mem::transmute(dest.get(0)),
size as c_uint,
n,
)
};
if ret == 0 {
Ok(dest)
} else {
Err(get_error())
}
}
/// Filter using `ShiftLeftUint`: D = ((uint)S << N).
pub fn shift_left_uint(src1: CVec<u8>, n: u8) -> Result<CVec<u8>, String> {
let size = src1.len();
let dest = cvec_with_size(size);
let ret = unsafe { imagefilter::SDL_imageFilterShiftLeftUint(mem::transmute(src1.get(0)),
mem::transmute(dest.get(0)),
size as c_uint, n) };
if ret == 0 { Ok(dest) }
else { Err(get_error()) }
let ret = unsafe {
imagefilter::SDL_imageFilterShiftLeftUint(
mem::transmute(src1.get(0)),
mem::transmute(dest.get(0)),
size as c_uint,
n,
)
};
if ret == 0 {
Ok(dest)
} else {
Err(get_error())
}
}
/// Filter `ShiftLeft`: D = saturation255(S << N).
pub fn shift_left(src1: CVec<u8>, n: u8) -> Result<CVec<u8>, String> {
let size = src1.len();
let dest = cvec_with_size(size);
let ret = unsafe { imagefilter::SDL_imageFilterShiftLeft(mem::transmute(src1.get(0)),
mem::transmute(dest.get(0)),
size as c_uint, n) };
if ret == 0 { Ok(dest) }
else { Err(get_error()) }
let ret = unsafe {
imagefilter::SDL_imageFilterShiftLeft(
mem::transmute(src1.get(0)),
mem::transmute(dest.get(0)),
size as c_uint,
n,
)
};
if ret == 0 {
Ok(dest)
} else {
Err(get_error())
}
}
/// Filter using `BinarizeUsingThreshold`: D = (S >= T) ? 255:0.
pub fn binarize_using_threshold(src1: CVec<u8>, t: u8) -> Result<CVec<u8>, String> {
let size = src1.len();
let dest = cvec_with_size(size);
let ret = unsafe { imagefilter::SDL_imageFilterBinarizeUsingThreshold(mem::transmute(src1.get(0)),
mem::transmute(dest.get(0)),
size as c_uint, t) };
if ret == 0 { Ok(dest) }
else { Err(get_error()) }
let ret = unsafe {
imagefilter::SDL_imageFilterBinarizeUsingThreshold(
mem::transmute(src1.get(0)),
mem::transmute(dest.get(0)),
size as c_uint,
t,
)
};
if ret == 0 {
Ok(dest)
} else {
Err(get_error())
}
}
/// Filter using `ClipToRange`: D = (S >= Tmin) & (S <= Tmax) S:Tmin | Tmax.
pub fn clip_to_range(src1: CVec<u8>, tmin: u8, tmax: u8) -> Result<CVec<u8>, String> {
let size = src1.len();
let dest = cvec_with_size(size);
let ret = unsafe { imagefilter::SDL_imageFilterClipToRange(mem::transmute(src1.get(0)),
mem::transmute(dest.get(0)),
size as c_uint, tmin, tmax) };
if ret == 0 { Ok(dest) }
else { Err(get_error()) }
let ret = unsafe {
imagefilter::SDL_imageFilterClipToRange(
mem::transmute(src1.get(0)),
mem::transmute(dest.get(0)),
size as c_uint,
tmin,
tmax,
)
};
if ret == 0 {
Ok(dest)
} else {
Err(get_error())
}
}
/// Filter using `NormalizeLinear`: D = saturation255((Nmax - Nmin)/(Cmax - Cmin)*(S - Cmin) + Nmin).
pub fn normalize_linear(src1: CVec<u8>, cmin: i32, cmax: i32, nmin: i32, nmax: i32) -> Result<CVec<u8>, String> {
pub fn normalize_linear(
src1: CVec<u8>,
cmin: i32,
cmax: i32,
nmin: i32,
nmax: i32,
) -> Result<CVec<u8>, String> {
let size = src1.len();
let dest = cvec_with_size(size);
let ret = unsafe { imagefilter::SDL_imageFilterNormalizeLinear(mem::transmute(src1.get(0)),
mem::transmute(dest.get(0)),
size as c_uint,
cmin as c_int, cmax as c_int,
nmin as c_int, nmax as c_int) };
if ret == 0 { Ok(dest) }
else { Err(get_error()) }
let ret = unsafe {
imagefilter::SDL_imageFilterNormalizeLinear(
mem::transmute(src1.get(0)),
mem::transmute(dest.get(0)),
size as c_uint,
cmin as c_int,
cmax as c_int,
nmin as c_int,
nmax as c_int,
)
};
if ret == 0 {
Ok(dest)
} else {
Err(get_error())
}
}

View File

@@ -20,7 +20,7 @@
//! features = ["gfx"]
//! ```
pub mod primitives;
pub mod rotozoom;
pub mod framerate;
pub mod imagefilter;
pub mod primitives;
pub mod rotozoom;

View File

@@ -1,15 +1,15 @@
//! Graphic Primitives
use get_error;
use libc::c_void;
use libc::{c_char, c_int};
use pixels;
use render::Canvas;
use std::convert::TryFrom;
use std::ffi::CString;
use std::mem;
use std::ptr;
use std::ffi::CString;
use std::convert::TryFrom;
use libc::{c_int, c_char};
use libc::c_void;
use render::Canvas;
use surface::Surface;
use pixels;
use get_error;
use sys::gfx::primitives;
/// generic Color type
@@ -71,339 +71,476 @@ pub trait DrawRenderer {
fn pixel<C: ToColor>(&self, x: i16, y: i16, color: C) -> Result<(), String>;
fn hline<C: ToColor>(&self, x1: i16, x2: i16, y: i16, color: C) -> Result<(), String>;
fn vline<C: ToColor>(&self, x: i16, y1: i16, y2: i16, color: C) -> Result<(), String>;
fn rectangle<C: ToColor>(&self,
x1: i16,
y1: i16,
x2: i16,
y2: i16,
color: C)
-> Result<(), String>;
fn rounded_rectangle<C: ToColor>(&self,
x1: i16,
y1: i16,
x2: i16,
y2: i16,
rad: i16,
color: C)
-> Result<(), String>;
fn rectangle<C: ToColor>(
&self,
x1: i16,
y1: i16,
x2: i16,
y2: i16,
color: C,
) -> Result<(), String>;
fn rounded_rectangle<C: ToColor>(
&self,
x1: i16,
y1: i16,
x2: i16,
y2: i16,
rad: i16,
color: C,
) -> Result<(), String>;
fn box_<C: ToColor>(&self, x1: i16, y1: i16, x2: i16, y2: i16, color: C) -> Result<(), String>;
fn rounded_box<C: ToColor>(&self,
x1: i16,
y1: i16,
x2: i16,
y2: i16,
rad: i16,
color: C)
-> Result<(), String>;
fn rounded_box<C: ToColor>(
&self,
x1: i16,
y1: i16,
x2: i16,
y2: i16,
rad: i16,
color: C,
) -> Result<(), String>;
fn line<C: ToColor>(&self, x1: i16, y1: i16, x2: i16, y2: i16, color: C) -> Result<(), String>;
fn aa_line<C: ToColor>(&self,
x1: i16,
y1: i16,
x2: i16,
y2: i16,
color: C)
-> Result<(), String>;
fn thick_line<C: ToColor>(&self,
x1: i16,
y1: i16,
x2: i16,
y2: i16,
width: u8,
color: C)
-> Result<(), String>;
fn aa_line<C: ToColor>(
&self,
x1: i16,
y1: i16,
x2: i16,
y2: i16,
color: C,
) -> Result<(), String>;
fn thick_line<C: ToColor>(
&self,
x1: i16,
y1: i16,
x2: i16,
y2: i16,
width: u8,
color: C,
) -> Result<(), String>;
fn circle<C: ToColor>(&self, x: i16, y: i16, rad: i16, color: C) -> Result<(), String>;
fn aa_circle<C: ToColor>(&self, x: i16, y: i16, rad: i16, color: C) -> Result<(), String>;
fn filled_circle<C: ToColor>(&self, x: i16, y: i16, rad: i16, color: C) -> Result<(), String>;
fn arc<C: ToColor>(&self,
x: i16,
y: i16,
rad: i16,
start: i16,
end: i16,
color: C)
-> Result<(), String>;
fn ellipse<C: ToColor>(&self,
x: i16,
y: i16,
rx: i16,
ry: i16,
color: C)
-> Result<(), String>;
fn aa_ellipse<C: ToColor>(&self,
x: i16,
y: i16,
rx: i16,
ry: i16,
color: C)
-> Result<(), String>;
fn filled_ellipse<C: ToColor>(&self,
x: i16,
y: i16,
rx: i16,
ry: i16,
color: C)
-> Result<(), String>;
fn pie<C: ToColor>(&self,
x: i16,
y: i16,
rad: i16,
start: i16,
end: i16,
color: C)
-> Result<(), String>;
fn filled_pie<C: ToColor>(&self,
x: i16,
y: i16,
rad: i16,
start: i16,
end: i16,
color: C)
-> Result<(), String>;
fn trigon<C: ToColor>(&self,
x1: i16,
y1: i16,
x2: i16,
y2: i16,
x3: i16,
y3: i16,
color: C)
-> Result<(), String>;
fn aa_trigon<C: ToColor>(&self,
x1: i16,
y1: i16,
x2: i16,
y2: i16,
x3: i16,
y3: i16,
color: C)
-> Result<(), String>;
fn filled_trigon<C: ToColor>(&self,
x1: i16,
y1: i16,
x2: i16,
y2: i16,
x3: i16,
y3: i16,
color: C)
-> Result<(), String>;
fn arc<C: ToColor>(
&self,
x: i16,
y: i16,
rad: i16,
start: i16,
end: i16,
color: C,
) -> Result<(), String>;
fn ellipse<C: ToColor>(&self, x: i16, y: i16, rx: i16, ry: i16, color: C)
-> Result<(), String>;
fn aa_ellipse<C: ToColor>(
&self,
x: i16,
y: i16,
rx: i16,
ry: i16,
color: C,
) -> Result<(), String>;
fn filled_ellipse<C: ToColor>(
&self,
x: i16,
y: i16,
rx: i16,
ry: i16,
color: C,
) -> Result<(), String>;
fn pie<C: ToColor>(
&self,
x: i16,
y: i16,
rad: i16,
start: i16,
end: i16,
color: C,
) -> Result<(), String>;
fn filled_pie<C: ToColor>(
&self,
x: i16,
y: i16,
rad: i16,
start: i16,
end: i16,
color: C,
) -> Result<(), String>;
fn trigon<C: ToColor>(
&self,
x1: i16,
y1: i16,
x2: i16,
y2: i16,
x3: i16,
y3: i16,
color: C,
) -> Result<(), String>;
fn aa_trigon<C: ToColor>(
&self,
x1: i16,
y1: i16,
x2: i16,
y2: i16,
x3: i16,
y3: i16,
color: C,
) -> Result<(), String>;
fn filled_trigon<C: ToColor>(
&self,
x1: i16,
y1: i16,
x2: i16,
y2: i16,
x3: i16,
y3: i16,
color: C,
) -> Result<(), String>;
fn polygon<C: ToColor>(&self, vx: &[i16], vy: &[i16], color: C) -> Result<(), String>;
fn aa_polygon<C: ToColor>(&self, vx: &[i16], vy: &[i16], color: C) -> Result<(), String>;
fn filled_polygon<C: ToColor>(&self, vx: &[i16], vy: &[i16], color: C) -> Result<(), String>;
fn textured_polygon<C: ToColor>(&self,
vx: &[i16],
vy: &[i16],
texture: &Surface,
texture_dx: i16,
texture_dy: i16,
color: C)
-> Result<(), String>;
fn textured_polygon<C: ToColor>(
&self,
vx: &[i16],
vy: &[i16],
texture: &Surface,
texture_dx: i16,
texture_dy: i16,
color: C,
) -> Result<(), String>;
fn bezier<C: ToColor>(&self, vx: &[i16], vy: &[i16], s: i32, color: C) -> Result<(), String>;
fn character<C: ToColor>(&self, x: i16, y: i16, c: char, color: C) -> Result<(), String>;
fn string<C: ToColor>(&self, x: i16, y: i16, s: &str, color: C) -> Result<(), String>;
}
impl<T> DrawRenderer for Canvas<T> where T: ::render::RenderTarget {
impl<T> DrawRenderer for Canvas<T>
where
T: ::render::RenderTarget,
{
fn pixel<C: ToColor>(&self, x: i16, y: i16, color: C) -> Result<(), String> {
let ret = unsafe { primitives::pixelColor(self.raw(), x, y, color.as_u32()) };
if ret == 0 { Ok(()) } else { Err(get_error()) }
if ret == 0 {
Ok(())
} else {
Err(get_error())
}
}
fn hline<C: ToColor>(&self, x1: i16, x2: i16, y: i16, color: C) -> Result<(), String> {
let ret = unsafe { primitives::hlineColor(self.raw(), x1, x2, y, color.as_u32()) };
if ret == 0 { Ok(()) } else { Err(get_error()) }
if ret == 0 {
Ok(())
} else {
Err(get_error())
}
}
fn vline<C: ToColor>(&self, x: i16, y1: i16, y2: i16, color: C) -> Result<(), String> {
let ret = unsafe { primitives::vlineColor(self.raw(), x, y1, y2, color.as_u32()) };
if ret == 0 { Ok(()) } else { Err(get_error()) }
if ret == 0 {
Ok(())
} else {
Err(get_error())
}
}
fn rectangle<C: ToColor>(&self,
x1: i16,
y1: i16,
x2: i16,
y2: i16,
color: C)
-> Result<(), String> {
fn rectangle<C: ToColor>(
&self,
x1: i16,
y1: i16,
x2: i16,
y2: i16,
color: C,
) -> Result<(), String> {
let ret = unsafe { primitives::rectangleColor(self.raw(), x1, y1, x2, y2, color.as_u32()) };
if ret == 0 { Ok(()) } else { Err(get_error()) }
if ret == 0 {
Ok(())
} else {
Err(get_error())
}
}
fn rounded_rectangle<C: ToColor>(&self,
x1: i16,
y1: i16,
x2: i16,
y2: i16,
rad: i16,
color: C)
-> Result<(), String> {
let ret =
unsafe { primitives::roundedRectangleColor(self.raw(), x1, y1, x2, y2, rad, color.as_u32()) };
if ret == 0 { Ok(()) } else { Err(get_error()) }
fn rounded_rectangle<C: ToColor>(
&self,
x1: i16,
y1: i16,
x2: i16,
y2: i16,
rad: i16,
color: C,
) -> Result<(), String> {
let ret = unsafe {
primitives::roundedRectangleColor(self.raw(), x1, y1, x2, y2, rad, color.as_u32())
};
if ret == 0 {
Ok(())
} else {
Err(get_error())
}
}
fn box_<C: ToColor>(&self, x1: i16, y1: i16, x2: i16, y2: i16, color: C) -> Result<(), String> {
let ret = unsafe { primitives::boxColor(self.raw(), x1, y1, x2, y2, color.as_u32()) };
if ret == 0 { Ok(()) } else { Err(get_error()) }
if ret == 0 {
Ok(())
} else {
Err(get_error())
}
}
fn rounded_box<C: ToColor>(&self,
x1: i16,
y1: i16,
x2: i16,
y2: i16,
rad: i16,
color: C)
-> Result<(), String> {
let ret = unsafe { primitives::roundedBoxColor(self.raw(), x1, y1, x2, y2, rad, color.as_u32()) };
if ret == 0 { Ok(()) } else { Err(get_error()) }
fn rounded_box<C: ToColor>(
&self,
x1: i16,
y1: i16,
x2: i16,
y2: i16,
rad: i16,
color: C,
) -> Result<(), String> {
let ret =
unsafe { primitives::roundedBoxColor(self.raw(), x1, y1, x2, y2, rad, color.as_u32()) };
if ret == 0 {
Ok(())
} else {
Err(get_error())
}
}
fn line<C: ToColor>(&self, x1: i16, y1: i16, x2: i16, y2: i16, color: C) -> Result<(), String> {
let ret = unsafe { primitives::lineColor(self.raw(), x1, y1, x2, y2, color.as_u32()) };
if ret == 0 { Ok(()) } else { Err(get_error()) }
if ret == 0 {
Ok(())
} else {
Err(get_error())
}
}
fn aa_line<C: ToColor>(&self,
x1: i16,
y1: i16,
x2: i16,
y2: i16,
color: C)
-> Result<(), String> {
fn aa_line<C: ToColor>(
&self,
x1: i16,
y1: i16,
x2: i16,
y2: i16,
color: C,
) -> Result<(), String> {
let ret = unsafe { primitives::aalineColor(self.raw(), x1, y1, x2, y2, color.as_u32()) };
if ret == 0 { Ok(()) } else { Err(get_error()) }
if ret == 0 {
Ok(())
} else {
Err(get_error())
}
}
fn thick_line<C: ToColor>(&self,
x1: i16,
y1: i16,
x2: i16,
y2: i16,
width: u8,
color: C)
-> Result<(), String> {
let ret = unsafe { primitives::thickLineColor(self.raw(), x1, y1, x2, y2, width, color.as_u32()) };
if ret == 0 { Ok(()) } else { Err(get_error()) }
fn thick_line<C: ToColor>(
&self,
x1: i16,
y1: i16,
x2: i16,
y2: i16,
width: u8,
color: C,
) -> Result<(), String> {
let ret = unsafe {
primitives::thickLineColor(self.raw(), x1, y1, x2, y2, width, color.as_u32())
};
if ret == 0 {
Ok(())
} else {
Err(get_error())
}
}
fn circle<C: ToColor>(&self, x: i16, y: i16, rad: i16, color: C) -> Result<(), String> {
let ret = unsafe { primitives::circleColor(self.raw(), x, y, rad, color.as_u32()) };
if ret == 0 { Ok(()) } else { Err(get_error()) }
if ret == 0 {
Ok(())
} else {
Err(get_error())
}
}
fn aa_circle<C: ToColor>(&self, x: i16, y: i16, rad: i16, color: C) -> Result<(), String> {
let ret = unsafe { primitives::aacircleColor(self.raw(), x, y, rad, color.as_u32()) };
if ret == 0 { Ok(()) } else { Err(get_error()) }
if ret == 0 {
Ok(())
} else {
Err(get_error())
}
}
fn filled_circle<C: ToColor>(&self, x: i16, y: i16, rad: i16, color: C) -> Result<(), String> {
let ret = unsafe { primitives::filledCircleColor(self.raw(), x, y, rad, color.as_u32()) };
if ret == 0 { Ok(()) } else { Err(get_error()) }
if ret == 0 {
Ok(())
} else {
Err(get_error())
}
}
fn arc<C: ToColor>(&self,
x: i16,
y: i16,
rad: i16,
start: i16,
end: i16,
color: C)
-> Result<(), String> {
let ret = unsafe { primitives::arcColor(self.raw(), x, y, rad, start, end, color.as_u32()) };
if ret == 0 { Ok(()) } else { Err(get_error()) }
}
fn ellipse<C: ToColor>(&self,
x: i16,
y: i16,
rx: i16,
ry: i16,
color: C)
-> Result<(), String> {
let ret = unsafe { primitives::ellipseColor(self.raw(), x, y, rx, ry, color.as_u32()) };
if ret == 0 { Ok(()) } else { Err(get_error()) }
}
fn aa_ellipse<C: ToColor>(&self,
x: i16,
y: i16,
rx: i16,
ry: i16,
color: C)
-> Result<(), String> {
let ret = unsafe { primitives::aaellipseColor(self.raw(), x, y, rx, ry, color.as_u32()) };
if ret == 0 { Ok(()) } else { Err(get_error()) }
}
fn filled_ellipse<C: ToColor>(&self,
x: i16,
y: i16,
rx: i16,
ry: i16,
color: C)
-> Result<(), String> {
let ret = unsafe { primitives::filledEllipseColor(self.raw(), x, y, rx, ry, color.as_u32()) };
if ret == 0 { Ok(()) } else { Err(get_error()) }
}
fn pie<C: ToColor>(&self,
x: i16,
y: i16,
rad: i16,
start: i16,
end: i16,
color: C)
-> Result<(), String> {
let ret = unsafe { primitives::pieColor(self.raw(), x, y, rad, start, end, color.as_u32()) };
if ret == 0 { Ok(()) } else { Err(get_error()) }
}
fn filled_pie<C: ToColor>(&self,
x: i16,
y: i16,
rad: i16,
start: i16,
end: i16,
color: C)
-> Result<(), String> {
let ret = unsafe { primitives::filledPieColor(self.raw(), x, y, rad, start, end, color.as_u32()) };
if ret == 0 { Ok(()) } else { Err(get_error()) }
}
fn trigon<C: ToColor>(&self,
x1: i16,
y1: i16,
x2: i16,
y2: i16,
x3: i16,
y3: i16,
color: C)
-> Result<(), String> {
let ret = unsafe { primitives::trigonColor(self.raw(), x1, y1, x2, y2, x3, y3, color.as_u32()) };
if ret == 0 { Ok(()) } else { Err(get_error()) }
}
fn aa_trigon<C: ToColor>(&self,
x1: i16,
y1: i16,
x2: i16,
y2: i16,
x3: i16,
y3: i16,
color: C)
-> Result<(), String> {
let ret = unsafe { primitives::aatrigonColor(self.raw(), x1, y1, x2, y2, x3, y3, color.as_u32()) };
if ret == 0 { Ok(()) } else { Err(get_error()) }
}
fn filled_trigon<C: ToColor>(&self,
x1: i16,
y1: i16,
x2: i16,
y2: i16,
x3: i16,
y3: i16,
color: C)
-> Result<(), String> {
fn arc<C: ToColor>(
&self,
x: i16,
y: i16,
rad: i16,
start: i16,
end: i16,
color: C,
) -> Result<(), String> {
let ret =
unsafe { primitives::filledTrigonColor(self.raw(), x1, y1, x2, y2, x3, y3, color.as_u32()) };
if ret == 0 { Ok(()) } else { Err(get_error()) }
unsafe { primitives::arcColor(self.raw(), x, y, rad, start, end, color.as_u32()) };
if ret == 0 {
Ok(())
} else {
Err(get_error())
}
}
fn ellipse<C: ToColor>(
&self,
x: i16,
y: i16,
rx: i16,
ry: i16,
color: C,
) -> Result<(), String> {
let ret = unsafe { primitives::ellipseColor(self.raw(), x, y, rx, ry, color.as_u32()) };
if ret == 0 {
Ok(())
} else {
Err(get_error())
}
}
fn aa_ellipse<C: ToColor>(
&self,
x: i16,
y: i16,
rx: i16,
ry: i16,
color: C,
) -> Result<(), String> {
let ret = unsafe { primitives::aaellipseColor(self.raw(), x, y, rx, ry, color.as_u32()) };
if ret == 0 {
Ok(())
} else {
Err(get_error())
}
}
fn filled_ellipse<C: ToColor>(
&self,
x: i16,
y: i16,
rx: i16,
ry: i16,
color: C,
) -> Result<(), String> {
let ret =
unsafe { primitives::filledEllipseColor(self.raw(), x, y, rx, ry, color.as_u32()) };
if ret == 0 {
Ok(())
} else {
Err(get_error())
}
}
fn pie<C: ToColor>(
&self,
x: i16,
y: i16,
rad: i16,
start: i16,
end: i16,
color: C,
) -> Result<(), String> {
let ret =
unsafe { primitives::pieColor(self.raw(), x, y, rad, start, end, color.as_u32()) };
if ret == 0 {
Ok(())
} else {
Err(get_error())
}
}
fn filled_pie<C: ToColor>(
&self,
x: i16,
y: i16,
rad: i16,
start: i16,
end: i16,
color: C,
) -> Result<(), String> {
let ret = unsafe {
primitives::filledPieColor(self.raw(), x, y, rad, start, end, color.as_u32())
};
if ret == 0 {
Ok(())
} else {
Err(get_error())
}
}
fn trigon<C: ToColor>(
&self,
x1: i16,
y1: i16,
x2: i16,
y2: i16,
x3: i16,
y3: i16,
color: C,
) -> Result<(), String> {
let ret =
unsafe { primitives::trigonColor(self.raw(), x1, y1, x2, y2, x3, y3, color.as_u32()) };
if ret == 0 {
Ok(())
} else {
Err(get_error())
}
}
fn aa_trigon<C: ToColor>(
&self,
x1: i16,
y1: i16,
x2: i16,
y2: i16,
x3: i16,
y3: i16,
color: C,
) -> Result<(), String> {
let ret = unsafe {
primitives::aatrigonColor(self.raw(), x1, y1, x2, y2, x3, y3, color.as_u32())
};
if ret == 0 {
Ok(())
} else {
Err(get_error())
}
}
fn filled_trigon<C: ToColor>(
&self,
x1: i16,
y1: i16,
x2: i16,
y2: i16,
x3: i16,
y3: i16,
color: C,
) -> Result<(), String> {
let ret = unsafe {
primitives::filledTrigonColor(self.raw(), x1, y1, x2, y2, x3, y3, color.as_u32())
};
if ret == 0 {
Ok(())
} else {
Err(get_error())
}
}
// FIXME: may we use pointer tuple?
fn polygon<C: ToColor>(&self, vx: &[i16], vy: &[i16], color: C) -> Result<(), String> {
assert_eq!(vx.len(), vy.len());
let n = vx.len() as c_int;
let ret =
unsafe { primitives::polygonColor(self.raw(), vx.as_ptr(), vy.as_ptr(), n, color.as_u32()) };
if ret == 0 { Ok(()) } else { Err(get_error()) }
let ret = unsafe {
primitives::polygonColor(self.raw(), vx.as_ptr(), vy.as_ptr(), n, color.as_u32())
};
if ret == 0 {
Ok(())
} else {
Err(get_error())
}
}
fn aa_polygon<C: ToColor>(&self, vx: &[i16], vy: &[i16], color: C) -> Result<(), String> {
assert_eq!(vx.len(), vy.len());
let n = vx.len() as c_int;
let ret =
unsafe { primitives::aapolygonColor(self.raw(), vx.as_ptr(), vy.as_ptr(), n, color.as_u32()) };
if ret == 0 { Ok(()) } else { Err(get_error()) }
let ret = unsafe {
primitives::aapolygonColor(self.raw(), vx.as_ptr(), vy.as_ptr(), n, color.as_u32())
};
if ret == 0 {
Ok(())
} else {
Err(get_error())
}
}
fn filled_polygon<C: ToColor>(&self, vx: &[i16], vy: &[i16], color: C) -> Result<(), String> {
@@ -412,17 +549,22 @@ impl<T> DrawRenderer for Canvas<T> where T: ::render::RenderTarget {
let ret = unsafe {
primitives::filledPolygonColor(self.raw(), vx.as_ptr(), vy.as_ptr(), n, color.as_u32())
};
if ret == 0 { Ok(()) } else { Err(get_error()) }
if ret == 0 {
Ok(())
} else {
Err(get_error())
}
}
#[allow(unused_variables)]
fn textured_polygon<C: ToColor>(&self,
vx: &[i16],
vy: &[i16],
texture: &Surface,
texture_dx: i16,
texture_dy: i16,
color: C)
-> Result<(), String> {
fn textured_polygon<C: ToColor>(
&self,
vx: &[i16],
vy: &[i16],
texture: &Surface,
texture_dx: i16,
texture_dy: i16,
color: C,
) -> Result<(), String> {
unimplemented!()
}
@@ -430,19 +572,30 @@ impl<T> DrawRenderer for Canvas<T> where T: ::render::RenderTarget {
assert_eq!(vx.len(), vy.len());
let n = vx.len() as c_int;
let ret = unsafe {
primitives::bezierColor(self.raw(),
vx.as_ptr(),
vy.as_ptr(),
n,
s as c_int,
color.as_u32())
primitives::bezierColor(
self.raw(),
vx.as_ptr(),
vy.as_ptr(),
n,
s as c_int,
color.as_u32(),
)
};
if ret == 0 { Ok(()) } else { Err(get_error()) }
if ret == 0 {
Ok(())
} else {
Err(get_error())
}
}
fn character<C: ToColor>(&self, x: i16, y: i16, c: char, color: C) -> Result<(), String> {
let ret = unsafe { primitives::characterColor(self.raw(), x, y, c as c_char, color.as_u32()) };
if ret == 0 { Ok(()) } else { Err(get_error()) }
let ret =
unsafe { primitives::characterColor(self.raw(), x, y, c as c_char, color.as_u32()) };
if ret == 0 {
Ok(())
} else {
Err(get_error())
}
}
fn string<C: ToColor>(&self, x: i16, y: i16, s: &str, color: C) -> Result<(), String> {
@@ -451,13 +604,18 @@ impl<T> DrawRenderer for Canvas<T> where T: ::render::RenderTarget {
let buf = cstring.as_bytes().as_ptr();
primitives::stringColor(self.raw(), x, y, buf as *mut c_char, color.as_u32())
};
if ret == 0 { Ok(()) } else { Err(get_error()) }
if ret == 0 {
Ok(())
} else {
Err(get_error())
}
}
}
/// Sets or resets the current global font data.
pub fn set_font<'b, F>(fontdata: F, cw: u32, ch: u32)
where F: Into<Option<&'b [u8]>>
where
F: Into<Option<&'b [u8]>>,
{
let actual_fontdata = match fontdata.into() {
None => ptr::null(),

View File

@@ -1,18 +1,23 @@
//! Surface Rotozoomer
use get_error;
use libc::c_int;
use ::surface::Surface;
use ::get_error;
pub use std::f64::consts::PI;
use surface::Surface;
use sys::gfx::rotozoom;
/// `RotozoomSurface` for work with rust-sdl2 Surface type
pub trait RotozoomSurface {
/// Rotates and zooms a surface and optional anti-aliasing.
fn rotozoom(&self, angle: f64, zoom: f64, smooth: bool) -> Result<Surface, String>;
/// Rotates and zooms a surface with different horizontal and vertical scaling factors and optional anti-aliasing.
fn rotozoom_xy(&self, angle: f64, zoomx: f64, zoomy: f64, smooth: bool) -> Result<Surface, String>;
fn rotozoom_xy(
&self,
angle: f64,
zoomx: f64,
zoomy: f64,
smooth: bool,
) -> Result<Surface, String>;
/// Zoom a surface by independent horizontal and vertical factors with optional smoothing.
fn zoom(&self, zoomx: f64, zoomy: f64, smooth: bool) -> Result<Surface, String>;
/// Shrink a surface by an integer ratio using averaging.
@@ -23,16 +28,20 @@ pub trait RotozoomSurface {
impl<'a> RotozoomSurface for Surface<'a> {
fn rotozoom(&self, angle: f64, zoom: f64, smooth: bool) -> Result<Surface, String> {
let raw = unsafe {
rotozoom::rotozoomSurface(self.raw(), angle, zoom, smooth as c_int)
};
let raw = unsafe { rotozoom::rotozoomSurface(self.raw(), angle, zoom, smooth as c_int) };
if (raw as *mut ()).is_null() {
Err(get_error())
} else {
unsafe { Ok(Surface::from_ll(raw)) }
}
}
fn rotozoom_xy(&self, angle: f64, zoomx: f64, zoomy: f64, smooth: bool) -> Result<Surface, String> {
fn rotozoom_xy(
&self,
angle: f64,
zoomx: f64,
zoomy: f64,
smooth: bool,
) -> Result<Surface, String> {
let raw = unsafe {
rotozoom::rotozoomSurfaceXY(self.raw(), angle, zoomx, zoomy, smooth as c_int)
};
@@ -43,9 +52,7 @@ impl<'a> RotozoomSurface for Surface<'a> {
}
}
fn zoom(&self, zoomx: f64, zoomy: f64, smooth: bool) -> Result<Surface, String> {
let raw = unsafe {
rotozoom::zoomSurface(self.raw(), zoomx, zoomy, smooth as c_int)
};
let raw = unsafe { rotozoom::zoomSurface(self.raw(), zoomx, zoomy, smooth as c_int) };
if (raw as *mut ()).is_null() {
Err(get_error())
} else {
@@ -53,9 +60,8 @@ impl<'a> RotozoomSurface for Surface<'a> {
}
}
fn shrink(&self, factorx: i32, factory: i32) -> Result<Surface, String> {
let raw = unsafe {
rotozoom::shrinkSurface(self.raw(), factorx as c_int, factory as c_int)
};
let raw =
unsafe { rotozoom::shrinkSurface(self.raw(), factorx as c_int, factory as c_int) };
if (raw as *mut ()).is_null() {
Err(get_error())
} else {
@@ -63,9 +69,7 @@ impl<'a> RotozoomSurface for Surface<'a> {
}
}
fn rotate_90deg(&self, turns: i32) -> Result<Surface, String> {
let raw = unsafe {
rotozoom::rotateSurface90Degrees(self.raw(), turns as c_int)
};
let raw = unsafe { rotozoom::rotateSurface90Degrees(self.raw(), turns as c_int) };
if (raw as *mut ()).is_null() {
Err(get_error())
} else {
@@ -77,20 +81,47 @@ impl<'a> RotozoomSurface for Surface<'a> {
pub fn get_zoom_size(width: i32, height: i32, zoomx: f64, zoomy: f64) -> (i32, i32) {
let mut w: c_int = 0;
let mut h: c_int = 0;
unsafe { rotozoom::zoomSurfaceSize(width as c_int, height as c_int, zoomx, zoomy, &mut w, &mut h) }
unsafe {
rotozoom::zoomSurfaceSize(
width as c_int,
height as c_int,
zoomx,
zoomy,
&mut w,
&mut h,
)
}
(w as i32, h as i32)
}
pub fn get_rotozoom_size(width: i32, height: i32, angle: f64, zoom: f64) -> (i32, i32) {
let mut w: c_int = 0;
let mut h: c_int = 0;
unsafe { rotozoom::rotozoomSurfaceSize(width as c_int, height as c_int, angle, zoom, &mut w, &mut h) }
unsafe {
rotozoom::rotozoomSurfaceSize(width as c_int, height as c_int, angle, zoom, &mut w, &mut h)
}
(w as i32, h as i32)
}
pub fn get_rotozoom_xy_size(width: i32, height: i32, angle: f64, zoomx: f64, zoomy: f64) -> (i32, i32) {
pub fn get_rotozoom_xy_size(
width: i32,
height: i32,
angle: f64,
zoomx: f64,
zoomy: f64,
) -> (i32, i32) {
let mut w: c_int = 0;
let mut h: c_int = 0;
unsafe { rotozoom::rotozoomSurfaceSizeXY(width as c_int, height as c_int, angle, zoomx, zoomy, &mut w, &mut h) }
unsafe {
rotozoom::rotozoomSurfaceSizeXY(
width as c_int,
height as c_int,
angle,
zoomx,
zoomy,
&mut w,
&mut h,
)
}
(w as i32, h as i32)
}

View File

@@ -1,9 +1,9 @@
//! Haptic Functions
use crate::sys;
use crate::HapticSubsystem;
use crate::common::{validate_int, IntegerOrSdlError};
use crate::get_error;
use crate::HapticSubsystem;
impl HapticSubsystem {
/// Attempt to open the joystick at index `joystick_index` and return its haptic device.
@@ -35,11 +35,12 @@ pub struct Haptic {
raw: *mut sys::SDL_Haptic,
}
impl Haptic {
#[inline]
#[doc(alias = "SDL_HapticRumblePlay")]
pub fn subsystem(&self) -> &HapticSubsystem { &self.subsystem }
pub fn subsystem(&self) -> &HapticSubsystem {
&self.subsystem
}
/// Run a simple rumble effect on the haptic device.
pub fn rumble_play(&mut self, strength: f32, duration: u32) {
@@ -53,7 +54,6 @@ impl Haptic {
}
}
impl Drop for Haptic {
#[doc(alias = "SDL_HapticClose")]
fn drop(&mut self) {

View File

@@ -1,13 +1,13 @@
use std::ffi::{CString, CStr};
use crate::sys;
use libc::c_char;
use std::ffi::{CStr, CString};
const VIDEO_MINIMIZE_ON_FOCUS_LOSS: &str = "SDL_VIDEO_MINIMIZE_ON_FOCUS_LOSS";
pub enum Hint {
Default,
Normal,
Override
Override,
}
/// A hint that specifies whether a fullscreen [Window](../video/Window.t.html) will be
@@ -45,7 +45,11 @@ pub fn set_video_minimize_on_focus_loss(value: bool) -> bool {
/// Hints will replace existing hints of their priority and lower.
/// Environment variables are considered to have override priority.
pub fn set_video_minimize_on_focus_loss_with_priority(value: bool, priority: &Hint) -> bool {
set_with_priority(VIDEO_MINIMIZE_ON_FOCUS_LOSS, if value { "1" } else { "0" }, priority)
set_with_priority(
VIDEO_MINIMIZE_ON_FOCUS_LOSS,
if value { "1" } else { "0" },
priority,
)
}
/// A hint that specifies whether a fullscreen [Window](../video/Window.t.html) will be
@@ -69,16 +73,19 @@ pub fn get_video_minimize_on_focus_loss() -> bool {
"1" => true,
_ => false,
},
_ => true
_ => true,
}
}
#[doc(alias = "SDL_SetHint")]
pub fn set(name: &str, value: &str) -> bool{
pub fn set(name: &str, value: &str) -> bool {
let name = CString::new(name).unwrap();
let value = CString::new(value).unwrap();
unsafe {
sys::SDL_SetHint(name.as_ptr() as *const c_char, value.as_ptr() as *const c_char) == sys::SDL_bool::SDL_TRUE
sys::SDL_SetHint(
name.as_ptr() as *const c_char,
value.as_ptr() as *const c_char,
) == sys::SDL_bool::SDL_TRUE
}
}
@@ -94,7 +101,11 @@ pub fn get(name: &str) -> Option<String> {
if res.is_null() {
None
} else {
Some(str::from_utf8(CStr::from_ptr(res as *const _).to_bytes()).unwrap().to_owned())
Some(
str::from_utf8(CStr::from_ptr(res as *const _).to_bytes())
.unwrap()
.to_owned(),
)
}
}
}
@@ -107,10 +118,14 @@ pub fn set_with_priority(name: &str, value: &str, priority: &Hint) -> bool {
let priority_val = match *priority {
Hint::Normal => sys::SDL_HintPriority::SDL_HINT_NORMAL,
Hint::Override => sys::SDL_HintPriority::SDL_HINT_OVERRIDE,
Hint::Default => sys::SDL_HintPriority::SDL_HINT_DEFAULT
Hint::Default => sys::SDL_HintPriority::SDL_HINT_DEFAULT,
};
unsafe {
sys::SDL_SetHintWithPriority(name.as_ptr() as *const c_char, value.as_ptr() as *const c_char, priority_val) == sys::SDL_bool::SDL_TRUE
sys::SDL_SetHintWithPriority(
name.as_ptr() as *const c_char,
value.as_ptr() as *const c_char,
priority_val,
) == sys::SDL_bool::SDL_TRUE
}
}

View File

@@ -20,16 +20,16 @@
//! features = ["image"]
//! ```
use std::os::raw::{c_int, c_char};
use get_error;
use render::{Texture, TextureCreator};
use rwops::RWops;
use std::ffi::CString;
use std::os::raw::{c_char, c_int};
use std::path::Path;
use surface::Surface;
use render::{TextureCreator, Texture};
use rwops::RWops;
use version::Version;
use get_error;
use sys;
use sys::image;
use version::Version;
bitflags! {
/// InitFlags are passed to init() to control which subsystem
@@ -61,7 +61,6 @@ impl ::std::fmt::Display for InitFlag {
}
}
/// Static method extensions for creating Surfaces
pub trait LoadSurface: Sized {
// Self is only returned here to type hint to the compiler.

View File

@@ -1,13 +1,13 @@
use crate::sys;
use crate::sys::SDL_JoystickPowerLevel;
use crate::JoystickSubsystem;
use crate::get_error;
use crate::clear_error;
use std::ffi::{CString, CStr, NulError};
use std::fmt::{Display, Formatter, Error};
use libc::c_char;
use crate::common::{validate_int, IntegerOrSdlError};
use crate::get_error;
use crate::JoystickSubsystem;
use libc::c_char;
use std::ffi::{CStr, CString, NulError};
use std::fmt::{Display, Error, Formatter};
impl JoystickSubsystem {
/// Retrieve the total number of attached joysticks *and* controllers identified by SDL.
@@ -24,8 +24,7 @@ impl JoystickSubsystem {
/// Attempt to open the joystick at index `joystick_index` and return it.
#[doc(alias = "SDL_JoystickOpen")]
pub fn open(&self, joystick_index: u32)
-> Result<Joystick, IntegerOrSdlError> {
pub fn open(&self, joystick_index: u32) -> Result<Joystick, IntegerOrSdlError> {
use crate::common::IntegerOrSdlError::*;
let joystick_index = validate_int(joystick_index, "joystick_index")?;
@@ -36,7 +35,7 @@ impl JoystickSubsystem {
} else {
Ok(Joystick {
subsystem: self.clone(),
raw: joystick
raw: joystick,
})
}
}
@@ -53,7 +52,10 @@ impl JoystickSubsystem {
Err(SdlError(get_error()))
} else {
Ok(unsafe {
CStr::from_ptr(c_str as *const _).to_str().unwrap().to_string()
CStr::from_ptr(c_str as *const _)
.to_str()
.unwrap()
.to_string()
})
}
}
@@ -85,8 +87,7 @@ impl JoystickSubsystem {
/// Return `true` if joystick events are processed.
#[doc(alias = "SDL_JoystickEventState")]
pub fn event_state(&self) -> bool {
unsafe { sys::SDL_JoystickEventState(sys::SDL_QUERY as i32)
== sys::SDL_ENABLE as i32 }
unsafe { sys::SDL_JoystickEventState(sys::SDL_QUERY as i32) == sys::SDL_ENABLE as i32 }
}
/// Force joystick update when not using the event loop
@@ -95,55 +96,55 @@ impl JoystickSubsystem {
pub fn update(&self) {
unsafe { sys::SDL_JoystickUpdate() };
}
}
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
#[repr(i32)]
pub enum PowerLevel {
Unknown = SDL_JoystickPowerLevel::SDL_JOYSTICK_POWER_UNKNOWN as i32,
Empty = SDL_JoystickPowerLevel::SDL_JOYSTICK_POWER_EMPTY as i32,
Low = SDL_JoystickPowerLevel::SDL_JOYSTICK_POWER_LOW as i32,
Medium = SDL_JoystickPowerLevel::SDL_JOYSTICK_POWER_MEDIUM as i32,
Full = SDL_JoystickPowerLevel::SDL_JOYSTICK_POWER_FULL as i32,
Wired = SDL_JoystickPowerLevel::SDL_JOYSTICK_POWER_WIRED as i32,
Empty = SDL_JoystickPowerLevel::SDL_JOYSTICK_POWER_EMPTY as i32,
Low = SDL_JoystickPowerLevel::SDL_JOYSTICK_POWER_LOW as i32,
Medium = SDL_JoystickPowerLevel::SDL_JOYSTICK_POWER_MEDIUM as i32,
Full = SDL_JoystickPowerLevel::SDL_JOYSTICK_POWER_FULL as i32,
Wired = SDL_JoystickPowerLevel::SDL_JOYSTICK_POWER_WIRED as i32,
}
impl PowerLevel {
pub fn from_ll(raw: SDL_JoystickPowerLevel) -> PowerLevel {
match raw {
SDL_JoystickPowerLevel::SDL_JOYSTICK_POWER_UNKNOWN => PowerLevel::Unknown,
SDL_JoystickPowerLevel::SDL_JOYSTICK_POWER_EMPTY => PowerLevel::Empty,
SDL_JoystickPowerLevel::SDL_JOYSTICK_POWER_LOW => PowerLevel::Low,
SDL_JoystickPowerLevel::SDL_JOYSTICK_POWER_MEDIUM => PowerLevel::Medium,
SDL_JoystickPowerLevel::SDL_JOYSTICK_POWER_FULL => PowerLevel::Full,
SDL_JoystickPowerLevel::SDL_JOYSTICK_POWER_WIRED => PowerLevel::Wired,
_ => panic!("Unexpected power level: {:?}", raw),
SDL_JoystickPowerLevel::SDL_JOYSTICK_POWER_EMPTY => PowerLevel::Empty,
SDL_JoystickPowerLevel::SDL_JOYSTICK_POWER_LOW => PowerLevel::Low,
SDL_JoystickPowerLevel::SDL_JOYSTICK_POWER_MEDIUM => PowerLevel::Medium,
SDL_JoystickPowerLevel::SDL_JOYSTICK_POWER_FULL => PowerLevel::Full,
SDL_JoystickPowerLevel::SDL_JOYSTICK_POWER_WIRED => PowerLevel::Wired,
_ => panic!("Unexpected power level: {:?}", raw),
}
}
pub fn to_ll(self) -> SDL_JoystickPowerLevel {
match self {
PowerLevel::Unknown => SDL_JoystickPowerLevel::SDL_JOYSTICK_POWER_UNKNOWN,
PowerLevel::Empty => SDL_JoystickPowerLevel::SDL_JOYSTICK_POWER_EMPTY,
PowerLevel::Low => SDL_JoystickPowerLevel::SDL_JOYSTICK_POWER_LOW,
PowerLevel::Medium => SDL_JoystickPowerLevel::SDL_JOYSTICK_POWER_MEDIUM,
PowerLevel::Full => SDL_JoystickPowerLevel::SDL_JOYSTICK_POWER_FULL,
PowerLevel::Wired => SDL_JoystickPowerLevel::SDL_JOYSTICK_POWER_WIRED,
PowerLevel::Empty => SDL_JoystickPowerLevel::SDL_JOYSTICK_POWER_EMPTY,
PowerLevel::Low => SDL_JoystickPowerLevel::SDL_JOYSTICK_POWER_LOW,
PowerLevel::Medium => SDL_JoystickPowerLevel::SDL_JOYSTICK_POWER_MEDIUM,
PowerLevel::Full => SDL_JoystickPowerLevel::SDL_JOYSTICK_POWER_FULL,
PowerLevel::Wired => SDL_JoystickPowerLevel::SDL_JOYSTICK_POWER_WIRED,
}
}
}
/// Wrapper around the `SDL_Joystick` object
pub struct Joystick {
subsystem: JoystickSubsystem,
raw: *mut sys::SDL_Joystick
raw: *mut sys::SDL_Joystick,
}
impl Joystick {
#[inline]
pub const fn subsystem(&self) -> &JoystickSubsystem { &self.subsystem }
pub const fn subsystem(&self) -> &JoystickSubsystem {
&self.subsystem
}
/// Return the name of the joystick or an empty string if no name
/// is found.
@@ -378,17 +379,19 @@ impl Joystick {
/// the effect ending immediately after starting due to an overflow.
/// Use some smaller, "huge enough" number instead.
#[doc(alias = "SDL_JoystickRumble")]
pub fn set_rumble(&mut self,
low_frequency_rumble: u16,
high_frequency_rumble: u16,
duration_ms: u32)
-> Result<(), IntegerOrSdlError>
{
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)
sys::SDL_JoystickRumble(
self.raw,
low_frequency_rumble,
high_frequency_rumble,
duration_ms,
)
};
if result != 0 {
@@ -453,7 +456,7 @@ impl Guid {
// maybe I'm wrong?
let mut buf = [0; 33];
let len = buf.len() as i32;
let len = buf.len() as i32;
let c_str = buf.as_mut_ptr();
unsafe {
@@ -467,7 +470,10 @@ impl Guid {
String::new()
} else {
unsafe {
CStr::from_ptr(c_str as *const _).to_str().unwrap().to_string()
CStr::from_ptr(c_str as *const _)
.to_str()
.unwrap()
.to_string()
}
}
}
@@ -490,34 +496,34 @@ impl Display for Guid {
/// is how the SDL2 docs present it anyway (using macros).
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum HatState {
Centered = 0,
Up = 0x01,
Right = 0x02,
Down = 0x04,
Left = 0x08,
RightUp = 0x02 | 0x01,
Centered = 0,
Up = 0x01,
Right = 0x02,
Down = 0x04,
Left = 0x08,
RightUp = 0x02 | 0x01,
RightDown = 0x02 | 0x04,
LeftUp = 0x08 | 0x01,
LeftDown = 0x08 | 0x04,
LeftUp = 0x08 | 0x01,
LeftDown = 0x08 | 0x04,
}
impl HatState {
pub fn from_raw(raw: u8) -> HatState {
match raw {
0 => HatState::Centered,
1 => HatState::Up,
2 => HatState::Right,
4 => HatState::Down,
8 => HatState::Left,
3 => HatState::RightUp,
6 => HatState::RightDown,
9 => HatState::LeftUp,
0 => HatState::Centered,
1 => HatState::Up,
2 => HatState::Right,
4 => HatState::Down,
8 => HatState::Left,
3 => HatState::RightUp,
6 => HatState::RightDown,
9 => HatState::LeftUp,
12 => HatState::LeftDown,
// The Xinput driver on Windows can report hat states on certain hardware that don't
// make any sense from a gameplay perspective, and so aren't worth putting in the
// HatState enumeration.
_ => HatState::Centered,
_ => HatState::Centered,
}
}
@@ -533,7 +539,6 @@ impl HatState {
HatState::LeftUp => 9,
HatState::LeftDown => 12,
}
}
}

View File

@@ -1,7 +1,7 @@
#![allow(unreachable_patterns)]
use std::ffi::{CString, CStr};
use libc::c_char;
use std::ffi::{CStr, CString};
use std::mem::transmute;
use crate::sys;
@@ -9,241 +9,241 @@ use crate::sys;
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
#[repr(i32)]
pub enum Keycode {
Backspace = sys::SDLK_BACKSPACE as i32,
Tab = sys::SDLK_TAB as i32,
Return = sys::SDLK_RETURN as i32,
Escape = sys::SDLK_ESCAPE as i32,
Space = sys::SDLK_SPACE as i32,
Exclaim = sys::SDLK_EXCLAIM as i32,
Quotedbl = sys::SDLK_QUOTEDBL as i32,
Hash = sys::SDLK_HASH as i32,
Dollar = sys::SDLK_DOLLAR as i32,
Percent = sys::SDLK_PERCENT as i32,
Ampersand = sys::SDLK_AMPERSAND as i32,
Quote = sys::SDLK_QUOTE as i32,
LeftParen = sys::SDLK_LEFTPAREN as i32,
RightParen = sys::SDLK_RIGHTPAREN as i32,
Asterisk = sys::SDLK_ASTERISK as i32,
Plus = sys::SDLK_PLUS as i32,
Comma = sys::SDLK_COMMA as i32,
Minus = sys::SDLK_MINUS as i32,
Period = sys::SDLK_PERIOD as i32,
Slash = sys::SDLK_SLASH as i32,
Num0 = sys::SDLK_0 as i32,
Num1 = sys::SDLK_1 as i32,
Num2 = sys::SDLK_2 as i32,
Num3 = sys::SDLK_3 as i32,
Num4 = sys::SDLK_4 as i32,
Num5 = sys::SDLK_5 as i32,
Num6 = sys::SDLK_6 as i32,
Num7 = sys::SDLK_7 as i32,
Num8 = sys::SDLK_8 as i32,
Num9 = sys::SDLK_9 as i32,
Colon = sys::SDLK_COLON as i32,
Semicolon = sys::SDLK_SEMICOLON as i32,
Less = sys::SDLK_LESS as i32,
Equals = sys::SDLK_EQUALS as i32,
Greater = sys::SDLK_GREATER as i32,
Question = sys::SDLK_QUESTION as i32,
At = sys::SDLK_AT as i32,
LeftBracket = sys::SDLK_LEFTBRACKET as i32,
Backslash = sys::SDLK_BACKSLASH as i32,
RightBracket = sys::SDLK_RIGHTBRACKET as i32,
Caret = sys::SDLK_CARET as i32,
Underscore = sys::SDLK_UNDERSCORE as i32,
Backquote = sys::SDLK_BACKQUOTE as i32,
A = sys::SDLK_a as i32,
B = sys::SDLK_b as i32,
C = sys::SDLK_c as i32,
D = sys::SDLK_d as i32,
E = sys::SDLK_e as i32,
F = sys::SDLK_f as i32,
G = sys::SDLK_g as i32,
H = sys::SDLK_h as i32,
I = sys::SDLK_i as i32,
J = sys::SDLK_j as i32,
K = sys::SDLK_k as i32,
L = sys::SDLK_l as i32,
M = sys::SDLK_m as i32,
N = sys::SDLK_n as i32,
O = sys::SDLK_o as i32,
P = sys::SDLK_p as i32,
Q = sys::SDLK_q as i32,
R = sys::SDLK_r as i32,
S = sys::SDLK_s as i32,
T = sys::SDLK_t as i32,
U = sys::SDLK_u as i32,
V = sys::SDLK_v as i32,
W = sys::SDLK_w as i32,
X = sys::SDLK_x as i32,
Y = sys::SDLK_y as i32,
Z = sys::SDLK_z as i32,
Delete = sys::SDLK_DELETE as i32,
CapsLock = sys::SDLK_CAPSLOCK as i32,
F1 = sys::SDLK_F1 as i32,
F2 = sys::SDLK_F2 as i32,
F3 = sys::SDLK_F3 as i32,
F4 = sys::SDLK_F4 as i32,
F5 = sys::SDLK_F5 as i32,
F6 = sys::SDLK_F6 as i32,
F7 = sys::SDLK_F7 as i32,
F8 = sys::SDLK_F8 as i32,
F9 = sys::SDLK_F9 as i32,
F10 = sys::SDLK_F10 as i32,
F11 = sys::SDLK_F11 as i32,
F12 = sys::SDLK_F12 as i32,
PrintScreen = sys::SDLK_PRINTSCREEN as i32,
ScrollLock = sys::SDLK_SCROLLLOCK as i32,
Pause = sys::SDLK_PAUSE as i32,
Insert = sys::SDLK_INSERT as i32,
Home = sys::SDLK_HOME as i32,
PageUp = sys::SDLK_PAGEUP as i32,
End = sys::SDLK_END as i32,
PageDown = sys::SDLK_PAGEDOWN as i32,
Right = sys::SDLK_RIGHT as i32,
Left = sys::SDLK_LEFT as i32,
Down = sys::SDLK_DOWN as i32,
Up = sys::SDLK_UP as i32,
NumLockClear = sys::SDLK_NUMLOCKCLEAR as i32,
KpDivide = sys::SDLK_KP_DIVIDE as i32,
KpMultiply = sys::SDLK_KP_MULTIPLY as i32,
KpMinus = sys::SDLK_KP_MINUS as i32,
KpPlus = sys::SDLK_KP_PLUS as i32,
KpEnter = sys::SDLK_KP_ENTER as i32,
Kp1 = sys::SDLK_KP_1 as i32,
Kp2 = sys::SDLK_KP_2 as i32,
Kp3 = sys::SDLK_KP_3 as i32,
Kp4 = sys::SDLK_KP_4 as i32,
Kp5 = sys::SDLK_KP_5 as i32,
Kp6 = sys::SDLK_KP_6 as i32,
Kp7 = sys::SDLK_KP_7 as i32,
Kp8 = sys::SDLK_KP_8 as i32,
Kp9 = sys::SDLK_KP_9 as i32,
Kp0 = sys::SDLK_KP_0 as i32,
KpPeriod = sys::SDLK_KP_PERIOD as i32,
Application = sys::SDLK_APPLICATION as i32,
Power = sys::SDLK_POWER as i32,
KpEquals = sys::SDLK_KP_EQUALS as i32,
F13 = sys::SDLK_F13 as i32,
F14 = sys::SDLK_F14 as i32,
F15 = sys::SDLK_F15 as i32,
F16 = sys::SDLK_F16 as i32,
F17 = sys::SDLK_F17 as i32,
F18 = sys::SDLK_F18 as i32,
F19 = sys::SDLK_F19 as i32,
F20 = sys::SDLK_F20 as i32,
F21 = sys::SDLK_F21 as i32,
F22 = sys::SDLK_F22 as i32,
F23 = sys::SDLK_F23 as i32,
F24 = sys::SDLK_F24 as i32,
Execute = sys::SDLK_EXECUTE as i32,
Help = sys::SDLK_HELP as i32,
Menu = sys::SDLK_MENU as i32,
Select = sys::SDLK_SELECT as i32,
Stop = sys::SDLK_STOP as i32,
Again = sys::SDLK_AGAIN as i32,
Undo = sys::SDLK_UNDO as i32,
Cut = sys::SDLK_CUT as i32,
Copy = sys::SDLK_COPY as i32,
Paste = sys::SDLK_PASTE as i32,
Find = sys::SDLK_FIND as i32,
Mute = sys::SDLK_MUTE as i32,
VolumeUp = sys::SDLK_VOLUMEUP as i32,
VolumeDown = sys::SDLK_VOLUMEDOWN as i32,
KpComma = sys::SDLK_KP_COMMA as i32,
KpEqualsAS400 = sys::SDLK_KP_EQUALSAS400 as i32,
AltErase = sys::SDLK_ALTERASE as i32,
Sysreq = sys::SDLK_SYSREQ as i32,
Cancel = sys::SDLK_CANCEL as i32,
Clear = sys::SDLK_CLEAR as i32,
Prior = sys::SDLK_PRIOR as i32,
Return2 = sys::SDLK_RETURN2 as i32,
Separator = sys::SDLK_SEPARATOR as i32,
Out = sys::SDLK_OUT as i32,
Oper = sys::SDLK_OPER as i32,
ClearAgain = sys::SDLK_CLEARAGAIN as i32,
CrSel = sys::SDLK_CRSEL as i32,
ExSel = sys::SDLK_EXSEL as i32,
Kp00 = sys::SDLK_KP_00 as i32,
Kp000 = sys::SDLK_KP_000 as i32,
Backspace = sys::SDLK_BACKSPACE as i32,
Tab = sys::SDLK_TAB as i32,
Return = sys::SDLK_RETURN as i32,
Escape = sys::SDLK_ESCAPE as i32,
Space = sys::SDLK_SPACE as i32,
Exclaim = sys::SDLK_EXCLAIM as i32,
Quotedbl = sys::SDLK_QUOTEDBL as i32,
Hash = sys::SDLK_HASH as i32,
Dollar = sys::SDLK_DOLLAR as i32,
Percent = sys::SDLK_PERCENT as i32,
Ampersand = sys::SDLK_AMPERSAND as i32,
Quote = sys::SDLK_QUOTE as i32,
LeftParen = sys::SDLK_LEFTPAREN as i32,
RightParen = sys::SDLK_RIGHTPAREN as i32,
Asterisk = sys::SDLK_ASTERISK as i32,
Plus = sys::SDLK_PLUS as i32,
Comma = sys::SDLK_COMMA as i32,
Minus = sys::SDLK_MINUS as i32,
Period = sys::SDLK_PERIOD as i32,
Slash = sys::SDLK_SLASH as i32,
Num0 = sys::SDLK_0 as i32,
Num1 = sys::SDLK_1 as i32,
Num2 = sys::SDLK_2 as i32,
Num3 = sys::SDLK_3 as i32,
Num4 = sys::SDLK_4 as i32,
Num5 = sys::SDLK_5 as i32,
Num6 = sys::SDLK_6 as i32,
Num7 = sys::SDLK_7 as i32,
Num8 = sys::SDLK_8 as i32,
Num9 = sys::SDLK_9 as i32,
Colon = sys::SDLK_COLON as i32,
Semicolon = sys::SDLK_SEMICOLON as i32,
Less = sys::SDLK_LESS as i32,
Equals = sys::SDLK_EQUALS as i32,
Greater = sys::SDLK_GREATER as i32,
Question = sys::SDLK_QUESTION as i32,
At = sys::SDLK_AT as i32,
LeftBracket = sys::SDLK_LEFTBRACKET as i32,
Backslash = sys::SDLK_BACKSLASH as i32,
RightBracket = sys::SDLK_RIGHTBRACKET as i32,
Caret = sys::SDLK_CARET as i32,
Underscore = sys::SDLK_UNDERSCORE as i32,
Backquote = sys::SDLK_BACKQUOTE as i32,
A = sys::SDLK_a as i32,
B = sys::SDLK_b as i32,
C = sys::SDLK_c as i32,
D = sys::SDLK_d as i32,
E = sys::SDLK_e as i32,
F = sys::SDLK_f as i32,
G = sys::SDLK_g as i32,
H = sys::SDLK_h as i32,
I = sys::SDLK_i as i32,
J = sys::SDLK_j as i32,
K = sys::SDLK_k as i32,
L = sys::SDLK_l as i32,
M = sys::SDLK_m as i32,
N = sys::SDLK_n as i32,
O = sys::SDLK_o as i32,
P = sys::SDLK_p as i32,
Q = sys::SDLK_q as i32,
R = sys::SDLK_r as i32,
S = sys::SDLK_s as i32,
T = sys::SDLK_t as i32,
U = sys::SDLK_u as i32,
V = sys::SDLK_v as i32,
W = sys::SDLK_w as i32,
X = sys::SDLK_x as i32,
Y = sys::SDLK_y as i32,
Z = sys::SDLK_z as i32,
Delete = sys::SDLK_DELETE as i32,
CapsLock = sys::SDLK_CAPSLOCK as i32,
F1 = sys::SDLK_F1 as i32,
F2 = sys::SDLK_F2 as i32,
F3 = sys::SDLK_F3 as i32,
F4 = sys::SDLK_F4 as i32,
F5 = sys::SDLK_F5 as i32,
F6 = sys::SDLK_F6 as i32,
F7 = sys::SDLK_F7 as i32,
F8 = sys::SDLK_F8 as i32,
F9 = sys::SDLK_F9 as i32,
F10 = sys::SDLK_F10 as i32,
F11 = sys::SDLK_F11 as i32,
F12 = sys::SDLK_F12 as i32,
PrintScreen = sys::SDLK_PRINTSCREEN as i32,
ScrollLock = sys::SDLK_SCROLLLOCK as i32,
Pause = sys::SDLK_PAUSE as i32,
Insert = sys::SDLK_INSERT as i32,
Home = sys::SDLK_HOME as i32,
PageUp = sys::SDLK_PAGEUP as i32,
End = sys::SDLK_END as i32,
PageDown = sys::SDLK_PAGEDOWN as i32,
Right = sys::SDLK_RIGHT as i32,
Left = sys::SDLK_LEFT as i32,
Down = sys::SDLK_DOWN as i32,
Up = sys::SDLK_UP as i32,
NumLockClear = sys::SDLK_NUMLOCKCLEAR as i32,
KpDivide = sys::SDLK_KP_DIVIDE as i32,
KpMultiply = sys::SDLK_KP_MULTIPLY as i32,
KpMinus = sys::SDLK_KP_MINUS as i32,
KpPlus = sys::SDLK_KP_PLUS as i32,
KpEnter = sys::SDLK_KP_ENTER as i32,
Kp1 = sys::SDLK_KP_1 as i32,
Kp2 = sys::SDLK_KP_2 as i32,
Kp3 = sys::SDLK_KP_3 as i32,
Kp4 = sys::SDLK_KP_4 as i32,
Kp5 = sys::SDLK_KP_5 as i32,
Kp6 = sys::SDLK_KP_6 as i32,
Kp7 = sys::SDLK_KP_7 as i32,
Kp8 = sys::SDLK_KP_8 as i32,
Kp9 = sys::SDLK_KP_9 as i32,
Kp0 = sys::SDLK_KP_0 as i32,
KpPeriod = sys::SDLK_KP_PERIOD as i32,
Application = sys::SDLK_APPLICATION as i32,
Power = sys::SDLK_POWER as i32,
KpEquals = sys::SDLK_KP_EQUALS as i32,
F13 = sys::SDLK_F13 as i32,
F14 = sys::SDLK_F14 as i32,
F15 = sys::SDLK_F15 as i32,
F16 = sys::SDLK_F16 as i32,
F17 = sys::SDLK_F17 as i32,
F18 = sys::SDLK_F18 as i32,
F19 = sys::SDLK_F19 as i32,
F20 = sys::SDLK_F20 as i32,
F21 = sys::SDLK_F21 as i32,
F22 = sys::SDLK_F22 as i32,
F23 = sys::SDLK_F23 as i32,
F24 = sys::SDLK_F24 as i32,
Execute = sys::SDLK_EXECUTE as i32,
Help = sys::SDLK_HELP as i32,
Menu = sys::SDLK_MENU as i32,
Select = sys::SDLK_SELECT as i32,
Stop = sys::SDLK_STOP as i32,
Again = sys::SDLK_AGAIN as i32,
Undo = sys::SDLK_UNDO as i32,
Cut = sys::SDLK_CUT as i32,
Copy = sys::SDLK_COPY as i32,
Paste = sys::SDLK_PASTE as i32,
Find = sys::SDLK_FIND as i32,
Mute = sys::SDLK_MUTE as i32,
VolumeUp = sys::SDLK_VOLUMEUP as i32,
VolumeDown = sys::SDLK_VOLUMEDOWN as i32,
KpComma = sys::SDLK_KP_COMMA as i32,
KpEqualsAS400 = sys::SDLK_KP_EQUALSAS400 as i32,
AltErase = sys::SDLK_ALTERASE as i32,
Sysreq = sys::SDLK_SYSREQ as i32,
Cancel = sys::SDLK_CANCEL as i32,
Clear = sys::SDLK_CLEAR as i32,
Prior = sys::SDLK_PRIOR as i32,
Return2 = sys::SDLK_RETURN2 as i32,
Separator = sys::SDLK_SEPARATOR as i32,
Out = sys::SDLK_OUT as i32,
Oper = sys::SDLK_OPER as i32,
ClearAgain = sys::SDLK_CLEARAGAIN as i32,
CrSel = sys::SDLK_CRSEL as i32,
ExSel = sys::SDLK_EXSEL as i32,
Kp00 = sys::SDLK_KP_00 as i32,
Kp000 = sys::SDLK_KP_000 as i32,
ThousandsSeparator = sys::SDLK_THOUSANDSSEPARATOR as i32,
DecimalSeparator = sys::SDLK_DECIMALSEPARATOR as i32,
CurrencyUnit = sys::SDLK_CURRENCYUNIT as i32,
CurrencySubUnit = sys::SDLK_CURRENCYSUBUNIT as i32,
KpLeftParen = sys::SDLK_KP_LEFTPAREN as i32,
KpRightParen = sys::SDLK_KP_RIGHTPAREN as i32,
KpLeftBrace = sys::SDLK_KP_LEFTBRACE as i32,
KpRightBrace = sys::SDLK_KP_RIGHTBRACE as i32,
KpTab = sys::SDLK_KP_TAB as i32,
KpBackspace = sys::SDLK_KP_BACKSPACE as i32,
KpA = sys::SDLK_KP_A as i32,
KpB = sys::SDLK_KP_B as i32,
KpC = sys::SDLK_KP_C as i32,
KpD = sys::SDLK_KP_D as i32,
KpE = sys::SDLK_KP_E as i32,
KpF = sys::SDLK_KP_F as i32,
KpXor = sys::SDLK_KP_XOR as i32,
KpPower = sys::SDLK_KP_POWER as i32,
KpPercent = sys::SDLK_KP_PERCENT as i32,
KpLess = sys::SDLK_KP_LESS as i32,
KpGreater = sys::SDLK_KP_GREATER as i32,
KpAmpersand = sys::SDLK_KP_AMPERSAND as i32,
KpDblAmpersand = sys::SDLK_KP_DBLAMPERSAND as i32,
KpVerticalBar = sys::SDLK_KP_VERTICALBAR as i32,
KpDblVerticalBar = sys::SDLK_KP_DBLVERTICALBAR as i32,
KpColon = sys::SDLK_KP_COLON as i32,
KpHash = sys::SDLK_KP_HASH as i32,
KpSpace = sys::SDLK_KP_SPACE as i32,
KpAt = sys::SDLK_KP_AT as i32,
KpExclam = sys::SDLK_KP_EXCLAM as i32,
KpMemStore = sys::SDLK_KP_MEMSTORE as i32,
KpMemRecall = sys::SDLK_KP_MEMRECALL as i32,
KpMemClear = sys::SDLK_KP_MEMCLEAR as i32,
KpMemAdd = sys::SDLK_KP_MEMADD as i32,
KpMemSubtract = sys::SDLK_KP_MEMSUBTRACT as i32,
KpMemMultiply = sys::SDLK_KP_MEMMULTIPLY as i32,
KpMemDivide = sys::SDLK_KP_MEMDIVIDE as i32,
KpPlusMinus = sys::SDLK_KP_PLUSMINUS as i32,
KpClear = sys::SDLK_KP_CLEAR as i32,
KpClearEntry = sys::SDLK_KP_CLEARENTRY as i32,
KpBinary = sys::SDLK_KP_BINARY as i32,
KpOctal = sys::SDLK_KP_OCTAL as i32,
KpDecimal = sys::SDLK_KP_DECIMAL as i32,
KpHexadecimal = sys::SDLK_KP_HEXADECIMAL as i32,
LCtrl = sys::SDLK_LCTRL as i32,
LShift = sys::SDLK_LSHIFT as i32,
LAlt = sys::SDLK_LALT as i32,
LGui = sys::SDLK_LGUI as i32,
RCtrl = sys::SDLK_RCTRL as i32,
RShift = sys::SDLK_RSHIFT as i32,
RAlt = sys::SDLK_RALT as i32,
RGui = sys::SDLK_RGUI as i32,
Mode = sys::SDLK_MODE as i32,
AudioNext = sys::SDLK_AUDIONEXT as i32,
AudioPrev = sys::SDLK_AUDIOPREV as i32,
AudioStop = sys::SDLK_AUDIOSTOP as i32,
AudioPlay = sys::SDLK_AUDIOPLAY as i32,
AudioMute = sys::SDLK_AUDIOMUTE as i32,
MediaSelect = sys::SDLK_MEDIASELECT as i32,
Www = sys::SDLK_WWW as i32,
Mail = sys::SDLK_MAIL as i32,
Calculator = sys::SDLK_CALCULATOR as i32,
Computer = sys::SDLK_COMPUTER as i32,
AcSearch = sys::SDLK_AC_SEARCH as i32,
AcHome = sys::SDLK_AC_HOME as i32,
AcBack = sys::SDLK_AC_BACK as i32,
AcForward = sys::SDLK_AC_FORWARD as i32,
AcStop = sys::SDLK_AC_STOP as i32,
AcRefresh = sys::SDLK_AC_REFRESH as i32,
AcBookmarks = sys::SDLK_AC_BOOKMARKS as i32,
BrightnessDown = sys::SDLK_BRIGHTNESSDOWN as i32,
BrightnessUp = sys::SDLK_BRIGHTNESSUP as i32,
DisplaySwitch = sys::SDLK_DISPLAYSWITCH as i32,
KbdIllumToggle = sys::SDLK_KBDILLUMTOGGLE as i32,
KbdIllumDown = sys::SDLK_KBDILLUMDOWN as i32,
KbdIllumUp = sys::SDLK_KBDILLUMUP as i32,
Eject = sys::SDLK_EJECT as i32,
Sleep = sys::SDLK_SLEEP as i32,
DecimalSeparator = sys::SDLK_DECIMALSEPARATOR as i32,
CurrencyUnit = sys::SDLK_CURRENCYUNIT as i32,
CurrencySubUnit = sys::SDLK_CURRENCYSUBUNIT as i32,
KpLeftParen = sys::SDLK_KP_LEFTPAREN as i32,
KpRightParen = sys::SDLK_KP_RIGHTPAREN as i32,
KpLeftBrace = sys::SDLK_KP_LEFTBRACE as i32,
KpRightBrace = sys::SDLK_KP_RIGHTBRACE as i32,
KpTab = sys::SDLK_KP_TAB as i32,
KpBackspace = sys::SDLK_KP_BACKSPACE as i32,
KpA = sys::SDLK_KP_A as i32,
KpB = sys::SDLK_KP_B as i32,
KpC = sys::SDLK_KP_C as i32,
KpD = sys::SDLK_KP_D as i32,
KpE = sys::SDLK_KP_E as i32,
KpF = sys::SDLK_KP_F as i32,
KpXor = sys::SDLK_KP_XOR as i32,
KpPower = sys::SDLK_KP_POWER as i32,
KpPercent = sys::SDLK_KP_PERCENT as i32,
KpLess = sys::SDLK_KP_LESS as i32,
KpGreater = sys::SDLK_KP_GREATER as i32,
KpAmpersand = sys::SDLK_KP_AMPERSAND as i32,
KpDblAmpersand = sys::SDLK_KP_DBLAMPERSAND as i32,
KpVerticalBar = sys::SDLK_KP_VERTICALBAR as i32,
KpDblVerticalBar = sys::SDLK_KP_DBLVERTICALBAR as i32,
KpColon = sys::SDLK_KP_COLON as i32,
KpHash = sys::SDLK_KP_HASH as i32,
KpSpace = sys::SDLK_KP_SPACE as i32,
KpAt = sys::SDLK_KP_AT as i32,
KpExclam = sys::SDLK_KP_EXCLAM as i32,
KpMemStore = sys::SDLK_KP_MEMSTORE as i32,
KpMemRecall = sys::SDLK_KP_MEMRECALL as i32,
KpMemClear = sys::SDLK_KP_MEMCLEAR as i32,
KpMemAdd = sys::SDLK_KP_MEMADD as i32,
KpMemSubtract = sys::SDLK_KP_MEMSUBTRACT as i32,
KpMemMultiply = sys::SDLK_KP_MEMMULTIPLY as i32,
KpMemDivide = sys::SDLK_KP_MEMDIVIDE as i32,
KpPlusMinus = sys::SDLK_KP_PLUSMINUS as i32,
KpClear = sys::SDLK_KP_CLEAR as i32,
KpClearEntry = sys::SDLK_KP_CLEARENTRY as i32,
KpBinary = sys::SDLK_KP_BINARY as i32,
KpOctal = sys::SDLK_KP_OCTAL as i32,
KpDecimal = sys::SDLK_KP_DECIMAL as i32,
KpHexadecimal = sys::SDLK_KP_HEXADECIMAL as i32,
LCtrl = sys::SDLK_LCTRL as i32,
LShift = sys::SDLK_LSHIFT as i32,
LAlt = sys::SDLK_LALT as i32,
LGui = sys::SDLK_LGUI as i32,
RCtrl = sys::SDLK_RCTRL as i32,
RShift = sys::SDLK_RSHIFT as i32,
RAlt = sys::SDLK_RALT as i32,
RGui = sys::SDLK_RGUI as i32,
Mode = sys::SDLK_MODE as i32,
AudioNext = sys::SDLK_AUDIONEXT as i32,
AudioPrev = sys::SDLK_AUDIOPREV as i32,
AudioStop = sys::SDLK_AUDIOSTOP as i32,
AudioPlay = sys::SDLK_AUDIOPLAY as i32,
AudioMute = sys::SDLK_AUDIOMUTE as i32,
MediaSelect = sys::SDLK_MEDIASELECT as i32,
Www = sys::SDLK_WWW as i32,
Mail = sys::SDLK_MAIL as i32,
Calculator = sys::SDLK_CALCULATOR as i32,
Computer = sys::SDLK_COMPUTER as i32,
AcSearch = sys::SDLK_AC_SEARCH as i32,
AcHome = sys::SDLK_AC_HOME as i32,
AcBack = sys::SDLK_AC_BACK as i32,
AcForward = sys::SDLK_AC_FORWARD as i32,
AcStop = sys::SDLK_AC_STOP as i32,
AcRefresh = sys::SDLK_AC_REFRESH as i32,
AcBookmarks = sys::SDLK_AC_BOOKMARKS as i32,
BrightnessDown = sys::SDLK_BRIGHTNESSDOWN as i32,
BrightnessUp = sys::SDLK_BRIGHTNESSUP as i32,
DisplaySwitch = sys::SDLK_DISPLAYSWITCH as i32,
KbdIllumToggle = sys::SDLK_KBDILLUMTOGGLE as i32,
KbdIllumDown = sys::SDLK_KBDILLUMDOWN as i32,
KbdIllumUp = sys::SDLK_KBDILLUMUP as i32,
Eject = sys::SDLK_EJECT as i32,
Sleep = sys::SDLK_SLEEP as i32,
}
impl Keycode {
@@ -251,243 +251,243 @@ impl Keycode {
use self::Keycode::*;
let n = n as u32;
Some( match unsafe { transmute(n) } {
sys::SDLK_BACKSPACE => Backspace,
sys::SDLK_TAB => Tab,
sys::SDLK_RETURN => Return,
sys::SDLK_ESCAPE => Escape,
sys::SDLK_SPACE => Space,
sys::SDLK_EXCLAIM => Exclaim,
sys::SDLK_QUOTEDBL => Quotedbl,
sys::SDLK_HASH => Hash,
sys::SDLK_DOLLAR => Dollar,
sys::SDLK_PERCENT => Percent,
sys::SDLK_AMPERSAND => Ampersand,
sys::SDLK_QUOTE => Quote,
sys::SDLK_LEFTPAREN => LeftParen,
sys::SDLK_RIGHTPAREN => RightParen,
sys::SDLK_ASTERISK => Asterisk,
sys::SDLK_PLUS => Plus,
sys::SDLK_COMMA => Comma,
sys::SDLK_MINUS => Minus,
sys::SDLK_PERIOD => Period,
sys::SDLK_SLASH => Slash,
sys::SDLK_0 => Num0,
sys::SDLK_1 => Num1,
sys::SDLK_2 => Num2,
sys::SDLK_3 => Num3,
sys::SDLK_4 => Num4,
sys::SDLK_5 => Num5,
sys::SDLK_6 => Num6,
sys::SDLK_7 => Num7,
sys::SDLK_8 => Num8,
sys::SDLK_9 => Num9,
sys::SDLK_COLON => Colon,
sys::SDLK_SEMICOLON => Semicolon,
sys::SDLK_LESS => Less,
sys::SDLK_EQUALS => Equals,
sys::SDLK_GREATER => Greater,
sys::SDLK_QUESTION => Question,
sys::SDLK_AT => At,
sys::SDLK_LEFTBRACKET => LeftBracket,
sys::SDLK_BACKSLASH => Backslash,
sys::SDLK_RIGHTBRACKET => RightBracket,
sys::SDLK_CARET => Caret,
sys::SDLK_UNDERSCORE => Underscore,
sys::SDLK_BACKQUOTE => Backquote,
sys::SDLK_a => A,
sys::SDLK_b => B,
sys::SDLK_c => C,
sys::SDLK_d => D,
sys::SDLK_e => E,
sys::SDLK_f => F,
sys::SDLK_g => G,
sys::SDLK_h => H,
sys::SDLK_i => I,
sys::SDLK_j => J,
sys::SDLK_k => K,
sys::SDLK_l => L,
sys::SDLK_m => M,
sys::SDLK_n => N,
sys::SDLK_o => O,
sys::SDLK_p => P,
sys::SDLK_q => Q,
sys::SDLK_r => R,
sys::SDLK_s => S,
sys::SDLK_t => T,
sys::SDLK_u => U,
sys::SDLK_v => V,
sys::SDLK_w => W,
sys::SDLK_x => X,
sys::SDLK_y => Y,
sys::SDLK_z => Z,
sys::SDLK_DELETE => Delete,
sys::SDLK_CAPSLOCK => CapsLock,
sys::SDLK_F1 => F1,
sys::SDLK_F2 => F2,
sys::SDLK_F3 => F3,
sys::SDLK_F4 => F4,
sys::SDLK_F5 => F5,
sys::SDLK_F6 => F6,
sys::SDLK_F7 => F7,
sys::SDLK_F8 => F8,
sys::SDLK_F9 => F9,
sys::SDLK_F10 => F10,
sys::SDLK_F11 => F11,
sys::SDLK_F12 => F12,
sys::SDLK_PRINTSCREEN => PrintScreen,
sys::SDLK_SCROLLLOCK => ScrollLock,
sys::SDLK_PAUSE => Pause,
sys::SDLK_INSERT => Insert,
sys::SDLK_HOME => Home,
sys::SDLK_PAGEUP => PageUp,
sys::SDLK_END => End,
sys::SDLK_PAGEDOWN => PageDown,
sys::SDLK_RIGHT => Right,
sys::SDLK_LEFT => Left,
sys::SDLK_DOWN => Down,
sys::SDLK_UP => Up,
sys::SDLK_NUMLOCKCLEAR => NumLockClear,
sys::SDLK_KP_DIVIDE => KpDivide,
sys::SDLK_KP_MULTIPLY => KpMultiply,
sys::SDLK_KP_MINUS => KpMinus,
sys::SDLK_KP_PLUS => KpPlus,
sys::SDLK_KP_ENTER => KpEnter,
sys::SDLK_KP_1 => Kp1,
sys::SDLK_KP_2 => Kp2,
sys::SDLK_KP_3 => Kp3,
sys::SDLK_KP_4 => Kp4,
sys::SDLK_KP_5 => Kp5,
sys::SDLK_KP_6 => Kp6,
sys::SDLK_KP_7 => Kp7,
sys::SDLK_KP_8 => Kp8,
sys::SDLK_KP_9 => Kp9,
sys::SDLK_KP_0 => Kp0,
sys::SDLK_KP_PERIOD => KpPeriod,
sys::SDLK_APPLICATION => Application,
sys::SDLK_POWER => Power,
sys::SDLK_KP_EQUALS => KpEquals,
sys::SDLK_F13 => F13,
sys::SDLK_F14 => F14,
sys::SDLK_F15 => F15,
sys::SDLK_F16 => F16,
sys::SDLK_F17 => F17,
sys::SDLK_F18 => F18,
sys::SDLK_F19 => F19,
sys::SDLK_F20 => F20,
sys::SDLK_F21 => F21,
sys::SDLK_F22 => F22,
sys::SDLK_F23 => F23,
sys::SDLK_F24 => F24,
sys::SDLK_EXECUTE => Execute,
sys::SDLK_HELP => Help,
sys::SDLK_MENU => Menu,
sys::SDLK_SELECT => Select,
sys::SDLK_STOP => Stop,
sys::SDLK_AGAIN => Again,
sys::SDLK_UNDO => Undo,
sys::SDLK_CUT => Cut,
sys::SDLK_COPY => Copy,
sys::SDLK_PASTE => Paste,
sys::SDLK_FIND => Find,
sys::SDLK_MUTE => Mute,
sys::SDLK_VOLUMEUP => VolumeUp,
sys::SDLK_VOLUMEDOWN => VolumeDown,
sys::SDLK_KP_COMMA => KpComma,
sys::SDLK_KP_EQUALSAS400 => KpEqualsAS400,
sys::SDLK_ALTERASE => AltErase,
sys::SDLK_SYSREQ => Sysreq,
sys::SDLK_CANCEL => Cancel,
sys::SDLK_CLEAR => Clear,
sys::SDLK_PRIOR => Prior,
sys::SDLK_RETURN2 => Return2,
sys::SDLK_SEPARATOR => Separator,
sys::SDLK_OUT => Out,
sys::SDLK_OPER => Oper,
sys::SDLK_CLEARAGAIN => ClearAgain,
sys::SDLK_CRSEL => CrSel,
sys::SDLK_EXSEL => ExSel,
sys::SDLK_KP_00 => Kp00,
sys::SDLK_KP_000 => Kp000,
sys::SDLK_THOUSANDSSEPARATOR => ThousandsSeparator,
sys::SDLK_DECIMALSEPARATOR => DecimalSeparator,
sys::SDLK_CURRENCYUNIT => CurrencyUnit,
sys::SDLK_CURRENCYSUBUNIT => CurrencySubUnit,
sys::SDLK_KP_LEFTPAREN => KpLeftParen,
sys::SDLK_KP_RIGHTPAREN => KpRightParen,
sys::SDLK_KP_LEFTBRACE => KpLeftBrace,
sys::SDLK_KP_RIGHTBRACE => KpRightBrace,
sys::SDLK_KP_TAB => KpTab,
sys::SDLK_KP_BACKSPACE => KpBackspace,
sys::SDLK_KP_A => KpA,
sys::SDLK_KP_B => KpB,
sys::SDLK_KP_C => KpC,
sys::SDLK_KP_D => KpD,
sys::SDLK_KP_E => KpE,
sys::SDLK_KP_F => KpF,
sys::SDLK_KP_XOR => KpXor,
sys::SDLK_KP_POWER => KpPower,
sys::SDLK_KP_PERCENT => KpPercent,
sys::SDLK_KP_LESS => KpLess,
sys::SDLK_KP_GREATER => KpGreater,
sys::SDLK_KP_AMPERSAND => KpAmpersand,
sys::SDLK_KP_DBLAMPERSAND => KpDblAmpersand,
sys::SDLK_KP_VERTICALBAR => KpVerticalBar,
sys::SDLK_KP_DBLVERTICALBAR => KpDblVerticalBar,
sys::SDLK_KP_COLON => KpColon,
sys::SDLK_KP_HASH => KpHash,
sys::SDLK_KP_SPACE => KpSpace,
sys::SDLK_KP_AT => KpAt,
sys::SDLK_KP_EXCLAM => KpExclam,
sys::SDLK_KP_MEMSTORE => KpMemStore,
sys::SDLK_KP_MEMRECALL => KpMemRecall,
sys::SDLK_KP_MEMCLEAR => KpMemClear,
sys::SDLK_KP_MEMADD => KpMemAdd,
sys::SDLK_KP_MEMSUBTRACT => KpMemSubtract,
sys::SDLK_KP_MEMMULTIPLY => KpMemMultiply,
sys::SDLK_KP_MEMDIVIDE => KpMemDivide,
sys::SDLK_KP_PLUSMINUS => KpPlusMinus,
sys::SDLK_KP_CLEAR => KpClear,
sys::SDLK_KP_CLEARENTRY => KpClearEntry,
sys::SDLK_KP_BINARY => KpBinary,
sys::SDLK_KP_OCTAL => KpOctal,
sys::SDLK_KP_DECIMAL => KpDecimal,
sys::SDLK_KP_HEXADECIMAL => KpHexadecimal,
sys::SDLK_LCTRL => LCtrl,
sys::SDLK_LSHIFT => LShift,
sys::SDLK_LALT => LAlt,
sys::SDLK_LGUI => LGui,
sys::SDLK_RCTRL => RCtrl,
sys::SDLK_RSHIFT => RShift,
sys::SDLK_RALT => RAlt,
sys::SDLK_RGUI => RGui,
sys::SDLK_MODE => Mode,
sys::SDLK_AUDIONEXT => AudioNext,
sys::SDLK_AUDIOPREV => AudioPrev,
sys::SDLK_AUDIOSTOP => AudioStop,
sys::SDLK_AUDIOPLAY => AudioPlay,
sys::SDLK_AUDIOMUTE => AudioMute,
sys::SDLK_MEDIASELECT => MediaSelect,
sys::SDLK_WWW => Www,
sys::SDLK_MAIL => Mail,
sys::SDLK_CALCULATOR => Calculator,
sys::SDLK_COMPUTER => Computer,
sys::SDLK_AC_SEARCH => AcSearch,
sys::SDLK_AC_HOME => AcHome,
sys::SDLK_AC_BACK => AcBack,
sys::SDLK_AC_FORWARD => AcForward,
sys::SDLK_AC_STOP => AcStop,
sys::SDLK_AC_REFRESH => AcRefresh,
sys::SDLK_AC_BOOKMARKS => AcBookmarks,
sys::SDLK_BRIGHTNESSDOWN => BrightnessDown,
sys::SDLK_BRIGHTNESSUP => BrightnessUp,
sys::SDLK_DISPLAYSWITCH => DisplaySwitch,
sys::SDLK_KBDILLUMTOGGLE => KbdIllumToggle,
sys::SDLK_KBDILLUMDOWN => KbdIllumDown,
sys::SDLK_KBDILLUMUP => KbdIllumUp,
sys::SDLK_EJECT => Eject,
sys::SDLK_SLEEP => Sleep,
_ => return None
Some(match unsafe { transmute(n) } {
sys::SDLK_BACKSPACE => Backspace,
sys::SDLK_TAB => Tab,
sys::SDLK_RETURN => Return,
sys::SDLK_ESCAPE => Escape,
sys::SDLK_SPACE => Space,
sys::SDLK_EXCLAIM => Exclaim,
sys::SDLK_QUOTEDBL => Quotedbl,
sys::SDLK_HASH => Hash,
sys::SDLK_DOLLAR => Dollar,
sys::SDLK_PERCENT => Percent,
sys::SDLK_AMPERSAND => Ampersand,
sys::SDLK_QUOTE => Quote,
sys::SDLK_LEFTPAREN => LeftParen,
sys::SDLK_RIGHTPAREN => RightParen,
sys::SDLK_ASTERISK => Asterisk,
sys::SDLK_PLUS => Plus,
sys::SDLK_COMMA => Comma,
sys::SDLK_MINUS => Minus,
sys::SDLK_PERIOD => Period,
sys::SDLK_SLASH => Slash,
sys::SDLK_0 => Num0,
sys::SDLK_1 => Num1,
sys::SDLK_2 => Num2,
sys::SDLK_3 => Num3,
sys::SDLK_4 => Num4,
sys::SDLK_5 => Num5,
sys::SDLK_6 => Num6,
sys::SDLK_7 => Num7,
sys::SDLK_8 => Num8,
sys::SDLK_9 => Num9,
sys::SDLK_COLON => Colon,
sys::SDLK_SEMICOLON => Semicolon,
sys::SDLK_LESS => Less,
sys::SDLK_EQUALS => Equals,
sys::SDLK_GREATER => Greater,
sys::SDLK_QUESTION => Question,
sys::SDLK_AT => At,
sys::SDLK_LEFTBRACKET => LeftBracket,
sys::SDLK_BACKSLASH => Backslash,
sys::SDLK_RIGHTBRACKET => RightBracket,
sys::SDLK_CARET => Caret,
sys::SDLK_UNDERSCORE => Underscore,
sys::SDLK_BACKQUOTE => Backquote,
sys::SDLK_a => A,
sys::SDLK_b => B,
sys::SDLK_c => C,
sys::SDLK_d => D,
sys::SDLK_e => E,
sys::SDLK_f => F,
sys::SDLK_g => G,
sys::SDLK_h => H,
sys::SDLK_i => I,
sys::SDLK_j => J,
sys::SDLK_k => K,
sys::SDLK_l => L,
sys::SDLK_m => M,
sys::SDLK_n => N,
sys::SDLK_o => O,
sys::SDLK_p => P,
sys::SDLK_q => Q,
sys::SDLK_r => R,
sys::SDLK_s => S,
sys::SDLK_t => T,
sys::SDLK_u => U,
sys::SDLK_v => V,
sys::SDLK_w => W,
sys::SDLK_x => X,
sys::SDLK_y => Y,
sys::SDLK_z => Z,
sys::SDLK_DELETE => Delete,
sys::SDLK_CAPSLOCK => CapsLock,
sys::SDLK_F1 => F1,
sys::SDLK_F2 => F2,
sys::SDLK_F3 => F3,
sys::SDLK_F4 => F4,
sys::SDLK_F5 => F5,
sys::SDLK_F6 => F6,
sys::SDLK_F7 => F7,
sys::SDLK_F8 => F8,
sys::SDLK_F9 => F9,
sys::SDLK_F10 => F10,
sys::SDLK_F11 => F11,
sys::SDLK_F12 => F12,
sys::SDLK_PRINTSCREEN => PrintScreen,
sys::SDLK_SCROLLLOCK => ScrollLock,
sys::SDLK_PAUSE => Pause,
sys::SDLK_INSERT => Insert,
sys::SDLK_HOME => Home,
sys::SDLK_PAGEUP => PageUp,
sys::SDLK_END => End,
sys::SDLK_PAGEDOWN => PageDown,
sys::SDLK_RIGHT => Right,
sys::SDLK_LEFT => Left,
sys::SDLK_DOWN => Down,
sys::SDLK_UP => Up,
sys::SDLK_NUMLOCKCLEAR => NumLockClear,
sys::SDLK_KP_DIVIDE => KpDivide,
sys::SDLK_KP_MULTIPLY => KpMultiply,
sys::SDLK_KP_MINUS => KpMinus,
sys::SDLK_KP_PLUS => KpPlus,
sys::SDLK_KP_ENTER => KpEnter,
sys::SDLK_KP_1 => Kp1,
sys::SDLK_KP_2 => Kp2,
sys::SDLK_KP_3 => Kp3,
sys::SDLK_KP_4 => Kp4,
sys::SDLK_KP_5 => Kp5,
sys::SDLK_KP_6 => Kp6,
sys::SDLK_KP_7 => Kp7,
sys::SDLK_KP_8 => Kp8,
sys::SDLK_KP_9 => Kp9,
sys::SDLK_KP_0 => Kp0,
sys::SDLK_KP_PERIOD => KpPeriod,
sys::SDLK_APPLICATION => Application,
sys::SDLK_POWER => Power,
sys::SDLK_KP_EQUALS => KpEquals,
sys::SDLK_F13 => F13,
sys::SDLK_F14 => F14,
sys::SDLK_F15 => F15,
sys::SDLK_F16 => F16,
sys::SDLK_F17 => F17,
sys::SDLK_F18 => F18,
sys::SDLK_F19 => F19,
sys::SDLK_F20 => F20,
sys::SDLK_F21 => F21,
sys::SDLK_F22 => F22,
sys::SDLK_F23 => F23,
sys::SDLK_F24 => F24,
sys::SDLK_EXECUTE => Execute,
sys::SDLK_HELP => Help,
sys::SDLK_MENU => Menu,
sys::SDLK_SELECT => Select,
sys::SDLK_STOP => Stop,
sys::SDLK_AGAIN => Again,
sys::SDLK_UNDO => Undo,
sys::SDLK_CUT => Cut,
sys::SDLK_COPY => Copy,
sys::SDLK_PASTE => Paste,
sys::SDLK_FIND => Find,
sys::SDLK_MUTE => Mute,
sys::SDLK_VOLUMEUP => VolumeUp,
sys::SDLK_VOLUMEDOWN => VolumeDown,
sys::SDLK_KP_COMMA => KpComma,
sys::SDLK_KP_EQUALSAS400 => KpEqualsAS400,
sys::SDLK_ALTERASE => AltErase,
sys::SDLK_SYSREQ => Sysreq,
sys::SDLK_CANCEL => Cancel,
sys::SDLK_CLEAR => Clear,
sys::SDLK_PRIOR => Prior,
sys::SDLK_RETURN2 => Return2,
sys::SDLK_SEPARATOR => Separator,
sys::SDLK_OUT => Out,
sys::SDLK_OPER => Oper,
sys::SDLK_CLEARAGAIN => ClearAgain,
sys::SDLK_CRSEL => CrSel,
sys::SDLK_EXSEL => ExSel,
sys::SDLK_KP_00 => Kp00,
sys::SDLK_KP_000 => Kp000,
sys::SDLK_THOUSANDSSEPARATOR => ThousandsSeparator,
sys::SDLK_DECIMALSEPARATOR => DecimalSeparator,
sys::SDLK_CURRENCYUNIT => CurrencyUnit,
sys::SDLK_CURRENCYSUBUNIT => CurrencySubUnit,
sys::SDLK_KP_LEFTPAREN => KpLeftParen,
sys::SDLK_KP_RIGHTPAREN => KpRightParen,
sys::SDLK_KP_LEFTBRACE => KpLeftBrace,
sys::SDLK_KP_RIGHTBRACE => KpRightBrace,
sys::SDLK_KP_TAB => KpTab,
sys::SDLK_KP_BACKSPACE => KpBackspace,
sys::SDLK_KP_A => KpA,
sys::SDLK_KP_B => KpB,
sys::SDLK_KP_C => KpC,
sys::SDLK_KP_D => KpD,
sys::SDLK_KP_E => KpE,
sys::SDLK_KP_F => KpF,
sys::SDLK_KP_XOR => KpXor,
sys::SDLK_KP_POWER => KpPower,
sys::SDLK_KP_PERCENT => KpPercent,
sys::SDLK_KP_LESS => KpLess,
sys::SDLK_KP_GREATER => KpGreater,
sys::SDLK_KP_AMPERSAND => KpAmpersand,
sys::SDLK_KP_DBLAMPERSAND => KpDblAmpersand,
sys::SDLK_KP_VERTICALBAR => KpVerticalBar,
sys::SDLK_KP_DBLVERTICALBAR => KpDblVerticalBar,
sys::SDLK_KP_COLON => KpColon,
sys::SDLK_KP_HASH => KpHash,
sys::SDLK_KP_SPACE => KpSpace,
sys::SDLK_KP_AT => KpAt,
sys::SDLK_KP_EXCLAM => KpExclam,
sys::SDLK_KP_MEMSTORE => KpMemStore,
sys::SDLK_KP_MEMRECALL => KpMemRecall,
sys::SDLK_KP_MEMCLEAR => KpMemClear,
sys::SDLK_KP_MEMADD => KpMemAdd,
sys::SDLK_KP_MEMSUBTRACT => KpMemSubtract,
sys::SDLK_KP_MEMMULTIPLY => KpMemMultiply,
sys::SDLK_KP_MEMDIVIDE => KpMemDivide,
sys::SDLK_KP_PLUSMINUS => KpPlusMinus,
sys::SDLK_KP_CLEAR => KpClear,
sys::SDLK_KP_CLEARENTRY => KpClearEntry,
sys::SDLK_KP_BINARY => KpBinary,
sys::SDLK_KP_OCTAL => KpOctal,
sys::SDLK_KP_DECIMAL => KpDecimal,
sys::SDLK_KP_HEXADECIMAL => KpHexadecimal,
sys::SDLK_LCTRL => LCtrl,
sys::SDLK_LSHIFT => LShift,
sys::SDLK_LALT => LAlt,
sys::SDLK_LGUI => LGui,
sys::SDLK_RCTRL => RCtrl,
sys::SDLK_RSHIFT => RShift,
sys::SDLK_RALT => RAlt,
sys::SDLK_RGUI => RGui,
sys::SDLK_MODE => Mode,
sys::SDLK_AUDIONEXT => AudioNext,
sys::SDLK_AUDIOPREV => AudioPrev,
sys::SDLK_AUDIOSTOP => AudioStop,
sys::SDLK_AUDIOPLAY => AudioPlay,
sys::SDLK_AUDIOMUTE => AudioMute,
sys::SDLK_MEDIASELECT => MediaSelect,
sys::SDLK_WWW => Www,
sys::SDLK_MAIL => Mail,
sys::SDLK_CALCULATOR => Calculator,
sys::SDLK_COMPUTER => Computer,
sys::SDLK_AC_SEARCH => AcSearch,
sys::SDLK_AC_HOME => AcHome,
sys::SDLK_AC_BACK => AcBack,
sys::SDLK_AC_FORWARD => AcForward,
sys::SDLK_AC_STOP => AcStop,
sys::SDLK_AC_REFRESH => AcRefresh,
sys::SDLK_AC_BOOKMARKS => AcBookmarks,
sys::SDLK_BRIGHTNESSDOWN => BrightnessDown,
sys::SDLK_BRIGHTNESSUP => BrightnessUp,
sys::SDLK_DISPLAYSWITCH => DisplaySwitch,
sys::SDLK_KBDILLUMTOGGLE => KbdIllumToggle,
sys::SDLK_KBDILLUMDOWN => KbdIllumDown,
sys::SDLK_KBDILLUMUP => KbdIllumUp,
sys::SDLK_EJECT => Eject,
sys::SDLK_SLEEP => Sleep,
_ => return None,
})
}
}
@@ -508,9 +508,10 @@ impl Keycode {
pub fn from_scancode(scancode: Scancode) -> Option<Keycode> {
const UNKNOWN: i32 = sys::SDLK_UNKNOWN as i32;
unsafe {
match sys::SDL_GetKeyFromScancode(transmute::<u32, sys::SDL_Scancode>(scancode as u32)) {
match sys::SDL_GetKeyFromScancode(transmute::<u32, sys::SDL_Scancode>(scancode as u32))
{
UNKNOWN => None,
keycode_id => Keycode::from_i32(keycode_id as i32)
keycode_id => Keycode::from_i32(keycode_id as i32),
}
}
}
@@ -522,10 +523,10 @@ impl Keycode {
match CString::new(name) {
Ok(name) => match sys::SDL_GetKeyFromName(name.as_ptr() as *const c_char) {
UNKNOWN => None,
keycode_id => Some(Keycode::from_i32(keycode_id as i32).unwrap())
keycode_id => Some(Keycode::from_i32(keycode_id as i32).unwrap()),
},
// string contains a nul byte - it won't match anything.
Err(_) => None
Err(_) => None,
}
}
}

View File

@@ -1,6 +1,6 @@
use crate::EventPump;
use crate::rect::Rect;
use crate::video::Window;
use crate::EventPump;
use std::fmt;
use std::mem::transmute;
@@ -37,7 +37,7 @@ impl fmt::Display for Mod {
}
pub struct KeyboardState<'a> {
keyboard_state: &'a [u8]
keyboard_state: &'a [u8],
}
impl<'a> KeyboardState<'a> {
@@ -50,9 +50,7 @@ impl<'a> KeyboardState<'a> {
::std::slice::from_raw_parts(state_ptr, count as usize)
};
KeyboardState {
keyboard_state
}
KeyboardState { keyboard_state }
}
/// Returns true if the scancode is pressed.
@@ -73,7 +71,7 @@ impl<'a> KeyboardState<'a> {
pub fn scancodes(&self) -> ScancodeIterator {
ScancodeIterator {
index: 0,
keyboard_state: self.keyboard_state
keyboard_state: self.keyboard_state,
}
}
@@ -102,14 +100,14 @@ impl<'a> KeyboardState<'a> {
/// ```
pub fn pressed_scancodes(&self) -> PressedScancodeIterator {
PressedScancodeIterator {
iter: self.scancodes()
iter: self.scancodes(),
}
}
}
pub struct ScancodeIterator<'a> {
index: i32,
keyboard_state: &'a [u8]
keyboard_state: &'a [u8],
}
impl<'a> Iterator for ScancodeIterator<'a> {
@@ -134,7 +132,7 @@ impl<'a> Iterator for ScancodeIterator<'a> {
}
pub struct PressedScancodeIterator<'a> {
iter: ScancodeIterator<'a>
iter: ScancodeIterator<'a>,
}
impl<'a> Iterator for PressedScancodeIterator<'a> {
@@ -142,7 +140,9 @@ impl<'a> Iterator for PressedScancodeIterator<'a> {
fn next(&mut self) -> Option<Scancode> {
while let Some((scancode, pressed)) = self.iter.next() {
if pressed { return Some(scancode) }
if pressed {
return Some(scancode);
}
}
None
@@ -153,7 +153,7 @@ impl crate::Sdl {
#[inline]
pub fn keyboard(&self) -> KeyboardUtil {
KeyboardUtil {
_sdldrop: self.sdldrop()
_sdldrop: self.sdldrop(),
}
}
}
@@ -162,7 +162,7 @@ impl crate::VideoSubsystem {
#[inline]
pub fn text_input(&self) -> TextInputUtil {
TextInputUtil {
_subsystem: self.clone()
_subsystem: self.clone(),
}
}
}
@@ -175,7 +175,7 @@ impl crate::VideoSubsystem {
/// let focused = sdl_context.keyboard().focused_window_id().is_some();
/// ```
pub struct KeyboardUtil {
_sdldrop: ::std::rc::Rc<crate::SdlDrop>
_sdldrop: ::std::rc::Rc<crate::SdlDrop>,
}
impl KeyboardUtil {
@@ -198,7 +198,9 @@ impl KeyboardUtil {
#[doc(alias = "SDL_SetModState")]
pub fn set_mod_state(&self, flags: Mod) {
unsafe { sys::SDL_SetModState(transmute::<u32, sys::SDL_Keymod>(flags.bits() as u32)); }
unsafe {
sys::SDL_SetModState(transmute::<u32, sys::SDL_Keymod>(flags.bits() as u32));
}
}
}
@@ -214,28 +216,34 @@ impl KeyboardUtil {
/// video_subsystem.text_input().start();
/// ```
pub struct TextInputUtil {
_subsystem: crate::VideoSubsystem
_subsystem: crate::VideoSubsystem,
}
impl TextInputUtil {
#[doc(alias = "SDL_StartTextInput")]
pub fn start(&self) {
unsafe { sys::SDL_StartTextInput(); }
unsafe {
sys::SDL_StartTextInput();
}
}
#[doc(alias = "SDL_IsTextInputActive")]
pub fn is_active(&self, ) -> bool {
pub fn is_active(&self) -> bool {
unsafe { sys::SDL_IsTextInputActive() == sys::SDL_bool::SDL_TRUE }
}
#[doc(alias = "SDL_StopTextInput")]
pub fn stop(&self) {
unsafe { sys::SDL_StopTextInput(); }
unsafe {
sys::SDL_StopTextInput();
}
}
#[doc(alias = "SDL_SetTextInputRect")]
pub fn set_rect(&self, rect: Rect) {
unsafe { sys::SDL_SetTextInputRect(rect.raw() as *mut sys::SDL_Rect); }
unsafe {
sys::SDL_SetTextInputRect(rect.raw() as *mut sys::SDL_Rect);
}
}
#[doc(alias = "SDL_HasScreenKeyboardSupport")]

File diff suppressed because it is too large Load Diff

View File

@@ -1,24 +1,24 @@
//! # Getting started
//!
//! ```rust,no_run
//! extern crate sdl2;
//! extern crate sdl2;
//!
//! use sdl2::pixels::Color;
//! use sdl2::event::Event;
//! use sdl2::keyboard::Keycode;
//! use std::time::Duration;
//!
//!
//! pub fn main() {
//! let sdl_context = sdl2::init().unwrap();
//! let video_subsystem = sdl_context.video().unwrap();
//!
//!
//! let window = video_subsystem.window("rust-sdl2 demo", 800, 600)
//! .position_centered()
//! .build()
//! .unwrap();
//!
//!
//! let mut canvas = window.into_canvas().build().unwrap();
//!
//!
//! canvas.set_draw_color(Color::RGB(0, 255, 255));
//! canvas.clear();
//! canvas.present();
@@ -47,7 +47,6 @@
#![crate_name = "sdl2"]
#![crate_type = "lib"]
#![allow(clippy::cast_lossless, clippy::transmute_ptr_to_ref)]
pub extern crate libc;
@@ -66,38 +65,39 @@ pub use crate::sdl::*;
pub mod clipboard;
pub mod cpuinfo;
#[macro_use] mod macros;
#[macro_use]
mod macros;
pub mod audio;
pub mod controller;
pub mod event;
pub mod filesystem;
pub mod touch;
pub mod joystick;
pub mod controller;
pub mod haptic;
pub mod hint;
pub mod joystick;
pub mod keyboard;
pub mod log;
pub mod messagebox;
pub mod mouse;
pub mod rect;
pub mod surface;
pub mod pixels;
pub mod video;
pub mod timer;
pub mod rect;
pub mod render;
pub mod rwops;
pub mod log;
mod sdl;
pub mod audio;
pub mod surface;
pub mod timer;
pub mod touch;
pub mod version;
pub mod messagebox;
pub mod hint;
pub mod video;
// modules
#[cfg(feature = "ttf")]
pub mod ttf;
#[cfg(feature = "gfx")]
pub mod gfx;
#[cfg(feature = "image")]
pub mod image;
#[cfg(feature = "mixer")]
pub mod mixer;
#[cfg(feature = "gfx")]
pub mod gfx;
#[cfg(feature = "ttf")]
pub mod ttf;
mod common;
// Export return types and such from the common module.

View File

@@ -1,6 +1,6 @@
use crate::sys;
use std::ptr::null_mut;
use std::ffi::{CStr, CString};
use std::ptr::null_mut;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum Category {
@@ -68,17 +68,18 @@ impl Priority {
}
}
fn dummy(_priority: Priority, _category: Category, _message: &str) {
}
fn dummy(_priority: Priority, _category: Category, _message: &str) {}
#[allow(non_upper_case_globals)]
// NEVER make this public
static mut custom_log_fn : fn(Priority, Category, &str) = dummy;
static mut custom_log_fn: fn(Priority, Category, &str) = dummy;
unsafe extern "C" fn rust_sdl2_log_fn(_userdata: *mut libc::c_void,
category: libc::c_int,
priority: sys::SDL_LogPriority,
message: *const libc::c_char) {
unsafe extern "C" fn rust_sdl2_log_fn(
_userdata: *mut libc::c_void,
category: libc::c_int,
priority: sys::SDL_LogPriority,
message: *const libc::c_char,
) {
let category = Category::from_ll(category as u32);
let priority = Priority::from_ll(priority);
let message = CStr::from_ptr(message).to_string_lossy();
@@ -86,7 +87,7 @@ unsafe extern "C" fn rust_sdl2_log_fn(_userdata: *mut libc::c_void,
}
#[doc(alias = "SDL_LogSetOutputFunction")]
pub fn set_output_function(callback : fn(Priority, Category, &str)) {
pub fn set_output_function(callback: fn(Priority, Category, &str)) {
unsafe {
custom_log_fn = callback;
sys::SDL_LogSetOutputFunction(Some(rust_sdl2_log_fn), null_mut());

View File

@@ -1,11 +1,11 @@
use std::error;
use std::ffi::{CString, NulError};
use std::fmt;
use std::os::raw::{c_char, c_int};
use std::ptr;
use std::os::raw::{c_char,c_int};
use crate::video::Window;
use crate::get_error;
use crate::video::Window;
use crate::sys;
@@ -32,16 +32,18 @@ bitflags! {
#[derive(Debug)]
pub struct MessageBoxColorScheme {
pub background:(u8,u8,u8),
pub text:(u8,u8,u8),
pub button_border:(u8,u8,u8),
pub button_background:(u8,u8,u8),
pub button_selected:(u8,u8,u8)
pub background: (u8, u8, u8),
pub text: (u8, u8, u8),
pub button_border: (u8, u8, u8),
pub button_background: (u8, u8, u8),
pub button_selected: (u8, u8, u8),
}
impl Into<sys::SDL_MessageBoxColorScheme> for MessageBoxColorScheme {
fn into(self) -> sys::SDL_MessageBoxColorScheme {
sys::SDL_MessageBoxColorScheme { colors: self.into() }
sys::SDL_MessageBoxColorScheme {
colors: self.into(),
}
}
}
@@ -56,40 +58,42 @@ impl From<sys::SDL_MessageBoxColorScheme> for MessageBoxColorScheme {
/// and should only be used to know which button has been triggered
#[derive(Debug)]
pub struct ButtonData<'a> {
pub flags:MessageBoxButtonFlag,
pub button_id:i32,
pub text:&'a str
pub flags: MessageBoxButtonFlag,
pub button_id: i32,
pub text: &'a str,
}
#[derive(Debug)]
pub enum ClickedButton<'a> {
CloseButton,
CustomButton(&'a ButtonData<'a>)
CustomButton(&'a ButtonData<'a>),
}
impl From<MessageBoxColorScheme> for [sys::SDL_MessageBoxColor ; 5] {
fn from(scheme:MessageBoxColorScheme) -> [sys::SDL_MessageBoxColor ; 5] {
fn to_message_box_color(t:(u8,u8,u8)) -> sys::SDL_MessageBoxColor {
impl From<MessageBoxColorScheme> for [sys::SDL_MessageBoxColor; 5] {
fn from(scheme: MessageBoxColorScheme) -> [sys::SDL_MessageBoxColor; 5] {
fn to_message_box_color(t: (u8, u8, u8)) -> sys::SDL_MessageBoxColor {
sys::SDL_MessageBoxColor {
r:t.0,
g:t.1,
b:t.2
r: t.0,
g: t.1,
b: t.2,
}
};
[to_message_box_color(scheme.background),
to_message_box_color(scheme.text),
to_message_box_color(scheme.button_border),
to_message_box_color(scheme.button_background),
to_message_box_color(scheme.button_selected)]
[
to_message_box_color(scheme.background),
to_message_box_color(scheme.text),
to_message_box_color(scheme.button_border),
to_message_box_color(scheme.button_background),
to_message_box_color(scheme.button_selected),
]
}
}
impl Into<MessageBoxColorScheme> for [sys::SDL_MessageBoxColor ; 5] {
impl Into<MessageBoxColorScheme> for [sys::SDL_MessageBoxColor; 5] {
fn into(self) -> MessageBoxColorScheme {
fn from_message_box_color(prim_color: sys::SDL_MessageBoxColor) -> (u8, u8, u8) {
(prim_color.r, prim_color.g, prim_color.b)
};
MessageBoxColorScheme{
MessageBoxColorScheme {
background: from_message_box_color(self[0]),
text: from_message_box_color(self[1]),
button_border: from_message_box_color(self[2]),
@@ -105,7 +109,7 @@ pub enum ShowMessageError {
InvalidMessage(NulError),
/// Second argument of the tuple (i32) corresponds to the
/// first button_id having an error
InvalidButton(NulError,i32),
InvalidButton(NulError, i32),
SdlError(String),
}
@@ -116,9 +120,8 @@ impl fmt::Display for ShowMessageError {
match *self {
InvalidTitle(ref e) => write!(f, "Invalid title: {}", e),
InvalidMessage(ref e) => write!(f, "Invalid message: {}", e),
InvalidButton(ref e, value) => write!(f,
"Invalid button ({}): {}", value, e),
SdlError(ref e) => write!(f, "SDL error: {}", e)
InvalidButton(ref e, value) => write!(f, "Invalid button ({}): {}", value, e),
SdlError(ref e) => write!(f, "SDL error: {}", e),
}
}
}
@@ -131,7 +134,7 @@ impl error::Error for ShowMessageError {
InvalidTitle(_) => "invalid title",
InvalidMessage(_) => "invalid message",
InvalidButton(..) => "invalid button",
SdlError(ref e) => e
SdlError(ref e) => e,
}
}
}
@@ -142,10 +145,14 @@ impl error::Error for ShowMessageError {
/// If you want to retrieve which button was clicked and customize a bit more
/// your message box, use `show_message_box` instead.
#[doc(alias = "SDL_ShowSimpleMessageBox")]
pub fn show_simple_message_box<'a, W>(flags: MessageBoxFlag, title: &str,
message: &str, window: W)
-> Result<(), ShowMessageError>
where W: Into<Option<&'a Window>>
pub fn show_simple_message_box<'a, W>(
flags: MessageBoxFlag,
title: &str,
message: &str,
window: W,
) -> Result<(), ShowMessageError>
where
W: Into<Option<&'a Window>>,
{
use self::ShowMessageError::*;
let result = unsafe {
@@ -161,7 +168,7 @@ where W: Into<Option<&'a Window>>
flags.bits(),
title.as_ptr() as *const c_char,
message.as_ptr() as *const c_char,
window.into().map_or(ptr::null_mut(), |win| win.raw())
window.into().map_or(ptr::null_mut(), |win| win.raw()),
)
} == 0;
@@ -182,17 +189,23 @@ where W: Into<Option<&'a Window>>
/// has been forcefully closed (Alt-F4, ...)
///
#[doc(alias = "SDL_ShowMessageBox")]
pub fn show_message_box<'a, 'b, W, M>(flags:MessageBoxFlag, buttons:&'a [ButtonData], title:&str,
message:&str, window: W, scheme: M)
-> Result<ClickedButton<'a>,ShowMessageError>
where W: Into<Option<&'b Window>>,
M: Into<Option<MessageBoxColorScheme>>,
pub fn show_message_box<'a, 'b, W, M>(
flags: MessageBoxFlag,
buttons: &'a [ButtonData],
title: &str,
message: &str,
window: W,
scheme: M,
) -> Result<ClickedButton<'a>, ShowMessageError>
where
W: Into<Option<&'b Window>>,
M: Into<Option<MessageBoxColorScheme>>,
{
let window = window.into();
let scheme = scheme.into();
use self::ShowMessageError::*;
let mut button_id : c_int = 0;
let mut button_id: c_int = 0;
let title = match CString::new(title) {
Ok(s) => s,
Err(err) => return Err(InvalidTitle(err)),
@@ -201,41 +214,40 @@ where W: Into<Option<&'b Window>>,
Ok(s) => s,
Err(err) => return Err(InvalidMessage(err)),
};
let button_texts : Result<Vec<_>,(_,i32)> = buttons.iter().map(|b|{
CString::new(b.text).map_err(|e|(e,b.button_id))
}).collect(); // Create CString for every button; and catch any CString Error
let button_texts: Result<Vec<_>, (_, i32)> = buttons
.iter()
.map(|b| CString::new(b.text).map_err(|e| (e, b.button_id)))
.collect(); // Create CString for every button; and catch any CString Error
let button_texts = match button_texts {
Ok(b) => b,
Err(e) => return Err(InvalidButton(e.0,e.1))
Err(e) => return Err(InvalidButton(e.0, e.1)),
};
let raw_buttons : Vec<sys::SDL_MessageBoxButtonData> =
buttons.iter().zip(button_texts.iter()).map(|(b,b_text)|{
sys::SDL_MessageBoxButtonData {
flags:b.flags.bits(),
buttonid:b.button_id as c_int,
text:b_text.as_ptr()
}
}).collect();
let raw_buttons: Vec<sys::SDL_MessageBoxButtonData> = buttons
.iter()
.zip(button_texts.iter())
.map(|(b, b_text)| sys::SDL_MessageBoxButtonData {
flags: b.flags.bits(),
buttonid: b.button_id as c_int,
text: b_text.as_ptr(),
})
.collect();
let result = unsafe {
let msg_box_data = sys::SDL_MessageBoxData {
flags:flags.bits(),
window:window.map_or(ptr::null_mut(), |win| win.raw()),
flags: flags.bits(),
window: window.map_or(ptr::null_mut(), |win| win.raw()),
title: title.as_ptr() as *const c_char,
message: message.as_ptr() as *const c_char,
numbuttons: raw_buttons.len() as c_int,
buttons: raw_buttons.as_ptr(),
colorScheme: if let Some(scheme) = scheme {
&sys::SDL_MessageBoxColorScheme {
colors:From::from(scheme)
colors: From::from(scheme),
} as *const _
} else {
ptr::null()
}
},
};
sys::SDL_ShowMessageBox(
&msg_box_data as *const _,
&mut button_id as &mut _
)
sys::SDL_ShowMessageBox(&msg_box_data as *const _, &mut button_id as &mut _)
} == 0;
if result {
match button_id {

View File

@@ -20,22 +20,22 @@
//! features = ["mixer"]
//! ```
use std::marker::PhantomData;
use audio::AudioFormatNum;
use get_error;
use libc::c_void;
use libc::{c_double, c_int, c_uint};
use rwops::RWops;
use std::borrow::ToOwned;
use std::convert::TryInto;
use std::default;
use std::ffi::{CStr, CString};
use std::fmt;
use std::ffi::{CString, CStr};
use std::str::from_utf8;
use std::borrow::ToOwned;
use std::marker::PhantomData;
use std::path::Path;
use libc::c_void;
use libc::{c_int, c_double, c_uint};
use ::audio::AudioFormatNum;
use ::get_error;
use ::rwops::RWops;
use ::version::Version;
use std::str::from_utf8;
use sys;
use sys::mixer;
use version::Version;
// This comes from SDL_audio.h
#[allow(non_camel_case_types)]
@@ -92,7 +92,6 @@ pub const MAX_VOLUME: i32 = 128;
/// Returns the version of the dynamically linked `SDL_mixer` library
pub fn get_linked_version() -> Version {
unsafe { Version::from_ll(*mixer::Mix_Linked_Version()) }
}
@@ -166,7 +165,6 @@ pub fn init(flags: InitFlag) -> Result<Sdl2MixerContext, String> {
}
}
/// Open the mixer with a certain audio format.
///
/// * `chunksize`: It is recommended to choose values between 256 and 1024, depending on whether
@@ -174,16 +172,19 @@ pub fn init(flags: InitFlag) -> Result<Sdl2MixerContext, String> {
/// work very well on older systems. For instance, a chunk size of 256 will give
/// you a latency of 6ms, while a chunk size of 1024 will give you a latency of 23ms
/// for a frequency of 44100kHz.
pub fn open_audio(frequency: i32,
format: AudioFormat,
channels: i32,
chunksize: i32)
-> Result<(), String> {
pub fn open_audio(
frequency: i32,
format: AudioFormat,
channels: i32,
chunksize: i32,
) -> Result<(), String> {
let ret = unsafe {
mixer::Mix_OpenAudio(frequency as c_int,
format,
channels as c_int,
chunksize as c_int)
mixer::Mix_OpenAudio(
frequency as c_int,
format,
channels as c_int,
chunksize as c_int,
)
};
if ret == 0 {
Ok(())
@@ -221,7 +222,9 @@ pub fn get_chunk_decoders_number() -> i32 {
pub fn get_chunk_decoder(index: i32) -> String {
unsafe {
let name = mixer::Mix_GetChunkDecoder(index as c_int);
from_utf8(CStr::from_ptr(name).to_bytes()).unwrap().to_owned()
from_utf8(CStr::from_ptr(name).to_bytes())
.unwrap()
.to_owned()
}
}
@@ -324,10 +327,8 @@ impl<'a> LoaderRWops<'a> for RWops<'a> {
})
}
}
}
// 4.3 Channels
/// Fader effect type enumerations
@@ -363,7 +364,9 @@ extern "C" fn c_channel_finished_callback(ch: c_int) {
pub fn set_channel_finished(f: fn(Channel)) {
unsafe {
CHANNEL_FINISHED_CALLBACK = Some(f);
mixer::Mix_ChannelFinished(Some(c_channel_finished_callback as extern "C" fn(ch: c_int)));
mixer::Mix_ChannelFinished(Some(
c_channel_finished_callback as extern "C" fn(ch: c_int),
));
}
}
@@ -421,19 +424,22 @@ impl Channel {
self.fade_in_timed(chunk, loops, ms, -1)
}
pub fn fade_in_timed(self,
chunk: &Chunk,
loops: i32,
ms: i32,
ticks: i32)
-> Result<Channel, String> {
pub fn fade_in_timed(
self,
chunk: &Chunk,
loops: i32,
ms: i32,
ticks: i32,
) -> Result<Channel, String> {
let Channel(ch) = self;
let ret = unsafe {
mixer::Mix_FadeInChannelTimed(ch as c_int,
chunk.raw,
loops as c_int,
ms as c_int,
ticks as c_int)
mixer::Mix_FadeInChannelTimed(
ch as c_int,
chunk.raw,
loops as c_int,
ms as c_int,
ticks as c_int,
)
};
if ret == -1 {
Err(get_error())
@@ -495,9 +501,9 @@ impl Channel {
let Channel(ch) = self;
let ret = unsafe { mixer::Mix_FadingChannel(ch as c_int) as c_uint };
match ret {
mixer::Mix_Fading_MIX_FADING_OUT => Fading::FadingOut,
mixer::Mix_Fading_MIX_FADING_IN => Fading::FadingIn,
mixer::Mix_Fading_MIX_NO_FADING | _ => Fading::NoFading
mixer::Mix_Fading_MIX_FADING_OUT => Fading::FadingOut,
mixer::Mix_Fading_MIX_FADING_IN => Fading::FadingIn,
mixer::Mix_Fading_MIX_NO_FADING | _ => Fading::NoFading,
}
}
@@ -717,7 +723,9 @@ pub fn get_music_decoders_number() -> i32 {
pub fn get_music_decoder(index: i32) -> String {
unsafe {
let name = mixer::Mix_GetMusicDecoder(index as c_int);
from_utf8(CStr::from_ptr(name).to_bytes()).unwrap().to_owned()
from_utf8(CStr::from_ptr(name).to_bytes())
.unwrap()
.to_owned()
}
}
@@ -754,7 +762,7 @@ extern "C" fn c_music_finished_hook() {
pub struct Music<'a> {
pub raw: *mut mixer::Mix_Music,
pub owned: bool,
_marker: PhantomData<&'a ()>
_marker: PhantomData<&'a ()>,
}
impl<'a> Drop for Music<'a> {
@@ -793,9 +801,8 @@ impl<'a> Music<'a> {
/// Load music from a static byte buffer.
#[doc(alias = "SDL_RWFromConstMem")]
pub fn from_static_bytes(buf: &'static [u8]) -> Result<Music<'static>, String> {
let rw = unsafe {
sys::SDL_RWFromConstMem(buf.as_ptr() as *const c_void, buf.len() as c_int)
};
let rw =
unsafe { sys::SDL_RWFromConstMem(buf.as_ptr() as *const c_void, buf.len() as c_int) };
if rw.is_null() {
return Err(get_error());
@@ -817,16 +824,16 @@ impl<'a> Music<'a> {
pub fn get_type(&self) -> MusicType {
let ret = unsafe { mixer::Mix_GetMusicType(self.raw) as i32 } as c_uint;
match ret {
mixer::Mix_MusicType_MUS_CMD => MusicType::MusicCmd,
mixer::Mix_MusicType_MUS_WAV => MusicType::MusicWav,
mixer::Mix_MusicType_MUS_MOD => MusicType::MusicMod,
mixer::Mix_MusicType_MUS_MID => MusicType::MusicMid,
mixer::Mix_MusicType_MUS_OGG => MusicType::MusicOgg,
mixer::Mix_MusicType_MUS_MP3 => MusicType::MusicMp3,
mixer::Mix_MusicType_MUS_MP3_MAD_UNUSED => MusicType::MusicMp3Mad,
mixer::Mix_MusicType_MUS_FLAC => MusicType::MusicFlac,
mixer::Mix_MusicType_MUS_MODPLUG_UNUSED => MusicType::MusicModPlug,
mixer::Mix_MusicType_MUS_NONE | _ => MusicType::MusicNone
mixer::Mix_MusicType_MUS_CMD => MusicType::MusicCmd,
mixer::Mix_MusicType_MUS_WAV => MusicType::MusicWav,
mixer::Mix_MusicType_MUS_MOD => MusicType::MusicMod,
mixer::Mix_MusicType_MUS_MID => MusicType::MusicMid,
mixer::Mix_MusicType_MUS_OGG => MusicType::MusicOgg,
mixer::Mix_MusicType_MUS_MP3 => MusicType::MusicMp3,
mixer::Mix_MusicType_MUS_MP3_MAD_UNUSED => MusicType::MusicMp3Mad,
mixer::Mix_MusicType_MUS_FLAC => MusicType::MusicFlac,
mixer::Mix_MusicType_MUS_MODPLUG_UNUSED => MusicType::MusicModPlug,
mixer::Mix_MusicType_MUS_NONE | _ => MusicType::MusicNone,
}
}
@@ -981,9 +988,9 @@ impl<'a> Music<'a> {
pub fn get_fading() -> Fading {
let ret = unsafe { mixer::Mix_FadingMusic() as i32 } as c_uint;
match ret {
mixer::Mix_Fading_MIX_FADING_OUT => Fading::FadingOut,
mixer::Mix_Fading_MIX_FADING_IN => Fading::FadingIn,
mixer::Mix_Fading_MIX_NO_FADING | _ => Fading::NoFading
mixer::Mix_Fading_MIX_FADING_OUT => Fading::FadingOut,
mixer::Mix_Fading_MIX_FADING_IN => Fading::FadingIn,
mixer::Mix_Fading_MIX_NO_FADING | _ => Fading::NoFading,
}
}
}

View File

@@ -28,7 +28,7 @@ pub enum SystemCursor {
}
pub struct Cursor {
raw: *mut sys::SDL_Cursor
raw: *mut sys::SDL_Cursor,
}
impl Drop for Cursor {
@@ -41,31 +41,46 @@ impl Drop for Cursor {
impl Cursor {
#[doc(alias = "SDL_CreateCursor")]
pub fn new(data: &[u8], mask: &[u8], width: i32, height: i32, hot_x: i32, hot_y: i32) -> Result<Cursor, String> {
pub fn new(
data: &[u8],
mask: &[u8],
width: i32,
height: i32,
hot_x: i32,
hot_y: i32,
) -> Result<Cursor, String> {
unsafe {
let raw = sys::SDL_CreateCursor(data.as_ptr(),
mask.as_ptr(),
width as i32, height as i32,
hot_x as i32, hot_y as i32);
let raw = sys::SDL_CreateCursor(
data.as_ptr(),
mask.as_ptr(),
width as i32,
height as i32,
hot_x as i32,
hot_y as i32,
);
if raw.is_null() {
Err(get_error())
} else {
Ok(Cursor{ raw })
Ok(Cursor { raw })
}
}
}
// TODO: figure out how to pass Surface in here correctly
#[doc(alias = "SDL_CreateColorCursor")]
pub fn from_surface<S: AsRef<SurfaceRef>>(surface: S, hot_x: i32, hot_y: i32) -> Result<Cursor, String> {
pub fn from_surface<S: AsRef<SurfaceRef>>(
surface: S,
hot_x: i32,
hot_y: i32,
) -> Result<Cursor, String> {
unsafe {
let raw = sys::SDL_CreateColorCursor(surface.as_ref().raw(), hot_x, hot_y);
if raw.is_null() {
Err(get_error())
} else {
Ok(Cursor{ raw })
Ok(Cursor { raw })
}
}
}
@@ -78,14 +93,16 @@ impl Cursor {
if raw.is_null() {
Err(get_error())
} else {
Ok(Cursor{ raw })
Ok(Cursor { raw })
}
}
}
#[doc(alias = "SDL_SetCursor")]
pub fn set(&self) {
unsafe { sys::SDL_SetCursor(self.raw); }
unsafe {
sys::SDL_SetCursor(self.raw);
}
}
}
@@ -136,23 +153,23 @@ impl MouseWheelDirection {
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum MouseButton {
Unknown = 0,
Left = sys::SDL_BUTTON_LEFT as u8,
Left = sys::SDL_BUTTON_LEFT as u8,
Middle = sys::SDL_BUTTON_MIDDLE as u8,
Right = sys::SDL_BUTTON_RIGHT as u8,
X1 = sys::SDL_BUTTON_X1 as u8,
X2 = sys::SDL_BUTTON_X2 as u8,
Right = sys::SDL_BUTTON_RIGHT as u8,
X1 = sys::SDL_BUTTON_X1 as u8,
X2 = sys::SDL_BUTTON_X2 as u8,
}
impl MouseButton {
#[inline]
pub fn from_ll(button: u8) -> MouseButton {
match button as u32 {
sys::SDL_BUTTON_LEFT => MouseButton::Left,
sys::SDL_BUTTON_LEFT => MouseButton::Left,
sys::SDL_BUTTON_MIDDLE => MouseButton::Middle,
sys::SDL_BUTTON_RIGHT => MouseButton::Right,
sys::SDL_BUTTON_X1 => MouseButton::X1,
sys::SDL_BUTTON_X2 => MouseButton::X2,
_ => MouseButton::Unknown,
sys::SDL_BUTTON_RIGHT => MouseButton::Right,
sys::SDL_BUTTON_X1 => MouseButton::X1,
sys::SDL_BUTTON_X2 => MouseButton::X2,
_ => MouseButton::Unknown,
}
}
}
@@ -161,7 +178,7 @@ impl MouseButton {
pub struct MouseState {
mouse_state: u32,
x: i32,
y: i32
y: i32,
}
impl MouseState {
@@ -169,19 +186,21 @@ impl MouseState {
pub fn new(_e: &EventPump) -> MouseState {
let mut x = 0;
let mut y = 0;
let mouse_state: u32 = unsafe {
sys::SDL_GetMouseState(&mut x, &mut y)
};
let mouse_state: u32 = unsafe { sys::SDL_GetMouseState(&mut x, &mut y) };
MouseState {
mouse_state,
x: x as i32,
y: y as i32
y: y as i32,
}
}
pub fn from_sdl_state(state: u32) -> MouseState {
MouseState { mouse_state : state, x: 0, y: 0 }
MouseState {
mouse_state: state,
x: 0,
y: 0,
}
}
pub fn to_sdl_state(&self) -> u32 {
self.mouse_state
@@ -201,25 +220,39 @@ impl MouseState {
/// e.mouse_state().left()
/// }
/// ```
pub fn left(&self) -> bool { (self.mouse_state & self.button_mask(sys::SDL_BUTTON_LEFT)) != 0 }
pub fn left(&self) -> bool {
(self.mouse_state & self.button_mask(sys::SDL_BUTTON_LEFT)) != 0
}
/// Tests if the middle mouse button was pressed.
pub fn middle(&self) -> bool { (self.mouse_state & self.button_mask(sys::SDL_BUTTON_MIDDLE)) != 0 }
pub fn middle(&self) -> bool {
(self.mouse_state & self.button_mask(sys::SDL_BUTTON_MIDDLE)) != 0
}
/// Tests if the right mouse button was pressed.
pub fn right(&self) -> bool { (self.mouse_state & self.button_mask(sys::SDL_BUTTON_RIGHT)) != 0 }
pub fn right(&self) -> bool {
(self.mouse_state & self.button_mask(sys::SDL_BUTTON_RIGHT)) != 0
}
/// Tests if the X1 mouse button was pressed.
pub fn x1(&self) -> bool { (self.mouse_state & self.button_mask(sys::SDL_BUTTON_X1)) != 0 }
pub fn x1(&self) -> bool {
(self.mouse_state & self.button_mask(sys::SDL_BUTTON_X1)) != 0
}
/// Tests if the X2 mouse button was pressed.
pub fn x2(&self) -> bool { (self.mouse_state & self.button_mask(sys::SDL_BUTTON_X2)) != 0 }
pub fn x2(&self) -> bool {
(self.mouse_state & self.button_mask(sys::SDL_BUTTON_X2)) != 0
}
/// Returns the x coordinate of the state
pub fn x(&self) -> i32 { self.x }
pub fn x(&self) -> i32 {
self.x
}
/// Returns the y coordinate of the state
pub fn y(&self) -> i32 { self.y }
pub fn y(&self) -> i32 {
self.y
}
/// Returns true if the mouse button is pressed.
///
@@ -232,7 +265,7 @@ impl MouseState {
/// }
/// ```
pub fn is_mouse_button_pressed(&self, mouse_button: MouseButton) -> bool {
let mask = 1 << ((mouse_button as u32)-1);
let mask = 1 << ((mouse_button as u32) - 1);
self.mouse_state & mask != 0
}
@@ -258,7 +291,7 @@ impl MouseState {
pub fn mouse_buttons(&self) -> MouseButtonIterator {
MouseButtonIterator {
cur_button: 1,
mouse_state: &self.mouse_state
mouse_state: &self.mouse_state,
}
}
@@ -280,14 +313,14 @@ impl MouseState {
/// ```
pub fn pressed_mouse_buttons(&self) -> PressedMouseButtonIterator {
PressedMouseButtonIterator {
iter: self.mouse_buttons()
iter: self.mouse_buttons(),
}
}
}
pub struct MouseButtonIterator<'a> {
cur_button: u8,
mouse_state: &'a u32
mouse_state: &'a u32,
}
impl<'a> Iterator for MouseButtonIterator<'a> {
@@ -296,7 +329,7 @@ impl<'a> Iterator for MouseButtonIterator<'a> {
fn next(&mut self) -> Option<(MouseButton, bool)> {
if self.cur_button < MouseButton::X2 as u8 + 1 {
let mouse_button = self.cur_button;
let mask = 1 << ((self.cur_button as u32)-1);
let mask = 1 << ((self.cur_button as u32) - 1);
let pressed = self.mouse_state & mask != 0;
self.cur_button += 1;
Some((MouseButton::from_ll(mouse_button), pressed))
@@ -307,7 +340,7 @@ impl<'a> Iterator for MouseButtonIterator<'a> {
}
pub struct PressedMouseButtonIterator<'a> {
iter: MouseButtonIterator<'a>
iter: MouseButtonIterator<'a>,
}
impl<'a> Iterator for PressedMouseButtonIterator<'a> {
@@ -315,7 +348,9 @@ impl<'a> Iterator for PressedMouseButtonIterator<'a> {
fn next(&mut self) -> Option<MouseButton> {
while let Some((mouse_button, pressed)) = self.iter.next() {
if pressed { return Some(mouse_button) }
if pressed {
return Some(mouse_button);
}
}
None
}
@@ -325,7 +360,7 @@ impl crate::Sdl {
#[inline]
pub fn mouse(&self) -> MouseUtil {
MouseUtil {
_sdldrop: self.sdldrop()
_sdldrop: self.sdldrop(),
}
}
}
@@ -339,7 +374,7 @@ impl crate::Sdl {
/// sdl_context.mouse().show_cursor(false);
/// ```
pub struct MouseUtil {
_sdldrop: ::std::rc::Rc<crate::SdlDrop>
_sdldrop: ::std::rc::Rc<crate::SdlDrop>,
}
impl MouseUtil {
@@ -357,13 +392,21 @@ impl MouseUtil {
#[doc(alias = "SDL_WarpMouseInWindow")]
pub fn warp_mouse_in_window(&self, window: &video::Window, x: i32, y: i32) {
unsafe { sys::SDL_WarpMouseInWindow(window.raw(), x, y); }
unsafe {
sys::SDL_WarpMouseInWindow(window.raw(), x, y);
}
}
#[doc(alias = "SDL_SetRelativeMouseMode")]
pub fn set_relative_mouse_mode(&self, on: bool) {
let on = if on { sys::SDL_bool::SDL_TRUE } else { sys::SDL_bool::SDL_FALSE };
unsafe { sys::SDL_SetRelativeMouseMode(on); }
let on = if on {
sys::SDL_bool::SDL_TRUE
} else {
sys::SDL_bool::SDL_FALSE
};
unsafe {
sys::SDL_SetRelativeMouseMode(on);
}
}
#[doc(alias = "SDL_GetRelativeMouseMode")]
@@ -378,12 +421,20 @@ impl MouseUtil {
#[doc(alias = "SDL_ShowCursor")]
pub fn show_cursor(&self, show: bool) {
unsafe { sys::SDL_ShowCursor(show as i32); }
unsafe {
sys::SDL_ShowCursor(show as i32);
}
}
#[doc(alias = "SDL_CaptureMouse")]
pub fn capture(&self, enable: bool) {
let enable = if enable { sys::SDL_bool::SDL_TRUE } else { sys::SDL_bool::SDL_FALSE };
unsafe { sys::SDL_CaptureMouse(enable); }
let enable = if enable {
sys::SDL_bool::SDL_TRUE
} else {
sys::SDL_bool::SDL_FALSE
};
unsafe {
sys::SDL_CaptureMouse(enable);
}
}
}

View File

@@ -8,7 +8,7 @@ use super::{MouseButton, MouseButtonIterator, PressedMouseButtonIterator};
pub struct RelativeMouseState {
mouse_state: u32,
x: i32,
y: i32
y: i32,
}
impl RelativeMouseState {
@@ -24,12 +24,16 @@ impl RelativeMouseState {
RelativeMouseState {
mouse_state,
x: x as i32,
y: y as i32
y: y as i32,
}
}
pub fn from_sdl_state(state: u32) -> RelativeMouseState {
RelativeMouseState { mouse_state : state, x: 0, y: 0 }
RelativeMouseState {
mouse_state: state,
x: 0,
y: 0,
}
}
pub fn to_sdl_state(&self) -> u32 {
self.mouse_state
@@ -49,25 +53,39 @@ impl RelativeMouseState {
/// e.mouse_state().left()
/// }
/// ```
pub fn left(&self) -> bool { (self.mouse_state & self.button_mask(sys::SDL_BUTTON_LEFT)) != 0 }
pub fn left(&self) -> bool {
(self.mouse_state & self.button_mask(sys::SDL_BUTTON_LEFT)) != 0
}
/// Tests if the middle mouse button was pressed.
pub fn middle(&self) -> bool { (self.mouse_state & self.button_mask(sys::SDL_BUTTON_MIDDLE)) != 0 }
pub fn middle(&self) -> bool {
(self.mouse_state & self.button_mask(sys::SDL_BUTTON_MIDDLE)) != 0
}
/// Tests if the right mouse button was pressed.
pub fn right(&self) -> bool { (self.mouse_state & self.button_mask(sys::SDL_BUTTON_RIGHT)) != 0 }
pub fn right(&self) -> bool {
(self.mouse_state & self.button_mask(sys::SDL_BUTTON_RIGHT)) != 0
}
/// Tests if the X1 mouse button was pressed.
pub fn x1(&self) -> bool { (self.mouse_state & self.button_mask(sys::SDL_BUTTON_X1)) != 0 }
pub fn x1(&self) -> bool {
(self.mouse_state & self.button_mask(sys::SDL_BUTTON_X1)) != 0
}
/// Tests if the X2 mouse button was pressed.
pub fn x2(&self) -> bool { (self.mouse_state & self.button_mask(sys::SDL_BUTTON_X2)) != 0 }
pub fn x2(&self) -> bool {
(self.mouse_state & self.button_mask(sys::SDL_BUTTON_X2)) != 0
}
/// Returns the x coordinate of the state
pub fn x(&self) -> i32 { self.x }
pub fn x(&self) -> i32 {
self.x
}
/// Returns the y coordinate of the state
pub fn y(&self) -> i32 { self.y }
pub fn y(&self) -> i32 {
self.y
}
/// Returns true if the mouse button is pressed.
///
@@ -80,7 +98,7 @@ impl RelativeMouseState {
/// }
/// ```
pub fn is_mouse_button_pressed(&self, mouse_button: MouseButton) -> bool {
let mask = 1 << ((mouse_button as u32)-1);
let mask = 1 << ((mouse_button as u32) - 1);
self.mouse_state & mask != 0
}
@@ -106,7 +124,7 @@ impl RelativeMouseState {
pub fn mouse_buttons(&self) -> MouseButtonIterator {
MouseButtonIterator {
cur_button: 1,
mouse_state: &self.mouse_state
mouse_state: &self.mouse_state,
}
}
@@ -128,7 +146,7 @@ impl RelativeMouseState {
/// ```
pub fn pressed_mouse_buttons(&self) -> PressedMouseButtonIterator {
PressedMouseButtonIterator {
iter: self.mouse_buttons()
iter: self.mouse_buttons(),
}
}
}

View File

@@ -1,11 +1,11 @@
use std::mem::transmute;
use std::convert::TryFrom;
use crate::sys;
use std::convert::TryFrom;
use std::mem::transmute;
use crate::get_error;
pub struct Palette {
raw: *mut sys::SDL_Palette
raw: *mut sys::SDL_Palette,
}
impl Palette {
@@ -20,7 +20,9 @@ impl Palette {
// ncolors is a c_int, and validate_int only takes a u32.
// FIXME: Modify validate_int to make this unnecessary
let u32_max = u32::max_value() as usize;
if capacity > u32_max { capacity = u32_max; }
if capacity > u32_max {
capacity = u32_max;
}
match validate_int(capacity as u32, "capacity") {
Ok(len) => len,
@@ -33,9 +35,7 @@ impl Palette {
if raw.is_null() {
Err(get_error())
} else {
Ok(Palette {
raw,
})
Ok(Palette { raw })
}
}
@@ -48,9 +48,8 @@ impl Palette {
let ncolors = colors.len() as ::libc::c_int;
let result = unsafe {
let mut raw_colors: Vec<sys::SDL_Color> = colors.iter()
.map(|color| color.raw())
.collect();
let mut raw_colors: Vec<sys::SDL_Color> =
colors.iter().map(|color| color.raw()).collect();
let pal_ptr = (&mut raw_colors[0]) as *mut sys::SDL_Color;
@@ -76,7 +75,9 @@ impl Palette {
impl Drop for Palette {
#[doc(alias = "SDL_FreePalette")]
fn drop(&mut self) {
unsafe { sys::SDL_FreePalette(self.raw); }
unsafe {
sys::SDL_FreePalette(self.raw);
}
}
}
@@ -84,9 +85,7 @@ impl_raw_accessors!((Palette, *mut sys::SDL_Palette));
#[test]
fn create_palette() {
let colors: Vec<_> = (0 .. 0xff).map(|u| {
Color::RGB(u, 0, 0xff - u)
}).collect();
let colors: Vec<_> = (0..0xff).map(|u| Color::RGB(u, 0, 0xff - u)).collect();
let palette = Palette::with_colors(&colors).unwrap();
@@ -98,7 +97,7 @@ pub struct Color {
pub r: u8,
pub g: u8,
pub b: u8,
pub a: u8
pub a: u8,
}
impl Color {
@@ -123,9 +122,7 @@ impl Color {
pub fn from_u32(format: &PixelFormat, pixel: u32) -> Color {
let (mut r, mut g, mut b, mut a) = (0, 0, 0, 0);
unsafe {
sys::SDL_GetRGBA(pixel, format.raw, &mut r, &mut g, &mut b, &mut a)
};
unsafe { sys::SDL_GetRGBA(pixel, format.raw, &mut r, &mut g, &mut b, &mut a) };
Color::RGBA(r, g, b, a)
}
@@ -146,7 +143,12 @@ impl Color {
// Implemented manually and kept private, because reasons
#[inline]
const fn raw(self) -> sys::SDL_Color {
sys::SDL_Color { r: self.r, g: self.g, b: self.b, a: self.a }
sys::SDL_Color {
r: self.r,
g: self.g,
b: self.b,
a: self.a,
}
}
pub const WHITE: Color = Color::RGBA(255, 255, 255, 255);
@@ -159,7 +161,6 @@ impl Color {
pub const MAGENTA: Color = Color::RGBA(255, 0, 255, 255);
pub const YELLOW: Color = Color::RGBA(255, 255, 0, 255);
pub const CYAN: Color = Color::RGBA(0, 255, 255, 255);
}
impl Into<sys::SDL_Color> for Color {
@@ -174,7 +175,6 @@ impl From<sys::SDL_Color> for Color {
}
}
impl From<(u8, u8, u8)> for Color {
fn from((r, g, b): (u8, u8, u8)) -> Color {
Color::RGB(r, g, b)
@@ -197,15 +197,15 @@ pub struct PixelMasks {
/// The blue mask
pub bmask: u32,
/// The alpha mask
pub amask: u32
pub amask: u32,
}
pub struct PixelFormat {
raw: *mut sys::SDL_PixelFormat
raw: *mut sys::SDL_PixelFormat,
}
impl_raw_accessors!((PixelFormat, *mut sys::SDL_PixelFormat));
impl_raw_constructor!((PixelFormat, PixelFormat (raw: *mut sys::SDL_PixelFormat)));
impl_raw_constructor!((PixelFormat, PixelFormat(raw: *mut sys::SDL_PixelFormat)));
#[repr(i32)]
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
@@ -245,7 +245,7 @@ pub enum PixelFormatEnum {
IYUV = sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_IYUV as i32,
YUY2 = sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_YUY2 as i32,
UYVY = sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_UYVY as i32,
YVYU = sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_YVYU as i32
YVYU = sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_YVYU as i32,
}
// Endianness-agnostic aliases for 32-bit formats
@@ -269,7 +269,13 @@ impl PixelFormatEnum {
#[doc(alias = "SDL_MasksToPixelFormatEnum")]
pub fn from_masks(masks: PixelMasks) -> PixelFormatEnum {
unsafe {
let format = sys::SDL_MasksToPixelFormatEnum(masks.bpp as i32, masks.rmask, masks.gmask, masks.bmask, masks.amask);
let format = sys::SDL_MasksToPixelFormatEnum(
masks.bpp as i32,
masks.rmask,
masks.gmask,
masks.bmask,
masks.amask,
);
PixelFormatEnum::try_from(format as u32).unwrap()
}
}
@@ -283,7 +289,9 @@ impl PixelFormatEnum {
let mut bmask = 0;
let mut amask = 0;
let result = unsafe {
sys::SDL_PixelFormatEnumToMasks(format, &mut bpp, &mut rmask, &mut gmask, &mut bmask, &mut amask)
sys::SDL_PixelFormatEnumToMasks(
format, &mut bpp, &mut rmask, &mut gmask, &mut bmask, &mut amask,
)
};
if result == sys::SDL_bool::SDL_FALSE {
// SDL_FALSE
@@ -294,7 +302,7 @@ impl PixelFormatEnum {
rmask,
gmask,
bmask,
amask
amask,
})
}
}
@@ -309,94 +317,100 @@ impl PixelFormatEnum {
// `height` is the height of the Y component.
// U and V have half the width and height of Y.
pitch * height + 2 * (pitch / 2 * height / 2)
},
_ => pitch * height
}
_ => pitch * height,
}
}
#[allow(clippy::match_same_arms)]
pub fn byte_size_of_pixels(self, num_of_pixels: usize) -> usize {
match self {
PixelFormatEnum::RGB332
=> num_of_pixels,
PixelFormatEnum::RGB444 | PixelFormatEnum::RGB555 |
PixelFormatEnum::BGR555 | PixelFormatEnum::ARGB4444 |
PixelFormatEnum::RGBA4444 | PixelFormatEnum::ABGR4444 |
PixelFormatEnum::BGRA4444 | PixelFormatEnum::ARGB1555 |
PixelFormatEnum::RGBA5551 | PixelFormatEnum::ABGR1555 |
PixelFormatEnum::BGRA5551 | PixelFormatEnum::RGB565 |
PixelFormatEnum::BGR565
=> num_of_pixels * 2,
PixelFormatEnum::RGB24 | PixelFormatEnum::BGR24
=> num_of_pixels * 3,
PixelFormatEnum::RGB888 | PixelFormatEnum::RGBX8888 |
PixelFormatEnum::BGR888 | PixelFormatEnum::BGRX8888 |
PixelFormatEnum::ARGB8888 | PixelFormatEnum::RGBA8888 |
PixelFormatEnum::ABGR8888 | PixelFormatEnum::BGRA8888 |
PixelFormatEnum::ARGB2101010
=> num_of_pixels * 4,
PixelFormatEnum::RGB332 => num_of_pixels,
PixelFormatEnum::RGB444
| PixelFormatEnum::RGB555
| PixelFormatEnum::BGR555
| PixelFormatEnum::ARGB4444
| PixelFormatEnum::RGBA4444
| PixelFormatEnum::ABGR4444
| PixelFormatEnum::BGRA4444
| PixelFormatEnum::ARGB1555
| PixelFormatEnum::RGBA5551
| PixelFormatEnum::ABGR1555
| PixelFormatEnum::BGRA5551
| PixelFormatEnum::RGB565
| PixelFormatEnum::BGR565 => num_of_pixels * 2,
PixelFormatEnum::RGB24 | PixelFormatEnum::BGR24 => num_of_pixels * 3,
PixelFormatEnum::RGB888
| PixelFormatEnum::RGBX8888
| PixelFormatEnum::BGR888
| PixelFormatEnum::BGRX8888
| PixelFormatEnum::ARGB8888
| PixelFormatEnum::RGBA8888
| PixelFormatEnum::ABGR8888
| PixelFormatEnum::BGRA8888
| PixelFormatEnum::ARGB2101010 => num_of_pixels * 4,
// YUV formats
// FIXME: rounding error here?
PixelFormatEnum::YV12 | PixelFormatEnum::IYUV
=> num_of_pixels / 2 * 3,
PixelFormatEnum::YUY2 | PixelFormatEnum::UYVY |
PixelFormatEnum::YVYU
=> num_of_pixels * 2,
PixelFormatEnum::YV12 | PixelFormatEnum::IYUV => num_of_pixels / 2 * 3,
PixelFormatEnum::YUY2 | PixelFormatEnum::UYVY | PixelFormatEnum::YVYU => {
num_of_pixels * 2
}
// Unsupported formats
PixelFormatEnum::Index8
=> num_of_pixels,
PixelFormatEnum::Unknown | PixelFormatEnum::Index1LSB |
PixelFormatEnum::Index1MSB | PixelFormatEnum::Index4LSB |
PixelFormatEnum::Index4MSB
=> panic!("not supported format: {:?}", self),
PixelFormatEnum::Index8 => num_of_pixels,
PixelFormatEnum::Unknown
| PixelFormatEnum::Index1LSB
| PixelFormatEnum::Index1MSB
| PixelFormatEnum::Index4LSB
| PixelFormatEnum::Index4MSB => panic!("not supported format: {:?}", self),
}
}
#[allow(clippy::match_same_arms)]
pub fn byte_size_per_pixel(self) -> usize {
match self {
PixelFormatEnum::RGB332
=> 1,
PixelFormatEnum::RGB444 | PixelFormatEnum::RGB555 |
PixelFormatEnum::BGR555 | PixelFormatEnum::ARGB4444 |
PixelFormatEnum::RGBA4444 | PixelFormatEnum::ABGR4444 |
PixelFormatEnum::BGRA4444 | PixelFormatEnum::ARGB1555 |
PixelFormatEnum::RGBA5551 | PixelFormatEnum::ABGR1555 |
PixelFormatEnum::BGRA5551 | PixelFormatEnum::RGB565 |
PixelFormatEnum::BGR565
=> 2,
PixelFormatEnum::RGB24 | PixelFormatEnum::BGR24
=> 3,
PixelFormatEnum::RGB888 | PixelFormatEnum::RGBX8888 |
PixelFormatEnum::BGR888 | PixelFormatEnum::BGRX8888 |
PixelFormatEnum::ARGB8888 | PixelFormatEnum::RGBA8888 |
PixelFormatEnum::ABGR8888 | PixelFormatEnum::BGRA8888 |
PixelFormatEnum::ARGB2101010
=> 4,
PixelFormatEnum::RGB332 => 1,
PixelFormatEnum::RGB444
| PixelFormatEnum::RGB555
| PixelFormatEnum::BGR555
| PixelFormatEnum::ARGB4444
| PixelFormatEnum::RGBA4444
| PixelFormatEnum::ABGR4444
| PixelFormatEnum::BGRA4444
| PixelFormatEnum::ARGB1555
| PixelFormatEnum::RGBA5551
| PixelFormatEnum::ABGR1555
| PixelFormatEnum::BGRA5551
| PixelFormatEnum::RGB565
| PixelFormatEnum::BGR565 => 2,
PixelFormatEnum::RGB24 | PixelFormatEnum::BGR24 => 3,
PixelFormatEnum::RGB888
| PixelFormatEnum::RGBX8888
| PixelFormatEnum::BGR888
| PixelFormatEnum::BGRX8888
| PixelFormatEnum::ARGB8888
| PixelFormatEnum::RGBA8888
| PixelFormatEnum::ABGR8888
| PixelFormatEnum::BGRA8888
| PixelFormatEnum::ARGB2101010 => 4,
// YUV formats
PixelFormatEnum::YV12 | PixelFormatEnum::IYUV
=> 2,
PixelFormatEnum::YUY2 | PixelFormatEnum::UYVY |
PixelFormatEnum::YVYU
=> 2,
PixelFormatEnum::YV12 | PixelFormatEnum::IYUV => 2,
PixelFormatEnum::YUY2 | PixelFormatEnum::UYVY | PixelFormatEnum::YVYU => 2,
// Unsupported formats
PixelFormatEnum::Index8
=> 1,
PixelFormatEnum::Unknown | PixelFormatEnum::Index1LSB |
PixelFormatEnum::Index1MSB | PixelFormatEnum::Index4LSB |
PixelFormatEnum::Index4MSB
=> panic!("not supported format: {:?}", self),
PixelFormatEnum::Index8 => 1,
PixelFormatEnum::Unknown
| PixelFormatEnum::Index1LSB
| PixelFormatEnum::Index1MSB
| PixelFormatEnum::Index4LSB
| PixelFormatEnum::Index4MSB => panic!("not supported format: {:?}", self),
}
}
pub fn supports_alpha(self) -> bool {
use crate::pixels::PixelFormatEnum::*;
match self {
ARGB4444 | ARGB1555 | ARGB8888 | ARGB2101010 |
ABGR4444 | ABGR1555 | ABGR8888 |
BGRA4444 | BGRA5551 | BGRA8888 |
RGBA4444 | RGBA5551 | RGBA8888 => true,
_ => false
ARGB4444 | ARGB1555 | ARGB8888 | ARGB2101010 | ABGR4444 | ABGR1555 | ABGR8888
| BGRA4444 | BGRA5551 | BGRA8888 | RGBA4444 | RGBA5551 | RGBA8888 => true,
_ => false,
}
}
}
@@ -407,56 +421,56 @@ impl From<PixelFormat> for PixelFormatEnum {
let sdl_pf = *pf.raw;
match PixelFormatEnum::try_from(sdl_pf.format as u32) {
Ok(pfe) => pfe,
Err(()) => panic!("Unknown pixel format: {:?}", sdl_pf.format)
Err(()) => panic!("Unknown pixel format: {:?}", sdl_pf.format),
}
}
}
}
impl TryFrom<u32> for PixelFormatEnum {
type Error = ();
type Error = ();
fn try_from(n: u32) -> Result<Self, Self::Error> {
use self::PixelFormatEnum::*;
Ok( match unsafe { transmute(n) } {
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_UNKNOWN => Unknown,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_INDEX1LSB => Index1LSB,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_INDEX1MSB => Index1MSB,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_INDEX4LSB => Index4LSB,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_INDEX4MSB => Index4MSB,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_INDEX8 => Index8,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_RGB332 => RGB332,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_RGB444 => RGB444,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_RGB555 => RGB555,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_BGR555 => BGR555,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_ARGB4444 => ARGB4444,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_RGBA4444 => RGBA4444,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_ABGR4444 => ABGR4444,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_BGRA4444 => BGRA4444,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_ARGB1555 => ARGB1555,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_RGBA5551 => RGBA5551,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_ABGR1555 => ABGR1555,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_BGRA5551 => BGRA5551,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_RGB565 => RGB565,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_BGR565 => BGR565,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_RGB24 => RGB24,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_BGR24 => BGR24,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_RGB888 => RGB888,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_RGBX8888 => RGBX8888,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_BGR888 => BGR888,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_BGRX8888 => BGRX8888,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_ARGB8888 => ARGB8888,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_RGBA8888 => RGBA8888,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_ABGR8888 => ABGR8888,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_BGRA8888 => BGRA8888,
Ok(match unsafe { transmute(n) } {
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_UNKNOWN => Unknown,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_INDEX1LSB => Index1LSB,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_INDEX1MSB => Index1MSB,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_INDEX4LSB => Index4LSB,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_INDEX4MSB => Index4MSB,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_INDEX8 => Index8,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_RGB332 => RGB332,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_RGB444 => RGB444,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_RGB555 => RGB555,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_BGR555 => BGR555,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_ARGB4444 => ARGB4444,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_RGBA4444 => RGBA4444,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_ABGR4444 => ABGR4444,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_BGRA4444 => BGRA4444,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_ARGB1555 => ARGB1555,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_RGBA5551 => RGBA5551,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_ABGR1555 => ABGR1555,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_BGRA5551 => BGRA5551,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_RGB565 => RGB565,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_BGR565 => BGR565,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_RGB24 => RGB24,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_BGR24 => BGR24,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_RGB888 => RGB888,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_RGBX8888 => RGBX8888,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_BGR888 => BGR888,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_BGRX8888 => BGRX8888,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_ARGB8888 => ARGB8888,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_RGBA8888 => RGBA8888,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_ABGR8888 => ABGR8888,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_BGRA8888 => BGRA8888,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_ARGB2101010 => ARGB2101010,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_YV12 => YV12,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_IYUV => IYUV,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_YUY2 => YUY2,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_UYVY => UYVY,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_YVYU => YVYU,
_ => return Err(()),
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_YV12 => YV12,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_IYUV => IYUV,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_YUY2 => YUY2,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_UYVY => UYVY,
sys::SDL_PixelFormatEnum::SDL_PIXELFORMAT_YVYU => YVYU,
_ => return Err(()),
})
}
}
@@ -477,28 +491,40 @@ impl TryFrom<PixelFormatEnum> for PixelFormat {
}
}
// Just test a round-trip conversion from PixelFormat to
// PixelFormatEnum and back.
#[test]
fn test_pixel_format_enum() {
let pixel_formats = vec![
PixelFormatEnum::RGB332,
PixelFormatEnum::RGB444, PixelFormatEnum::RGB555,
PixelFormatEnum::BGR555, PixelFormatEnum::ARGB4444,
PixelFormatEnum::RGBA4444, PixelFormatEnum::ABGR4444,
PixelFormatEnum::BGRA4444, PixelFormatEnum::ARGB1555,
PixelFormatEnum::RGBA5551, PixelFormatEnum::ABGR1555,
PixelFormatEnum::BGRA5551, PixelFormatEnum::RGB565,
PixelFormatEnum::RGB444,
PixelFormatEnum::RGB555,
PixelFormatEnum::BGR555,
PixelFormatEnum::ARGB4444,
PixelFormatEnum::RGBA4444,
PixelFormatEnum::ABGR4444,
PixelFormatEnum::BGRA4444,
PixelFormatEnum::ARGB1555,
PixelFormatEnum::RGBA5551,
PixelFormatEnum::ABGR1555,
PixelFormatEnum::BGRA5551,
PixelFormatEnum::RGB565,
PixelFormatEnum::BGR565,
PixelFormatEnum::RGB24, PixelFormatEnum::BGR24,
PixelFormatEnum::RGB888, PixelFormatEnum::RGBX8888,
PixelFormatEnum::BGR888, PixelFormatEnum::BGRX8888,
PixelFormatEnum::ARGB8888, PixelFormatEnum::RGBA8888,
PixelFormatEnum::ABGR8888, PixelFormatEnum::BGRA8888,
PixelFormatEnum::RGB24,
PixelFormatEnum::BGR24,
PixelFormatEnum::RGB888,
PixelFormatEnum::RGBX8888,
PixelFormatEnum::BGR888,
PixelFormatEnum::BGRX8888,
PixelFormatEnum::ARGB8888,
PixelFormatEnum::RGBA8888,
PixelFormatEnum::ABGR8888,
PixelFormatEnum::BGRA8888,
PixelFormatEnum::ARGB2101010,
PixelFormatEnum::YV12, PixelFormatEnum::IYUV,
PixelFormatEnum::YUY2, PixelFormatEnum::UYVY,
PixelFormatEnum::YV12,
PixelFormatEnum::IYUV,
PixelFormatEnum::YUY2,
PixelFormatEnum::UYVY,
PixelFormatEnum::YVYU,
PixelFormatEnum::Index8,
// These don't seem to be supported;
@@ -508,7 +534,6 @@ fn test_pixel_format_enum() {
//PixelFormatEnum::Index4MSB
];
let _sdl_context = crate::sdl::init().unwrap();
for format in pixel_formats {
// If we don't support making a surface of a specific format,

View File

@@ -27,13 +27,13 @@ unsafe impl HasRawWindowHandle for Window {
hwnd: unsafe { wm_info.info.win }.window as *mut libc::c_void,
..WindowsHandle::empty()
})
},
}
#[cfg(any(
target_os = "linux",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd",
target_os = "linux",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd",
))]
SDL_SYSWM_WAYLAND => {
use self::raw_window_handle::unix::WaylandHandle;
@@ -42,13 +42,13 @@ unsafe impl HasRawWindowHandle for Window {
display: unsafe { wm_info.info.wl }.display as *mut libc::c_void,
..WaylandHandle::empty()
})
},
}
#[cfg(any(
target_os = "linux",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd",
target_os = "linux",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd",
))]
SDL_SYSWM_X11 => {
use self::raw_window_handle::unix::XlibHandle;
@@ -57,7 +57,7 @@ unsafe impl HasRawWindowHandle for Window {
display: unsafe { wm_info.info.x11 }.display as *mut libc::c_void,
..XlibHandle::empty()
})
},
}
#[cfg(target_os = "macos")]
SDL_SYSWM_COCOA => {
use self::raw_window_handle::macos::MacOSHandle;
@@ -66,7 +66,7 @@ unsafe impl HasRawWindowHandle for Window {
ns_view: 0 as *mut libc::c_void, // consumer of RawWindowHandle should determine this
..MacOSHandle::empty()
})
},
}
#[cfg(any(target_os = "ios"))]
SDL_SYSWM_UIKIT => {
use self::raw_window_handle::ios::IOSHandle;
@@ -75,14 +75,17 @@ unsafe impl HasRawWindowHandle for Window {
ui_view: 0 as *mut libc::c_void, // consumer of RawWindowHandle should determine this
..IOSHandle::empty()
})
},
}
SDL_SYSWM_ANDROID => {
let window_system = match wm_info.subsystem {
SDL_SYSWM_ANDROID => "Android",
_ => unreachable!(),
};
panic!("raw-window-handle support for {} not yet implemented", window_system);
},
panic!(
"raw-window-handle support for {} not yet implemented",
window_system
);
}
x => {
let window_system = match x {
SDL_SYSWM_DIRECTFB => "DirectFB",
@@ -92,7 +95,7 @@ unsafe impl HasRawWindowHandle for Window {
_ => unreachable!(),
};
panic!("{} window system is not supported, please file issue with raw-window-handle: https://github.com/rust-windowing/raw-window-handle/issues/new", window_system);
},
}
}
}
}
@@ -101,7 +104,6 @@ extern "C" {
fn SDL_GetWindowWMInfo(window: *mut SDL_Window, info: *mut SDL_SysWMinfo) -> SDL_bool;
}
#[repr(u32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[allow(non_camel_case_types, dead_code)]
@@ -145,11 +147,11 @@ pub struct SDL_SysWMinfo {
pub info: windows::WindowsSysWMinfo,
#[cfg(any(
target_os = "linux",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd",
target_os = "linux",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd",
))]
pub info: linux::LinuxSysWMinfo,
@@ -216,11 +218,11 @@ pub mod windows {
}
#[cfg(any(
target_os = "linux",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd",
target_os = "linux",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd",
))]
pub mod linux {
#[repr(C)]

View File

@@ -2,11 +2,14 @@
#![allow(const_err)]
use crate::sys;
use std::mem;
use std::ptr;
use std::ops::{Deref, DerefMut, Add, AddAssign, BitAnd, BitOr, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
use std::convert::{AsRef, AsMut};
use std::convert::{AsMut, AsRef};
use std::hash::{Hash, Hasher};
use std::mem;
use std::ops::{
Add, AddAssign, BitAnd, BitOr, Deref, DerefMut, Div, DivAssign, Mul, MulAssign, Neg, Sub,
SubAssign,
};
use std::ptr;
/// The maximal integer value that can be used for rectangles.
///
@@ -72,17 +75,20 @@ pub struct Rect {
impl ::std::fmt::Debug for Rect {
fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
return write!(fmt, "Rect {{ x: {}, y: {}, w: {}, h: {} }}",
self.raw.x, self.raw.y, self.raw.w, self.raw.h);
return write!(
fmt,
"Rect {{ x: {}, y: {}, w: {}, h: {} }}",
self.raw.x, self.raw.y, self.raw.w, self.raw.h
);
}
}
impl PartialEq for Rect {
fn eq(&self, other: &Rect) -> bool {
self.raw.x == other.raw.x &&
self.raw.y == other.raw.y &&
self.raw.w == other.raw.w &&
self.raw.h == other.raw.h
self.raw.x == other.raw.x
&& self.raw.y == other.raw.y
&& self.raw.w == other.raw.w
&& self.raw.h == other.raw.h
}
}
@@ -128,8 +134,10 @@ impl Rect {
///
/// `Rect`s must always be non-empty, so a `width` and/or `height` argument
/// of 0 will be replaced with 1.
pub fn from_center<P>(center: P, width: u32, height: u32)
-> Rect where P: Into<Point> {
pub fn from_center<P>(center: P, width: u32, height: u32) -> Rect
where
P: Into<Point>,
{
let raw = sys::SDL_Rect {
x: 0,
y: 0,
@@ -299,10 +307,13 @@ impl Rect {
}
/// Centers the rectangle on the given point.
pub fn center_on<P>(&mut self, point: P) where P: Into<(i32, i32)> {
pub fn center_on<P>(&mut self, point: P)
where
P: Into<(i32, i32)>,
{
let (x, y) = point.into();
self.raw.x = clamp_position(clamp_position(x) - self.raw.w / 2);
self.raw.y = clamp_position(clamp_position(y) - self.raw. h / 2);
self.raw.y = clamp_position(clamp_position(y) - self.raw.h / 2);
}
/// Move this rect and clamp the positions to prevent over/underflow.
@@ -316,7 +327,7 @@ impl Rect {
} else {
self.raw.x = i32::min_value();
}
},
}
}
match self.raw.y.checked_add(y) {
Some(val) => self.raw.y = clamp_position(val),
@@ -326,12 +337,15 @@ impl Rect {
} else {
self.raw.y = i32::min_value();
}
},
}
}
}
/// Moves this rect to the given position after clamping the values.
pub fn reposition<P>(&mut self, point: P) where P: Into<(i32, i32)> {
pub fn reposition<P>(&mut self, point: P)
where
P: Into<(i32, i32)>,
{
let (x, y) = point.into();
self.raw.x = clamp_position(x);
self.raw.y = clamp_position(y);
@@ -363,7 +377,9 @@ impl Rect {
/// assert!(!rect.contains_point(Point::new(4, 6)));
/// ```
pub fn contains_point<P>(&self, point: P) -> bool
where P: Into<(i32, i32)> {
where
P: Into<(i32, i32)>,
{
let (x, y) = point.into();
let inside_x = x >= self.left() && x < self.right();
inside_x && (y >= self.top() && y < self.bottom())
@@ -386,8 +402,10 @@ impl Rect {
/// assert!(!rect.contains_rect(Rect::new(3, 3, 2, 1)));
/// ```
pub fn contains_rect(&self, other: Rect) -> bool {
other.left() >= self.left() && other.right() <= self.right() &&
other.top() >= self.top() && other.bottom() <= self.bottom()
other.left() >= self.left()
&& other.right() <= self.right()
&& other.top() >= self.top()
&& other.bottom() <= self.bottom()
}
/// Returns the underlying C Rect.
@@ -415,9 +433,12 @@ impl Rect {
/// If a clipping rectangle is given, only points that are within it will be
/// considered.
#[doc(alias = "SDL_EnclosePoints")]
pub fn from_enclose_points<R: Into<Option<Rect>>>(points: &[Point], clipping_rect: R)
-> Option<Rect>
where R: Into<Option<Rect>>
pub fn from_enclose_points<R: Into<Option<Rect>>>(
points: &[Point],
clipping_rect: R,
) -> Option<Rect>
where
R: Into<Option<Rect>>,
{
let clipping_rect = clipping_rect.into();
@@ -429,7 +450,7 @@ impl Rect {
let clip_ptr = match clipping_rect.as_ref() {
Some(r) => r.raw(),
None => ptr::null()
None => ptr::null(),
};
let result = unsafe {
@@ -437,7 +458,7 @@ impl Rect {
Point::raw_slice(points),
points.len() as i32,
clip_ptr,
out.as_mut_ptr()
out.as_mut_ptr(),
) != sys::SDL_bool::SDL_FALSE
};
@@ -467,9 +488,7 @@ impl Rect {
/// ```
#[doc(alias = "SDL_HasIntersection")]
pub fn has_intersection(&self, other: Rect) -> bool {
unsafe {
sys::SDL_HasIntersection(self.raw(), other.raw()) != sys::SDL_bool::SDL_FALSE
}
unsafe { sys::SDL_HasIntersection(self.raw(), other.raw()) != sys::SDL_bool::SDL_FALSE }
}
/// Calculates the intersection of two rectangles.
@@ -495,7 +514,8 @@ impl Rect {
let mut out = mem::MaybeUninit::uninit();
let success = unsafe {
sys::SDL_IntersectRect(self.raw(), other.raw(), out.as_mut_ptr()) != sys::SDL_bool::SDL_FALSE
sys::SDL_IntersectRect(self.raw(), other.raw(), out.as_mut_ptr())
!= sys::SDL_bool::SDL_FALSE
};
if success {
@@ -538,17 +558,17 @@ impl Rect {
/// Calculates the intersection of a rectangle and a line segment and
/// returns the points of their intersection.
#[doc(alias = "SDL_IntersectRectAndLine")]
pub fn intersect_line(&self, start: Point, end: Point)
-> Option<(Point, Point)> {
pub fn intersect_line(&self, start: Point, end: Point) -> Option<(Point, Point)> {
let (mut start_x, mut start_y) = (start.x(), start.y());
let (mut end_x, mut end_y) = (end.x(), end.y());
let intersected = unsafe {
sys::SDL_IntersectRectAndLine(
self.raw(),
&mut start_x, &mut start_y,
&mut end_x, &mut end_y
&mut start_x,
&mut start_y,
&mut end_x,
&mut end_y,
) != sys::SDL_bool::SDL_FALSE
};
@@ -629,19 +649,23 @@ impl AsMut<sys::SDL_Rect> for Rect {
impl BitAnd<Rect> for Rect {
type Output = Option<Rect>;
#[doc(alias = "SDL_Point")]
fn bitand(self, rhs: Rect) -> Option<Rect> { self.intersection(rhs) }
fn bitand(self, rhs: Rect) -> Option<Rect> {
self.intersection(rhs)
}
}
// Union
impl BitOr<Rect> for Rect {
type Output = Rect;
fn bitor(self, rhs: Rect) -> Rect { self.union(rhs) }
fn bitor(self, rhs: Rect) -> Rect {
self.union(rhs)
}
}
/// Immutable point type, consisting of x and y.
#[derive(Copy, Clone)]
pub struct Point {
raw: sys::SDL_Point
raw: sys::SDL_Point,
}
impl ::std::fmt::Debug for Point {
@@ -737,7 +761,7 @@ impl Point {
raw: sys::SDL_Point {
x: clamp_position(x),
y: clamp_position(y),
}
},
}
}
@@ -785,8 +809,7 @@ impl Point {
/// Returns a new point by multiplying this point's coordinates by the
/// given scale factor.
pub fn scale(self, f: i32) -> Point {
Point::new(clamped_mul(self.raw.x, f),
clamped_mul(self.raw.y, f))
Point::new(clamped_mul(self.raw.x, f), clamped_mul(self.raw.y, f))
}
/// Returns the x-coordinate of this point.
@@ -870,7 +893,7 @@ impl DivAssign<i32> for Point {
#[cfg(test)]
mod test {
use super::{Rect, Point, max_int_value, min_int_value};
use super::{max_int_value, min_int_value, Point, Rect};
/// Used to compare "literal" (unclamped) rect values.
fn tuple(x: i32, y: i32, w: u32, h: u32) -> (i32, i32, u32, u32) {
@@ -881,10 +904,8 @@ mod test {
fn enclose_points_valid() {
assert_eq!(
Some(tuple(2, 4, 4, 6)),
Rect::from_enclose_points(
&[Point::new(2, 4), Point::new(5,9)],
None
).map(|r| r.into())
Rect::from_enclose_points(&[Point::new(2, 4), Point::new(5, 9)], None)
.map(|r| r.into())
);
}
@@ -892,8 +913,9 @@ mod test {
fn enclose_points_outside_clip_rect() {
assert_eq!(
Rect::from_enclose_points(
&[Point::new(0, 0), Point::new(10,10)],
Some(Rect::new(3, 3, 1, 1))),
&[Point::new(0, 0), Point::new(10, 10)],
Some(Rect::new(3, 3, 1, 1))
),
None
);
}
@@ -903,13 +925,19 @@ mod test {
// Try to enclose the top-left-most and bottom-right-most points.
assert_eq!(
Some(tuple(
min_int_value(), min_int_value(),
max_int_value(), max_int_value()
min_int_value(),
min_int_value(),
max_int_value(),
max_int_value()
)),
Rect::from_enclose_points(
&[Point::new(i32::min_value(), i32::min_value()),
Point::new(i32::max_value(), i32::max_value())], None
).map(|r| r.into())
&[
Point::new(i32::min_value(), i32::min_value()),
Point::new(i32::max_value(), i32::max_value())
],
None
)
.map(|r| r.into())
);
}
@@ -918,22 +946,16 @@ mod test {
let rect = Rect::new(0, 0, 10, 10);
assert!(rect.has_intersection(Rect::new(9, 9, 10, 10)));
// edge
assert!(! rect.has_intersection(Rect::new(10, 10, 10, 10)));
assert!(!rect.has_intersection(Rect::new(10, 10, 10, 10)));
// out
assert!(! rect.has_intersection(Rect::new(11, 11, 10, 10)));
assert!(!rect.has_intersection(Rect::new(11, 11, 10, 10)));
}
#[test]
fn intersection() {
let rect = Rect::new(0, 0, 10, 10);
assert_eq!(
rect & Rect::new(9, 9, 10, 10),
Some(Rect::new(9, 9, 1, 1))
);
assert_eq!(
rect & Rect::new(11, 11, 10, 10),
None
);
assert_eq!(rect & Rect::new(9, 9, 10, 10), Some(Rect::new(9, 9, 1, 1)));
assert_eq!(rect & Rect::new(11, 11, 10, 10), None);
}
#[test]
@@ -947,19 +969,14 @@ mod test {
#[test]
fn intersect_line() {
assert_eq!(
Rect::new(1, 1, 5, 5).intersect_line(
Point::new(0, 0), Point::new(10, 10)
),
Rect::new(1, 1, 5, 5).intersect_line(Point::new(0, 0), Point::new(10, 10)),
Some((Point::new(1, 1), Point::new(5, 5)))
);
}
#[test]
fn clamp_size_zero() {
assert_eq!(
tuple(0, 0, 1, 1),
Rect::new(0, 0, 0, 0).into()
);
assert_eq!(tuple(0, 0, 1, 1), Rect::new(0, 0, 0, 0).into());
}
#[test]
@@ -982,9 +999,7 @@ mod test {
fn clamp_i32_max() {
assert_eq!(
tuple(0, 0, max_int_value(), max_int_value()),
Rect::new(
0, 0, i32::max_value() as u32, i32::max_value() as u32
).into()
Rect::new(0, 0, i32::max_value() as u32, i32::max_value() as u32).into()
)
}
@@ -992,99 +1007,67 @@ mod test {
fn clamp_position_max() {
assert_eq!(
tuple(max_int_value() as i32, max_int_value() as i32, 1, 1),
Rect::new(
max_int_value() as i32 + 1, max_int_value() as i32 + 1, 1, 1
).into()
Rect::new(max_int_value() as i32 + 1, max_int_value() as i32 + 1, 1, 1).into()
);
}
#[test]
fn rect_into() {
let test: (i32, i32, u32, u32) = (-11, 5, 50, 20);
assert_eq!(
test,
Rect::new(-11, 5, 50, 20).into()
);
assert_eq!(test, Rect::new(-11, 5, 50, 20).into());
}
#[test]
fn rect_from() {
assert_eq!(
Rect::from((-11, 5, 50, 20)),
Rect::new(-11, 5, 50, 20)
);
assert_eq!(Rect::from((-11, 5, 50, 20)), Rect::new(-11, 5, 50, 20));
}
#[test]
fn point_into() {
let test: (i32, i32) = (-11, 5);
assert_eq!(
test,
Point::new(-11, 5).into()
);
assert_eq!(test, Point::new(-11, 5).into());
}
#[test]
fn point_from() {
let test: (i32, i32) = (-11, 5);
assert_eq!(
test,
Point::new(-11, 5).into()
);
assert_eq!(test, Point::new(-11, 5).into());
}
#[test]
fn point_add() {
assert_eq!(
Point::new(-5, 7),
Point::new(-11, 5) + Point::new(6, 2)
);
assert_eq!(Point::new(-5, 7), Point::new(-11, 5) + Point::new(6, 2));
}
#[test]
fn point_add_assign() {
let mut point = Point::new(-11, 5);
point += Point::new(6, 2);
assert_eq!(
point,
Point::new(-11, 5) + Point::new(6, 2)
);
assert_eq!(point, Point::new(-11, 5) + Point::new(6, 2));
}
#[test]
fn point_sub() {
assert_eq!(
Point::new(-17, 3),
Point::new(-11, 5) - Point::new(6, 2)
);
assert_eq!(Point::new(-17, 3), Point::new(-11, 5) - Point::new(6, 2));
}
#[test]
fn point_sub_assign() {
let mut point = Point::new(-11, 5);
point -= Point::new(6, 2);
assert_eq!(
point,
Point::new(-11, 5) - Point::new(6, 2)
);
assert_eq!(point, Point::new(-11, 5) - Point::new(6, 2));
}
#[test]
fn point_mul() {
assert_eq!(
Point::new(-33, 15),
Point::new(-11, 5) * 3
);
assert_eq!(Point::new(-33, 15), Point::new(-11, 5) * 3);
}
#[test]
fn point_mul_assign() {
let mut point = Point::new(-11, 5);
point *= 3;
assert_eq!(
point,
Point::new(-11, 5) * 3
);
assert_eq!(point, Point::new(-11, 5) * 3);
}
#[test]
@@ -1099,28 +1082,18 @@ mod test {
fn point_mul_assign_clamp() {
let mut point = Point::new(-1000000, 5000000);
point *= -3000000;
assert_eq!(
point,
Point::new(-1000000, 5000000) * -3000000
);
assert_eq!(point, Point::new(-1000000, 5000000) * -3000000);
}
#[test]
fn point_div() {
assert_eq!(
Point::new(-3, 1),
Point::new(-11, 5) / 3
);
assert_eq!(Point::new(-3, 1), Point::new(-11, 5) / 3);
}
#[test]
fn point_div_assign () {
fn point_div_assign() {
let mut point = Point::new(-11, 5);
point /= 3;
assert_eq!(
point,
Point::new(-11, 5) / 3
);
assert_eq!(point, Point::new(-11, 5) / 3);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,40 +1,45 @@
use crate::get_error;
use libc::c_void;
use libc::{c_char, c_int, size_t};
use std::ffi::CString;
use std::io;
use std::path::Path;
use std::marker::PhantomData;
use libc::{c_int, size_t, c_char};
use libc::c_void;
use crate::get_error;
use std::mem::transmute;
use std::path::Path;
use crate::sys;
/// A structure that provides an abstract interface to stream I/O.
pub struct RWops<'a> {
raw: *mut sys::SDL_RWops,
_marker: PhantomData<&'a ()>
_marker: PhantomData<&'a ()>,
}
impl<'a> RWops<'a> {
// this can prevent introducing UB until
// https://github.com/rust-lang/rust-clippy/issues/5953 is fixed
#[allow(clippy::trivially_copy_pass_by_ref)]
pub unsafe fn raw(&self) -> *mut sys::SDL_RWops { self.raw }
pub unsafe fn raw(&self) -> *mut sys::SDL_RWops {
self.raw
}
pub unsafe fn from_ll<'b>(raw: *mut sys::SDL_RWops) -> RWops<'b> {
RWops {
raw,
_marker: PhantomData
_marker: PhantomData,
}
}
/// Creates an SDL file stream.
#[doc(alias = "SDL_RWFromFile")]
pub fn from_file<P: AsRef<Path>>(path: P, mode: &str) -> Result<RWops <'static>, String> {
pub fn from_file<P: AsRef<Path>>(path: P, mode: &str) -> Result<RWops<'static>, String> {
let raw = unsafe {
let path_c = CString::new(path.as_ref().to_str().unwrap()).unwrap();
let mode_c = CString::new(mode).unwrap();
sys::SDL_RWFromFile(path_c.as_ptr() as *const c_char, mode_c.as_ptr() as *const c_char)
sys::SDL_RWFromFile(
path_c.as_ptr() as *const c_char,
mode_c.as_ptr() as *const c_char,
)
};
if raw.is_null() {
@@ -42,7 +47,7 @@ impl<'a> RWops<'a> {
} else {
Ok(RWops {
raw,
_marker: PhantomData
_marker: PhantomData,
})
}
}
@@ -51,17 +56,16 @@ impl<'a> RWops<'a> {
///
/// This method can only fail if the buffer size is zero.
#[doc(alias = "SDL_RWFromConstMem")]
pub fn from_bytes(buf: &'a [u8]) -> Result<RWops <'a>, String> {
let raw = unsafe {
sys::SDL_RWFromConstMem(buf.as_ptr() as *const c_void, buf.len() as c_int)
};
pub fn from_bytes(buf: &'a [u8]) -> Result<RWops<'a>, String> {
let raw =
unsafe { sys::SDL_RWFromConstMem(buf.as_ptr() as *const c_void, buf.len() as c_int) };
if raw.is_null() {
Err(get_error())
} else {
Ok(RWops {
raw,
_marker: PhantomData
_marker: PhantomData,
})
}
}
@@ -71,7 +75,9 @@ impl<'a> RWops<'a> {
/// The buffer must be provided to this function and must live as long as the
/// `RWops`, but the `RWops` does not take ownership of it.
pub fn from_read<T>(r: &mut T, buffer: &'a mut Vec<u8>) -> Result<RWops<'a>, String>
where T: io::Read + Sized {
where
T: io::Read + Sized,
{
match r.read_to_end(buffer) {
Ok(_size) => RWops::from_bytes(buffer),
Err(ioerror) => {
@@ -85,17 +91,15 @@ impl<'a> RWops<'a> {
///
/// This method can only fail if the buffer size is zero.
#[doc(alias = "SDL_RWFromMem")]
pub fn from_bytes_mut(buf: &'a mut [u8]) -> Result<RWops <'a>, String> {
let raw = unsafe {
sys::SDL_RWFromMem(buf.as_ptr() as *mut c_void, buf.len() as c_int)
};
pub fn from_bytes_mut(buf: &'a mut [u8]) -> Result<RWops<'a>, String> {
let raw = unsafe { sys::SDL_RWFromMem(buf.as_ptr() as *mut c_void, buf.len() as c_int) };
if raw.is_null() {
Err(get_error())
} else {
Ok(RWops {
raw,
_marker: PhantomData
_marker: PhantomData,
})
}
}
@@ -109,7 +113,7 @@ impl<'a> RWops<'a> {
match result {
-1 => None,
v => Some(v as usize)
v => Some(v as usize),
}
}
@@ -137,7 +141,12 @@ impl<'a> io::Read for RWops<'a> {
// FIXME: it's better to use as_mut_ptr().
// number of objects read, or 0 at error or end of file.
let ret = unsafe {
((*self.raw).read.unwrap())(self.raw, buf.as_ptr() as *mut c_void, 1, out_len as sys::size_t)
((*self.raw).read.unwrap())(
self.raw,
buf.as_ptr() as *mut c_void,
1,
out_len as sys::size_t,
)
};
Ok(ret as usize)
}
@@ -147,7 +156,12 @@ impl<'a> io::Write for RWops<'a> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
let in_len = buf.len() as size_t;
let ret = unsafe {
((*self.raw).write.unwrap())(self.raw, buf.as_ptr() as *const c_void, 1, in_len as sys::size_t)
((*self.raw).write.unwrap())(
self.raw,
buf.as_ptr() as *const c_void,
1,
in_len as sys::size_t,
)
};
Ok(ret as usize)
}
@@ -163,11 +177,9 @@ impl<'a> io::Seek for RWops<'a> {
let (whence, offset) = match pos {
io::SeekFrom::Start(pos) => (sys::RW_SEEK_SET, pos as i64),
io::SeekFrom::End(pos) => (sys::RW_SEEK_END, pos),
io::SeekFrom::Current(pos) => (sys::RW_SEEK_CUR, pos)
};
let ret = unsafe {
((*self.raw).seek.unwrap())(self.raw, offset, transmute(whence))
io::SeekFrom::Current(pos) => (sys::RW_SEEK_CUR, pos),
};
let ret = unsafe { ((*self.raw).seek.unwrap())(self.raw, offset, transmute(whence)) };
if ret == -1 {
Err(io::Error::last_os_error())
} else {

View File

@@ -1,9 +1,9 @@
use libc::c_char;
use std::error;
use std::ffi::{CStr, CString, NulError};
use std::fmt;
use std::rc::Rc;
use libc::c_char;
use std::mem::transmute;
use std::rc::Rc;
use crate::sys;
@@ -14,7 +14,7 @@ pub enum Error {
ReadError = sys::SDL_errorcode::SDL_EFREAD as i32,
WriteError = sys::SDL_errorcode::SDL_EFWRITE as i32,
SeekError = sys::SDL_errorcode::SDL_EFSEEK as i32,
UnsupportedError = sys::SDL_errorcode::SDL_UNSUPPORTED as i32
UnsupportedError = sys::SDL_errorcode::SDL_UNSUPPORTED as i32,
}
impl fmt::Display for Error {
@@ -26,7 +26,7 @@ impl fmt::Display for Error {
ReadError => write!(f, "Error reading from datastream"),
WriteError => write!(f, "Error writing to datastream"),
SeekError => write!(f, "Error seeking in datastream"),
UnsupportedError => write!(f, "Unknown SDL error")
UnsupportedError => write!(f, "Unknown SDL error"),
}
}
}
@@ -40,12 +40,12 @@ impl error::Error for Error {
ReadError => "error reading from datastream",
WriteError => "error writing to datastream",
SeekError => "error seeking in datastream",
UnsupportedError => "unknown SDL error"
UnsupportedError => "unknown SDL error",
}
}
}
use std::sync::atomic::{AtomicBool};
use std::sync::atomic::AtomicBool;
/// Only one Sdl context can be alive at a time.
/// Set to false by default (not alive).
static IS_SDL_CONTEXT_ALIVE: AtomicBool = AtomicBool::new(false);
@@ -64,7 +64,7 @@ static IS_SDL_CONTEXT_ALIVE: AtomicBool = AtomicBool::new(false);
/// the main thread.
#[derive(Clone)]
pub struct Sdl {
sdldrop: Rc<SdlDrop>
sdldrop: Rc<SdlDrop>,
}
impl Sdl {
@@ -82,7 +82,7 @@ impl Sdl {
} else if sys::SDL_Init(0) == 0 {
// Initialize SDL without any explicit subsystems (flags = 0).
Ok(Sdl {
sdldrop: Rc::new(SdlDrop)
sdldrop: Rc::new(SdlDrop),
})
} else {
IS_SDL_CONTEXT_ALIVE.swap(false, Ordering::Relaxed);
@@ -93,31 +93,45 @@ impl Sdl {
/// Initializes the audio subsystem.
#[inline]
pub fn audio(&self) -> Result<AudioSubsystem, String> { AudioSubsystem::new(self) }
pub fn audio(&self) -> Result<AudioSubsystem, String> {
AudioSubsystem::new(self)
}
/// Initializes the event subsystem.
#[inline]
pub fn event(&self) -> Result<EventSubsystem, String> { EventSubsystem::new(self) }
pub fn event(&self) -> Result<EventSubsystem, String> {
EventSubsystem::new(self)
}
/// Initializes the joystick subsystem.
#[inline]
pub fn joystick(&self) -> Result<JoystickSubsystem, String> { JoystickSubsystem::new(self) }
pub fn joystick(&self) -> Result<JoystickSubsystem, String> {
JoystickSubsystem::new(self)
}
/// Initializes the haptic subsystem.
#[inline]
pub fn haptic(&self) -> Result<HapticSubsystem, String> { HapticSubsystem::new(self) }
pub fn haptic(&self) -> Result<HapticSubsystem, String> {
HapticSubsystem::new(self)
}
/// Initializes the game controller subsystem.
#[inline]
pub fn game_controller(&self) -> Result<GameControllerSubsystem, String> { GameControllerSubsystem::new(self) }
pub fn game_controller(&self) -> Result<GameControllerSubsystem, String> {
GameControllerSubsystem::new(self)
}
/// Initializes the timer subsystem.
#[inline]
pub fn timer(&self) -> Result<TimerSubsystem, String> { TimerSubsystem::new(self) }
pub fn timer(&self) -> Result<TimerSubsystem, String> {
TimerSubsystem::new(self)
}
/// Initializes the video subsystem.
#[inline]
pub fn video(&self) -> Result<VideoSubsystem, String> { VideoSubsystem::new(self) }
pub fn video(&self) -> Result<VideoSubsystem, String> {
VideoSubsystem::new(self)
}
/// Obtains the SDL event pump.
///
@@ -150,7 +164,9 @@ impl Drop for SdlDrop {
let was_alive = IS_SDL_CONTEXT_ALIVE.swap(false, Ordering::Relaxed);
assert!(was_alive);
unsafe { sys::SDL_Quit(); }
unsafe {
sys::SDL_Quit();
}
}
}
@@ -160,7 +176,7 @@ impl Drop for SdlDrop {
// the event queue. These subsystems implement `Sync`.
macro_rules! subsystem {
($name:ident, $flag:expr) => (
($name:ident, $flag:expr) => {
impl $name {
#[inline]
#[doc(alias = "SDL_InitSubSystem")]
@@ -171,38 +187,40 @@ macro_rules! subsystem {
Ok($name {
_subsystem_drop: Rc::new(SubsystemDrop {
_sdldrop: sdl.sdldrop.clone(),
flag: $flag
})
flag: $flag,
}),
})
} else {
Err(get_error())
}
}
}
);
($name:ident, $flag:expr, nosync) => (
};
($name:ident, $flag:expr, nosync) => {
#[derive(Debug, Clone)]
pub struct $name {
/// Subsystems cannot be moved or (usually) used on non-main threads.
/// Luckily, Rc restricts use to the main thread.
_subsystem_drop: Rc<SubsystemDrop>
_subsystem_drop: Rc<SubsystemDrop>,
}
impl $name {
/// Obtain an SDL context.
#[inline]
pub fn sdl(&self) -> Sdl {
Sdl { sdldrop: self._subsystem_drop._sdldrop.clone() }
Sdl {
sdldrop: self._subsystem_drop._sdldrop.clone(),
}
}
}
subsystem!($name, $flag);
);
($name:ident, $flag:expr, sync) => (
};
($name:ident, $flag:expr, sync) => {
pub struct $name {
/// Subsystems cannot be moved or (usually) used on non-main threads.
/// Luckily, Rc restricts use to the main thread.
_subsystem_drop: Rc<SubsystemDrop>
_subsystem_drop: Rc<SubsystemDrop>,
}
unsafe impl Sync for $name {}
@@ -210,7 +228,7 @@ macro_rules! subsystem {
#[inline]
fn clone(&self) -> $name {
$name {
_subsystem_drop: self._subsystem_drop.clone()
_subsystem_drop: self._subsystem_drop.clone(),
}
}
}
@@ -219,12 +237,14 @@ macro_rules! subsystem {
/// Obtain an SDL context.
#[inline]
pub fn sdl(&self) -> Sdl {
Sdl { sdldrop: self._subsystem_drop._sdldrop.clone() }
Sdl {
sdldrop: self._subsystem_drop._sdldrop.clone(),
}
}
}
subsystem!($name, $flag);
)
};
}
/// When a subsystem is no longer in use (the refcount in an `Rc<SubsystemDrop>` reaches 0),
@@ -232,19 +252,25 @@ macro_rules! subsystem {
#[derive(Debug, Clone)]
struct SubsystemDrop {
_sdldrop: Rc<SdlDrop>,
flag: u32
flag: u32,
}
impl Drop for SubsystemDrop {
#[inline]
#[doc(alias = "SDL_QuitSubSystem")]
fn drop(&mut self) {
unsafe { sys::SDL_QuitSubSystem(self.flag); }
unsafe {
sys::SDL_QuitSubSystem(self.flag);
}
}
}
subsystem!(AudioSubsystem, sys::SDL_INIT_AUDIO, nosync);
subsystem!(GameControllerSubsystem, sys::SDL_INIT_GAMECONTROLLER, nosync);
subsystem!(
GameControllerSubsystem,
sys::SDL_INIT_GAMECONTROLLER,
nosync
);
subsystem!(HapticSubsystem, sys::SDL_INIT_HAPTIC, nosync);
subsystem!(JoystickSubsystem, sys::SDL_INIT_JOYSTICK, nosync);
subsystem!(VideoSubsystem, sys::SDL_INIT_VIDEO, nosync);
@@ -257,7 +283,7 @@ static mut IS_EVENT_PUMP_ALIVE: bool = false;
/// A thread-safe type that encapsulates SDL event-pumping functions.
pub struct EventPump {
_sdldrop: Rc<SdlDrop>
_sdldrop: Rc<SdlDrop>,
}
impl EventPump {
@@ -278,7 +304,7 @@ impl EventPump {
IS_EVENT_PUMP_ALIVE = true;
Ok(EventPump {
_sdldrop: sdl.sdldrop.clone()
_sdldrop: sdl.sdldrop.clone(),
})
} else {
Err(get_error())
@@ -306,9 +332,7 @@ impl Drop for EventPump {
#[inline]
#[doc(alias = "SDL_GetPlatform")]
pub fn get_platform() -> &'static str {
unsafe {
CStr::from_ptr(sys::SDL_GetPlatform()).to_str().unwrap()
}
unsafe { CStr::from_ptr(sys::SDL_GetPlatform()).to_str().unwrap() }
}
/// Initializes the SDL library.
@@ -327,7 +351,9 @@ pub fn get_platform() -> &'static str {
/// ```
#[inline]
#[doc(alias = "SDL_GetError")]
pub fn init() -> Result<Sdl, String> { Sdl::new() }
pub fn init() -> Result<Sdl, String> {
Sdl::new()
}
pub fn get_error() -> String {
unsafe {
@@ -347,10 +373,14 @@ pub fn set_error(err: &str) -> Result<(), NulError> {
#[doc(alias = "SDL_Error")]
pub fn set_error_from_code(err: Error) {
unsafe { sys::SDL_Error(transmute(err)); }
unsafe {
sys::SDL_Error(transmute(err));
}
}
#[doc(alias = "SDL_ClearError")]
pub fn clear_error() {
unsafe { sys::SDL_ClearError(); }
unsafe {
sys::SDL_ClearError();
}
}

View File

@@ -4,16 +4,16 @@ use std::ops::{Deref, DerefMut};
use std::path::Path;
use std::rc::Rc;
use crate::rect::Rect;
use crate::get_error;
use std::ptr;
use crate::pixels;
use crate::rect::Rect;
use crate::render::{BlendMode, Canvas};
use crate::render::{Texture, TextureCreator, TextureValueError};
use crate::rwops::RWops;
use libc::c_int;
use std::convert::TryFrom;
use crate::pixels;
use crate::render::{BlendMode, Canvas};
use crate::rwops::RWops;
use std::mem::transmute;
use crate::render::{Texture, TextureCreator, TextureValueError};
use std::ptr;
use crate::sys;
@@ -24,14 +24,16 @@ use crate::sys;
/// *INTERNAL USE ONLY*
pub struct SurfaceContext<'a> {
raw: *mut sys::SDL_Surface,
_marker: PhantomData<&'a ()>
_marker: PhantomData<&'a ()>,
}
impl<'a> Drop for SurfaceContext<'a> {
#[inline]
#[doc(alias = "SDL_FreeSurface")]
fn drop(&mut self) {
unsafe { sys::SDL_FreeSurface(self.raw); }
unsafe {
sys::SDL_FreeSurface(self.raw);
}
}
}
@@ -52,10 +54,10 @@ pub struct SurfaceRef {
// The empty private field is need to a) make `std::mem::swap()` copy nothing instead of
// clobbering two surfaces (SDL_Surface's size could change in the future),
// and b) prevent user initialization of this type.
_raw: ()
_raw: (),
}
impl AsRef<SurfaceRef> for SurfaceRef {
impl AsRef<SurfaceRef> for SurfaceRef {
fn as_ref(&self) -> &SurfaceRef {
self
}
@@ -97,14 +99,15 @@ impl<'a> AsMut<SurfaceRef> for Surface<'a> {
}
}
impl<'a> Surface<'a> {
pub unsafe fn from_ll<'b>(raw: *mut sys::SDL_Surface) -> Surface<'b> {
let context = SurfaceContext {
raw,
_marker: PhantomData,
};
Surface { context: Rc::new(context) }
Surface {
context: Rc::new(context),
}
}
/// Creates a new surface using a pixel format.
@@ -116,7 +119,11 @@ impl<'a> Surface<'a> {
///
/// let surface = Surface::new(512, 512, PixelFormatEnum::RGB24).unwrap();
/// ```
pub fn new(width: u32, height: u32, format: pixels::PixelFormatEnum) -> Result<Surface<'static>, String> {
pub fn new(
width: u32,
height: u32,
format: pixels::PixelFormatEnum,
) -> Result<Surface<'static>, String> {
let masks = format.into_masks()?;
Surface::from_pixelmasks(width, height, masks)
}
@@ -132,13 +139,25 @@ impl<'a> Surface<'a> {
/// let surface = Surface::from_pixelmasks(512, 512, masks).unwrap();
/// ```
#[doc(alias = "SDL_CreateRGBSurface")]
pub fn from_pixelmasks(width: u32, height: u32, masks: pixels::PixelMasks) -> Result<Surface<'static>, String> {
pub fn from_pixelmasks(
width: u32,
height: u32,
masks: pixels::PixelMasks,
) -> Result<Surface<'static>, String> {
unsafe {
if width >= (1<<31) || height >= (1<<31) {
if width >= (1 << 31) || height >= (1 << 31) {
Err("Image is too large.".to_owned())
} else {
let raw = sys::SDL_CreateRGBSurface(0, width as c_int, height as c_int,
masks.bpp as c_int, masks.rmask, masks.gmask, masks.bmask, masks.amask);
let raw = sys::SDL_CreateRGBSurface(
0,
width as c_int,
height as c_int,
masks.bpp as c_int,
masks.rmask,
masks.gmask,
masks.bmask,
masks.amask,
);
if raw.is_null() {
Err(get_error())
@@ -150,23 +169,43 @@ impl<'a> Surface<'a> {
}
/// Creates a new surface from an existing buffer, using a pixel format.
pub fn from_data(data: &'a mut [u8], width: u32, height: u32, pitch: u32, format: pixels::PixelFormatEnum) -> Result<Surface<'a>, String> {
pub fn from_data(
data: &'a mut [u8],
width: u32,
height: u32,
pitch: u32,
format: pixels::PixelFormatEnum,
) -> Result<Surface<'a>, String> {
let masks = format.into_masks()?;
Surface::from_data_pixelmasks(data, width, height, pitch, masks)
}
/// Creates a new surface from an existing buffer, using pixel masks.
#[doc(alias = "SDL_CreateRGBSurfaceFrom")]
pub fn from_data_pixelmasks(data: &'a mut [u8], width: u32, height: u32, pitch: u32, masks: pixels::PixelMasks) -> Result<Surface<'a>, String> {
pub fn from_data_pixelmasks(
data: &'a mut [u8],
width: u32,
height: u32,
pitch: u32,
masks: pixels::PixelMasks,
) -> Result<Surface<'a>, String> {
unsafe {
if width >= (1<<31) || height >= (1<<31) {
if width >= (1 << 31) || height >= (1 << 31) {
Err("Image is too large.".to_owned())
} else if pitch >= (1<<31) {
} else if pitch >= (1 << 31) {
Err("Pitch is too large.".to_owned())
} else {
let raw = sys::SDL_CreateRGBSurfaceFrom(
data.as_mut_ptr() as *mut _, width as c_int, height as c_int,
masks.bpp as c_int, pitch as c_int, masks.rmask, masks.gmask, masks.bmask, masks.amask);
data.as_mut_ptr() as *mut _,
width as c_int,
height as c_int,
masks.bpp as c_int,
pitch as c_int,
masks.rmask,
masks.gmask,
masks.bmask,
masks.amask,
);
if raw.is_null() {
Err(get_error())
@@ -204,7 +243,10 @@ impl<'a> Surface<'a> {
/// let texture = surface.as_texture(&texture_creator).unwrap();
/// ```
#[cfg(not(feature = "unsafe_textures"))]
pub fn as_texture<'b, T>(&self, texture_creator: &'b TextureCreator<T>) -> Result<Texture<'b>, TextureValueError> {
pub fn as_texture<'b, T>(
&self,
texture_creator: &'b TextureCreator<T>,
) -> Result<Texture<'b>, TextureValueError> {
texture_creator.create_texture_from_surface(self)
}
@@ -235,20 +277,21 @@ impl<'a> Surface<'a> {
/// let texture = surface.as_texture(&texture_creator).unwrap();
/// ```
#[cfg(feature = "unsafe_textures")]
pub fn as_texture<T>(&self, texture_creator: &TextureCreator<T>) -> Result<Texture, TextureValueError> {
pub fn as_texture<T>(
&self,
texture_creator: &TextureCreator<T>,
) -> Result<Texture, TextureValueError> {
texture_creator.create_texture_from_surface(self)
}
#[doc(alias = "SDL_LoadBMP_RW")]
pub fn load_bmp_rw(rwops: &mut RWops) -> Result<Surface<'static>, String> {
let raw = unsafe {
sys::SDL_LoadBMP_RW(rwops.raw(), 0)
};
let raw = unsafe { sys::SDL_LoadBMP_RW(rwops.raw(), 0) };
if raw.is_null() {
Err(get_error())
} else {
Ok( unsafe{ Surface::from_ll(raw) } )
Ok(unsafe { Surface::from_ll(raw) })
}
}
@@ -295,9 +338,7 @@ impl SurfaceRef {
#[inline]
fn raw_ref(&self) -> &sys::SDL_Surface {
unsafe {
&*(self as *const _ as *const () as *const sys::SDL_Surface)
}
unsafe { &*(self as *const _ as *const () as *const sys::SDL_Surface) }
}
pub fn width(&self) -> u32 {
@@ -321,9 +362,7 @@ impl SurfaceRef {
}
pub fn pixel_format(&self) -> pixels::PixelFormat {
unsafe {
pixels::PixelFormat::from_ll(self.raw_ref().format)
}
unsafe { pixels::PixelFormat::from_ll(self.raw_ref().format) }
}
pub fn pixel_format_enum(&self) -> pixels::PixelFormatEnum {
@@ -334,7 +373,9 @@ impl SurfaceRef {
#[doc(alias = "SDL_LockSurface")]
pub fn with_lock<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
unsafe {
if sys::SDL_LockSurface(self.raw()) != 0 { panic!("could not lock surface"); }
if sys::SDL_LockSurface(self.raw()) != 0 {
panic!("could not lock surface");
}
let raw_pixels = self.raw_ref().pixels as *const _;
let len = self.raw_ref().pitch as usize * (self.raw_ref().h as usize);
@@ -349,7 +390,9 @@ impl SurfaceRef {
#[doc(alias = "SDL_LockSurface")]
pub fn with_lock_mut<R, F: FnOnce(&mut [u8]) -> R>(&mut self, f: F) -> R {
unsafe {
if sys::SDL_LockSurface(self.raw()) != 0 { panic!("could not lock surface"); }
if sys::SDL_LockSurface(self.raw()) != 0 {
panic!("could not lock surface");
}
let raw_pixels = self.raw_ref().pixels as *mut _;
let len = self.raw_ref().pitch as usize * (self.raw_ref().h as usize);
@@ -398,11 +441,12 @@ impl SurfaceRef {
#[doc(alias = "SDL_SaveBMP_RW")]
pub fn save_bmp_rw(&self, rwops: &mut RWops) -> Result<(), String> {
let ret = unsafe {
sys::SDL_SaveBMP_RW(self.raw(), rwops.raw(), 0)
};
if ret == 0 { Ok(()) }
else { Err(get_error()) }
let ret = unsafe { sys::SDL_SaveBMP_RW(self.raw(), rwops.raw(), 0) };
if ret == 0 {
Ok(())
} else {
Err(get_error())
}
}
pub fn save_bmp<P: AsRef<Path>>(&self, path: P) -> Result<(), String> {
@@ -416,7 +460,7 @@ impl SurfaceRef {
match result {
0 => Ok(()),
_ => Err(get_error())
_ => Err(get_error()),
}
}
@@ -445,9 +489,7 @@ impl SurfaceRef {
#[doc(alias = "SDL_SetColorKey")]
pub fn set_color_key(&mut self, enable: bool, color: pixels::Color) -> Result<(), String> {
let key = color.to_u32(&self.pixel_format());
let result = unsafe {
sys::SDL_SetColorKey(self.raw(), if enable { 1 } else { 0 }, key)
};
let result = unsafe { sys::SDL_SetColorKey(self.raw(), if enable { 1 } else { 0 }, key) };
if result == 0 {
Ok(())
} else {
@@ -462,9 +504,7 @@ impl SurfaceRef {
// SDL_GetColorKey does not mutate, but requires a non-const pointer anyway.
let result = unsafe {
sys::SDL_GetColorKey(self.raw(), &mut key)
};
let result = unsafe { sys::SDL_GetColorKey(self.raw(), &mut key) };
if result == 0 {
Ok(pixels::Color::from_u32(&self.pixel_format(), key))
@@ -492,9 +532,8 @@ impl SurfaceRef {
// SDL_GetSurfaceColorMod does not mutate, but requires a non-const pointer anyway.
let result = unsafe {
sys::SDL_GetSurfaceColorMod(self.raw(), &mut r, &mut g, &mut b) == 0
};
let result =
unsafe { sys::SDL_GetSurfaceColorMod(self.raw(), &mut r, &mut g, &mut b) == 0 };
if result {
pixels::Color::RGB(r, g, b)
@@ -506,27 +545,26 @@ impl SurfaceRef {
#[doc(alias = "SDL_FillRect")]
pub fn fill_rect<R>(&mut self, rect: R, color: pixels::Color) -> Result<(), String>
where R: Into<Option<Rect>>
where
R: Into<Option<Rect>>,
{
unsafe {
let rect = rect.into();
let rect_ptr = mem::transmute(rect.as_ref()); // TODO find a better way to transform
// Option<&...> into a *const _
// Option<&...> into a *const _
let format = self.pixel_format();
let result = sys::SDL_FillRect(self.raw(), rect_ptr, color.to_u32(&format) );
let result = sys::SDL_FillRect(self.raw(), rect_ptr, color.to_u32(&format));
match result {
0 => Ok(()),
_ => Err(get_error())
_ => Err(get_error()),
}
}
}
#[allow(clippy::clone_on_copy)]
pub fn fill_rects(&mut self, rects: &[Rect], color: pixels::Color) -> Result<(), String>
{
pub fn fill_rects(&mut self, rects: &[Rect], color: pixels::Color) -> Result<(), String> {
for rect in rects.iter() {
if let Err(e) = self.fill_rect(rect.clone(), color)
{
if let Err(e) = self.fill_rect(rect.clone(), color) {
return Err(e);
}
}
@@ -536,9 +574,7 @@ impl SurfaceRef {
#[doc(alias = "SDL_SetSurfaceAlphaMod")]
pub fn set_alpha_mod(&mut self, alpha: u8) {
let result = unsafe {
sys::SDL_SetSurfaceAlphaMod(self.raw(), alpha)
};
let result = unsafe { sys::SDL_SetSurfaceAlphaMod(self.raw(), alpha) };
if result != 0 {
// Should only fail on a null Surface
@@ -549,41 +585,35 @@ impl SurfaceRef {
#[doc(alias = "SDL_GetSurfaceAlphaMod")]
pub fn alpha_mod(&self) -> u8 {
let mut alpha = 0;
let result = unsafe {
sys::SDL_GetSurfaceAlphaMod(self.raw(), &mut alpha)
};
let result = unsafe { sys::SDL_GetSurfaceAlphaMod(self.raw(), &mut alpha) };
match result {
0 => alpha,
// Should only fail on a null Surface
_ => panic!(get_error())
_ => panic!(get_error()),
}
}
/// The function will fail if the blend mode is not supported by SDL.
#[doc(alias = "SDL_SetSurfaceBlendMode")]
pub fn set_blend_mode(&mut self, mode: BlendMode) -> Result<(), String> {
let result = unsafe {
sys::SDL_SetSurfaceBlendMode(self.raw(), transmute(mode))
};
let result = unsafe { sys::SDL_SetSurfaceBlendMode(self.raw(), transmute(mode)) };
match result {
0 => Ok(()),
_ => Err(get_error())
_ => Err(get_error()),
}
}
#[doc(alias = "SDL_GetSurfaceBlendMode")]
pub fn blend_mode(&self) -> BlendMode {
let mut mode = sys::SDL_BlendMode::SDL_BLENDMODE_NONE;
let result = unsafe {
sys::SDL_GetSurfaceBlendMode(self.raw(), &mut mode)
};
let result = unsafe { sys::SDL_GetSurfaceBlendMode(self.raw(), &mut mode) };
match result {
0 => BlendMode::try_from(mode as u32).unwrap(),
// Should only fail on a null Surface
_ => panic!(get_error())
_ => panic!(get_error()),
}
}
@@ -592,14 +622,18 @@ impl SurfaceRef {
/// If the rectangle is `None`, clipping will be disabled.
#[doc(alias = "SDL_SetClipRect")]
pub fn set_clip_rect<R>(&mut self, rect: R) -> bool
where R: Into<Option<Rect>>
where
R: Into<Option<Rect>>,
{
let rect = rect.into();
unsafe {
sys::SDL_SetClipRect(self.raw(), match rect {
Some(rect) => rect.raw(),
None => ptr::null()
}) == sys::SDL_bool::SDL_TRUE
sys::SDL_SetClipRect(
self.raw(),
match rect {
Some(rect) => rect.raw(),
None => ptr::null(),
},
) == sys::SDL_bool::SDL_TRUE
}
}
@@ -609,9 +643,7 @@ impl SurfaceRef {
#[doc(alias = "SDL_GetClipRect")]
pub fn clip_rect(&self) -> Option<Rect> {
let mut raw = mem::MaybeUninit::uninit();
unsafe {
sys::SDL_GetClipRect(self.raw(), raw.as_mut_ptr())
};
unsafe { sys::SDL_GetClipRect(self.raw(), raw.as_mut_ptr()) };
let raw = unsafe { raw.assume_init() };
if raw.w == 0 || raw.h == 0 {
@@ -636,7 +668,10 @@ impl SurfaceRef {
/// Copies the surface into a new one of a specified pixel format.
#[doc(alias = "SDL_ConvertSurfaceFormat")]
pub fn convert_format(&self, format: pixels::PixelFormatEnum) -> Result<Surface<'static>, String> {
pub fn convert_format(
&self,
format: pixels::PixelFormatEnum,
) -> Result<Surface<'static>, String> {
// SDL_ConvertSurfaceFormat takes a flag as the last parameter, which should be 0 by the docs.
let surface_ptr = unsafe { sys::SDL_ConvertSurfaceFormat(self.raw(), format as u32, 0u32) };
@@ -651,11 +686,15 @@ impl SurfaceRef {
///
/// Returns the final blit rectangle, if a `dst_rect` was provided.
#[doc(alias = "SDL_UpperBlit")]
pub fn blit<R1, R2>(&self, src_rect: R1,
dst: &mut SurfaceRef, dst_rect: R2)
-> Result<Option<Rect>, String>
where R1: Into<Option<Rect>>,
R2: Into<Option<Rect>>,
pub fn blit<R1, R2>(
&self,
src_rect: R1,
dst: &mut SurfaceRef,
dst_rect: R2,
) -> Result<Option<Rect>, String>
where
R1: Into<Option<Rect>>,
R2: Into<Option<Rect>>,
{
let src_rect = src_rect.into();
let dst_rect = dst_rect.into();
@@ -666,11 +705,11 @@ impl SurfaceRef {
// Copy the rect here to make a mutable copy without requiring
// a mutable argument
let mut dst_rect = dst_rect;
let dst_rect_ptr = dst_rect.as_mut().map(|r| r.raw_mut())
let dst_rect_ptr = dst_rect
.as_mut()
.map(|r| r.raw_mut())
.unwrap_or(ptr::null_mut());
let result = sys::SDL_UpperBlit(
self.raw(), src_rect_ptr, dst.raw(), dst_rect_ptr
);
let result = sys::SDL_UpperBlit(self.raw(), src_rect_ptr, dst.raw(), dst_rect_ptr);
if result == 0 {
Ok(dst_rect)
@@ -684,24 +723,27 @@ impl SurfaceRef {
///
/// Unless you know what you're doing, use `blit()` instead, which will clip the input rectangles.
/// This function could crash if the rectangles aren't pre-clipped to the surface, and is therefore unsafe.
pub unsafe fn lower_blit<R1, R2>(&self, src_rect: R1,
dst: &mut SurfaceRef, dst_rect: R2) -> Result<(), String>
where R1: Into<Option<Rect>>,
R2: Into<Option<Rect>>,
pub unsafe fn lower_blit<R1, R2>(
&self,
src_rect: R1,
dst: &mut SurfaceRef,
dst_rect: R2,
) -> Result<(), String>
where
R1: Into<Option<Rect>>,
R2: Into<Option<Rect>>,
{
let src_rect = src_rect.into();
let dst_rect = dst_rect.into();
match {
// The rectangles don't change, but the function requires mutable pointers.
let src_rect_ptr = src_rect.as_ref().map(|r| r.raw())
.unwrap_or(ptr::null()) as *mut _;
let dst_rect_ptr = dst_rect.as_ref().map(|r| r.raw())
.unwrap_or(ptr::null()) as *mut _;
let src_rect_ptr = src_rect.as_ref().map(|r| r.raw()).unwrap_or(ptr::null()) as *mut _;
let dst_rect_ptr = dst_rect.as_ref().map(|r| r.raw()).unwrap_or(ptr::null()) as *mut _;
sys::SDL_LowerBlit(self.raw(), src_rect_ptr, dst.raw(), dst_rect_ptr)
} {
0 => Ok(()),
_ => Err(get_error())
_ => Err(get_error()),
}
}
@@ -709,10 +751,15 @@ impl SurfaceRef {
///
/// Returns the final blit rectangle, if a `dst_rect` was provided.
#[doc(alias = "SDL_UpperBlitScaled")]
pub fn blit_scaled<R1, R2>(&self, src_rect: R1,
dst: &mut SurfaceRef, dst_rect: R2) -> Result<Option<Rect>, String>
where R1: Into<Option<Rect>>,
R2: Into<Option<Rect>>,
pub fn blit_scaled<R1, R2>(
&self,
src_rect: R1,
dst: &mut SurfaceRef,
dst_rect: R2,
) -> Result<Option<Rect>, String>
where
R1: Into<Option<Rect>>,
R2: Into<Option<Rect>>,
{
let src_rect = src_rect.into();
let dst_rect = dst_rect.into();
@@ -723,12 +770,14 @@ impl SurfaceRef {
// Copy the rect here to make a mutable copy without requiring
// a mutable argument
let mut dst_rect = dst_rect;
let dst_rect_ptr = dst_rect.as_mut().map(|r| r.raw_mut())
let dst_rect_ptr = dst_rect
.as_mut()
.map(|r| r.raw_mut())
.unwrap_or(ptr::null_mut());
sys::SDL_UpperBlitScaled(self.raw(), src_rect_ptr, dst.raw(), dst_rect_ptr)
} {
0 => Ok(dst_rect),
_ => Err(get_error())
_ => Err(get_error()),
}
}
@@ -736,22 +785,32 @@ impl SurfaceRef {
///
/// Unless you know what you're doing, use `blit_scaled()` instead, which will clip the input rectangles.
/// This function could crash if the rectangles aren't pre-clipped to the surface, and is therefore unsafe.
pub unsafe fn lower_blit_scaled<R1, R2>(&self, src_rect: R1,
dst: &mut SurfaceRef, dst_rect: R2) -> Result<(), String>
where R1: Into<Option<Rect>>,
R2: Into<Option<Rect>>
pub unsafe fn lower_blit_scaled<R1, R2>(
&self,
src_rect: R1,
dst: &mut SurfaceRef,
dst_rect: R2,
) -> Result<(), String>
where
R1: Into<Option<Rect>>,
R2: Into<Option<Rect>>,
{
match {
// The rectangles don't change, but the function requires mutable pointers.
let src_rect_ptr = src_rect.into().as_ref().map(|r| r.raw())
let src_rect_ptr = src_rect
.into()
.as_ref()
.map(|r| r.raw())
.unwrap_or(ptr::null()) as *mut _;
let dst_rect_ptr = dst_rect.into().as_ref().map(|r| r.raw())
let dst_rect_ptr = dst_rect
.into()
.as_ref()
.map(|r| r.raw())
.unwrap_or(ptr::null()) as *mut _;
sys::SDL_LowerBlitScaled(self.raw(), src_rect_ptr, dst.raw(), dst_rect_ptr)
} {
0 => Ok(()),
_ => Err(get_error())
_ => Err(get_error()),
}
}

View File

@@ -1,7 +1,7 @@
use crate::sys;
use libc::c_void;
use std::marker::PhantomData;
use std::mem;
use crate::sys;
use crate::TimerSubsystem;
@@ -17,14 +17,16 @@ impl TimerSubsystem {
pub fn add_timer<'b, 'c>(&'b self, delay: u32, callback: TimerCallback<'c>) -> Timer<'b, 'c> {
unsafe {
let callback = Box::new(callback);
let timer_id = sys::SDL_AddTimer(delay,
Some(c_timer_callback),
mem::transmute_copy(&callback));
let timer_id = sys::SDL_AddTimer(
delay,
Some(c_timer_callback),
mem::transmute_copy(&callback),
);
Timer {
callback: Some(callback),
raw: timer_id,
_marker: PhantomData
_marker: PhantomData,
}
}
}
@@ -58,12 +60,12 @@ impl TimerSubsystem {
}
}
pub type TimerCallback<'a> = Box<dyn FnMut() -> u32+'a+Sync>;
pub type TimerCallback<'a> = Box<dyn FnMut() -> u32 + 'a + Sync>;
pub struct Timer<'b, 'a> {
callback: Option<Box<TimerCallback<'a>>>,
raw: sys::SDL_TimerID,
_marker: PhantomData<&'b ()>
_marker: PhantomData<&'b ()>,
}
impl<'b, 'a> Timer<'b, 'a> {
@@ -87,12 +89,9 @@ impl<'b, 'a> Drop for Timer<'b, 'a> {
extern "C" fn c_timer_callback(_interval: u32, param: *mut c_void) -> u32 {
let f = param as *mut std::boxed::Box<dyn std::ops::Fn() -> u32>;
unsafe {
(*f)()
}
unsafe { (*f)() }
}
#[cfg(not(target_os = "macos"))]
#[cfg(test)]
mod test {
@@ -113,21 +112,26 @@ mod test {
let local_num = Arc::new(Mutex::new(0));
let timer_num = local_num.clone();
let _timer = timer_subsystem.add_timer(20, Box::new(|| {
// increment up to 10 times (0 -> 9)
// tick again in 100ms after each increment
//
let mut num = timer_num.lock().unwrap();
if *num < 9 {
*num += 1;
20
} else { 0 }
}));
let _timer = timer_subsystem.add_timer(
20,
Box::new(|| {
// increment up to 10 times (0 -> 9)
// tick again in 100ms after each increment
//
let mut num = timer_num.lock().unwrap();
if *num < 9 {
*num += 1;
20
} else {
0
}
}),
);
// tick the timer at least 10 times w/ 200ms of "buffer"
::std::thread::sleep(Duration::from_millis(250));
let num = local_num.lock().unwrap(); // read the number back
assert_eq!(*num, 9); // it should have incremented at least 10 times...
assert_eq!(*num, 9); // it should have incremented at least 10 times...
}
fn test_timer_runs_at_least_once() {
@@ -137,10 +141,14 @@ mod test {
let local_flag = Arc::new(Mutex::new(false));
let timer_flag = local_flag.clone();
let _timer = timer_subsystem.add_timer(20, Box::new(|| {
let mut flag = timer_flag.lock().unwrap();
*flag = true; 0
}));
let _timer = timer_subsystem.add_timer(
20,
Box::new(|| {
let mut flag = timer_flag.lock().unwrap();
*flag = true;
0
}),
);
::std::thread::sleep(Duration::from_millis(50));
let flag = local_flag.lock().unwrap();
@@ -155,11 +163,14 @@ mod test {
let timer_num = local_num.clone();
// run the timer once and reclaim its closure
let timer_1 = timer_subsystem.add_timer(20, Box::new(move|| {
let mut num = timer_num.lock().unwrap();
*num += 1; // increment the number
0 // do not run timer again
}));
let timer_1 = timer_subsystem.add_timer(
20,
Box::new(move || {
let mut num = timer_num.lock().unwrap();
*num += 1; // increment the number
0 // do not run timer again
}),
);
// reclaim closure after timer runs
::std::thread::sleep(Duration::from_millis(50));

View File

@@ -1,18 +1,15 @@
use std::io;
use get_error;
use rwops::RWops;
use std::error;
use std::fmt;
use std::io;
use std::os::raw::{c_int, c_long};
use std::path::Path;
use ::get_error;
use ::rwops::RWops;
use ::version::Version;
use sys::ttf;
use version::Version;
use super::font::{
internal_load_font,
internal_load_font_at_index,
internal_load_font_from_ll,
Font,
internal_load_font, internal_load_font_at_index, internal_load_font_from_ll, Font,
};
/// A context manager for `SDL2_TTF` to manage C code initialization and clean-up.
@@ -22,30 +19,41 @@ pub struct Sdl2TtfContext;
// Clean up the context once it goes out of scope
impl Drop for Sdl2TtfContext {
fn drop(&mut self) {
unsafe { ttf::TTF_Quit(); }
unsafe {
ttf::TTF_Quit();
}
}
}
impl Sdl2TtfContext {
/// Loads a font from the given file with the given size in points.
pub fn load_font<'ttf, P: AsRef<Path>>(&'ttf self, path: P, point_size: u16) -> Result<Font<'ttf,'static>, String> {
pub fn load_font<'ttf, P: AsRef<Path>>(
&'ttf self,
path: P,
point_size: u16,
) -> Result<Font<'ttf, 'static>, String> {
internal_load_font(path, point_size)
}
/// Loads the font at the given index of the file, with the given
/// size in points.
pub fn load_font_at_index<'ttf, P: AsRef<Path>>(&'ttf self, path: P, index: u32, point_size: u16)
-> Result<Font<'ttf,'static>, String> {
pub fn load_font_at_index<'ttf, P: AsRef<Path>>(
&'ttf self,
path: P,
index: u32,
point_size: u16,
) -> Result<Font<'ttf, 'static>, String> {
internal_load_font_at_index(path, index, point_size)
}
/// Loads a font from the given SDL2 rwops object with the given size in
/// points.
pub fn load_font_from_rwops<'ttf,'r>(&'ttf self, rwops: RWops<'r>, point_size: u16)
-> Result<Font<'ttf,'r>, String> {
let raw = unsafe {
ttf::TTF_OpenFontRW(rwops.raw(), 0, point_size as c_int)
};
pub fn load_font_from_rwops<'ttf, 'r>(
&'ttf self,
rwops: RWops<'r>,
point_size: u16,
) -> Result<Font<'ttf, 'r>, String> {
let raw = unsafe { ttf::TTF_OpenFontRW(rwops.raw(), 0, point_size as c_int) };
if (raw as *mut ()).is_null() {
Err(get_error())
} else {
@@ -55,11 +63,14 @@ impl Sdl2TtfContext {
/// Loads the font at the given index of the SDL2 rwops object with
/// the given size in points.
pub fn load_font_at_index_from_rwops<'ttf,'r>(&'ttf self, rwops: RWops<'r>, index: u32,
point_size: u16) -> Result<Font<'ttf,'r>, String> {
pub fn load_font_at_index_from_rwops<'ttf, 'r>(
&'ttf self,
rwops: RWops<'r>,
index: u32,
point_size: u16,
) -> Result<Font<'ttf, 'r>, String> {
let raw = unsafe {
ttf::TTF_OpenFontIndexRW(rwops.raw(), 0, point_size as c_int,
index as c_long)
ttf::TTF_OpenFontIndexRW(rwops.raw(), 0, point_size as c_int, index as c_long)
};
if (raw as *mut ()).is_null() {
Err(get_error())
@@ -71,9 +82,7 @@ impl Sdl2TtfContext {
/// Returns the version of the dynamically linked `SDL_TTF` library
pub fn get_linked_version() -> Version {
unsafe {
Version::from_ll(*ttf::TTF_Linked_Version())
}
unsafe { Version::from_ll(*ttf::TTF_Linked_Version()) }
}
/// An error for when `sdl2_ttf` is attempted initialized twice
@@ -87,23 +96,15 @@ pub enum InitError {
impl error::Error for InitError {
fn description(&self) -> &str {
match *self {
InitError::AlreadyInitializedError => {
"SDL2_TTF has already been initialized"
},
InitError::InitializationError(ref error) => {
error.description()
},
InitError::AlreadyInitializedError => "SDL2_TTF has already been initialized",
InitError::InitializationError(ref error) => error.description(),
}
}
fn cause(&self) -> Option<&dyn error::Error> {
match *self {
InitError::AlreadyInitializedError => {
None
},
InitError::InitializationError(ref error) => {
Some(error)
},
InitError::AlreadyInitializedError => None,
InitError::InitializationError(ref error) => Some(error),
}
}
}
@@ -123,16 +124,12 @@ pub fn init() -> Result<Sdl2TtfContext, InitError> {
} else if ttf::TTF_Init() == 0 {
Ok(Sdl2TtfContext)
} else {
Err(InitError::InitializationError(
io::Error::last_os_error()
))
Err(InitError::InitializationError(io::Error::last_os_error()))
}
}
}
/// Returns whether library has been initialized already.
pub fn has_been_initialized() -> bool {
unsafe {
ttf::TTF_WasInit() == 1
}
unsafe { ttf::TTF_WasInit() == 1 }
}

View File

@@ -1,17 +1,17 @@
use std::ffi::{CString, CStr};
use std::os::raw::{c_uint, c_int, c_long};
use std::path::Path;
use get_error;
use pixels::Color;
use rwops::RWops;
use std::error;
use std::error::Error;
use std::ffi::NulError;
use std::ffi::{CStr, CString};
use std::fmt;
use std::marker::PhantomData;
use ::surface::Surface;
use std::os::raw::{c_int, c_long, c_uint};
use std::path::Path;
use surface::Surface;
use sys::ttf;
use sys::SDL_Surface;
use ::get_error;
use ::pixels::Color;
use ::rwops::RWops;
bitflags! {
/// The styling of a font.
@@ -30,9 +30,9 @@ bitflags! {
#[derive(Debug, PartialEq, Clone)]
pub enum Hinting {
Normal = ttf::TTF_HINTING_NORMAL as i32,
Light = ttf::TTF_HINTING_LIGHT as i32,
Mono = ttf::TTF_HINTING_MONO as i32,
None = ttf::TTF_HINTING_NONE as i32,
Light = ttf::TTF_HINTING_LIGHT as i32,
Mono = ttf::TTF_HINTING_MONO as i32,
None = ttf::TTF_HINTING_NONE as i32,
}
/// Information about a specific glyph (character) in a font face.
@@ -42,7 +42,7 @@ pub struct GlyphMetrics {
pub maxx: i32,
pub miny: i32,
pub maxy: i32,
pub advance: i32
pub advance: i32,
}
/// The result of an `SDL2_TTF` font operation.
@@ -60,23 +60,15 @@ pub enum FontError {
impl error::Error for FontError {
fn description(&self) -> &str {
match *self {
FontError::InvalidLatin1Text(ref error) => {
error.description()
},
FontError::SdlError(ref message) => {
message
},
FontError::InvalidLatin1Text(ref error) => error.description(),
FontError::SdlError(ref message) => message,
}
}
fn cause(&self) -> Option<&dyn error::Error> {
match *self {
FontError::InvalidLatin1Text(ref error) => {
Some(error)
},
FontError::SdlError(_) => {
None
},
FontError::InvalidLatin1Text(ref error) => Some(error),
FontError::SdlError(_) => None,
}
}
}
@@ -86,12 +78,11 @@ impl fmt::Display for FontError {
match *self {
FontError::InvalidLatin1Text(ref err) => {
write!(f, "Invalid Latin-1 bytes: {}", err.description())
},
}
FontError::SdlError(ref msg) => {
write!(f, "SDL2 error: {}", msg)
},
}
}
}
}
@@ -105,22 +96,12 @@ impl<'a> RenderableText<'a> {
/// Converts the given text to a c-style string if possible.
fn convert(&self) -> FontResult<CString> {
match *self {
RenderableText::Utf8(text) => {
Ok(CString::new(text).unwrap())
RenderableText::Utf8(text) => Ok(CString::new(text).unwrap()),
RenderableText::Latin1(bytes) => match CString::new(bytes) {
Err(err) => Err(FontError::InvalidLatin1Text(err)),
Ok(cstring) => Ok(cstring),
},
RenderableText::Latin1(bytes) => {
match CString::new(bytes) {
Err(err) => {
Err(FontError::InvalidLatin1Text(err))
},
Ok(cstring) => {
Ok(cstring)
}
}
},
RenderableText::Char(ref string) => {
Ok(CString::new(string.as_bytes()).unwrap())
}
RenderableText::Char(ref string) => Ok(CString::new(string.as_bytes()).unwrap()),
}
}
}
@@ -137,30 +118,28 @@ fn convert_to_surface<'a>(raw: *mut SDL_Surface) -> FontResult<Surface<'a>> {
if (raw as *mut ()).is_null() {
Err(FontError::SdlError(get_error()))
} else {
Ok(unsafe {
Surface::from_ll(raw)
})
Ok(unsafe { Surface::from_ll(raw) })
}
}
impl<'f,'text> PartialRendering<'f,'text> {
impl<'f, 'text> PartialRendering<'f, 'text> {
/// Renders the text in *solid* mode.
/// See [the SDL2_TTF docs](https://www.libsdl.org/projects/SDL_ttf/docs/SDL_ttf.html#SEC42)
/// for an explanation.
pub fn solid<'b, T>(self, color: T )
-> FontResult<Surface<'b>> where T: Into<Color> {
pub fn solid<'b, T>(self, color: T) -> FontResult<Surface<'b>>
where
T: Into<Color>,
{
let source = self.text.convert()?;
let color = color.into().into();
let raw = unsafe {
match self.text {
RenderableText::Utf8(_) | RenderableText::Char(_) => {
ttf::TTF_RenderUTF8_Solid(self.font.raw(),
source.as_ptr(), color)
},
ttf::TTF_RenderUTF8_Solid(self.font.raw(), source.as_ptr(), color)
}
RenderableText::Latin1(_) => {
ttf::TTF_RenderText_Solid(self.font.raw(),
source.as_ptr(), color)
},
ttf::TTF_RenderText_Solid(self.font.raw(), source.as_ptr(), color)
}
}
};
convert_to_surface(raw)
@@ -169,21 +148,27 @@ impl<'f,'text> PartialRendering<'f,'text> {
/// Renders the text in *shaded* mode.
/// See [the SDL2_TTF docs](https://www.libsdl.org/projects/SDL_ttf/docs/SDL_ttf.html#SEC42)
/// for an explanation.
pub fn shaded<'b, T>(self, color: T, background: T)
-> FontResult<Surface<'b>> where T: Into<Color> {
pub fn shaded<'b, T>(self, color: T, background: T) -> FontResult<Surface<'b>>
where
T: Into<Color>,
{
let source = self.text.convert()?;
let foreground = color.into().into();
let background = background.into().into();
let raw = unsafe {
match self.text {
RenderableText::Utf8(_) | RenderableText::Char(_) => {
ttf::TTF_RenderUTF8_Shaded(self.font.raw(),
source.as_ptr(), foreground, background)
},
RenderableText::Latin1(_) => {
ttf::TTF_RenderText_Shaded(self.font.raw(),
source.as_ptr(), foreground, background)
},
RenderableText::Utf8(_) | RenderableText::Char(_) => ttf::TTF_RenderUTF8_Shaded(
self.font.raw(),
source.as_ptr(),
foreground,
background,
),
RenderableText::Latin1(_) => ttf::TTF_RenderText_Shaded(
self.font.raw(),
source.as_ptr(),
foreground,
background,
),
}
};
convert_to_surface(raw)
@@ -192,20 +177,20 @@ impl<'f,'text> PartialRendering<'f,'text> {
/// Renders the text in *blended* mode.
/// See [the SDL2_TTF docs](https://www.libsdl.org/projects/SDL_ttf/docs/SDL_ttf.html#SEC42)
/// for an explanation.
pub fn blended<'b, T>(self, color: T)
-> FontResult<Surface<'b>> where T: Into<Color> {
pub fn blended<'b, T>(self, color: T) -> FontResult<Surface<'b>>
where
T: Into<Color>,
{
let source = self.text.convert()?;
let color = color.into().into();
let raw = unsafe {
match self.text {
RenderableText::Utf8(_) | RenderableText::Char(_) => {
ttf::TTF_RenderUTF8_Blended(self.font.raw(),
source.as_ptr(), color)
},
ttf::TTF_RenderUTF8_Blended(self.font.raw(), source.as_ptr(), color)
}
RenderableText::Latin1(_) => {
ttf::TTF_RenderText_Blended(self.font.raw(),
source.as_ptr(), color)
},
ttf::TTF_RenderText_Blended(self.font.raw(), source.as_ptr(), color)
}
}
};
convert_to_surface(raw)
@@ -215,20 +200,28 @@ impl<'f,'text> PartialRendering<'f,'text> {
/// exceeds the given maximum width.
/// See [the SDL2_TTF docs](https://www.libsdl.org/projects/SDL_ttf/docs/SDL_ttf.html#SEC42)
/// for an explanation of the mode.
pub fn blended_wrapped<'b, T>(self, color: T, wrap_max_width: u32)
-> FontResult<Surface<'b>> where T: Into<Color> {
pub fn blended_wrapped<'b, T>(self, color: T, wrap_max_width: u32) -> FontResult<Surface<'b>>
where
T: Into<Color>,
{
let source = self.text.convert()?;
let color = color.into().into();
let raw = unsafe {
match self.text {
RenderableText::Utf8(_) | RenderableText::Char(_) => {
ttf::TTF_RenderUTF8_Blended_Wrapped(self.font.raw(),
source.as_ptr(), color, wrap_max_width)
},
RenderableText::Latin1(_) => {
ttf::TTF_RenderText_Blended_Wrapped(self.font.raw(),
source.as_ptr(), color, wrap_max_width)
},
ttf::TTF_RenderUTF8_Blended_Wrapped(
self.font.raw(),
source.as_ptr(),
color,
wrap_max_width,
)
}
RenderableText::Latin1(_) => ttf::TTF_RenderText_Blended_Wrapped(
self.font.raw(),
source.as_ptr(),
color,
wrap_max_width,
),
}
};
convert_to_surface(raw)
@@ -236,7 +229,7 @@ impl<'f,'text> PartialRendering<'f,'text> {
}
/// A loaded TTF font.
pub struct Font<'ttf_module,'rwops> {
pub struct Font<'ttf_module, 'rwops> {
raw: *mut ttf::TTF_Font,
// RWops is only stored here because it must not outlive
// the Font struct, and this RWops should not be used by
@@ -250,9 +243,7 @@ pub struct Font<'ttf_module,'rwops> {
_marker: PhantomData<&'ttf_module ()>,
}
impl<'ttf,'r> Drop for Font<'ttf,'r> {
impl<'ttf, 'r> Drop for Font<'ttf, 'r> {
fn drop(&mut self) {
unsafe {
// avoid close font after quit()
@@ -264,42 +255,59 @@ impl<'ttf,'r> Drop for Font<'ttf,'r> {
}
/// Internally used to load a font (for internal visibility).
pub fn internal_load_font<'ttf,P:AsRef<Path>>(path: P, ptsize: u16) -> Result<Font<'ttf,'static>, String> {
pub fn internal_load_font<'ttf, P: AsRef<Path>>(
path: P,
ptsize: u16,
) -> Result<Font<'ttf, 'static>, String> {
unsafe {
let cstring = CString::new(path.as_ref().to_str().unwrap()).unwrap();
let raw = ttf::TTF_OpenFont(cstring.as_ptr(), ptsize as c_int);
if raw.is_null() {
Err(get_error())
} else {
Ok(Font { raw: raw, rwops: None, _marker: PhantomData })
Ok(Font {
raw: raw,
rwops: None,
_marker: PhantomData,
})
}
}
}
/// Internally used to load a font (for internal visibility).
pub fn internal_load_font_from_ll<'ttf,'r, R>(raw: *mut ttf::TTF_Font, rwops: R)
-> Font<'ttf,'r>
where R: Into<Option<RWops<'r>>> {
Font { raw: raw, rwops: rwops.into(), _marker: PhantomData }
pub fn internal_load_font_from_ll<'ttf, 'r, R>(raw: *mut ttf::TTF_Font, rwops: R) -> Font<'ttf, 'r>
where
R: Into<Option<RWops<'r>>>,
{
Font {
raw: raw,
rwops: rwops.into(),
_marker: PhantomData,
}
}
/// Internally used to load a font (for internal visibility).
pub fn internal_load_font_at_index<'ttf,P: AsRef<Path>>(path: P, index: u32, ptsize: u16)
-> Result<Font<'ttf, 'static>, String> {
pub fn internal_load_font_at_index<'ttf, P: AsRef<Path>>(
path: P,
index: u32,
ptsize: u16,
) -> Result<Font<'ttf, 'static>, String> {
unsafe {
let cstring = CString::new(path.as_ref().to_str().unwrap().as_bytes())
.unwrap();
let raw = ttf::TTF_OpenFontIndex(cstring.as_ptr(),
ptsize as c_int, index as c_long);
let cstring = CString::new(path.as_ref().to_str().unwrap().as_bytes()).unwrap();
let raw = ttf::TTF_OpenFontIndex(cstring.as_ptr(), ptsize as c_int, index as c_long);
if raw.is_null() {
Err(get_error())
} else {
Ok(Font { raw: raw, rwops: None, _marker: PhantomData})
Ok(Font {
raw: raw,
rwops: None,
_marker: PhantomData,
})
}
}
}
impl<'ttf,'r> Font<'ttf,'r> {
impl<'ttf, 'r> Font<'ttf, 'r> {
/// Returns the underlying C font object.
// this can prevent introducing UB until
// https://github.com/rust-lang/rust-clippy/issues/5953 is fixed
@@ -354,13 +362,17 @@ impl<'ttf,'r> Font<'ttf,'r> {
/// Returns the width and height of the given text when rendered using this
/// font.
#[allow(unused_mut)]
pub fn size_of_latin1(&self, text: &[u8])
-> FontResult<(u32, u32)> {
pub fn size_of_latin1(&self, text: &[u8]) -> FontResult<(u32, u32)> {
let c_string = RenderableText::Latin1(text).convert()?;
let (res, size) = unsafe {
let mut w : i32 = 0; // mutated by C code
let mut h : i32 = 0; // mutated by C code
let ret = ttf::TTF_SizeText(self.raw, c_string.as_ptr(), &w as *const _ as *mut i32, &h as *const _ as *mut i32);
let mut w: i32 = 0; // mutated by C code
let mut h: i32 = 0; // mutated by C code
let ret = ttf::TTF_SizeText(
self.raw,
c_string.as_ptr(),
&w as *const _ as *mut i32,
&h as *const _ as *mut i32,
);
(ret, (w as u32, h as u32))
};
if res == 0 {
@@ -388,99 +400,75 @@ impl<'ttf,'r> Font<'ttf,'r> {
/// Sets the font's style flags.
pub fn set_style(&mut self, styles: FontStyle) {
unsafe {
ttf::TTF_SetFontStyle(self.raw, styles.bits() as c_int)
}
unsafe { ttf::TTF_SetFontStyle(self.raw, styles.bits() as c_int) }
}
/// Returns the width of the font's outline.
pub fn get_outline_width(&self) -> u16 {
unsafe {
ttf::TTF_GetFontOutline(self.raw) as u16
}
unsafe { ttf::TTF_GetFontOutline(self.raw) as u16 }
}
/// Sets the width of the font's outline.
pub fn set_outline_width(&mut self, width: u16) {
unsafe {
ttf::TTF_SetFontOutline(self.raw, width as c_int)
}
unsafe { ttf::TTF_SetFontOutline(self.raw, width as c_int) }
}
/// Returns the font's freetype hints.
pub fn get_hinting(&self) -> Hinting {
unsafe {
match ttf::TTF_GetFontHinting(self.raw) as c_uint {
ttf::TTF_HINTING_NORMAL => Hinting::Normal,
ttf::TTF_HINTING_LIGHT => Hinting::Light,
ttf::TTF_HINTING_MONO => Hinting::Mono,
ttf::TTF_HINTING_NONE | _ => Hinting::None
ttf::TTF_HINTING_NORMAL => Hinting::Normal,
ttf::TTF_HINTING_LIGHT => Hinting::Light,
ttf::TTF_HINTING_MONO => Hinting::Mono,
ttf::TTF_HINTING_NONE | _ => Hinting::None,
}
}
}
/// Sets the font's freetype hints.
pub fn set_hinting(&mut self, hinting: Hinting) {
unsafe {
ttf::TTF_SetFontHinting(self.raw, hinting as c_int)
}
unsafe { ttf::TTF_SetFontHinting(self.raw, hinting as c_int) }
}
/// Returns whether the font is kerning.
pub fn get_kerning(&self) -> bool {
unsafe {
ttf::TTF_GetFontKerning(self.raw) != 0
}
unsafe { ttf::TTF_GetFontKerning(self.raw) != 0 }
}
/// Sets whether the font should use kerning.
pub fn set_kerning(&mut self, kerning: bool) {
unsafe {
ttf::TTF_SetFontKerning(self.raw, kerning as c_int)
}
unsafe { ttf::TTF_SetFontKerning(self.raw, kerning as c_int) }
}
pub fn height(&self) -> i32 {
//! Get font maximum total height.
unsafe {
ttf::TTF_FontHeight(self.raw) as i32
}
unsafe { ttf::TTF_FontHeight(self.raw) as i32 }
}
/// Returns the font's highest ascent (height above base).
pub fn ascent(&self) -> i32 {
unsafe {
ttf::TTF_FontAscent(self.raw) as i32
}
unsafe { ttf::TTF_FontAscent(self.raw) as i32 }
}
/// Returns the font's lowest descent (height below base).
/// This is a negative number.
pub fn descent(&self) -> i32 {
unsafe {
ttf::TTF_FontDescent(self.raw) as i32
}
unsafe { ttf::TTF_FontDescent(self.raw) as i32 }
}
/// Returns the recommended line spacing for text rendered with this font.
pub fn recommended_line_spacing(&self) -> i32 {
unsafe {
ttf::TTF_FontLineSkip(self.raw) as i32
}
unsafe { ttf::TTF_FontLineSkip(self.raw) as i32 }
}
/// Returns the number of faces in this font.
pub fn face_count(&self) -> u16 {
unsafe {
ttf::TTF_FontFaces(self.raw) as u16
}
unsafe { ttf::TTF_FontFaces(self.raw) as u16 }
}
/// Returns whether the font is monospaced.
pub fn face_is_fixed_width(&self) -> bool {
unsafe {
ttf::TTF_FontFaceIsFixedWidth(self.raw) != 0
}
unsafe { ttf::TTF_FontFaceIsFixedWidth(self.raw) != 0 }
}
/// Returns the family name of the current font face.
@@ -535,14 +523,17 @@ impl<'ttf,'r> Font<'ttf,'r> {
&maxx as *const _ as *mut _,
&miny as *const _ as *mut _,
&maxy as *const _ as *mut _,
&advance as *const _ as *mut _
&advance as *const _ as *mut _,
)
};
if ret == 0 {
Some(GlyphMetrics {
minx: minx as i32, maxx: maxx as i32, miny: miny as i32,
maxy: maxy as i32, advance: advance as i32
} )
minx: minx as i32,
maxx: maxx as i32,
miny: miny as i32,
maxy: maxy as i32,
advance: advance as i32,
})
} else {
None
}

View File

@@ -1,7 +1,7 @@
//!
//! A binding for the library `SDL2_ttf`
//!
//!
//!
//! Note that you need to build with the
//! feature `ttf` for this module to be enabled,
//! like so:
@@ -20,13 +20,12 @@
//! features = ["ttf"]
//! ```
mod font;
mod context;
mod font;
pub use self::context::{
init, has_been_initialized, get_linked_version, Sdl2TtfContext, InitError,
get_linked_version, has_been_initialized, init, InitError, Sdl2TtfContext,
};
pub use self::font::{
Font, FontStyle, Hinting, GlyphMetrics, PartialRendering, FontError,
FontResult
Font, FontError, FontResult, FontStyle, GlyphMetrics, Hinting, PartialRendering,
};

View File

@@ -21,7 +21,11 @@ pub struct Version {
impl Version {
/// Convert a raw *SDL_version to Version.
pub fn from_ll(v: sys::SDL_version) -> Version {
Version { major: v.major, minor: v.minor, patch: v.patch }
Version {
major: v.major,
minor: v.minor,
patch: v.patch,
}
}
}
@@ -35,7 +39,11 @@ impl fmt::Display for Version {
#[doc(alias = "SDL_GetVersion")]
pub fn version() -> Version {
unsafe {
let mut cver = sys::SDL_version { major: 0, minor: 0, patch: 0};
let mut cver = sys::SDL_version {
major: 0,
minor: 0,
patch: 0,
};
sys::SDL_GetVersion(&mut cver);
Version::from_ll(cver)
}
@@ -53,7 +61,5 @@ pub fn revision() -> String {
/// Get the revision number of SDL that is linked against your program.
#[doc(alias = "SDL_GetRevisionNumber")]
pub fn revision_number() -> i32 {
unsafe {
sys::SDL_GetRevisionNumber()
}
unsafe { sys::SDL_GetRevisionNumber() }
}

File diff suppressed because it is too large Load Diff

View File

@@ -69,23 +69,24 @@ fn test2(ev: &sdl2::EventSubsystem, ep: &mut sdl2::EventPump) {
#[allow(unused)]
struct SomeEventTypeTest3 {
a: u32
a: u32,
}
#[allow(unused)]
struct SomeOtherEventTypeTest3 {
b: u32
b: u32,
}
fn test3(ev: &sdl2::EventSubsystem) {
ev.register_custom_event::<SomeEventTypeTest3>().unwrap();
ev.register_custom_event::<SomeOtherEventTypeTest3>().unwrap();
ev.register_custom_event::<SomeOtherEventTypeTest3>()
.unwrap();
assert!(ev.register_custom_event::<SomeEventTypeTest3>().is_err());
}
struct SomeEventTypeTest4 {
a: u32
a: u32,
}
fn test4(ev: &sdl2::EventSubsystem, ep: &mut sdl2::EventPump) {
@@ -106,18 +107,22 @@ fn test_event_sender_no_subsystem() {
let ev = sdl.event().unwrap();
let tx = ev.event_sender();
assert!(tx.push_event(sdl2::event::Event::Window {
timestamp: 0,
window_id: 0,
win_event: sdl2::event::WindowEvent::Shown,
}).is_ok());
assert!(tx
.push_event(sdl2::event::Event::Window {
timestamp: 0,
window_id: 0,
win_event: sdl2::event::WindowEvent::Shown,
})
.is_ok());
drop(ev);
// Should return an error now the evet subsystem has been shut down
assert!(tx.push_event(sdl2::event::Event::Window {
timestamp: 0,
window_id: 0,
win_event: sdl2::event::WindowEvent::Hidden,
}).is_err());
}
assert!(tx
.push_event(sdl2::event::Event::Window {
timestamp: 0,
window_id: 0,
win_event: sdl2::event::WindowEvent::Hidden,
})
.is_err());
}

View File

@@ -14,17 +14,21 @@ mod raw_window_handle_test {
RawWindowHandle::Windows(windows_handle) => {
assert_ne!(windows_handle.hwnd, 0 as *mut libc::c_void);
println!("Successfully received Windows RawWindowHandle!");
},
x => assert!(false, "Received wrong RawWindowHandle type for Windows: {:?}", x),
}
x => assert!(
false,
"Received wrong RawWindowHandle type for Windows: {:?}",
x
),
}
}
#[cfg(any(
target_os = "linux",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd",
target_os = "linux",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd",
))]
#[test]
fn get_linux_handle() {
@@ -32,15 +36,28 @@ mod raw_window_handle_test {
match window.raw_window_handle() {
RawWindowHandle::Xlib(x11_handle) => {
assert_ne!(x11_handle.window, 0, "Window for X11 should not be 0");
assert_ne!(x11_handle.display, 0 as *mut libc::c_void, "Display for X11 should not be null");
assert_ne!(
x11_handle.display, 0 as *mut libc::c_void,
"Display for X11 should not be null"
);
println!("Successfully received linux X11 RawWindowHandle!");
},
}
RawWindowHandle::Wayland(wayland_handle) => {
assert_ne!(wayland_handle.surface, 0 as *mut libc::c_void, "Surface for Wayland should not be null");
assert_ne!(wayland_handle.display, 0 as *mut libc::c_void, "Display for Wayland should not be null");
assert_ne!(
wayland_handle.surface, 0 as *mut libc::c_void,
"Surface for Wayland should not be null"
);
assert_ne!(
wayland_handle.display, 0 as *mut libc::c_void,
"Display for Wayland should not be null"
);
println!("Successfully received linux Wayland RawWindowHandle!");
},
x => assert!(false, "Received wrong RawWindowHandle type for linux: {:?}", x),
}
x => assert!(
false,
"Received wrong RawWindowHandle type for linux: {:?}",
x
),
}
}
@@ -50,11 +67,21 @@ mod raw_window_handle_test {
let window = new_hidden_window();
match window.raw_window_handle() {
RawWindowHandle::MacOS(macos_handle) => {
assert_ne!(macos_handle.ns_window, 0 as *mut libc::c_void, "ns_window should not be null");
assert_eq!(macos_handle.ns_view, 0 as *mut libc::c_void, "nw_view should be null");
assert_ne!(
macos_handle.ns_window, 0 as *mut libc::c_void,
"ns_window should not be null"
);
assert_eq!(
macos_handle.ns_view, 0 as *mut libc::c_void,
"nw_view should be null"
);
println!("Successfully received macOS RawWindowHandle!");
},
x => assert!(false, "Received wrong RawWindowHandle type for macOS: {:?}", x),
}
x => assert!(
false,
"Received wrong RawWindowHandle type for macOS: {:?}",
x
),
};
}

View File

@@ -9,5 +9,5 @@ fn display_name_no_segfault() {
let r = video_subsystem.display_name(99);
assert!(r.is_err());
} // in Err(), environment has no video device (for instance travis)
// so ignore it
// so ignore it
}