diff --git a/src/sdl2/surface.rs b/src/sdl2/surface.rs index b5e75bb5..49d031ba 100644 --- a/src/sdl2/surface.rs +++ b/src/sdl2/surface.rs @@ -3,18 +3,20 @@ use rect::Rect; use get_error; use SdlResult; use std::ptr; -use libc::c_int; +use libc::{c_int, uint32_t}; use pixels; +use render::BlendMode; use rwops; #[allow(non_camel_case_types)] pub mod ll { use pixels::ll::SDL_PixelFormat; use pixels::ll::SDL_Palette; - use render::ll::SDL_BlendMode; use rwops::ll::SDL_RWops; use rect::Rect; use libc::{c_int, c_void, uint32_t, uint8_t}; + pub use render::ll::SDL_BlendMode; + pub type SDL_Rect = Rect; pub type SDL_bool = c_int; @@ -119,7 +121,22 @@ impl Surface { } } - //TODO: From Data + pub fn from_data(data: &mut [u8], width: int, height: int, bpp: int, pitch: int, + rmask: u32, gmask: u32, bmask: u32, amask: u32) -> SdlResult { + + unsafe { + let raw = ll::SDL_CreateRGBSurfaceFrom( + mem::transmute(data.as_ptr()), width as c_int, height as c_int, + bpp as c_int, pitch as c_int, rmask, gmask, bmask, amask); + + if raw == ptr::null() { + Err(get_error()) + } else { + Ok(Surface { raw: raw, owned: true }) + } + } + } + pub fn get_width(&self) -> int { unsafe { (*self.raw).w as int } } @@ -268,20 +285,164 @@ impl Surface { } } + pub fn fill_rect(&mut self, rect: Option, color: pixels::Color) -> SdlResult<()> { + unsafe { + let rect_ptr = mem::transmute( rect.as_ref() ); + let format = self.get_pixel_format(); + let result = ll::SDL_FillRect( self.raw, rect_ptr, color.to_u32(&format) ); + match result { + 0 => Ok(()), + _ => Err(get_error()) + } + } + } + + pub fn fill_rects(&mut self, rects: &[Option], color: pixels::Color) -> SdlResult<()> { + for rect in rects.iter() { + let result = self.fill_rect(*rect, color); + match result { + Err(e) => return Err(e), + _ => () + }; + } + + Ok(()) + } + + pub fn set_alpha_mod(&mut self, alpha: u8) -> SdlResult<()> { + let result = unsafe { + ll::SDL_SetSurfaceAlphaMod(self.raw, alpha) + }; + + match result { + 0 => Ok(()), + _ => Err(get_error()) + } + } + + pub fn get_alpha_mod(&self) -> SdlResult { + let alpha = 0u8; + let result = unsafe { + ll::SDL_GetSurfaceAlphaMod(self.raw, &alpha) + }; + + match result { + 0 => Ok(alpha), + _ => Err(get_error()) + } + } + + pub fn set_blend_mode(&mut self, mode: BlendMode) -> SdlResult<()> { + let result = unsafe { + ll::SDL_SetSurfaceBlendMode(self.raw, FromPrimitive::from_int(mode as int).unwrap()) + }; + + match result { + 0 => Ok(()), + _ => Err(get_error()) + } + } + + pub fn get_blend_mode(&self) -> SdlResult { + let mode: ll::SDL_BlendMode = FromPrimitive::from_int(0).unwrap(); + let result = unsafe { + ll::SDL_GetSurfaceBlendMode(self.raw, &mode) + }; + + match result { + 0 => Ok(FromPrimitive::from_int(mode as int).unwrap()), + _ => Err(get_error()) + } + } + + pub fn set_clip_rect(&mut self, rect: Option) -> bool { + unsafe { + ll::SDL_SetClipRect(self.raw, mem::transmute(rect.as_ref())) == 1 + } + } + + pub fn get_clip_rect(&self) -> Rect { + let rect = Rect::new(0, 0, 0, 0); + unsafe { + ll::SDL_GetClipRect(self.raw, &rect) + }; + rect + } + + pub fn convert(&self, format: &pixels::PixelFormat) -> SdlResult { + // SDL_ConvertSurface takes a flag as the last parameter, which should be 0 by the docs. + let surface_ptr = unsafe { ll::SDL_ConvertSurface(self.raw, format.raw(), 0u32) }; + + if surface_ptr == ptr::null() { + Err(get_error()) + } else { + unsafe { Ok(Surface::from_ll(surface_ptr, true)) } + } + } + + pub fn convert_format(&self, format: pixels::PixelFormatFlag) -> SdlResult { + let surface_ptr = unsafe { ll::SDL_ConvertSurfaceFormat(self.raw, format as uint32_t, 0u32) }; + + if surface_ptr == ptr::null() { + Err(get_error()) + } else { + unsafe { Ok(Surface::from_ll(surface_ptr, true)) } + } + } + + pub fn lower_blit(&self, src_rect: Option, + dst: &mut Surface, dst_rect: Option) -> SdlResult<()> { + + match unsafe { + let src_rect_ptr = mem::transmute(src_rect.as_ref()); + let dst_rect_ptr = mem::transmute(dst_rect.as_ref()); + ll::SDL_LowerBlit(self.raw, src_rect_ptr, dst.raw, dst_rect_ptr) + } { + 0 => Ok(()), + _ => Err(get_error()) + } + } + + pub fn soft_stretch(&self, src_rect: Option, + dst: &mut Surface, dst_rect: Option) -> SdlResult<()> { + + match unsafe { + let src_rect_ptr = mem::transmute(src_rect.as_ref()); + let dst_rect_ptr = mem::transmute(dst_rect.as_ref()); + ll::SDL_SoftStretch(self.raw, src_rect_ptr, dst.raw, dst_rect_ptr) + } { + 0 => Ok(()), + _ => Err(get_error()) + } + } + + pub fn upper_blit_scaled(&self, src_rect: Option, + dst: &mut Surface, dst_rect: Option) -> SdlResult<()> { + + match unsafe { + let src_rect_ptr = mem::transmute(src_rect.as_ref()); + let dst_rect_ptr = mem::transmute(dst_rect.as_ref()); + ll::SDL_UpperBlitScaled(self.raw, src_rect_ptr, dst.raw, dst_rect_ptr) + } { + 0 => Ok(()), + _ => Err(get_error()) + } + } + + pub fn lower_blit_scaled(&self, src_rect: Option, + dst: &mut Surface, dst_rect: Option) -> SdlResult<()> { + + match unsafe { + let src_rect_ptr = mem::transmute(src_rect.as_ref()); + let dst_rect_ptr = mem::transmute(dst_rect.as_ref()); + ll::SDL_LowerBlitScaled(self.raw, src_rect_ptr, dst.raw, dst_rect_ptr) + } { + 0 => Ok(()), + _ => Err(get_error()) + } + } + /* - pub fn SDL_SetSurfaceAlphaMod(surface: *SDL_Surface, alpha: uint8_t) -> c_int; - pub fn SDL_GetSurfaceAlphaMod(surface: *SDL_Surface, alpha: *uint8_t ) -> c_int; - pub fn SDL_SetSurfaceBlendMode(surface: *SDL_Surface, blendMode: SDL_BlendMode) -> c_int; - pub fn SDL_GetSurfaceBlendMode(surface: *SDL_Surface, blendMode: *SDL_BlendMode) -> c_int; - pub fn SDL_SetClipRect(surface: *SDL_Surface, rect: *SDL_Rect) -> SDL_bool; - pub fn SDL_GetClipRect(surface: *SDL_Surface, rect: *SDL_Rect); - pub fn SDL_ConvertSurface(src: *SDL_Surface, fmt: *SDL_PixelFormat, flags: uint32_t) -> *SDL_Surface; - pub fn SDL_ConvertSurfaceFormat(src: *SDL_Surface, pixel_format: uint32_t, flags: uint32_t) -> *SDL_Surface; pub fn SDL_ConvertPixels(width: c_int, height: c_int, src_format: uint32_t, src: *c_void, src_pitch: c_int, dst_format: uint32_t, dst: *c_void, dst_pitch: c_int) -> c_int; - pub fn SDL_FillRect(dst: *SDL_Surface, rect: *SDL_Rect, color: uint32_t) -> c_int; - pub fn SDL_FillRects(dst: *SDL_Surface, rects: *SDL_Rect, count: c_int, color: uint32_t) -> c_int; - pub fn SDL_LowerBlit(src: *SDL_Surface, srcrect: *SDL_Rect, dst: *SDL_Surface, dstrect: *SDL_Rect) -> c_int; - pub fn SDL_SoftStretch(src: *SDL_Surface, srcrect: *SDL_Rect, dst: *SDL_Surface, dstrect: *SDL_Rect) -> c_int; - pub fn SDL_UpperBlitScaled(src: *SDL_Surface, srcrect: *SDL_Rect, dst: *SDL_Surface, dstrect: *SDL_Rect) -> c_int; - pub fn SDL_LowerBlitScaled(src: *SDL_Surface, srcrect: *SDL_Rect, dst: *SDL_Surface, dstrect: *SDL_Rect) -> c_int)*/ + */ }