1use std::ffi::{CStr, CString};
2use std::str;
3
4#[cfg(target_os = "macos")]
6mod mac {
7 #[cfg(mac_framework)]
8 #[link(name = "SDL", kind = "framework")]
9 extern "C" {}
10
11 #[cfg(not(mac_framework))]
12 #[link(name = "SDL")]
13 extern "C" {}
14}
15
16#[cfg(not(target_os = "macos"))]
17mod others {
18 #[link(name = "SDL")]
19 extern "C" {}
20}
21
22pub mod ll {
23 #![allow(non_camel_case_types)]
24
25 use std::ffi::c_char;
26
27 use libc::{c_int, c_uint, uint32_t};
28
29 pub type SDL_errorcode = c_uint;
30 pub const SDL_ENOMEM: SDL_errorcode = 0;
31 pub const SDL_EFREAD: SDL_errorcode = 1;
32 pub const SDL_EFWRITE: SDL_errorcode = 2;
33 pub const SDL_EFSEEK: SDL_errorcode = 3;
34 pub const SDL_UNSUPPORTED: SDL_errorcode = 4;
35 pub const SDL_LASTERROR: SDL_errorcode = 5;
36
37 pub type SDL_InitFlag = uint32_t;
38 pub const SDL_INIT_TIMER: SDL_InitFlag = 0x00000001;
39 pub const SDL_INIT_AUDIO: SDL_InitFlag = 0x00000010;
40 pub const SDL_INIT_VIDEO: SDL_InitFlag = 0x00000020;
41 pub const SDL_INIT_CDROM: SDL_InitFlag = 0x00000100;
42 pub const SDL_INIT_JOYSTICK: SDL_InitFlag = 0x00000200;
43 pub const SDL_INIT_NOPARACHUTE: SDL_InitFlag = 0x00100000;
44 pub const SDL_INIT_EVENTTHREAD: SDL_InitFlag = 0x01000000;
45 pub const SDL_INIT_EVERYTHING: SDL_InitFlag = 0x0000FFFF;
46
47 extern "C" {
48 pub fn SDL_ClearError();
49 pub fn SDL_Error(code: SDL_errorcode);
50 pub fn SDL_SetError(fmt: *const c_char);
51 pub fn SDL_GetError() -> *mut c_char;
52 pub fn SDL_Quit();
53 pub fn SDL_QuitSubSystem(flags: SDL_InitFlag);
54 pub fn SDL_Init(flags: uint32_t) -> c_int;
55 pub fn SDL_InitSubSystem(flags: SDL_InitFlag) -> c_int;
56 pub fn SDL_WasInit(flags: SDL_InitFlag) -> SDL_InitFlag;
57 pub fn SDL_GetTicks() -> uint32_t;
58 }
59}
60
61#[repr(C)]
62#[derive(PartialEq, Copy, Clone)]
63pub struct Rect {
64 pub x: i16,
65 pub y: i16,
66 pub w: u16,
67 pub h: u16,
68}
69
70#[allow(non_snake_case)]
71pub fn Rect(x: i16, y: i16, w: u16, h: u16) -> Rect {
72 Rect {
73 x: x,
74 y: y,
75 w: w,
76 h: h,
77 }
78}
79
80impl Rect {
81 pub fn new(x: i16, y: i16, w: u16, h: u16) -> Rect {
82 Rect {
83 x: x,
84 y: y,
85 w: w,
86 h: h,
87 }
88 }
89}
90
91#[derive(PartialEq, Eq, Copy, Clone)]
92pub enum InitFlag {
93 Timer = ll::SDL_INIT_TIMER as isize,
94 Audio = ll::SDL_INIT_AUDIO as isize,
95 Video = ll::SDL_INIT_VIDEO as isize,
96 CDRom = ll::SDL_INIT_CDROM as isize,
97 Joystick = ll::SDL_INIT_JOYSTICK as isize,
98 NoParachute = ll::SDL_INIT_NOPARACHUTE as isize,
99 EventThread = ll::SDL_INIT_EVENTTHREAD as isize,
100 Everything = ll::SDL_INIT_EVERYTHING as isize,
101}
102
103#[derive(PartialEq, Eq, Copy, Clone)]
104pub enum Error {
105 NoMem = ll::SDL_ENOMEM as isize,
106 Read = ll::SDL_EFREAD as isize,
107 Write = ll::SDL_EFWRITE as isize,
108 Seek = ll::SDL_EFSEEK as isize,
109 Unsupported = ll::SDL_UNSUPPORTED as isize,
110}
111
112pub fn init(flags: &[InitFlag]) -> bool {
113 unsafe {
114 ll::SDL_Init(
115 flags
116 .iter()
117 .fold(0u32, |flags, &flag| flags | flag as ll::SDL_InitFlag),
118 ) == 0
119 }
120}
121
122pub fn init_subsystem(flags: &[InitFlag]) -> bool {
123 unsafe {
124 ll::SDL_InitSubSystem(
125 flags
126 .iter()
127 .fold(0u32, |flags, &flag| flags | flag as ll::SDL_InitFlag),
128 ) == 0
129 }
130}
131
132pub fn quit_subsystem(flags: &[InitFlag]) {
133 let flags = flags
134 .iter()
135 .fold(0u32, |flags, &flag| flags | flag as ll::SDL_InitFlag);
136
137 unsafe {
138 ll::SDL_QuitSubSystem(flags);
139 }
140}
141
142pub fn quit() {
143 unsafe {
144 ll::SDL_Quit();
145 }
146}
147
148pub fn was_inited(flags: &[InitFlag]) -> Vec<InitFlag> {
149 let flags = flags
150 .iter()
151 .fold(0u32, |flags, &flag| flags | flag as ll::SDL_InitFlag);
152 let bitflags = unsafe { ll::SDL_WasInit(flags) };
153
154 let flags = [
155 InitFlag::Timer,
156 InitFlag::Audio,
157 InitFlag::Video,
158 InitFlag::CDRom,
159 InitFlag::Joystick,
160 InitFlag::NoParachute,
161 InitFlag::EventThread,
162 InitFlag::Everything,
163 ];
164
165 flags
166 .iter()
167 .filter_map(|&flag| {
168 if bitflags & (flag as ll::SDL_InitFlag) != 0 {
169 Some(flag)
170 } else {
171 None
172 }
173 })
174 .collect()
175}
176
177pub fn get_error() -> String {
178 unsafe {
179 let cstr = ll::SDL_GetError();
180 let slice = CStr::from_ptr(cstr).to_bytes();
181
182 str::from_utf8(slice).unwrap().to_string()
183 }
184}
185
186pub fn set_error(err: &str) {
187 let err_str = CString::new(err.as_bytes()).unwrap();
188 unsafe {
189 ll::SDL_SetError(err_str.as_ptr());
190 }
191}
192
193pub fn set_error_from_code(err: Error) {
194 unsafe { ll::SDL_Error(err as ll::SDL_errorcode) }
195}
196
197pub fn clear_error() {
198 unsafe {
199 ll::SDL_ClearError();
200 }
201}
202
203pub fn get_ticks() -> usize {
204 unsafe { ll::SDL_GetTicks() as usize }
205}