1use std::mem;
2use libc::{c_int, c_float};
3use std::ptr;
4use rand::Rng;
5use std::slice;
6use std::ffi::CString;
7use std::path::Path;
8
9use Rect;
10use get_error;
11
12pub use self::Color::{RGB, RGBA};
13
14pub mod ll {
15 #![allow(non_camel_case_types)]
16
17 use Rect;
18
19 use libc::{c_void, c_uint, c_int, c_float, c_uchar, uint8_t, uint16_t};
20 use libc::{uint32_t, int32_t};
21 use libc::types::os::arch::c95::c_schar;
22
23 pub type SDL_Rect = Rect;
24
25 #[repr(C)]
26 #[derive(Copy, Clone)]
27 pub struct SDL_RWops {
28 pub seek: *mut uint8_t,
29 pub read: *mut uint8_t,
30 pub write: *mut uint8_t,
31 pub close: *mut uint8_t,
32 pub _type: uint32_t,
33 _hidden: [c_uchar; 24]
34 }
35
36 #[repr(C)]
37 #[derive(Copy, Clone)]
38 pub struct SDL_Surface {
39 pub flags: uint32_t,
40 pub format: *mut SDL_PixelFormat,
41 pub w: c_int,
42 pub h: c_int,
43 pub pitch: uint16_t,
44 pub pixels: *mut c_void,
45 pub offset: c_int,
46 pub hwdata: *mut c_void,
47 pub clip_rect: SDL_Rect,
48 pub unused1: uint32_t,
49 pub locked: uint32_t,
50 pub map: *mut c_void,
51 pub format_version: c_uint,
52 pub refcount: c_int
53 }
54
55 #[repr(C)]
56 #[derive(Copy, Clone)]
57 pub struct SDL_Color {
58 pub r: uint8_t,
59 pub g: uint8_t,
60 pub b: uint8_t,
61 pub unused: uint8_t
62 }
63
64 #[repr(C)]
65 #[derive(Copy, Clone)]
66 pub struct SDL_Palette {
67 pub ncolors: c_int,
68 pub colors: *mut SDL_Color,
69 }
70
71 #[allow(non_snake_case)]
72 #[repr(C)]
73 #[derive(Copy, Clone)]
74 pub struct SDL_PixelFormat {
75 pub palette: *mut SDL_Palette,
76 pub BitsPerPixel: uint8_t,
77 pub BytesPerPixel: uint8_t,
78 pub Rloss: uint8_t,
79 pub Gloss: uint8_t,
80 pub Bloss: uint8_t,
81 pub Aloss: uint8_t,
82 pub Rshift: uint8_t,
83 pub Gshift: uint8_t,
84 pub Bshift: uint8_t,
85 pub Ashift: uint8_t,
86 pub Rmask: uint32_t,
87 pub Gmask: uint32_t,
88 pub Bmask: uint32_t,
89 pub Amask: uint32_t,
90 pub colorkey: uint32_t,
91 pub alpha: uint8_t,
92 }
93
94 #[repr(C)]
95 #[derive(Copy, Clone)]
96 pub struct SDL_VideoInfo {
97 pub flags: uint32_t, pub video_mem: uint32_t,
99 pub vfmt: *mut SDL_PixelFormat,
100 pub current_w: c_int,
101 pub current_h: c_int,
102 }
103
104 extern "C" {
105 pub fn SDL_CreateRGBSurface(flags: uint32_t,
106 width: c_int,
107 height: c_int,
108 depth: c_int,
109 Rmask: uint32_t,
110 Gmask: uint32_t,
111 Bmask: uint32_t,
112 Amask: uint32_t) -> *mut SDL_Surface;
113 pub fn SDL_CreateRGBSurfaceFrom(pixels: *mut c_void,
114 width: c_int,
115 height: c_int,
116 depth: c_int,
117 pitch: c_int,
118 Rmask: uint32_t,
119 Gmask: uint32_t,
120 Bmask: uint32_t,
121 Amask: uint32_t) -> *mut SDL_Surface;
122 pub fn SDL_FreeSurface(surface: *mut SDL_Surface);
123 pub fn SDL_MapRGB(format: *const SDL_PixelFormat,
124 r: uint8_t,
125 g: uint8_t,
126 b: uint8_t) -> uint32_t;
127 pub fn SDL_MapRGBA(format: *const SDL_PixelFormat,
128 r: uint8_t,
129 g: uint8_t,
130 b: uint8_t,
131 a: uint8_t) -> uint32_t;
132 pub fn SDL_GetRGB(pixel: uint32_t,
133 fmt: *const SDL_PixelFormat,
134 r: *mut uint8_t,
135 g: *mut uint8_t,
136 b: *mut uint8_t);
137 pub fn SDL_GetRGBA(pixel: uint32_t,
138 fmt: *const SDL_PixelFormat,
139 r: *mut uint8_t,
140 g: *mut uint8_t,
141 b: *mut uint8_t,
142 a: *mut uint8_t);
143 pub fn SDL_SetVideoMode(width: c_int, height: c_int, bpp: c_int, flags: uint32_t)
144 -> *mut SDL_Surface;
145 pub fn SDL_VideoModeOK(width: c_int, height: c_int, bpp: c_int, flags: uint32_t) -> c_int;
146 pub fn SDL_GetVideoInfo() -> *const SDL_VideoInfo;
147 pub fn SDL_GetVideoSurface() -> *mut SDL_Surface;
148 pub fn SDL_UpdateRect(screen: *mut SDL_Surface,
149 x: int32_t,
150 y: int32_t,
151 w: uint32_t,
152 h: uint32_t);
153 pub fn SDL_UpdateRects(screen: *mut SDL_Surface, numrects: c_int, rects: *mut SDL_Rect);
154 pub fn SDL_SetColors(surface: *mut SDL_Surface,
155 colors: *mut SDL_Color,
156 firstcolor: c_int,
157 ncolors: c_int) -> c_int;
158 pub fn SDL_SetPalette(surface: *mut SDL_Surface,
159 flags: c_int,
160 colors: *mut SDL_Color,
161 firstcolor: c_int,
162 ncolors: c_int) -> c_int;
163 pub fn SDL_LockSurface(surface: *mut SDL_Surface) -> c_int;
164 pub fn SDL_UnlockSurface(surface: *mut SDL_Surface);
165 pub fn SDL_Flip(screen: *mut SDL_Surface) -> c_int;
166 pub fn SDL_ConvertSurface(src: *mut SDL_Surface, fmt: *mut SDL_PixelFormat, flags: uint32_t)
167 -> *mut SDL_Surface;
168 pub fn SDL_DisplayFormat(surface: *mut SDL_Surface) -> *mut SDL_Surface;
169 pub fn SDL_DisplayFormatAlpha(surface: *mut SDL_Surface) -> *mut SDL_Surface;
170 pub fn SDL_SetColorKey(surface: *mut SDL_Surface, flag: uint32_t, key: uint32_t) -> c_int;
171 pub fn SDL_SetAlpha(surface: *mut SDL_Surface, flag: uint32_t, alpha: uint8_t) -> c_int;
172 pub fn SDL_SetClipRect(surface: *mut SDL_Surface, rect: *const SDL_Rect);
173 pub fn SDL_UpperBlit(src: *mut SDL_Surface,
174 srcrect: *mut SDL_Rect,
175 dst: *mut SDL_Surface,
176 dstrect: *mut SDL_Rect) -> c_int;
177 pub fn SDL_FillRect(dst: *mut SDL_Surface, dstrect: *mut SDL_Rect, color: uint32_t) -> c_int;
178 pub fn SDL_SetGamma(r: c_float, g: c_float, b: c_float) -> c_int;
179 pub fn SDL_SetGammaRamp(r: *const uint16_t, g: *const uint16_t, b: *const uint16_t) -> c_int;
180 pub fn SDL_GetGammaRamp(r: *mut uint16_t, g: *mut uint16_t, b: *mut uint16_t) -> c_int;
181 pub fn SDL_RWFromFile(file: *const c_schar, mode: *const c_schar) -> *mut SDL_RWops;
182 pub fn SDL_LoadBMP_RW(src: *mut SDL_RWops, freesrc: c_int) -> *mut SDL_Surface;
183 pub fn SDL_SaveBMP_RW(surface: *mut SDL_Surface, dst: *mut SDL_RWops, freedst: c_int) -> c_int;
184 pub fn SDL_GL_SwapBuffers();
185 }
186}
187
188#[derive(PartialEq)]
189pub struct Surface {
190 pub raw: *mut ll::SDL_Surface,
191 pub owned: bool
192}
193
194fn wrap_surface(raw: *mut ll::SDL_Surface, owned: bool) -> Surface {
195 Surface{ raw: raw, owned: owned }
196}
197
198impl Drop for Surface {
199 fn drop(&mut self) {
200 unsafe {
201 if self.owned {
202 ll::SDL_FreeSurface(self.raw);
203 }
204 }
205 }
206}
207
208#[allow(raw_pointer_derive)]
209#[derive(PartialEq, Copy, Clone)]
210pub struct Palette {
211 pub raw: *mut ll::SDL_Palette
212}
213
214fn wrap_palette(palette: *mut ll::SDL_Palette) -> Option<Palette> {
215 if palette.is_null() {
216 None
217 } else {
218 Some(Palette { raw: palette })
219 }
220}
221
222pub type PaletteColors<'a> =
223 slice::Iter<'a, ll::SDL_Color>;
224
225impl Palette {
226 pub fn colors<'a>(&'a self) -> PaletteColors<'a> {
227 let colors = unsafe { (*self.raw).colors } as *const ll::SDL_Color;
228 let ncolors = unsafe { (*self.raw).ncolors } as usize;
229 let colors: &'a [ll::SDL_Color] =
230 unsafe { mem::transmute(slice::from_raw_parts(&colors, ncolors)) };
231 colors.iter()
232 }
233}
234
235#[derive(PartialEq, Copy, Clone)]
236pub struct PixelFormat {
237 pub palette: Option<Palette>,
238 pub bpp: u8,
239 pub r_loss: u8,
240 pub g_loss: u8,
241 pub b_loss: u8,
242 pub a_loss: u8,
243 pub r_shift: u8,
244 pub g_shift: u8,
245 pub b_shift: u8,
246 pub a_shift: u8,
247 pub r_mask: u32,
248 pub g_mask: u32,
249 pub b_mask: u32,
250 pub a_mask: u32,
251 pub color_key: u32,
252 pub alpha: u8
253}
254
255fn wrap_pixel_format(raw: *mut ll::SDL_PixelFormat) -> PixelFormat {
256 let fmt = & unsafe { *raw };
257 PixelFormat {
258 palette: wrap_palette(fmt.palette),
259 bpp: fmt.BitsPerPixel,
260 r_loss: fmt.Rloss,
261 g_loss: fmt.Gloss,
262 b_loss: fmt.Bloss,
263 a_loss: fmt.Aloss,
264 r_shift: fmt.Rshift,
265 g_shift: fmt.Gshift,
266 b_shift: fmt.Bshift,
267 a_shift: fmt.Ashift,
268 r_mask: fmt.Rmask,
269 g_mask: fmt.Gmask,
270 b_mask: fmt.Bmask,
271 a_mask: fmt.Amask,
272 color_key: fmt.colorkey,
273 alpha: fmt.alpha,
274 }
275}
276
277fn unwrap_pixel_format(fmt: &PixelFormat) -> ll::SDL_PixelFormat {
278 ll::SDL_PixelFormat {
279 palette: match fmt.palette {
280 None => ptr::null_mut(),
281 Some(palette) => palette.raw
282 },
283 BitsPerPixel: fmt.bpp,
284 BytesPerPixel: fmt.bpp / 8,
285 Rloss: fmt.r_loss,
286 Gloss: fmt.g_loss,
287 Bloss: fmt.b_loss,
288 Aloss: fmt.a_loss,
289 Rshift: fmt.r_shift,
290 Gshift: fmt.g_shift,
291 Bshift: fmt.b_shift,
292 Ashift: fmt.a_shift,
293 Rmask: fmt.r_mask,
294 Gmask: fmt.g_mask,
295 Bmask: fmt.b_mask,
296 Amask: fmt.a_mask,
297 colorkey: fmt.color_key,
298 alpha: fmt.alpha
299 }
300}
301
302#[derive(PartialEq, Eq, Copy, Clone)]
303pub enum Color {
304 RGB(u8, u8, u8),
305 RGBA(u8, u8, u8, u8)
306}
307
308impl ::rand::Rand for Color {
309 fn rand<R: ::rand::Rng>(rng: &mut R) -> Color {
310 if rng.gen() { RGBA(rng.gen(), rng.gen(), rng.gen(), rng.gen()) }
311 else { RGB(rng.gen(), rng.gen(), rng.gen()) }
312 }
313}
314
315impl Color {
316 pub fn from_mapped(bit: u32, fmt: *const ll::SDL_PixelFormat) -> Color {
317 let mut r = 0;
318 let mut g = 0;
319 let mut b = 0;
320 let mut a = 0;
321
322 unsafe { ll::SDL_GetRGBA(bit, fmt,
323 &mut r, &mut g,
324 &mut b, &mut a) }
325
326 RGBA(r, g, b, a)
327 }
328
329 pub fn to_mapped(&self, fmt: *const ll::SDL_PixelFormat) -> u32 {
330 match *self {
331 RGB(r, g, b) => unsafe { ll::SDL_MapRGB(fmt, r, g, b) },
332 RGBA(r, g, b, a) => unsafe { ll::SDL_MapRGBA(fmt, r, g, b, a) }
333 }
334 }
335
336 pub fn from_struct(c: &ll::SDL_Color) -> Color {
337 RGB(c.r, c.g, c.b)
338 }
339
340 pub fn to_struct(&self) -> ll::SDL_Color {
341 match *self {
342 RGB(r, g, b) => ll::SDL_Color {
343 r: r,
344 g: g,
345 b: b,
346 unused: 0,
347 },
348 RGBA(r, g, b, _) => ll::SDL_Color {
349 r: r,
350 g: g,
351 b: b,
352 unused: 0,
353 }
354 }
355 }
356}
357
358#[derive(PartialEq, Eq, Copy, Clone)]
359pub enum SurfaceFlag {
360 SWSurface = 0x00000000,
361 HWSurface = 0x00000001,
362 AsyncBlit = 0x00000004,
363 SrcColorKey = 0x00001000,
364 SrcAlpha = 0x00010000,
365 RLEAccel = 0x00004000
366}
367
368#[derive(PartialEq, Eq, Copy, Clone)]
369pub enum VideoFlag {
370 AnyFormat = 0x10000000,
371 HWPalette = 0x20000000,
372 DoubleBuf = 0x40000000,
373 Fullscreen = 0x80000000usize as isize, OpenGL = 0x00000002,
375 OpenGLBlit = 0x0000000A,
376 Resizable = 0x00000010,
377 NoFrame = 0x00000020
378}
379
380pub fn set_video_mode(w: isize, h: isize, bpp: isize,
381 surface_flags: &[SurfaceFlag],
382 video_flags: &[VideoFlag]) -> Result<Surface, String> {
383 let flags = surface_flags.iter().fold(0u32, |flags, &flag| {
384 flags | flag as u32
385 });
386 let flags = video_flags.iter().fold(flags, |flags, &flag| {
387 flags | flag as u32
388 });
389
390 unsafe {
391 let raw = ll::SDL_SetVideoMode(w as c_int, h as c_int,
392 bpp as c_int, flags);
393
394 if raw.is_null() { Err(get_error()) }
395 else { Ok(wrap_surface(raw, false)) }
396 }
397}
398
399pub fn is_video_mode_ok(w: isize, h: isize, bpp: isize,
400 surface_flags: &[SurfaceFlag],
401 video_flags: &[VideoFlag]) -> Option<isize> {
402 let flags = surface_flags.iter().fold(0u32, |flags, &flag| {
403 flags | flag as u32
404 });
405 let flags = video_flags.iter().fold(flags, |flags, &flag| {
406 flags | flag as u32
407 });
408
409 unsafe {
410 let bpp = ll::SDL_VideoModeOK(w as c_int, h as c_int,
411 bpp as c_int, flags);
412
413 if bpp == 0 { None }
414 else { Some(bpp as isize) }
415 }
416}
417
418#[derive(PartialEq, Eq, Copy, Clone)]
419pub enum VideoInfoFlag {
420 HWAvailable = 0x00000001,
421 WMAvailable = 0x00000002,
422 BlitHW = 0x00000200,
423 BlitHWColorkey = 0x00000400,
424 BlitHWAlpha = 0x00000800,
425 BlitSW = 0x00001000,
426 BlitSWColorkey = 0x00002000,
427 BlitSWAlpha = 0x00004000,
428 BlitFill = 0x00008000,
429}
430
431pub struct VideoInfo {
432 pub flags: Vec<VideoInfoFlag>,
433 pub width: isize,
434 pub height: isize,
435 pub format: PixelFormat,
436}
437
438fn wrap_video_info_flags(bitflags: u32) -> Vec<VideoInfoFlag> {
439 let flags = [VideoInfoFlag::HWAvailable,
440 VideoInfoFlag::WMAvailable,
441 VideoInfoFlag::BlitHW,
442 VideoInfoFlag::BlitHWColorkey,
443 VideoInfoFlag::BlitHWAlpha,
444 VideoInfoFlag::BlitSW,
445 VideoInfoFlag::BlitSWColorkey,
446 VideoInfoFlag::BlitSWAlpha,
447 VideoInfoFlag::BlitFill];
448
449 flags.iter().filter_map(|&flag| {
450 if bitflags & (flag as u32) != 0 { Some(flag) }
451 else { None }
452 }).collect()
453}
454
455pub fn get_video_info() -> VideoInfo {
456 let raw = unsafe { ll::SDL_GetVideoInfo() };
457 VideoInfo {
458 flags: wrap_video_info_flags(unsafe { (*raw).flags } as u32),
459 width: unsafe { (*raw).current_w } as isize,
460 height: unsafe { (*raw).current_h } as isize,
461 format: wrap_pixel_format(unsafe { (*raw).vfmt }),
462 }
463}
464
465#[derive(Copy, Clone)]
466pub enum PaletteType {
467 Logical = 1,
468 Physical
469}
470
471pub fn get_video_surface() -> Result<Surface, String> {
472 let raw = unsafe { ll::SDL_GetVideoSurface() };
473
474 if raw.is_null() { Err(get_error()) }
475 else { Ok(wrap_surface(raw, false)) }
476}
477
478impl Surface {
481 pub fn new(surface_flags: &[SurfaceFlag], width: isize, height: isize, bpp: isize,
482 rmask: u32, gmask: u32, bmask: u32, amask: u32) -> Result<Surface, String> {
483 let flags = surface_flags.iter().fold(0u32, |flags, flag| { flags | *flag as u32 });
484
485 unsafe {
486 let raw = ll::SDL_CreateRGBSurface(flags, width as c_int, height as c_int, bpp as c_int,
487 rmask, gmask, bmask, amask);
488
489 if raw.is_null() {
490 Err(get_error())
491 } else {
492 Ok(Surface { raw: raw, owned: true })
493 }
494 }
495 }
496
497 pub fn from_bmp(path: &Path) -> Result<Surface, String> {
498 let cpath = CString::new(path.to_str().unwrap()).unwrap();
499 let mode = CString::new("rb".as_bytes()).unwrap();
500 let raw = unsafe {
501 ll::SDL_LoadBMP_RW(ll::SDL_RWFromFile(cpath.as_ptr(), mode.as_ptr()), 1)
502 };
503
504 if raw.is_null() { Err(get_error()) }
505 else { Ok(wrap_surface(raw, true)) }
506 }
507
508 pub fn get_width(&self) -> u16 {
511 unsafe { (*self.raw).w as u16 }
512 }
513
514 pub fn get_height(&self) -> u16 {
515 unsafe { (*self.raw).h as u16 }
516 }
517
518 pub fn get_size(&self) -> (u16, u16) {
519 (self.get_width(), self.get_height())
520 }
521
522 pub fn get_rect(&self) -> Rect {
523 Rect {
524 x: 0,
525 y: 0,
526 w: self.get_width(),
527 h: self.get_height()
528 }
529 }
530
531 pub fn update_rect(&self, rect: &Rect) {
532 unsafe {
533 ll::SDL_UpdateRect(self.raw, rect.x as i32, rect.y as i32,
534 rect.w as u32, rect.h as u32);
535 }
536 }
537
538 pub fn update_rects(&self, rects: &[Rect]) {
539 unsafe {
540 ll::SDL_UpdateRects(self.raw, rects.len() as c_int,
541 mem::transmute(rects.as_ptr()));
542 }
543 }
544
545 pub fn set_colors(&self, colors: &[Color]) -> bool {
546 let mut colors: Vec<_> = colors.iter().map(|color| {
547 color.to_struct()
548 }).collect();
549
550 unsafe { ll::SDL_SetColors(self.raw, colors.as_mut_ptr(), 0,
551 colors.len() as c_int) == 1 }
552 }
553
554 pub fn set_palette(&self, palettes: &[PaletteType],
555 colors: &[Color]) -> bool {
556 let mut colors: Vec<_> = colors.iter().map(|color| {
557 color.to_struct()
558 }).collect();
559 let flags = palettes.iter().fold(0 as c_int, |flags, &flag| {
560 flags | flag as c_int
561 });
562
563 unsafe { ll::SDL_SetPalette(self.raw, flags,
564 colors.as_mut_ptr(), 0,
565 colors.len() as c_int) == 1 }
566 }
567
568 pub fn lock(&self) -> bool {
569 unsafe { ll::SDL_LockSurface(self.raw) == 0 }
570 }
571
572 pub fn with_lock<F: Fn(&mut [u8]) -> bool>(&self, f: F) -> bool {
574 unsafe {
575 if ll::SDL_LockSurface(self.raw) != 0 { panic!("could not lock surface"); }
576 let len = (*self.raw).pitch as usize * ((*self.raw).h as usize);
577 let pixels: &mut [u8] = mem::transmute(((*self.raw).pixels, len));
578 let rv = f(pixels);
579 ll::SDL_UnlockSurface(self.raw);
580 rv
581 }
582 }
583
584 pub fn unlock(&self) {
585 unsafe { ll::SDL_UnlockSurface(self.raw); }
586 }
587
588 pub fn flip(&self) -> bool {
589 unsafe { ll::SDL_Flip(self.raw) == 0 }
590 }
591
592 pub fn convert(&self, fmt: &PixelFormat, flags: &[SurfaceFlag]) -> Result<Surface, String> {
593 let flags = flags.iter().fold(0u32, |flags, &flag| {
594 flags | flag as u32
595 });
596
597 let mut rawfmt = unwrap_pixel_format(fmt);
598
599 let new = unsafe { ll::SDL_ConvertSurface(self.raw, &mut rawfmt, flags) };
600 match new.is_null() {
601 true => Err(get_error()),
602 false => Ok(wrap_surface(new, true)),
603 }
604 }
605
606 pub fn display_format(&self) -> Result<Surface, String> {
607 let raw = unsafe { ll::SDL_DisplayFormat(self.raw) };
608
609 if raw.is_null() { Err(get_error()) }
610 else { Ok(wrap_surface(raw, true)) }
611 }
612
613 pub fn display_format_alpha(&self) -> Result<Surface, String> {
614 let raw = unsafe { ll::SDL_DisplayFormatAlpha(self.raw) };
615
616 if raw.is_null() { Err(get_error()) }
617 else { Ok(wrap_surface(raw, true)) }
618 }
619
620 pub fn save_bmp(&self, path: &Path) -> bool {
621 let cpath = CString::new(path.to_str().unwrap()).unwrap();
622 let mode = CString::new("wb".as_bytes()).unwrap();
623 unsafe {
624 ll::SDL_SaveBMP_RW(self.raw, ll::SDL_RWFromFile(cpath.as_ptr(), mode.as_ptr()), 1) == 0
625 }
626 }
627
628 pub fn set_alpha(&self, flags: &[SurfaceFlag], alpha: u8) -> bool {
629 let flags = flags.iter().fold(0u32, |flags, &flag| {
630 flags | flag as u32
631 });
632
633 unsafe {
634 ll::SDL_SetAlpha(self.raw, flags, alpha) == 0
635 }
636 }
637
638 pub fn set_color_key(&self, flags: &[SurfaceFlag], color: Color) -> bool {
639 let flags = flags.iter().fold(0u32, |flags, &flag| {
640 flags | flag as u32
641 });
642
643 unsafe {
644 ll::SDL_SetColorKey(self.raw, flags,
645 color.to_mapped((*self.raw).format as *const _)) == 0
646 }
647 }
648
649 pub fn set_clip_rect(&self, rect: &Rect) {
650 unsafe {
651 ll::SDL_SetClipRect(self.raw, rect);
652 }
653 }
654
655 pub fn get_clip_rect(&self) -> Rect {
656 let rect = Rect {
657 x: 0,
658 y: 0,
659 w: 0,
660 h: 0
661 };
662
663 unsafe {
664 ll::SDL_SetClipRect(self.raw,
665 mem::transmute(&rect));
666 }
667
668 rect
669 }
670
671 pub fn blit_rect(&self, src: &Surface, src_rect: Option<Rect>,
672 dest_rect: Option<Rect>) -> bool {
673 unsafe {
674 ll::SDL_UpperBlit(src.raw, match src_rect {
675 Some(ref rect) => mem::transmute(rect),
676 None => ptr::null_mut()
677 }, self.raw, match dest_rect {
678 Some(ref rect) => mem::transmute(rect),
679 None => ptr::null_mut()
680 }) == 0
681 }
682 }
683
684 pub fn blit(&self, src: &Surface) -> bool {
685 self.blit_rect(src, None, None)
686 }
687
688 pub fn blit_at(&self, src: &Surface, x: i16, y: i16) -> bool {
689 let (w, h) = src.get_size();
690
691 self.blit_rect(src, None, Some(Rect {
692 x: x,
693 y: y,
694 w: w,
695 h: h
696 }))
697 }
698
699 pub fn fill_rect(&self, rect: Option<Rect>,
700 color: Color) -> bool {
701 unsafe { ll::SDL_FillRect(self.raw, match rect {
702 Some(ref rect) => mem::transmute(rect),
703 None => ptr::null_mut()
704 }, color.to_mapped((*self.raw).format as *const _)) == 0 }
705 }
706
707 pub fn fill(&self, color: Color) -> bool {
708 self.fill_rect(None, color)
709 }
710
711 pub fn clear(&self) -> bool {
712 self.fill(RGB(0, 0, 0))
713 }
714}
715
716pub fn set_gamma(r: f32, g: f32, b: f32) -> bool {
717 unsafe { ll::SDL_SetGamma(r as c_float, g as c_float,
718 b as c_float) != -1 }
719}
720
721pub fn set_gamma_ramp(r: Option<[u16; 256]>, g: Option<[u16; 256]>,
722 b: Option<[u16; 256]>) -> bool {
723 unsafe { ll::SDL_SetGammaRamp(match r {
724 Some(r) => r.as_ptr(),
725 None => ptr::null()
726 }, match g {
727 Some(g) => g.as_ptr(),
728 None => ptr::null()
729 }, match b {
730 Some(b) => b.as_ptr(),
731 None => ptr::null()
732 }) != -1 }
733}
734
735pub fn get_gamma_ramp() -> ([u16; 256], [u16; 256], [u16; 256]) {
736 let mut r = [0u16; 256];
737 let mut g = [0u16; 256];
738 let mut b = [0u16; 256];
739
740 unsafe { ll::SDL_GetGammaRamp(r.as_mut_ptr(),
741 g.as_mut_ptr(),
742 b.as_mut_ptr()); }
743
744 (r, g, b)
745}
746
747pub fn swap_buffers() {
748 unsafe {
749 ll::SDL_GL_SwapBuffers();
750 }
751}
752
753
754