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