mirror of
https://github.com/touchHLE/rust-sdl2.git
synced 2026-01-31 01:25:23 +01:00
run cargo fmt
This commit is contained in:
2
build.rs
2
build.rs
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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)?;
|
||||
|
||||
|
||||
@@ -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)?;
|
||||
|
||||
@@ -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(())
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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() {}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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(())
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
},
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()]);
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
pub mod primitives;
|
||||
pub mod framerate;
|
||||
pub mod imagefilter;
|
||||
pub mod primitives;
|
||||
pub mod rotozoom;
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
1529
src/sdl2/event.rs
1529
src/sdl2/event.rs
File diff suppressed because it is too large
Load Diff
@@ -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()
|
||||
};
|
||||
|
||||
|
||||
@@ -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()),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
//! features = ["gfx"]
|
||||
//! ```
|
||||
|
||||
pub mod primitives;
|
||||
pub mod rotozoom;
|
||||
pub mod framerate;
|
||||
pub mod imagefilter;
|
||||
pub mod primitives;
|
||||
pub mod rotozoom;
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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.
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)]
|
||||
|
||||
231
src/sdl2/rect.rs
231
src/sdl2/rect.rs
@@ -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
@@ -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 {
|
||||
|
||||
110
src/sdl2/sdl.rs
110
src/sdl2/sdl.rs
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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 }
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user