From ca27df126b9f83be135c356feeebf5cc6dccf43a Mon Sep 17 00:00:00 2001 From: Mischa Spiegelmock Date: Sat, 19 Oct 2024 14:29:37 -0700 Subject: [PATCH 1/8] version, url --- src/sdl3/url.rs | 12 ++++++------ src/sdl3/version.rs | 30 ++++++++---------------------- 2 files changed, 14 insertions(+), 28 deletions(-) diff --git a/src/sdl3/url.rs b/src/sdl3/url.rs index 4e6cb332f2..fbc52601ef 100644 --- a/src/sdl3/url.rs +++ b/src/sdl3/url.rs @@ -1,10 +1,10 @@ //! Opening URLs in default system handlers +use crate::get_error; use std::error; use std::ffi::{CString, NulError}; use std::fmt; - -use crate::get_error; +use sys::misc::SDL_OpenURL; use crate::sys; @@ -49,9 +49,9 @@ impl error::Error for OpenUrlError { /// # Examples /// /// ```no_run -/// use sdl2::url::open_url; +/// use sdl3::url::open_url; /// -/// open_url("https://github.com/Rust-SDL2/rust-sdl2") +/// open_url("https://github.com/revmischa/sdl3-rs") /// .expect("Opening URLs not supported on this platform"); /// ``` #[doc(alias = "SDL_OpenURL")] @@ -62,8 +62,8 @@ pub fn open_url(url: &str) -> Result<(), OpenUrlError> { Ok(s) => s, Err(err) => return Err(InvalidUrl(err)), }; - sys::SDL_OpenURL(url.as_ptr()) - } == 0; + SDL_OpenURL(url.as_ptr()) + }; if result { Ok(()) diff --git a/src/sdl3/version.rs b/src/sdl3/version.rs index d422b35697..c50c91a435 100644 --- a/src/sdl3/version.rs +++ b/src/sdl3/version.rs @@ -2,7 +2,6 @@ Querying SDL Version */ -use std::ffi::CStr; use std::fmt; use crate::sys; @@ -19,12 +18,13 @@ pub struct Version { } impl Version { - /// Convert a raw *SDL_version to Version. - pub fn from_ll(v: sys::SDL_version) -> Version { + /// Convert a raw sdl version number to Version. + pub fn from_ll(v: i32) -> Version { + // pub const SDL_VERSION: i32 = _; // 3_001_003i32 Version { - major: v.major, - minor: v.minor, - patch: v.patch, + major: (v >> 16) as u8, + minor: ((v >> 8) & 0xFF) as u8, + patch: (v & 0xFF) as u8, } } } @@ -39,21 +39,7 @@ 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, - }; - sys::SDL_GetVersion(&mut cver); - Version::from_ll(cver) - } -} - -/// Get the code revision of SDL that is linked against your program. -#[doc(alias = "SDL_GetRevision")] -pub fn revision() -> String { - unsafe { - let rev = sys::SDL_GetRevision(); - CStr::from_ptr(rev as *const _).to_str().unwrap().to_owned() + let version = sys::version::SDL_GetVersion(); + Version::from_ll(version) } } From 52e39ee5fb7d062781bca43801f65b645789112c Mon Sep 17 00:00:00 2001 From: Mischa Spiegelmock Date: Sat, 19 Oct 2024 11:12:17 -0700 Subject: [PATCH 2/8] RWOps -> IOStream --- src/sdl3/audio.rs | 2 +- src/sdl3/gamepad.rs | 58 +++++++++++++------- src/sdl3/image/mod.rs | 2 +- src/sdl3/{rwops.rs => iostream.rs} | 88 ++++++++++++++---------------- src/sdl3/lib.rs | 19 +++---- src/sdl3/mixer/mod.rs | 10 +++- src/sdl3/surface.rs | 2 +- src/sdl3/ttf/context.rs | 2 +- src/sdl3/ttf/font.rs | 2 +- 9 files changed, 99 insertions(+), 86 deletions(-) rename src/sdl3/{rwops.rs => iostream.rs} (57%) diff --git a/src/sdl3/audio.rs b/src/sdl3/audio.rs index c93a8c193c..e0d2cf2824 100644 --- a/src/sdl3/audio.rs +++ b/src/sdl3/audio.rs @@ -62,7 +62,7 @@ use std::path::Path; use std::ptr; use crate::get_error; -use crate::rwops::RWops; +use crate::iostream::RWops; use crate::AudioSubsystem; use crate::sys; diff --git a/src/sdl3/gamepad.rs b/src/sdl3/gamepad.rs index 0694b85837..43ebef93ec 100644 --- a/src/sdl3/gamepad.rs +++ b/src/sdl3/gamepad.rs @@ -1,4 +1,4 @@ -use crate::rwops::RWops; +use crate::iostream::RWops; use libc::{c_char, c_void}; use std::error; use std::ffi::{CStr, CString, NulError}; @@ -140,7 +140,8 @@ impl GamepadSubsystem { Err(err) => return Err(InvalidMapping(err)), }; - let result = unsafe { sys::gamepad::SDL_AddGamepadMapping(mapping.as_ptr() as *const c_char) }; + let result = + unsafe { sys::gamepad::SDL_AddGamepadMapping(mapping.as_ptr() as *const c_char) }; match result { 1 => Ok(MappingStatus::Added), @@ -330,8 +331,12 @@ impl Button { sys::gamepad::SDL_GamepadButton::SDL_GAMEPAD_BUTTON_START => Button::Start, sys::gamepad::SDL_GamepadButton::SDL_GAMEPAD_BUTTON_LEFT_STICK => Button::LeftStick, sys::gamepad::SDL_GamepadButton::SDL_GAMEPAD_BUTTON_RIGHT_STICK => Button::RightStick, - sys::gamepad::SDL_GamepadButton::SDL_GAMEPAD_BUTTON_LEFT_SHOULDER => Button::LeftShoulder, - sys::gamepad::SDL_GamepadButton::SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER => Button::RightShoulder, + sys::gamepad::SDL_GamepadButton::SDL_GAMEPAD_BUTTON_LEFT_SHOULDER => { + Button::LeftShoulder + } + sys::gamepad::SDL_GamepadButton::SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER => { + Button::RightShoulder + } sys::gamepad::SDL_GamepadButton::SDL_GAMEPAD_BUTTON_DPAD_UP => Button::DPadUp, sys::gamepad::SDL_GamepadButton::SDL_GAMEPAD_BUTTON_DPAD_DOWN => Button::DPadDown, sys::gamepad::SDL_GamepadButton::SDL_GAMEPAD_BUTTON_DPAD_LEFT => Button::DPadLeft, @@ -357,8 +362,12 @@ impl Button { Button::Start => sys::gamepad::SDL_GamepadButton::SDL_GAMEPAD_BUTTON_START, Button::LeftStick => sys::gamepad::SDL_GamepadButton::SDL_GAMEPAD_BUTTON_LEFT_STICK, Button::RightStick => sys::gamepad::SDL_GamepadButton::SDL_GAMEPAD_BUTTON_RIGHT_STICK, - Button::LeftShoulder => sys::gamepad::SDL_GamepadButton::SDL_GAMEPAD_BUTTON_LEFT_SHOULDER, - Button::RightShoulder => sys::gamepad::SDL_GamepadButton::SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER, + Button::LeftShoulder => { + sys::gamepad::SDL_GamepadButton::SDL_GAMEPAD_BUTTON_LEFT_SHOULDER + } + Button::RightShoulder => { + sys::gamepad::SDL_GamepadButton::SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER + } Button::DPadUp => sys::gamepad::SDL_GamepadButton::SDL_GAMEPAD_BUTTON_DPAD_UP, Button::DPadDown => sys::gamepad::SDL_GamepadButton::SDL_GAMEPAD_BUTTON_DPAD_DOWN, Button::DPadLeft => sys::gamepad::SDL_GamepadButton::SDL_GAMEPAD_BUTTON_DPAD_LEFT, @@ -502,7 +511,12 @@ impl Gamepad { duration_ms: u32, ) -> Result<(), IntegerOrSdlError> { let result = unsafe { - sys::gamepad::SDL_RumbleGamepadTriggers(self.raw, left_rumble, right_rumble, duration_ms) + sys::gamepad::SDL_RumbleGamepadTriggers( + self.raw, + left_rumble, + right_rumble, + duration_ms, + ) }; if !result { @@ -516,22 +530,33 @@ impl Gamepad { #[doc(alias = "SDL_PROP_JOYSTICK_CAP_RGB_LED_BOOLEAN")] pub unsafe fn has_led(&self) -> bool { let props = sys::gamepad::SDL_GetGamepadProperties(self.raw); - sys::properties::SDL_GetBooleanProperty(props, sys::gamepad::SDL_PROP_GAMEPAD_CAP_RGB_LED_BOOLEAN.into(), false) + sys::properties::SDL_GetBooleanProperty( + props, + sys::gamepad::SDL_PROP_GAMEPAD_CAP_RGB_LED_BOOLEAN.into(), + false, + ) } /// Query whether a game controller has rumble support. #[doc(alias = "SDL_PROP_GAMEPAD_CAP_RUMBLE_BOOLEAN")] pub unsafe fn has_rumble(&self) -> bool { let props = sys::gamepad::SDL_GetGamepadProperties(self.raw); - sys::properties::SDL_GetBooleanProperty(props, sys::gamepad::SDL_PROP_GAMEPAD_CAP_RUMBLE_BOOLEAN.into(), false) - + sys::properties::SDL_GetBooleanProperty( + props, + sys::gamepad::SDL_PROP_GAMEPAD_CAP_RUMBLE_BOOLEAN.into(), + false, + ) } /// Query whether a game controller has rumble support on triggers. #[doc(alias = "SDL_PROP_GAMEPAD_CAP_TRIGGER_RUMBLE_BOOLEAN")] pub unsafe fn has_rumble_triggers(&self) -> bool { - let props = sys::gamepad::SDL_GetGamepadProperties(self.raw) ; - sys::properties::SDL_GetBooleanProperty(props, sys::gamepad::SDL_PROP_GAMEPAD_CAP_TRIGGER_RUMBLE_BOOLEAN.into(), false) + let props = sys::gamepad::SDL_GetGamepadProperties(self.raw); + sys::properties::SDL_GetBooleanProperty( + props, + sys::gamepad::SDL_PROP_GAMEPAD_CAP_TRIGGER_RUMBLE_BOOLEAN.into(), + false, + ) } /// Update a game controller's LED color. @@ -574,8 +599,7 @@ impl Gamepad { #[doc(alias = "SDL_GamepadSensorEnabled")] pub fn sensor_enabled(&self, sensor_type: crate::sensor::SensorType) -> bool { - unsafe { sys::gamepad::SDL_GamepadSensorEnabled(self.raw, sensor_type.into()) } - + unsafe { sys::gamepad::SDL_GamepadSensorEnabled(self.raw, sensor_type.into()) } } #[doc(alias = "SDL_SetGamepadSensorEnabled")] @@ -588,11 +612,7 @@ impl Gamepad { sys::gamepad::SDL_SetGamepadSensorEnabled( self.raw, sensor_type.into(), - if enabled { - true - } else { - false - }, + if enabled { true } else { false }, ) }; diff --git a/src/sdl3/image/mod.rs b/src/sdl3/image/mod.rs index f672b166f9..a34af3b880 100644 --- a/src/sdl3/image/mod.rs +++ b/src/sdl3/image/mod.rs @@ -21,8 +21,8 @@ //! ``` use get_error; +use iostream::RWops; use render::{Texture, TextureCreator}; -use rwops::RWops; use std::ffi::CString; use std::os::raw::{c_char, c_int}; use std::path::Path; diff --git a/src/sdl3/rwops.rs b/src/sdl3/iostream.rs similarity index 57% rename from src/sdl3/rwops.rs rename to src/sdl3/iostream.rs index 7ba95e2d7c..cb651934af 100644 --- a/src/sdl3/rwops.rs +++ b/src/sdl3/iostream.rs @@ -1,6 +1,6 @@ use crate::get_error; -use libc::c_void; use libc::c_char; +use libc::c_void; use std::ffi::CString; use std::io; use std::marker::PhantomData; @@ -10,33 +10,30 @@ 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, +pub struct IOStream<'a> { + raw: *mut sys::iostream::SDL_IOStream, _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 { +impl<'a> IOStream<'a> { + pub unsafe fn raw(&self) -> *mut sys::iostream::SDL_IOStream { self.raw } - pub unsafe fn from_ll<'b>(raw: *mut sys::SDL_RWops) -> RWops<'b> { - RWops { + pub unsafe fn from_ll<'b>(raw: *mut sys::iostream::SDL_IOStream) -> IOStream<'b> { + IOStream { raw, _marker: PhantomData, } } /// Creates an SDL file stream. - #[doc(alias = "SDL_RWFromFile")] - pub fn from_file>(path: P, mode: &str) -> Result, String> { + #[doc(alias = "SDL_IOFromFile")] + pub fn from_file>(path: P, mode: &str) -> Result, 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( + sys::iostream::SDL_IOFromFile( path_c.as_ptr() as *const c_char, mode_c.as_ptr() as *const c_char, ) @@ -45,41 +42,41 @@ impl<'a> RWops<'a> { if raw.is_null() { Err(get_error()) } else { - Ok(RWops { + Ok(IOStream { raw, _marker: PhantomData, }) } } - /// Prepares a read-only memory buffer for use with `RWops`. + /// Prepares a read-only memory buffer for use with `IOStream`. /// /// This method can only fail if the buffer size is zero. - #[doc(alias = "SDL_RWFromConstMem")] - pub fn from_bytes(buf: &'a [u8]) -> Result, String> { + #[doc(alias = "SDL_IOFromConstMem")] + pub fn from_bytes(buf: &'a [u8]) -> Result, String> { let raw = - unsafe { sys::SDL_RWFromConstMem(buf.as_ptr() as *const c_void, buf.len()) }; + unsafe { sys::iostream::SDL_IOFromConstMem(buf.as_ptr() as *const c_void, buf.len()) }; if raw.is_null() { Err(get_error()) } else { - Ok(RWops { + Ok(IOStream { raw, _marker: PhantomData, }) } } - /// Reads a `Read` object into a buffer and then passes it to `RWops.from_bytes`. + /// Reads a `Read` object into a buffer and then passes it to `IOStream.from_bytes`. /// /// 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(r: &mut T, buffer: &'a mut Vec) -> Result, String> + /// `IOStream`, but the `IOStream` does not take ownership of it. + pub fn from_read(r: &mut T, buffer: &'a mut Vec) -> Result, String> where T: io::Read + Sized, { match r.read_to_end(buffer) { - Ok(_size) => RWops::from_bytes(buffer), + Ok(_size) => IOStream::from_bytes(buffer), Err(ioerror) => { let msg = format!("IO error: {}", ioerror); Err(msg) @@ -87,17 +84,17 @@ impl<'a> RWops<'a> { } } - /// Prepares a read-write memory buffer for use with `RWops`. + /// Prepares a read-write memory buffer for use with `IOStream`. /// /// 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, String> { - let raw = unsafe { sys::SDL_RWFromMem(buf.as_ptr() as *mut c_void, buf.len()) }; + #[doc(alias = "SDL_IOFromMem")] + pub fn from_bytes_mut(buf: &'a mut [u8]) -> Result, String> { + let raw = unsafe { sys::iostream::SDL_IOFromMem(buf.as_ptr() as *mut c_void, buf.len()) }; if raw.is_null() { Err(get_error()) } else { - Ok(RWops { + Ok(IOStream { raw, _marker: PhantomData, }) @@ -109,7 +106,7 @@ impl<'a> RWops<'a> { /// Returns `None` if the stream size can't be determined /// (either because it doesn't make sense for the stream type, or there was an error). pub fn len(&self) -> Option { - let result = unsafe { ((*self.raw).size.unwrap())(self.raw) }; + let result = unsafe { sys::iostream::SDL_GetIOSize(self.raw) }; match result { -1 => None, @@ -126,33 +123,29 @@ impl<'a> RWops<'a> { } } -impl<'a> Drop for RWops<'a> { +impl<'a> Drop for IOStream<'a> { fn drop(&mut self) { - let ret = unsafe { ((*self.raw).close.unwrap())(self.raw) }; - if ret != 0 { + let ret = unsafe { sys::iostream::SDL_CloseIO(self.raw) }; + if !ret { panic!("{}", get_error()); } } } -impl<'a> io::Read for RWops<'a> { +impl<'a> io::Read for IOStream<'a> { fn read(&mut self, buf: &mut [u8]) -> io::Result { let out_len = buf.len(); - // 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, out_len as i64) - }; + let ret = + unsafe { sys::iostream::SDL_ReadIO(self.raw, buf.as_ptr() as *mut c_void, out_len) }; Ok(ret as usize) } } -impl<'a> io::Write for RWops<'a> { +impl<'a> io::Write for IOStream<'a> { fn write(&mut self, buf: &[u8]) -> io::Result { let in_len = buf.len(); - let ret = unsafe { - ((*self.raw).write.unwrap())(self.raw, buf.as_ptr() as *const c_void, in_len as i64) - }; + let ret = + unsafe { sys::iostream::SDL_WriteIO(self.raw, buf.as_ptr() as *const c_void, in_len) }; Ok(ret as usize) } @@ -161,15 +154,14 @@ impl<'a> io::Write for RWops<'a> { } } -impl<'a> io::Seek for RWops<'a> { +impl<'a> io::Seek for IOStream<'a> { fn seek(&mut self, pos: io::SeekFrom) -> io::Result { - // whence code is different from SeekStyle let (whence, offset) = match pos { - io::SeekFrom::Start(pos) => (sys::SDL_RW_SEEK_SET, pos as i64), - io::SeekFrom::End(pos) => (sys::SDL_RW_SEEK_END, pos), - io::SeekFrom::Current(pos) => (sys::SDL_RW_SEEK_CUR, pos), + io::SeekFrom::Start(pos) => (sys::iostream::SDL_IO_SEEK_SET, pos as i64), + io::SeekFrom::End(pos) => (sys::iostream::SDL_IO_SEEK_END, pos), + io::SeekFrom::Current(pos) => (sys::iostream::SDL_IO_SEEK_CUR, pos), }; - let ret = unsafe { ((*self.raw).seek.unwrap())(self.raw, offset, transmute(whence)) }; + let ret = unsafe { sys::iostream::SDL_SeekIO(self.raw, offset, transmute(whence)) }; if ret == -1 { Err(io::Error::last_os_error()) } else { diff --git a/src/sdl3/lib.rs b/src/sdl3/lib.rs index 7c0ddab98c..aa1295e26b 100644 --- a/src/sdl3/lib.rs +++ b/src/sdl3/lib.rs @@ -49,19 +49,16 @@ #![crate_type = "lib"] #![allow(clippy::cast_lossless, clippy::transmute_ptr_to_ref)] -pub extern crate libc; - -#[macro_use] -extern crate lazy_static; - #[macro_use] extern crate bitflags; - -pub extern crate sdl3_sys as sys; -// use sdl3_sys as sys; - #[cfg(feature = "gfx")] extern crate c_vec; +#[macro_use] +extern crate lazy_static; +pub extern crate libc; +pub extern crate sdl3_sys as sys; + +// use sdl3_sys as sys; pub use crate::sdl::*; @@ -75,6 +72,7 @@ pub mod filesystem; pub mod gamepad; pub mod haptic; pub mod hint; +pub mod iostream; pub mod joystick; pub mod keyboard; pub mod log; @@ -83,7 +81,6 @@ pub mod mouse; pub mod pixels; pub mod rect; pub mod render; -pub mod rwops; mod sdl; #[cfg(feature = "hidapi")] pub mod sensor; @@ -108,6 +105,6 @@ mod common; // Export return types and such from the common module. pub use crate::common::IntegerOrSdlError; +mod guid; #[cfg(feature = "raw-window-handle")] pub mod raw_window_handle; -mod guid; diff --git a/src/sdl3/mixer/mod.rs b/src/sdl3/mixer/mod.rs index 368047dde0..1c11266c77 100644 --- a/src/sdl3/mixer/mod.rs +++ b/src/sdl3/mixer/mod.rs @@ -22,9 +22,9 @@ use audio::AudioFormatNum; use get_error; +use iostream::RWops; 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; @@ -801,8 +801,12 @@ impl<'a> Music<'a> { /// Load music from a static byte buffer. #[doc(alias = "SDL_RWFromConstMem")] pub fn from_static_bytes(buf: &'static [u8]) -> Result, String> { - let rw = - unsafe { sys::SDL_RWFromConstMem(buf.as_ptr() as *const c_void, (buf.len() as c_int).try_into().unwrap() ) }; + let rw = unsafe { + sys::SDL_RWFromConstMem( + buf.as_ptr() as *const c_void, + (buf.len() as c_int).try_into().unwrap(), + ) + }; if rw.is_null() { return Err(get_error()); diff --git a/src/sdl3/surface.rs b/src/sdl3/surface.rs index fc4d7d2275..60913a2b21 100644 --- a/src/sdl3/surface.rs +++ b/src/sdl3/surface.rs @@ -5,11 +5,11 @@ use std::path::Path; use std::rc::Rc; use crate::get_error; +use crate::iostream::RWops; 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 std::mem::transmute; diff --git a/src/sdl3/ttf/context.rs b/src/sdl3/ttf/context.rs index c3e7a0b731..4f0e5283d9 100644 --- a/src/sdl3/ttf/context.rs +++ b/src/sdl3/ttf/context.rs @@ -1,5 +1,5 @@ use get_error; -use rwops::RWops; +use iostream::RWops; use std::error; use std::fmt; use std::io; diff --git a/src/sdl3/ttf/font.rs b/src/sdl3/ttf/font.rs index d99686b912..685682d516 100644 --- a/src/sdl3/ttf/font.rs +++ b/src/sdl3/ttf/font.rs @@ -1,6 +1,6 @@ use get_error; +use iostream::RWops; use pixels::Color; -use rwops::RWops; use std::error; use std::error::Error; use std::ffi::NulError; From d6a98a5a8d9b3339d065d78a5887c2a3f9da169e Mon Sep 17 00:00:00 2001 From: Mischa Spiegelmock Date: Sat, 19 Oct 2024 11:19:35 -0700 Subject: [PATCH 3/8] RWOps -> IOStream --- src/sdl3/audio.rs | 11 +++++------ src/sdl3/gamepad.rs | 13 ++++++------- src/sdl3/image/mod.rs | 12 ++++++------ src/sdl3/mixer/mod.rs | 10 +++++----- src/sdl3/surface.rs | 17 ++++++++--------- src/sdl3/ttf/context.rs | 22 +++++++++++----------- src/sdl3/ttf/font.rs | 27 +++++++++++++++------------ 7 files changed, 56 insertions(+), 56 deletions(-) diff --git a/src/sdl3/audio.rs b/src/sdl3/audio.rs index e0d2cf2824..825e51440e 100644 --- a/src/sdl3/audio.rs +++ b/src/sdl3/audio.rs @@ -52,6 +52,9 @@ //! std::thread::sleep(Duration::from_millis(2000)); //! ``` +use crate::get_error; +use crate::AudioSubsystem; +use iostream::IOStream; use libc::{c_char, c_int, c_void}; use std::convert::TryFrom; use std::ffi::{CStr, CString}; @@ -61,10 +64,6 @@ use std::ops::{Deref, DerefMut}; use std::path::Path; use std::ptr; -use crate::get_error; -use crate::iostream::RWops; -use crate::AudioSubsystem; - use crate::sys; use crate::sys::SDL_AudioStatus; @@ -388,13 +387,13 @@ pub struct AudioSpecWAV { impl AudioSpecWAV { /// Loads a WAVE from the file path. pub fn load_wav>(path: P) -> Result { - let mut file = RWops::from_file(path, "rb")?; + let mut file = IOStream::from_file(path, "rb")?; AudioSpecWAV::load_wav_rw(&mut file) } /// Loads a WAVE from the data source. #[doc(alias = "SDL_LoadWAV_RW")] - pub fn load_wav_rw(src: &mut RWops) -> Result { + pub fn load_wav_rw(src: &mut IOStream) -> Result { use std::mem::MaybeUninit; use std::ptr::null_mut; diff --git a/src/sdl3/gamepad.rs b/src/sdl3/gamepad.rs index 43ebef93ec..b1b78512c6 100644 --- a/src/sdl3/gamepad.rs +++ b/src/sdl3/gamepad.rs @@ -1,4 +1,4 @@ -use crate::iostream::RWops; +use crate::iostream::IOStream; use libc::{c_char, c_void}; use std::error; use std::ffi::{CStr, CString, NulError}; @@ -14,11 +14,10 @@ use std::convert::TryInto; use crate::common::IntegerOrSdlError; use crate::get_error; use crate::joystick; +use crate::sys; use crate::GamepadSubsystem; use std::mem::transmute; -use crate::sys; - #[derive(Debug, Clone)] pub enum AddMappingError { InvalidMapping(NulError), @@ -154,7 +153,7 @@ impl GamepadSubsystem { pub fn load_mappings>(&self, path: P) -> Result { use self::AddMappingError::*; - let rw = RWops::from_file(path, "r").map_err(InvalidFilePath)?; + let rw = IOStream::from_file(path, "r").map_err(InvalidFilePath)?; self.load_mappings_from_rw(rw) } @@ -166,13 +165,13 @@ impl GamepadSubsystem { use self::AddMappingError::*; let mut buffer = Vec::with_capacity(1024); - let rw = RWops::from_read(read, &mut buffer).map_err(ReadError)?; + let rw = IOStream::from_read(read, &mut buffer).map_err(ReadError)?; self.load_mappings_from_rw(rw) } - /// Load controller input mappings from an SDL [`RWops`] object. + /// Load controller input mappings from an SDL [`IOStream`] object. #[doc(alias = "SDL_AddGamepadMappingsFromIO")] - pub fn load_mappings_from_rw<'a>(&self, rw: RWops<'a>) -> Result { + pub fn load_mappings_from_rw<'a>(&self, rw: IOStream<'a>) -> Result { use self::AddMappingError::*; let result = unsafe { sys::gamepad::SDL_AddGamepadMappingsFromIO(rw.raw(), false) }; diff --git a/src/sdl3/image/mod.rs b/src/sdl3/image/mod.rs index a34af3b880..2fe8c4da6f 100644 --- a/src/sdl3/image/mod.rs +++ b/src/sdl3/image/mod.rs @@ -21,7 +21,7 @@ //! ``` use get_error; -use iostream::RWops; +use iostream::IOStream; use render::{Texture, TextureCreator}; use std::ffi::CString; use std::os::raw::{c_char, c_int}; @@ -73,7 +73,7 @@ pub trait LoadSurface: Sized { /// Method extensions to Surface for saving to disk pub trait SaveSurface { fn save>(&self, filename: P) -> Result<(), String>; - fn save_rw(&self, dst: &mut RWops) -> Result<(), String>; + fn save_rw(&self, dst: &mut IOStream) -> Result<(), String>; } impl<'a> LoadSurface for Surface<'a> { @@ -117,8 +117,8 @@ impl<'a> SaveSurface for Surface<'a> { } } - fn save_rw(&self, dst: &mut RWops) -> Result<(), String> { - //! Saves an SDL Surface to an RWops + fn save_rw(&self, dst: &mut IOStream) -> Result<(), String> { + //! Saves an SDL Surface to an IOStream unsafe { let status = image::IMG_SavePNG_RW(self.raw(), dst.raw(), 0); @@ -214,7 +214,7 @@ fn to_surface_result<'a>(raw: *mut sys::SDL_Surface) -> Result, Stri } } -pub trait ImageRWops { +pub trait ImageIOStream { /// load as a surface. except TGA fn load(&self) -> Result, String>; /// load as a surface. This can load all supported image formats. @@ -252,7 +252,7 @@ pub trait ImageRWops { fn is_webp(&self) -> bool; } -impl<'a> ImageRWops for RWops<'a> { +impl<'a> ImageIOStream for IOStream<'a> { fn load(&self) -> Result, String> { let raw = unsafe { image::IMG_Load_RW(self.raw(), 0) }; to_surface_result(raw) diff --git a/src/sdl3/mixer/mod.rs b/src/sdl3/mixer/mod.rs index 1c11266c77..e2c2e4dab0 100644 --- a/src/sdl3/mixer/mod.rs +++ b/src/sdl3/mixer/mod.rs @@ -22,7 +22,7 @@ use audio::AudioFormatNum; use get_error; -use iostream::RWops; +use iostream::IOStream; use libc::c_void; use libc::{c_double, c_int, c_uint}; use std::borrow::ToOwned; @@ -254,7 +254,7 @@ impl Drop for Chunk { impl Chunk { /// Load file for use as a sample. pub fn from_file>(path: P) -> Result { - let raw = unsafe { mixer::Mix_LoadWAV_RW(RWops::from_file(path, "rb")?.raw(), 0) }; + let raw = unsafe { mixer::Mix_LoadWAV_RW(IOStream::from_file(path, "rb")?.raw(), 0) }; Self::from_owned_raw(raw) } @@ -292,15 +292,15 @@ impl Chunk { } } -/// Loader trait for `RWops` -pub trait LoaderRWops<'a> { +/// Loader trait for `IOStream` +pub trait LoaderIOStream<'a> { /// Load src for use as a sample. fn load_wav(&self) -> Result; fn load_music(&'a self) -> Result, String>; } -impl<'a> LoaderRWops<'a> for RWops<'a> { +impl<'a> LoaderIOStream<'a> for IOStream<'a> { /// Load src for use as a sample. fn load_wav(&self) -> Result { let raw = unsafe { mixer::Mix_LoadWAV_RW(self.raw(), 0) }; diff --git a/src/sdl3/surface.rs b/src/sdl3/surface.rs index 60913a2b21..db39cfe096 100644 --- a/src/sdl3/surface.rs +++ b/src/sdl3/surface.rs @@ -5,18 +5,17 @@ use std::path::Path; use std::rc::Rc; use crate::get_error; -use crate::iostream::RWops; use crate::pixels; use crate::rect::Rect; use crate::render::{BlendMode, Canvas}; use crate::render::{Texture, TextureCreator, TextureValueError}; +use crate::sys; +use iostream::IOStream; use libc::c_int; use std::convert::TryFrom; use std::mem::transmute; use std::ptr; -use crate::sys; - /// Holds a `SDL_Surface` /// /// When the `SurfaceContext` is dropped, it frees the `SDL_Surface` @@ -288,8 +287,8 @@ impl<'a> Surface<'a> { } #[doc(alias = "SDL_LoadBMP_RW")] - pub fn load_bmp_rw(rwops: &mut RWops) -> Result, String> { - let raw = unsafe { sys::SDL_LoadBMP_RW(rwops.raw(), sys::SDL_bool::SDL_FALSE) }; + pub fn load_bmp_rw(iostream: &mut IOStream) -> Result, String> { + let raw = unsafe { sys::SDL_LoadBMP_RW(iostream.raw(), sys::SDL_bool::SDL_FALSE) }; if raw.is_null() { Err(get_error()) @@ -299,7 +298,7 @@ impl<'a> Surface<'a> { } pub fn load_bmp>(path: P) -> Result, String> { - let mut file = RWops::from_file(path, "rb")?; + let mut file = IOStream::from_file(path, "rb")?; Surface::load_bmp_rw(&mut file) } @@ -444,8 +443,8 @@ 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) }; + pub fn save_bmp_rw(&self, iostream: &mut Iostream) -> Result<(), String> { + let ret = unsafe { sys::SDL_SaveBMP_RW(self.raw(), iostream.raw(), 0) }; if ret == 0 { Ok(()) } else { @@ -454,7 +453,7 @@ impl SurfaceRef { } pub fn save_bmp>(&self, path: P) -> Result<(), String> { - let mut file = RWops::from_file(path, "wb")?; + let mut file = Iostream::from_file(path, "wb")?; self.save_bmp_rw(&mut file) } diff --git a/src/sdl3/ttf/context.rs b/src/sdl3/ttf/context.rs index 4f0e5283d9..ac0dd0d8f4 100644 --- a/src/sdl3/ttf/context.rs +++ b/src/sdl3/ttf/context.rs @@ -1,5 +1,5 @@ use get_error; -use iostream::RWops; +use iostream::IOStream; use std::error; use std::fmt; use std::io; @@ -46,36 +46,36 @@ impl Sdl2TtfContext { internal_load_font_at_index(path, index, point_size) } - /// Loads a font from the given SDL2 rwops object with the given size in + /// Loads a font from the given SDL2 iostream object with the given size in /// points. - pub fn load_font_from_rwops<'ttf, 'r>( + pub fn load_font_from_iostream<'ttf, 'r>( &'ttf self, - rwops: RWops<'r>, + iostream: IOStream<'r>, point_size: u16, ) -> Result, String> { - let raw = unsafe { ttf::TTF_OpenFontRW(rwops.raw(), 0, point_size as c_int) }; + let raw = unsafe { ttf::TTF_OpenFontRW(iostream.raw(), 0, point_size as c_int) }; if (raw as *mut ()).is_null() { Err(get_error()) } else { - Ok(internal_load_font_from_ll(raw, Some(rwops))) + Ok(internal_load_font_from_ll(raw, Some(iostream))) } } - /// Loads the font at the given index of the SDL2 rwops object with + /// Loads the font at the given index of the SDL2 iostream object with /// the given size in points. - pub fn load_font_at_index_from_rwops<'ttf, 'r>( + pub fn load_font_at_index_from_iostream<'ttf, 'r>( &'ttf self, - rwops: RWops<'r>, + iostream: Iostream<'r>, index: u32, point_size: u16, ) -> Result, String> { let raw = unsafe { - ttf::TTF_OpenFontIndexRW(rwops.raw(), 0, point_size as c_int, index as c_long) + ttf::TTF_OpenFontIndexRW(iostream.raw(), 0, point_size as c_int, index as c_long) }; if (raw as *mut ()).is_null() { Err(get_error()) } else { - Ok(internal_load_font_from_ll(raw, Some(rwops))) + Ok(internal_load_font_from_ll(raw, Some(iostream))) } } } diff --git a/src/sdl3/ttf/font.rs b/src/sdl3/ttf/font.rs index 685682d516..52eeef9a1d 100644 --- a/src/sdl3/ttf/font.rs +++ b/src/sdl3/ttf/font.rs @@ -1,5 +1,5 @@ use get_error; -use iostream::RWops; +use iostream::IOStream; use pixels::Color; use std::error; use std::error::Error; @@ -229,16 +229,16 @@ impl<'f, 'text> PartialRendering<'f, 'text> { } /// A loaded TTF font. -pub struct Font<'ttf_module, 'rwops> { +pub struct Font<'ttf_module, 'iostream> { 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 + // Iostream is only stored here because it must not outlive + // the Font struct, and this Iostream should not be used by // anything else - // None means that the RWops is handled by SDL itself, - // and Some(rwops) means that the RWops is handled by the Rust + // None means that the Iostream is handled by SDL itself, + // and Some(iostream) means that the Iostream is handled by the Rust // side #[allow(dead_code)] - rwops: Option>, + iostream: Option>, #[allow(dead_code)] _marker: PhantomData<&'ttf_module ()>, } @@ -267,7 +267,7 @@ pub fn internal_load_font<'ttf, P: AsRef>( } else { Ok(Font { raw: raw, - rwops: None, + iostream: None, _marker: PhantomData, }) } @@ -275,13 +275,16 @@ pub fn internal_load_font<'ttf, P: AsRef>( } /// 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> +pub fn internal_load_font_from_ll<'ttf, 'r, R>( + raw: *mut ttf::TTF_Font, + iostream: R, +) -> Font<'ttf, 'r> where - R: Into>>, + R: Into>>, { Font { raw: raw, - rwops: rwops.into(), + iostream: iostream.into(), _marker: PhantomData, } } @@ -300,7 +303,7 @@ pub fn internal_load_font_at_index<'ttf, P: AsRef>( } else { Ok(Font { raw: raw, - rwops: None, + iostream: None, _marker: PhantomData, }) } From e0e02b8c603d37f42d16c1239e8e6d7f09b1e6e2 Mon Sep 17 00:00:00 2001 From: Mischa Spiegelmock Date: Sat, 19 Oct 2024 11:20:19 -0700 Subject: [PATCH 4/8] RWOps -> IOStream --- src/sdl3/surface.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sdl3/surface.rs b/src/sdl3/surface.rs index db39cfe096..2102dc3cd7 100644 --- a/src/sdl3/surface.rs +++ b/src/sdl3/surface.rs @@ -443,7 +443,7 @@ impl SurfaceRef { } #[doc(alias = "SDL_SaveBMP_RW")] - pub fn save_bmp_rw(&self, iostream: &mut Iostream) -> Result<(), String> { + pub fn save_bmp_rw(&self, iostream: &mut IOStream) -> Result<(), String> { let ret = unsafe { sys::SDL_SaveBMP_RW(self.raw(), iostream.raw(), 0) }; if ret == 0 { Ok(()) @@ -453,7 +453,7 @@ impl SurfaceRef { } pub fn save_bmp>(&self, path: P) -> Result<(), String> { - let mut file = Iostream::from_file(path, "wb")?; + let mut file = IOStream::from_file(path, "wb")?; self.save_bmp_rw(&mut file) } From e2446d7844d248f87b579fa5203caf719039083d Mon Sep 17 00:00:00 2001 From: Mischa Spiegelmock Date: Wed, 16 Oct 2024 22:15:09 -0700 Subject: [PATCH 5/8] Renderer WIP --- src/sdl3/render.rs | 340 +++++++++++++++++++-------------------------- 1 file changed, 142 insertions(+), 198 deletions(-) diff --git a/src/sdl3/render.rs b/src/sdl3/render.rs index dd4429c6ca..05fefc1661 100644 --- a/src/sdl3/render.rs +++ b/src/sdl3/render.rs @@ -52,8 +52,8 @@ use std::ptr; use std::rc::Rc; use crate::sys; -use crate::sys::SDL_BlendMode; -use crate::sys::SDL_TextureAccess; +use crate::sys::render::SDL_BlendMode; +use crate::sys::render::SDL_TextureAccess; /// Contains the description of an error returned by SDL #[derive(Debug, Clone)] @@ -118,8 +118,8 @@ impl FPoint { pub fn new(x: f32, y: f32) -> FPoint { FPoint { x, y } } - pub fn to_ll(&self) -> sys::SDL_FPoint { - sys::SDL_FPoint { + pub fn to_ll(&self) -> sys::rect::SDL_FPoint { + sys::rect::SDL_FPoint { x: self.x, y: self.y, } @@ -147,8 +147,8 @@ impl FRect { pub fn new(x: f32, y: f32, w: f32, h: f32) -> FRect { FRect { x, y, w, h } } - pub fn to_ll(&self) -> sys::SDL_FRect { - sys::SDL_FRect { + pub fn to_ll(&self) -> sys::rect::SDL_FRect { + sys::rect::SDL_FRect { x: self.x, y: self.y, w: self.w, @@ -189,7 +189,7 @@ impl TryFrom for TextureAccess { fn try_from(n: u32) -> Result { use self::TextureAccess::*; - use crate::sys::SDL_TextureAccess::*; + use crate::sys::render::SDL_TextureAccess::*; Ok(match unsafe { transmute(n) } { SDL_TEXTUREACCESS_STATIC => Static, @@ -243,7 +243,7 @@ impl TryFrom for BlendMode { fn try_from(n: u32) -> Result { use self::BlendMode::*; - use crate::sys::SDL_BlendMode::*; + use crate::sys::render::SDL_BlendMode::*; Ok(match unsafe { transmute(n) } { SDL_BLENDMODE_NONE => None, @@ -256,34 +256,11 @@ impl TryFrom for BlendMode { } } -impl RendererInfo { - pub unsafe fn from_ll(info: &sys::SDL_RendererInfo) -> RendererInfo { - let texture_formats: Vec = info.texture_formats - [0..(info.num_texture_formats as usize)] - .iter() - .map(|&format| { - PixelFormatEnum::try_from(format as u32).unwrap_or(PixelFormatEnum::Unknown) - }) - .collect(); - - // The driver name is always a static string, compiled into SDL2. - let name = CStr::from_ptr(info.name as *const _).to_str().unwrap(); - - RendererInfo { - name, - flags: info.flags, - texture_formats, - max_texture_width: info.max_texture_width as u32, - max_texture_height: info.max_texture_height as u32, - } - } -} - /// Manages what keeps a `SDL_Renderer` alive /// /// When the `RendererContext` is dropped, it destroys the `SDL_Renderer` pub struct RendererContext { - raw: *mut sys::SDL_Renderer, + raw: *mut sys::render::SDL_Renderer, _target: Rc, } @@ -291,55 +268,37 @@ impl Drop for RendererContext { #[doc(alias = "SDL_DestroyRenderer")] fn drop(&mut self) { unsafe { - sys::SDL_DestroyRenderer(self.raw); + sys::render::SDL_DestroyRenderer(self.raw); }; } } impl RendererContext { - /// Gets information about the rendering context. - #[doc(alias = "SDL_GetRendererInfo")] - pub fn info(&self) -> RendererInfo { - let mut renderer_info_raw = mem::MaybeUninit::uninit(); - let result = - unsafe { sys::SDL_GetRendererInfo(self.raw, renderer_info_raw.as_mut_ptr()) != 0 }; - - if result { - // Should only fail on an invalid renderer - panic!(); - } else { - unsafe { - let renderer_info_raw = renderer_info_raw.assume_init(); - RendererInfo::from_ll(&renderer_info_raw) - } - } - } - /// Gets the raw pointer to the SDL_Renderer // 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 fn raw(&self) -> *mut sys::SDL_Renderer { + pub fn raw(&self) -> *mut sys::render::SDL_Renderer { self.raw } - pub unsafe fn from_ll(raw: *mut sys::SDL_Renderer, target: Rc) -> Self { + pub unsafe fn from_ll(raw: *mut sys::render::SDL_Renderer, target: Rc) -> Self { RendererContext { raw, _target: target, } } - unsafe fn set_raw_target(&self, raw_texture: *mut sys::SDL_Texture) -> Result<(), SdlError> { - if sys::SDL_SetRenderTarget(self.raw, raw_texture) == 0 { + unsafe fn set_raw_target(&self, raw_texture: *mut sys::render::SDL_Texture) -> Result<(), SdlError> { + if sys::render::SDL_SetRenderTarget(self.raw, raw_texture) == true { Ok(()) } else { Err(SdlError(get_error())) } } - unsafe fn get_raw_target(&self) -> *mut sys::SDL_Texture { - sys::SDL_GetRenderTarget(self.raw) + unsafe fn get_raw_target(&self) -> *mut sys::render::SDL_Texture { + sys::render::SDL_GetRenderTarget(self.raw) } } @@ -381,18 +340,16 @@ impl<'s> RenderTarget for Surface<'s> { /// # Examples /// /// ```rust,no_run -/// # use sdl2::render::Canvas; -/// # use sdl2::video::Window; -/// # use sdl2::pixels::Color; -/// # use sdl2::rect::Rect; -/// # let sdl_context = sdl2::init().unwrap(); +/// # use sdl3::render::Canvas; +/// # use sdl3::video::Window; +/// # use sdl3::pixels::Color; +/// # use sdl3::rect::Rect; +/// # let sdl_context = sdl3::init().unwrap(); /// # let video_subsystem = sdl_context.video().unwrap(); /// let window = video_subsystem.window("Example", 800, 600).build().unwrap(); /// /// // Let's create a Canvas which we will use to draw in our Window /// let mut canvas : Canvas = window.into_canvas() -/// .present_vsync() //< this means the screen cannot -/// // render faster than your display rate (usually 60Hz or 144Hz) /// .build().unwrap(); /// /// canvas.set_draw_color(Color::RGB(0, 0, 0)); @@ -436,7 +393,7 @@ impl<'s> Canvas> { /// support, or there's an out-of-memory error. #[doc(alias = "SDL_CreateSoftwareRenderer")] pub fn from_surface(surface: surface::Surface<'s>) -> Result { - let raw_renderer = unsafe { sys::SDL_CreateSoftwareRenderer(surface.raw()) }; + let raw_renderer = unsafe { sys::render::SDL_CreateSoftwareRenderer(surface.raw()) }; if !raw_renderer.is_null() { let context = Rc::new(unsafe { RendererContext::from_ll(raw_renderer, surface.context()) }); @@ -566,7 +523,7 @@ impl Canvas { /// * returns `TargetRenderError::SdlError` if SDL2 returned with an error code. /// /// The texture *must* be created with the texture access: - /// `sdl2::render::TextureAccess::Target`. + /// `sdl3::render::TextureAccess::Target`. /// Using a texture which was not created with the texture access `Target` is undefined /// behavior. /// @@ -576,10 +533,10 @@ impl Canvas { /// 50-by-50 red square in the middle. /// /// ```rust,no_run - /// # use sdl2::render::{Canvas, Texture}; - /// # use sdl2::video::Window; - /// # use sdl2::pixels::Color; - /// # use sdl2::rect::Rect; + /// # use sdl3::render::{Canvas, Texture}; + /// # use sdl3::video::Window; + /// # use sdl3::pixels::Color; + /// # use sdl3::rect::Rect; /// # let mut canvas : Canvas = unimplemented!(); /// let texture_creator = canvas.texture_creator(); /// let mut texture = texture_creator @@ -625,10 +582,10 @@ impl Canvas { /// Let's create two textures, one which will be yellow, and the other will be white /// /// ```rust,no_run - /// # use sdl2::pixels::Color; - /// # use sdl2::rect::Rect; - /// # use sdl2::video::Window; - /// # use sdl2::render::{Canvas, Texture}; + /// # use sdl3::pixels::Color; + /// # use sdl3::rect::Rect; + /// # use sdl3::video::Window; + /// # use sdl3::render::{Canvas, Texture}; /// # let mut canvas : Canvas = unimplemented!(); /// let texture_creator = canvas.texture_creator(); /// enum TextureColor { @@ -750,7 +707,7 @@ impl CanvasBuilder { pub fn build(self) -> Result { use crate::common::IntegerOrSdlError::*; let raw = unsafe { - sys::SDL_CreateRenderer( + sys::render::SDL_CreateRenderer( self.window.raw(), if self.renderer_name.is_none() { std::ptr::null() @@ -783,23 +740,10 @@ impl CanvasBuilder { /// Set the renderer to a software fallback. /// This flag is accumulative, and may be specified with other flags. pub fn software(mut self) -> CanvasBuilder { - self.renderer_flags |= sys::SDL_RendererFlags::SDL_RENDERER_SOFTWARE as u32; - self - } - - /// Set the renderer to use hardware acceleration. - /// This flag is accumulative, and may be specified with other flags. - pub fn accelerated(mut self) -> CanvasBuilder { - self.renderer_flags |= sys::SDL_RendererFlags::SDL_RENDERER_ACCELERATED as u32; + self.renderer_name = Some(sys::render::SDL_SOFTWARE_RENDERER.into()); self } - /// Synchronize renderer `present` method calls with the refresh rate. - /// This flag is accumulative, and may be specified with other flags. - pub fn present_vsync(mut self) -> CanvasBuilder { - self.renderer_flags |= sys::SDL_RendererFlags::SDL_RENDERER_PRESENTVSYNC as u32; - self - } } #[derive(Debug, Clone)] @@ -844,12 +788,12 @@ impl Error for TextureValueError { #[doc(alias = "SDL_CreateTexture")] fn ll_create_texture( - context: *mut sys::SDL_Renderer, + context: *mut sys::render::SDL_Renderer, pixel_format: PixelFormatEnum, access: TextureAccess, width: u32, height: u32, -) -> Result<*mut sys::SDL_Texture, TextureValueError> { +) -> Result<*mut sys::render::SDL_Texture, TextureValueError> { use self::TextureValueError::*; let w = match validate_int(width, "width") { Ok(w) => w, @@ -871,7 +815,7 @@ fn ll_create_texture( _ => (), }; - Ok(unsafe { sys::SDL_CreateTexture(context, pixel_format as u32, access as c_int, w, h) }) + Ok(unsafe { sys::render::SDL_CreateTexture(context, pixel_format as u32, access as c_int, w, h) }) } /// Texture-creating methods for the renderer @@ -879,7 +823,7 @@ impl TextureCreator { // 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 fn raw(&self) -> *mut sys::SDL_Renderer { + pub fn raw(&self) -> *mut sys::render::SDL_Renderer { self.context.raw() } @@ -967,17 +911,17 @@ impl TextureCreator { /// The access hint for the created texture is [`TextureAccess::Static`]. /// /// ```no_run - /// use sdl2::pixels::PixelFormatEnum; - /// use sdl2::surface::Surface; - /// use sdl2::render::{Canvas, Texture}; - /// use sdl2::video::Window; + /// use sdl3::pixels::PixelFormatEnum; + /// use sdl3::surface::Surface; + /// use sdl3::render::{Canvas, Texture}; + /// use sdl3::video::Window; /// /// // We init systems. - /// let sdl_context = sdl2::init().expect("failed to init SDL"); + /// let sdl_context = sdl3::init().expect("failed to init SDL"); /// let video_subsystem = sdl_context.video().expect("failed to get video context"); /// /// // We create a window. - /// let window = video_subsystem.window("sdl2 demo", 800, 600) + /// let window = video_subsystem.window("sdl3 demo", 800, 600) /// .build() /// .expect("failed to build window"); /// @@ -997,7 +941,7 @@ impl TextureCreator { ) -> Result { use self::TextureValueError::*; let result = - unsafe { sys::SDL_CreateTextureFromSurface(self.context.raw, surface.as_ref().raw()) }; + unsafe { sys::render::SDL_CreateTextureFromSurface(self.context.raw, surface.as_ref().raw()) }; if result.is_null() { Err(SdlError(get_error())) } else { @@ -1008,7 +952,7 @@ impl TextureCreator { /// Create a texture from its raw `SDL_Texture`. #[cfg(not(feature = "unsafe_textures"))] #[inline] - pub const unsafe fn raw_create_texture(&self, raw: *mut sys::SDL_Texture) -> Texture { + pub const unsafe fn raw_create_texture(&self, raw: *mut sys::render::SDL_Texture) -> Texture { Texture { raw, _marker: PhantomData, @@ -1017,7 +961,7 @@ impl TextureCreator { /// Create a texture from its raw `SDL_Texture`. Should be used with care. #[cfg(feature = "unsafe_textures")] - pub const unsafe fn raw_create_texture(&self, raw: *mut sys::SDL_Texture) -> Texture { + pub const unsafe fn raw_create_texture(&self, raw: *mut sys::render::SDL_Texture) -> Texture { Texture { raw } } } @@ -1027,7 +971,7 @@ impl Canvas { // 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 fn raw(&self) -> *mut sys::SDL_Renderer { + pub fn raw(&self) -> *mut sys::render::SDL_Renderer { self.context.raw() } @@ -1035,9 +979,9 @@ impl Canvas { #[doc(alias = "SDL_SetRenderDrawColor")] pub fn set_draw_color>(&mut self, color: C) { let (r, g, b, a) = color.into().rgba(); - let ret = unsafe { sys::SDL_SetRenderDrawColor(self.raw, r, g, b, a) }; + let ret = unsafe { sys::render::SDL_SetRenderDrawColor(self.raw, r, g, b, a) }; // Should only fail on an invalid renderer - if ret != 0 { + if !ret { panic!("{}", get_error()) } } @@ -1047,10 +991,10 @@ impl Canvas { pub fn draw_color(&self) -> pixels::Color { let (mut r, mut g, mut b, mut a) = (0, 0, 0, 0); let ret = unsafe { - sys::SDL_GetRenderDrawColor(self.context.raw, &mut r, &mut g, &mut b, &mut a) + sys::render::SDL_GetRenderDrawColor(self.context.raw, &mut r, &mut g, &mut b, &mut a) }; // Should only fail on an invalid renderer - if ret != 0 { + if !ret { panic!("{}", get_error()) } else { pixels::Color::RGBA(r, g, b, a) @@ -1061,9 +1005,9 @@ impl Canvas { #[doc(alias = "SDL_SetRenderDrawBlendMode")] pub fn set_blend_mode(&mut self, blend: BlendMode) { let ret = - unsafe { sys::SDL_SetRenderDrawBlendMode(self.context.raw, transmute(blend as u32)) }; + unsafe { sys::render::SDL_SetRenderDrawBlendMode(self.context.raw, transmute(blend as u32)) }; // Should only fail on an invalid renderer - if ret != 0 { + if !ret { panic!("{}", get_error()) } } @@ -1072,9 +1016,9 @@ impl Canvas { #[doc(alias = "SDL_GetRenderDrawBlendMode")] pub fn blend_mode(&self) -> BlendMode { let mut blend: MaybeUninit = mem::MaybeUninit::uninit(); - let ret = unsafe { sys::SDL_GetRenderDrawBlendMode(self.context.raw, blend.as_mut_ptr()) }; + let ret = unsafe { sys::render::SDL_GetRenderDrawBlendMode(self.context.raw, blend.as_mut_ptr()) }; // Should only fail on an invalid renderer - if ret != 0 { + if !ret { panic!("{}", get_error()) } else { let blend = unsafe { blend.assume_init() }; @@ -1085,8 +1029,8 @@ impl Canvas { /// Clears the current rendering target with the drawing color. #[doc(alias = "SDL_RenderClear")] pub fn clear(&mut self) { - let ret = unsafe { sys::SDL_RenderClear(self.context.raw) }; - if ret != 0 { + let ret = unsafe { sys::render::SDL_RenderClear(self.context.raw) }; + if !ret { panic!("Could not clear: {}", get_error()) } } @@ -1100,7 +1044,7 @@ impl Canvas { /// backbuffer to the screen as a complete picture. #[doc(alias = "SDL_RenderPresent")] pub fn present(&mut self) -> i32 { - unsafe { sys::SDL_RenderPresent(self.context.raw) } + unsafe { sys::render::SDL_RenderPresent(self.context.raw) } } /// Gets the output size of a rendering context. @@ -1110,7 +1054,7 @@ impl Canvas { let mut height = 0; let result = unsafe { - sys::SDL_GetCurrentRenderOutputSize(self.context.raw, &mut width, &mut height) + sys::render::SDL_GetCurrentRenderOutputSize(self.context.raw, &mut width, &mut height) }; if result == 0 { @@ -1126,14 +1070,14 @@ impl Canvas { &mut self, width: u32, height: u32, - mode: sys::SDL_RendererLogicalPresentation, - scale_mode: sys::SDL_ScaleMode, + mode: sys::render::SDL_RendererLogicalPresentation, + scale_mode: sys::render::SDL_ScaleMode, ) -> Result<(), IntegerOrSdlError> { use crate::common::IntegerOrSdlError::*; let width = validate_int(width, "width")?; let height = validate_int(height, "height")?; let result = unsafe { - sys::SDL_SetRenderLogicalPresentation(self.context.raw, width, height, mode, scale_mode) + sys::render::SDL_SetRenderLogicalPresentation(self.context.raw, width, height, mode, scale_mode) }; match result { 0 => Ok(()), @@ -1148,17 +1092,17 @@ impl Canvas { ) -> ( u32, u32, - sys::SDL_RendererLogicalPresentation, - sys::SDL_ScaleMode, + sys::render::SDL_RendererLogicalPresentation, + sys::render::SDL_ScaleMode, ) { let mut width = 0; let mut height = 0; - let mut mode: sys::SDL_RendererLogicalPresentation = - sys::SDL_RendererLogicalPresentation::SDL_LOGICAL_PRESENTATION_DISABLED; - let mut scale_mode: sys::SDL_ScaleMode = sys::SDL_ScaleMode::SDL_SCALEMODE_BEST; + let mut mode: sys::render::SDL_RendererLogicalPresentation = + sys::render::SDL_RendererLogicalPresentation::SDL_LOGICAL_PRESENTATION_DISABLED; + let mut scale_mode: sys::render::SDL_ScaleMode = sys::render::SDL_ScaleMode::SDL_SCALEMODE_BEST; unsafe { - sys::SDL_GetRenderLogicalPresentation( + sys::render::SDL_GetRenderLogicalPresentation( self.context.raw, &mut width, &mut height, @@ -1176,8 +1120,8 @@ impl Canvas { let rect = rect.into(); // as_ref is important because we need rect to live until the end of the FFI call, but map_or consumes an Option let ptr = rect.as_ref().map_or(ptr::null(), |rect| rect.raw()); - let ret = unsafe { sys::SDL_SetRenderViewport(self.context.raw, ptr) }; - if ret != 0 { + let ret = unsafe { sys::render::SDL_SetRenderViewport(self.context.raw, ptr) }; + if !ret { panic!("Could not set viewport: {}", get_error()) } } @@ -1186,7 +1130,7 @@ impl Canvas { #[doc(alias = "SDL_GetRenderViewport")] pub fn viewport(&self) -> Rect { let mut rect = mem::MaybeUninit::uninit(); - unsafe { sys::SDL_GetRenderViewport(self.context.raw, rect.as_mut_ptr()) }; + unsafe { sys::render::SDL_GetRenderViewport(self.context.raw, rect.as_mut_ptr()) }; let rect = unsafe { rect.assume_init() }; Rect::from_ll(rect) } @@ -1199,8 +1143,8 @@ impl Canvas { let rect = rect.into(); // as_ref is important because we need rect to live until the end of the FFI call, but map_or consumes an Option let ptr = rect.as_ref().map_or(ptr::null(), |rect| rect.raw()); - let ret = unsafe { sys::SDL_SetRenderClipRect(self.context.raw, ptr) }; - if ret != 0 { + let ret = unsafe { sys::render::SDL_SetRenderClipRect(self.context.raw, ptr) }; + if !ret { panic!("Could not set clip rect: {}", get_error()) } } @@ -1211,7 +1155,7 @@ impl Canvas { #[doc(alias = "SDL_GetRenderClipRect")] pub fn clip_rect(&self) -> Option { let mut raw = mem::MaybeUninit::uninit(); - unsafe { sys::SDL_GetRenderClipRect(self.context.raw, raw.as_mut_ptr()) }; + unsafe { sys::render::SDL_GetRenderClipRect(self.context.raw, raw.as_mut_ptr()) }; let raw = unsafe { raw.assume_init() }; if raw.w == 0 || raw.h == 0 { None @@ -1223,9 +1167,9 @@ impl Canvas { /// Sets the drawing scale for rendering on the current target. #[doc(alias = "SDL_SetRenderScale")] pub fn set_scale(&mut self, scale_x: f32, scale_y: f32) -> Result<(), String> { - let ret = unsafe { sys::SDL_SetRenderScale(self.context.raw, scale_x, scale_y) }; + let ret = unsafe { sys::render::SDL_SetRenderScale(self.context.raw, scale_x, scale_y) }; // Should only fail on an invalid renderer - if ret != 0 { + if !ret { Err(get_error()) } else { Ok(()) @@ -1237,7 +1181,7 @@ impl Canvas { pub fn scale(&self) -> (f32, f32) { let mut scale_x = 0.0; let mut scale_y = 0.0; - unsafe { sys::SDL_GetRenderScale(self.context.raw, &mut scale_x, &mut scale_y) }; + unsafe { sys::render::SDL_GetRenderScale(self.context.raw, &mut scale_x, &mut scale_y) }; (scale_x, scale_y) } @@ -1246,7 +1190,7 @@ impl Canvas { #[doc(alias = "SDL_RenderPoint")] pub fn draw_point>(&mut self, point: P) -> Result<(), String> { let point = point.into(); - let result = unsafe { sys::SDL_RenderPoint(self.context.raw, point.x, point.y) }; + let result = unsafe { sys::render::SDL_RenderPoint(self.context.raw, point.x, point.y) }; if result != 0 { Err(get_error()) } else { @@ -1260,9 +1204,9 @@ impl Canvas { pub fn draw_points<'a, P: Into<&'a [FPoint]>>(&mut self, points: P) -> Result<(), String> { let points = points.into(); let result = unsafe { - sys::SDL_RenderPoints( + sys::render::SDL_RenderPoints( self.context.raw, - points.as_ptr() as *const sys::SDL_FPoint, + points.as_ptr() as *const sys::rect::SDL_FPoint, points.len() as c_int, ) }; @@ -1284,7 +1228,7 @@ impl Canvas { let start = start.into(); let end = end.into(); let result = - unsafe { sys::SDL_RenderLine(self.context.raw, start.x, start.y, end.x, end.y) }; + unsafe { sys::render::SDL_RenderLine(self.context.raw, start.x, start.y, end.x, end.y) }; if result != 0 { Err(get_error()) } else { @@ -1298,7 +1242,7 @@ impl Canvas { pub fn draw_lines<'a, P: Into<&'a [FPoint]>>(&mut self, points: P) -> Result<(), String> { let points = points.into(); let result = unsafe { - sys::SDL_RenderLines( + sys::render::SDL_RenderLines( self.context.raw, points .iter() @@ -1319,7 +1263,7 @@ impl Canvas { /// Errors if drawing fails for any reason (e.g. driver failure) #[doc(alias = "SDL_RenderRect")] pub fn draw_rect(&mut self, rect: FRect) -> Result<(), String> { - let result = unsafe { sys::SDL_RenderRect(self.context.raw, &rect.to_ll()) }; + let result = unsafe { sys::render::SDL_RenderRect(self.context.raw, &rect.to_ll()) }; if result != 0 { Err(get_error()) } else { @@ -1332,7 +1276,7 @@ impl Canvas { #[doc(alias = "SDL_RenderRects")] pub fn draw_rects(&mut self, rects: &[FRect]) -> Result<(), String> { let result = unsafe { - sys::SDL_RenderRects( + sys::render::SDL_RenderRects( self.context.raw, rects.iter().map(|r| r.to_ll()).collect::>().as_ptr(), rects.len() as c_int, @@ -1352,7 +1296,7 @@ impl Canvas { #[doc(alias = "SDL_RenderFillRect")] pub fn fill_rect>>(&mut self, rect: R) -> Result<(), String> { let result = unsafe { - sys::SDL_RenderFillRect( + sys::render::SDL_RenderFillRect( self.context.raw, rect.into().map_or(ptr::null(), |r| &r.to_ll()), ) @@ -1370,7 +1314,7 @@ impl Canvas { #[doc(alias = "SDL_RenderFillRects")] pub fn fill_rects(&mut self, rects: &[FRect]) -> Result<(), String> { let result = unsafe { - sys::SDL_RenderFillRects( + sys::render::SDL_RenderFillRects( self.context.raw, rects.iter().map(|r| r.to_ll()).collect::>().as_ptr(), rects.len() as c_int, @@ -1398,7 +1342,7 @@ impl Canvas { R2: Into>, { let ret = unsafe { - sys::SDL_RenderTexture( + sys::render::SDL_RenderTexture( self.context.raw, texture.raw, match src.into() { @@ -1412,7 +1356,7 @@ impl Canvas { ) }; - if ret != 0 { + if !ret { Err(get_error()) } else { Ok(()) @@ -1448,21 +1392,21 @@ impl Canvas { R2: Into>, P: Into>, { - use crate::sys::SDL_RendererFlip::*; + use crate::sys::render::SDL_RendererFlip::*; let flip = unsafe { match (flip_horizontal, flip_vertical) { (false, false) => SDL_FLIP_NONE, (true, false) => SDL_FLIP_HORIZONTAL, (false, true) => SDL_FLIP_VERTICAL, - (true, true) => transmute::( - transmute::(SDL_FLIP_HORIZONTAL) - | transmute::(SDL_FLIP_VERTICAL), + (true, true) => transmute::( + transmute::(SDL_FLIP_HORIZONTAL) + | transmute::(SDL_FLIP_VERTICAL), ), } }; let ret = unsafe { - sys::SDL_RenderTextureRotated( + sys::render::SDL_RenderTextureRotated( self.context.raw, texture.raw, match src.into() { @@ -1482,7 +1426,7 @@ impl Canvas { ) }; - if ret != 0 { + if !ret { Err(get_error()) } else { Ok(()) @@ -1515,7 +1459,7 @@ impl Canvas { // Pass the interior of `pixels: Vec` to SDL let ret = { - sys::SDL_RenderReadPixels( + sys::render::SDL_RenderReadPixels( self.context.raw, actual_rect, format as u32, @@ -1644,7 +1588,7 @@ impl Canvas { ) -> Result { use self::TextureValueError::*; let result = - unsafe { sys::SDL_CreateTextureFromSurface(self.context.raw, surface.as_ref().raw()) }; + unsafe { sys::render::SDL_CreateTextureFromSurface(self.context.raw, surface.as_ref().raw()) }; if result.is_null() { Err(SdlError(get_error())) } else { @@ -1658,15 +1602,15 @@ impl Canvas { /// # Notes /// /// Note that this method is only accessible in Canvas with the `unsafe_textures` feature. - pub unsafe fn raw_create_texture(&self, raw: *mut sys::SDL_Texture) -> Texture { + pub unsafe fn raw_create_texture(&self, raw: *mut sys::render::SDL_Texture) -> Texture { Texture { raw } } #[doc(alias = "SDL_RenderFlush")] pub unsafe fn render_flush(&self) { - let ret = sys::SDL_RenderFlush(self.context.raw); + let ret = sys::render::SDL_RenderFlush(self.context.raw); - if ret != 0 { + if !ret { panic!("Error setting blend: {}", get_error()) } } @@ -1708,7 +1652,7 @@ pub struct TextureQuery { /// it is not possible to access a `Texture` while the `Canvas` is dropped. #[cfg(feature = "unsafe_textures")] pub struct Texture { - raw: *mut sys::SDL_Texture, + raw: *mut sys::render::SDL_Texture, } /// A texture for a rendering context. @@ -1718,7 +1662,7 @@ pub struct Texture { /// is undefined behavior otherwise. #[cfg(not(feature = "unsafe_textures"))] pub struct Texture<'r> { - raw: *mut sys::SDL_Texture, + raw: *mut sys::render::SDL_Texture, _marker: PhantomData<&'r ()>, } @@ -1727,7 +1671,7 @@ impl<'r> Drop for Texture<'r> { #[doc(alias = "SDL_DestroyTexture")] fn drop(&mut self) { unsafe { - sys::SDL_DestroyTexture(self.raw); + sys::render::SDL_DestroyTexture(self.raw); } } } @@ -1751,7 +1695,7 @@ impl Texture { /// /// **Calling this method while no parent is alive is undefined behavior** pub unsafe fn destroy(self) { - sys::SDL_DestroyTexture(self.raw) + sys::render::SDL_DestroyTexture(self.raw) } } @@ -1904,7 +1848,7 @@ impl Error for UpdateTextureYUVError { } struct InternalTexture { - raw: *mut sys::SDL_Texture, + raw: *mut sys::render::SDL_Texture, } impl InternalTexture { @@ -1916,10 +1860,10 @@ impl InternalTexture { let mut height = 0; let ret = unsafe { - sys::SDL_QueryTexture(self.raw, &mut format, &mut access, &mut width, &mut height) + sys::render::SDL_QueryTexture(self.raw, &mut format, &mut access, &mut width, &mut height) }; // Should only fail on an invalid texture - if ret != 0 { + if !ret { panic!("{}", get_error()) } else { TextureQuery { @@ -1933,9 +1877,9 @@ impl InternalTexture { #[doc(alias = "SDL_SetTextureColorMod")] pub fn set_color_mod(&mut self, red: u8, green: u8, blue: u8) { - let ret = unsafe { sys::SDL_SetTextureColorMod(self.raw, red, green, blue) }; + let ret = unsafe { sys::render::SDL_SetTextureColorMod(self.raw, red, green, blue) }; - if ret != 0 { + if !ret { panic!("Error setting color mod: {}", get_error()) } } @@ -1943,10 +1887,10 @@ impl InternalTexture { #[doc(alias = "SDL_GetTextureColorMod")] pub fn color_mod(&self) -> (u8, u8, u8) { let (mut r, mut g, mut b) = (0, 0, 0); - let ret = unsafe { sys::SDL_GetTextureColorMod(self.raw, &mut r, &mut g, &mut b) }; + let ret = unsafe { sys::render::SDL_GetTextureColorMod(self.raw, &mut r, &mut g, &mut b) }; // Should only fail on an invalid texture - if ret != 0 { + if !ret { panic!("{}", get_error()) } else { (r, g, b) @@ -1955,9 +1899,9 @@ impl InternalTexture { #[doc(alias = "SDL_SetTextureAlphaMod")] pub fn set_alpha_mod(&mut self, alpha: u8) { - let ret = unsafe { sys::SDL_SetTextureAlphaMod(self.raw, alpha) }; + let ret = unsafe { sys::render::SDL_SetTextureAlphaMod(self.raw, alpha) }; - if ret != 0 { + if !ret { panic!("Error setting alpha mod: {}", get_error()) } } @@ -1965,10 +1909,10 @@ impl InternalTexture { #[doc(alias = "SDL_GetTextureAlphaMod")] pub fn alpha_mod(&self) -> u8 { let mut alpha = 0; - let ret = unsafe { sys::SDL_GetTextureAlphaMod(self.raw, &mut alpha) }; + let ret = unsafe { sys::render::SDL_GetTextureAlphaMod(self.raw, &mut alpha) }; // Should only fail on an invalid texture - if ret != 0 { + if !ret { panic!("{}", get_error()) } else { alpha @@ -1977,9 +1921,9 @@ impl InternalTexture { #[doc(alias = "SDL_SetTextureBlendMode")] pub fn set_blend_mode(&mut self, blend: BlendMode) { - let ret = unsafe { sys::SDL_SetTextureBlendMode(self.raw, transmute(blend as u32)) }; + let ret = unsafe { sys::render::SDL_SetTextureBlendMode(self.raw, transmute(blend as u32)) }; - if ret != 0 { + if !ret { panic!("Error setting blend: {}", get_error()) } } @@ -1987,10 +1931,10 @@ impl InternalTexture { #[doc(alias = "SDL_GetTextureBlendMode")] pub fn blend_mode(&self) -> BlendMode { let mut blend: MaybeUninit = mem::MaybeUninit::uninit(); - let ret = unsafe { sys::SDL_GetTextureBlendMode(self.raw, blend.as_mut_ptr()) }; + let ret = unsafe { sys::render::SDL_GetTextureBlendMode(self.raw, blend.as_mut_ptr()) }; // Should only fail on an invalid texture - if ret != 0 { + if !ret { panic!("{}", get_error()) } else { let blend = unsafe { blend.assume_init() }; @@ -2045,7 +1989,7 @@ impl InternalTexture { }; let result = unsafe { - sys::SDL_UpdateTexture( + sys::render::SDL_UpdateTexture( self.raw, rect_raw_ptr, pixel_data.as_ptr() as *const _, @@ -2172,7 +2116,7 @@ impl InternalTexture { }; let result = unsafe { - sys::SDL_UpdateYUVTexture( + sys::render::SDL_UpdateYUVTexture( self.raw, rect_raw_ptr, y_plane.as_ptr(), @@ -2207,7 +2151,7 @@ impl InternalTexture { None => (ptr::null(), q.height as usize), }; - let ret = sys::SDL_LockTexture(self.raw, rect_raw_ptr, &mut pixels, &mut pitch); + let ret = sys::render::SDL_LockTexture(self.raw, rect_raw_ptr, &mut pixels, &mut pitch); if ret == 0 { let size = q .format @@ -2226,7 +2170,7 @@ impl InternalTexture { let result; unsafe { result = func(interior, pitch as usize); - sys::SDL_UnlockTexture(self.raw); + sys::render::SDL_UnlockTexture(self.raw); } Ok(result) } @@ -2238,7 +2182,7 @@ impl InternalTexture { let mut texw = 0.0; let mut texh = 0.0; - if sys::SDL_GL_BindTexture(self.raw, &mut texw, &mut texh) == 0 { + if sys::render::SDL_GL_BindTexture(self.raw, &mut texw, &mut texh) == 0 { (texw, texh) } else { panic!("OpenGL texture binding not supported"); @@ -2246,7 +2190,7 @@ impl InternalTexture { } pub unsafe fn gl_unbind_texture(&mut self) { - if sys::SDL_GL_UnbindTexture(self.raw) != 0 { + if sys::render::SDL_GL_UnbindTexture(self.raw) != 0 { panic!("OpenGL texture unbinding not supported"); } } @@ -2257,10 +2201,10 @@ impl InternalTexture { let mut texw = 0.0; let mut texh = 0.0; - if sys::SDL_GL_BindTexture(self.raw, &mut texw, &mut texh) == 0 { + if sys::render::SDL_GL_BindTexture(self.raw, &mut texw, &mut texh) == 0 { let return_value = f(texw, texh); - if sys::SDL_GL_UnbindTexture(self.raw) == 0 { + if sys::render::SDL_GL_UnbindTexture(self.raw) == 0 { return_value } else { // This should never happen... @@ -2397,24 +2341,24 @@ impl<'r> Texture<'r> { // 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 const fn raw(&self) -> *mut sys::SDL_Texture { + pub const fn raw(&self) -> *mut sys::render::SDL_Texture { self.raw } /// A convenience function for [`TextureCreator::create_texture_from_surface`]. /// /// ```no_run - /// use sdl2::pixels::PixelFormatEnum; - /// use sdl2::surface::Surface; - /// use sdl2::render::{Canvas, Texture}; - /// use sdl2::video::Window; + /// use sdl3::pixels::PixelFormatEnum; + /// use sdl3::surface::Surface; + /// use sdl3::render::{Canvas, Texture}; + /// use sdl3::video::Window; /// /// // We init systems. - /// let sdl_context = sdl2::init().expect("failed to init SDL"); + /// let sdl_context = sdl3::init().expect("failed to init SDL"); /// let video_subsystem = sdl_context.video().expect("failed to get video context"); /// /// // We create a window. - /// let window = video_subsystem.window("sdl2 demo", 800, 600) + /// let window = video_subsystem.window("sdl3 demo", 800, 600) /// .build() /// .expect("failed to build window"); /// @@ -2438,17 +2382,17 @@ impl<'r> Texture<'r> { /// A convenience function for [`TextureCreator::create_texture_from_surface`]. /// /// ```no_run - /// use sdl2::pixels::PixelFormatEnum; - /// use sdl2::surface::Surface; - /// use sdl2::render::{Canvas, Texture}; - /// use sdl2::video::Window; + /// use sdl3::pixels::PixelFormatEnum; + /// use sdl3::surface::Surface; + /// use sdl3::render::{Canvas, Texture}; + /// use sdl3::video::Window; /// /// // We init systems. - /// let sdl_context = sdl2::init().expect("failed to init SDL"); + /// let sdl_context = sdl3::init().expect("failed to init SDL"); /// let video_subsystem = sdl_context.video().expect("failed to get video context"); /// /// // We create a window. - /// let window = video_subsystem.window("sdl2 demo", 800, 600) + /// let window = video_subsystem.window("sdl3 demo", 800, 600) /// .build() /// .expect("failed to build window"); /// @@ -2594,7 +2538,7 @@ impl Texture { // 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 const fn raw(&self) -> *mut sys::SDL_Texture { + pub const fn raw(&self) -> *mut sys::render::SDL_Texture { self.raw } } @@ -2614,7 +2558,7 @@ impl Iterator for DriverIterator { if self.index >= self.length { None } else { - let result = unsafe { sys::SDL_GetRenderDriver(self.index) }; + let result = unsafe { sys::render::SDL_GetRenderDriver(self.index) }; self.index += 1; Some( @@ -2643,7 +2587,7 @@ pub fn drivers() -> DriverIterator { // SDL_GetNumRenderDrivers can never return a negative value. DriverIterator { - length: unsafe { sys::SDL_GetNumRenderDrivers() }, + length: unsafe { sys::render::SDL_GetNumRenderDrivers() }, index: 0, } } From 0fde7bed641ff2cb0ac44ef5738105df4d7d3661 Mon Sep 17 00:00:00 2001 From: Mischa Spiegelmock Date: Sat, 19 Oct 2024 10:26:42 -0700 Subject: [PATCH 6/8] get rid of WindowCanvas because there are no more flags to SDL_CreateRenderer() --- examples/game-of-life-unsafe-textures.rs | 2 +- examples/game-of-life.rs | 121 +++++++++++------------ src/sdl3/render.rs | 87 +++++----------- src/sdl3/video.rs | 61 ++++++++---- 4 files changed, 126 insertions(+), 145 deletions(-) diff --git a/examples/game-of-life-unsafe-textures.rs b/examples/game-of-life-unsafe-textures.rs index cdff6bfb4d..795bc93091 100644 --- a/examples/game-of-life-unsafe-textures.rs +++ b/examples/game-of-life-unsafe-textures.rs @@ -230,7 +230,7 @@ pub fn main() -> Result<(), String> { .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. + // via hardware or software rendering. let mut canvas = window .into_canvas() .target_texture() diff --git a/examples/game-of-life.rs b/examples/game-of-life.rs index a0feedf737..3855a5e681 100644 --- a/examples/game-of-life.rs +++ b/examples/game-of-life.rs @@ -6,7 +6,7 @@ use sdl3::keyboard::Keycode; use sdl3::mouse::MouseButton; use sdl3::pixels::Color; use sdl3::rect::Point; -use sdl3::render::{Canvas, Texture, TextureCreator, FRect}; +use sdl3::render::{Canvas, FRect, Texture, TextureCreator}; use sdl3::video::{Window, WindowContext}; mod game_of_life { @@ -131,73 +131,72 @@ fn dummy_texture<'a>( (&mut square_texture1, TextureColor::Yellow), (&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"); } } - }); + } + }); } Ok((square_texture1, square_texture2)) } @@ -221,7 +220,7 @@ pub fn main() -> Result<(), String> { .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. + // via hardware or software rendering. let mut canvas = window .into_canvas() //.target_texture() //FIXME: Unclear how to migrate this to SDL3, cf: https://github.com/libsdl-org/SDL/issues/8059 diff --git a/src/sdl3/render.rs b/src/sdl3/render.rs index 05fefc1661..ab20ad916a 100644 --- a/src/sdl3/render.rs +++ b/src/sdl3/render.rs @@ -678,72 +678,35 @@ pub struct TextureCreator { default_pixel_format: PixelFormatEnum, } -/// The type that allows you to build Window-based renderers. -/// -/// By default, the renderer builder will prioritize for a hardware-accelerated -/// renderer, which is probably what you want. -pub struct CanvasBuilder { - window: Window, - renderer_name: Option, - renderer_flags: u32, -} - -impl CanvasBuilder { - /// Initializes a new `CanvasBuilder`. - pub fn new(window: Window) -> CanvasBuilder { - CanvasBuilder { - window, - // None means to initialize the first rendering driver supporting the - // renderer flags - renderer_name: None, - // no flags gives priority to available SDL_RENDERER_ACCELERATED - // renderers - renderer_flags: 0, - } - } - - /// Builds the renderer. - #[doc(alias = "SDL_CreateRenderer")] - pub fn build(self) -> Result { - use crate::common::IntegerOrSdlError::*; - let raw = unsafe { - sys::render::SDL_CreateRenderer( - self.window.raw(), - if self.renderer_name.is_none() { - std::ptr::null() - } else { - self.renderer_name.unwrap().as_ptr() as *const _ - }, - self.renderer_flags, - ) - }; - if raw.is_null() { - Err(SdlError(get_error())) - } else { - let context = Rc::new(unsafe { RendererContext::from_ll(raw, self.window.context()) }); - let default_pixel_format = self.window.window_pixel_format(); - Ok(Canvas { - context, - target: self.window, - default_pixel_format, - }) - } - } - /// Sets the rendering driver to initialize. - pub fn renderer_name(mut self, renderer_name: String) -> CanvasBuilder { - self.renderer_name = Some(renderer_name); - self - } +/// Create a new renderer for a window. +#[doc(alias = "SDL_CreateRenderer")] +pub fn create_renderer(window: Window, renderer_name: Option<&str>) + -> Result { + use crate::common::IntegerOrSdlError::*; + let raw = unsafe { + sys::render::SDL_CreateRenderer( + window.raw(), + if renderer_name.is_none() { + std::ptr::null() + } else { + renderer_name.unwrap().as_ptr() as *const _ + }, + ) + }; - /// Set the renderer to a software fallback. - /// This flag is accumulative, and may be specified with other flags. - pub fn software(mut self) -> CanvasBuilder { - self.renderer_name = Some(sys::render::SDL_SOFTWARE_RENDERER.into()); - self + if raw.is_null() { + Err(SdlError(get_error())) + } else { + let context = Rc::new(unsafe { RendererContext::from_ll(raw, window.context()) }); + let default_pixel_format = window.window_pixel_format(); + Ok(Canvas { + context, + target: window, + default_pixel_format, + }) } - } #[derive(Debug, Clone)] diff --git a/src/sdl3/video.rs b/src/sdl3/video.rs index be85f215d2..e720fcdac9 100644 --- a/src/sdl3/video.rs +++ b/src/sdl3/video.rs @@ -1,4 +1,12 @@ +use crate::common::{validate_int, IntegerOrSdlError}; +use crate::pixels::PixelFormatEnum; +use crate::rect::Rect; +use crate::render::create_renderer; +use crate::surface::SurfaceRef; +use crate::EventPump; +use crate::VideoSubsystem; use libc::{c_char, c_int, c_uint, c_void}; +use render::WindowCanvas; use std::convert::TryFrom; use std::error::Error; use std::ffi::{CStr, CString, NulError}; @@ -6,14 +14,6 @@ use std::ops::{Deref, DerefMut}; use std::rc::Rc; use std::{fmt, mem, ptr}; -use crate::common::{validate_int, IntegerOrSdlError}; -use crate::pixels::PixelFormatEnum; -use crate::rect::Rect; -use crate::render::CanvasBuilder; -use crate::surface::SurfaceRef; -use crate::EventPump; -use crate::VideoSubsystem; - use crate::get_error; use crate::sys; @@ -725,7 +725,12 @@ impl VideoSubsystem { } /// Initializes a new `PopupWindowBuilder`; a convenience method that calls `PopupWindowBuilder::new()`. - pub unsafe fn popup_window(&self, window: &Window, width: u32, height: u32) -> PopupWindowBuilder { + pub unsafe fn popup_window( + &self, + window: &Window, + width: u32, + height: u32, + ) -> PopupWindowBuilder { PopupWindowBuilder::new(self, window, width, height) } @@ -1296,7 +1301,12 @@ pub struct PopupWindowBuilder { impl PopupWindowBuilder { /// Initializes a new `PopupWindowBuilder`. - pub unsafe fn new(v: &VideoSubsystem, parent_window: &Window, width: u32, height: u32) -> PopupWindowBuilder { + pub unsafe fn new( + v: &VideoSubsystem, + parent_window: &Window, + width: u32, + height: u32, + ) -> PopupWindowBuilder { PopupWindowBuilder { parent_window: Window::from_ref(parent_window.context()), width, @@ -1319,11 +1329,19 @@ impl PopupWindowBuilder { if self.height >= (1 << 31) { return Err(HeightOverflows(self.width)); } - if (self.window_flags & sys::SDL_WindowFlags::SDL_WINDOW_TOOLTIP as u32 != 0) && (self.window_flags & sys::SDL_WindowFlags::SDL_WINDOW_POPUP_MENU as u32 != 0) { - return Err(SdlError("SDL_WINDOW_TOOLTIP and SDL_WINDOW_POPUP are mutually exclusive".to_owned())); + if (self.window_flags & sys::SDL_WindowFlags::SDL_WINDOW_TOOLTIP as u32 != 0) + && (self.window_flags & sys::SDL_WindowFlags::SDL_WINDOW_POPUP_MENU as u32 != 0) + { + return Err(SdlError( + "SDL_WINDOW_TOOLTIP and SDL_WINDOW_POPUP are mutually exclusive".to_owned(), + )); } - if (self.window_flags & sys::SDL_WindowFlags::SDL_WINDOW_TOOLTIP as u32 == 0) && (self.window_flags & sys::SDL_WindowFlags::SDL_WINDOW_POPUP_MENU as u32 == 0) { - return Err(SdlError("SDL_WINDOW_TOOLTIP or SDL_WINDOW_POPUP are required for popup windows".to_owned())); + if (self.window_flags & sys::SDL_WindowFlags::SDL_WINDOW_TOOLTIP as u32 == 0) + && (self.window_flags & sys::SDL_WindowFlags::SDL_WINDOW_POPUP_MENU as u32 == 0) + { + return Err(SdlError( + "SDL_WINDOW_TOOLTIP or SDL_WINDOW_POPUP are required for popup windows".to_owned(), + )); } let raw_width = self.width as c_int; @@ -1351,9 +1369,10 @@ impl PopupWindowBuilder { } } - /// Gets the underlying window flags. - pub fn window_flags(&self) -> u32 { self.window_flags } + pub fn window_flags(&self) -> u32 { + self.window_flags + } /// Sets the underlying window flags. /// This will effectively undo any previous build operations, excluding window size and position. @@ -1432,9 +1451,9 @@ impl PopupWindowBuilder { } } -impl From for CanvasBuilder { - fn from(window: Window) -> CanvasBuilder { - CanvasBuilder::new(window) +impl From for WindowCanvas { + fn from(window: Window) -> Result { + create_renderer(window, None) } } @@ -1468,8 +1487,8 @@ impl Window { &self.context.subsystem } - /// Initializes a new `CanvasBuilder`; a convenience method that calls `CanvasBuilder::new()`. - pub fn into_canvas(self) -> CanvasBuilder { + /// Initializes a new `WindowCanvas'; + pub fn into_canvas(self) -> WindowCanvas { self.into() } From ea1e70698adf52d2003ceaaceedefd8737ac9c16 Mon Sep 17 00:00:00 2001 From: Mischa Spiegelmock Date: Sat, 19 Oct 2024 10:27:26 -0700 Subject: [PATCH 7/8] fmt --- src/sdl3/render.rs | 90 +++++++++++++++++++++++++++------------------- 1 file changed, 53 insertions(+), 37 deletions(-) diff --git a/src/sdl3/render.rs b/src/sdl3/render.rs index ab20ad916a..b4ab11f614 100644 --- a/src/sdl3/render.rs +++ b/src/sdl3/render.rs @@ -128,10 +128,7 @@ impl FPoint { impl From for FPoint { fn from(point: Point) -> Self { - FPoint::new( - point.x as f32, - point.y as f32, - ) + FPoint::new(point.x as f32, point.y as f32) } } @@ -156,31 +153,26 @@ impl FRect { } } pub fn set_x(&mut self, update: f32) { - self.x = update; + self.x = update; } pub fn set_y(&mut self, update: f32) { - self.y = update; + self.y = update; } pub fn set_w(&mut self, update: f32) { - self.w = update; + self.w = update; } pub fn set_h(&mut self, update: f32) { - self.h = update; + self.h = update; } pub fn set_xy(&mut self, update: FPoint) { - self.x = update.x; - self.y = update.y; + self.x = update.x; + self.y = update.y; } } impl From for FRect { fn from(rect: Rect) -> Self { - FRect::new( - rect.x as f32, - rect.y as f32, - rect.w as f32, - rect.h as f32, - ) + FRect::new(rect.x as f32, rect.y as f32, rect.w as f32, rect.h as f32) } } @@ -289,7 +281,10 @@ impl RendererContext { } } - unsafe fn set_raw_target(&self, raw_texture: *mut sys::render::SDL_Texture) -> Result<(), SdlError> { + unsafe fn set_raw_target( + &self, + raw_texture: *mut sys::render::SDL_Texture, + ) -> Result<(), SdlError> { if sys::render::SDL_SetRenderTarget(self.raw, raw_texture) == true { Ok(()) } else { @@ -349,8 +344,7 @@ impl<'s> RenderTarget for Surface<'s> { /// let window = video_subsystem.window("Example", 800, 600).build().unwrap(); /// /// // Let's create a Canvas which we will use to draw in our Window -/// let mut canvas : Canvas = window.into_canvas() -/// .build().unwrap(); +/// let mut canvas : Canvas = window.into_canvas(); /// /// canvas.set_draw_color(Color::RGB(0, 0, 0)); /// // fills the canvas with the color we set in `set_draw_color`. @@ -678,12 +672,12 @@ pub struct TextureCreator { default_pixel_format: PixelFormatEnum, } - - /// Create a new renderer for a window. #[doc(alias = "SDL_CreateRenderer")] -pub fn create_renderer(window: Window, renderer_name: Option<&str>) - -> Result { +pub fn create_renderer( + window: Window, + renderer_name: Option<&str>, +) -> Result { use crate::common::IntegerOrSdlError::*; let raw = unsafe { sys::render::SDL_CreateRenderer( @@ -778,7 +772,9 @@ fn ll_create_texture( _ => (), }; - Ok(unsafe { sys::render::SDL_CreateTexture(context, pixel_format as u32, access as c_int, w, h) }) + Ok(unsafe { + sys::render::SDL_CreateTexture(context, pixel_format as u32, access as c_int, w, h) + }) } /// Texture-creating methods for the renderer @@ -903,8 +899,9 @@ impl TextureCreator { surface: S, ) -> Result { use self::TextureValueError::*; - let result = - unsafe { sys::render::SDL_CreateTextureFromSurface(self.context.raw, surface.as_ref().raw()) }; + let result = unsafe { + sys::render::SDL_CreateTextureFromSurface(self.context.raw, surface.as_ref().raw()) + }; if result.is_null() { Err(SdlError(get_error())) } else { @@ -967,8 +964,9 @@ impl Canvas { /// Sets the blend mode used for drawing operations (Fill and Line). #[doc(alias = "SDL_SetRenderDrawBlendMode")] pub fn set_blend_mode(&mut self, blend: BlendMode) { - let ret = - unsafe { sys::render::SDL_SetRenderDrawBlendMode(self.context.raw, transmute(blend as u32)) }; + let ret = unsafe { + sys::render::SDL_SetRenderDrawBlendMode(self.context.raw, transmute(blend as u32)) + }; // Should only fail on an invalid renderer if !ret { panic!("{}", get_error()) @@ -979,7 +977,9 @@ impl Canvas { #[doc(alias = "SDL_GetRenderDrawBlendMode")] pub fn blend_mode(&self) -> BlendMode { let mut blend: MaybeUninit = mem::MaybeUninit::uninit(); - let ret = unsafe { sys::render::SDL_GetRenderDrawBlendMode(self.context.raw, blend.as_mut_ptr()) }; + let ret = unsafe { + sys::render::SDL_GetRenderDrawBlendMode(self.context.raw, blend.as_mut_ptr()) + }; // Should only fail on an invalid renderer if !ret { panic!("{}", get_error()) @@ -1040,7 +1040,13 @@ impl Canvas { let width = validate_int(width, "width")?; let height = validate_int(height, "height")?; let result = unsafe { - sys::render::SDL_SetRenderLogicalPresentation(self.context.raw, width, height, mode, scale_mode) + sys::render::SDL_SetRenderLogicalPresentation( + self.context.raw, + width, + height, + mode, + scale_mode, + ) }; match result { 0 => Ok(()), @@ -1062,7 +1068,8 @@ impl Canvas { let mut height = 0; let mut mode: sys::render::SDL_RendererLogicalPresentation = sys::render::SDL_RendererLogicalPresentation::SDL_LOGICAL_PRESENTATION_DISABLED; - let mut scale_mode: sys::render::SDL_ScaleMode = sys::render::SDL_ScaleMode::SDL_SCALEMODE_BEST; + let mut scale_mode: sys::render::SDL_ScaleMode = + sys::render::SDL_ScaleMode::SDL_SCALEMODE_BEST; unsafe { sys::render::SDL_GetRenderLogicalPresentation( @@ -1190,8 +1197,9 @@ impl Canvas { ) -> Result<(), String> { let start = start.into(); let end = end.into(); - let result = - unsafe { sys::render::SDL_RenderLine(self.context.raw, start.x, start.y, end.x, end.y) }; + let result = unsafe { + sys::render::SDL_RenderLine(self.context.raw, start.x, start.y, end.x, end.y) + }; if result != 0 { Err(get_error()) } else { @@ -1550,8 +1558,9 @@ impl Canvas { surface: S, ) -> Result { use self::TextureValueError::*; - let result = - unsafe { sys::render::SDL_CreateTextureFromSurface(self.context.raw, surface.as_ref().raw()) }; + let result = unsafe { + sys::render::SDL_CreateTextureFromSurface(self.context.raw, surface.as_ref().raw()) + }; if result.is_null() { Err(SdlError(get_error())) } else { @@ -1823,7 +1832,13 @@ impl InternalTexture { let mut height = 0; let ret = unsafe { - sys::render::SDL_QueryTexture(self.raw, &mut format, &mut access, &mut width, &mut height) + sys::render::SDL_QueryTexture( + self.raw, + &mut format, + &mut access, + &mut width, + &mut height, + ) }; // Should only fail on an invalid texture if !ret { @@ -1884,7 +1899,8 @@ impl InternalTexture { #[doc(alias = "SDL_SetTextureBlendMode")] pub fn set_blend_mode(&mut self, blend: BlendMode) { - let ret = unsafe { sys::render::SDL_SetTextureBlendMode(self.raw, transmute(blend as u32)) }; + let ret = + unsafe { sys::render::SDL_SetTextureBlendMode(self.raw, transmute(blend as u32)) }; if !ret { panic!("Error setting blend: {}", get_error()) From 1dcab297e70930109f38019c09a835a1af3d1b4b Mon Sep 17 00:00:00 2001 From: Mischa Spiegelmock Date: Sat, 19 Oct 2024 11:08:19 -0700 Subject: [PATCH 8/8] renderer --- src/sdl3/rect.rs | 13 +- src/sdl3/render.rs | 333 +++++++++++++++++++++++++-------------------- 2 files changed, 194 insertions(+), 152 deletions(-) diff --git a/src/sdl3/rect.rs b/src/sdl3/rect.rs index 08f079a563..4ba930636a 100644 --- a/src/sdl3/rect.rs +++ b/src/sdl3/rect.rs @@ -1,6 +1,7 @@ //! Rectangles and points. use crate::sys; +use render::FRect; use std::convert::{AsMut, AsRef}; use std::hash::{Hash, Hasher}; use std::mem; @@ -514,7 +515,6 @@ impl Rect { let success = unsafe { sys::rect::SDL_GetRectIntersection(self.raw(), other.raw(), out.as_mut_ptr()) - }; if success { @@ -626,6 +626,17 @@ impl From for Rect { } } +impl Into> for Rect { + fn into(self) -> Option { + Some(FRect::new( + self.raw.x as f32, + self.raw.y as f32, + self.raw.w as f32, + self.raw.h as f32, + )) + } +} + impl From<(i32, i32, u32, u32)> for Rect { fn from((x, y, width, height): (i32, i32, u32, u32)) -> Rect { Rect::new(x, y, width, height) diff --git a/src/sdl3/render.rs b/src/sdl3/render.rs index b4ab11f614..85213a44c3 100644 --- a/src/sdl3/render.rs +++ b/src/sdl3/render.rs @@ -36,8 +36,10 @@ use crate::rect::Point; use crate::rect::Rect; use crate::surface; use crate::surface::{Surface, SurfaceContext, SurfaceRef}; +use crate::sys; +use crate::sys::render::SDL_BlendMode; +use crate::sys::render::SDL_TextureAccess; use crate::video::{Window, WindowContext}; -use libc::c_void; use libc::{c_double, c_int}; use std::convert::TryFrom; use std::error::Error; @@ -50,10 +52,10 @@ use std::mem::{transmute, MaybeUninit}; use std::ops::Deref; use std::ptr; use std::rc::Rc; - -use crate::sys; -use crate::sys::render::SDL_BlendMode; -use crate::sys::render::SDL_TextureAccess; +use sys::everything::SDL_PropertiesID; +use sys::render::SDL_GetTextureProperties; +use sys::stdinc::Sint64; +use sys::surface::{SDL_FLIP_HORIZONTAL, SDL_FLIP_NONE, SDL_FLIP_VERTICAL}; /// Contains the description of an error returned by SDL #[derive(Debug, Clone)] @@ -772,9 +774,11 @@ fn ll_create_texture( _ => (), }; - Ok(unsafe { - sys::render::SDL_CreateTexture(context, pixel_format as u32, access as c_int, w, h) - }) + Ok( + unsafe { + sys::render::SDL_CreateTexture(context, pixel_format.into(), access.into(), w, h) + }, + ) } /// Texture-creating methods for the renderer @@ -885,9 +889,7 @@ impl TextureCreator { /// .expect("failed to build window"); /// /// // We get the canvas from which we can get the `TextureCreator`. - /// let mut canvas: Canvas = window.into_canvas() - /// .build() - /// .expect("failed to build window's canvas"); + /// let mut canvas: Canvas = window.into_canvas(); /// let texture_creator = canvas.texture_creator(); /// /// let surface = Surface::new(512, 512, PixelFormatEnum::RGB24).unwrap(); @@ -1005,8 +1007,10 @@ impl Canvas { /// the screen, but rather updates the backbuffer. /// As such, you compose your entire scene and present the composed /// backbuffer to the screen as a complete picture. + /// + /// Returns `true` on success, or `false` on error. Call `get_error()` for more information. #[doc(alias = "SDL_RenderPresent")] - pub fn present(&mut self) -> i32 { + pub fn present(&mut self) -> bool { unsafe { sys::render::SDL_RenderPresent(self.context.raw) } } @@ -1020,7 +1024,7 @@ impl Canvas { sys::render::SDL_GetCurrentRenderOutputSize(self.context.raw, &mut width, &mut height) }; - if result == 0 { + if result { Ok((width as u32, height as u32)) } else { Err(get_error()) @@ -1034,42 +1038,26 @@ impl Canvas { width: u32, height: u32, mode: sys::render::SDL_RendererLogicalPresentation, - scale_mode: sys::render::SDL_ScaleMode, ) -> Result<(), IntegerOrSdlError> { use crate::common::IntegerOrSdlError::*; let width = validate_int(width, "width")?; let height = validate_int(height, "height")?; let result = unsafe { - sys::render::SDL_SetRenderLogicalPresentation( - self.context.raw, - width, - height, - mode, - scale_mode, - ) + sys::render::SDL_SetRenderLogicalPresentation(self.context.raw, width, height, mode) }; match result { - 0 => Ok(()), - _ => Err(SdlError(get_error())), + true => Ok(()), + false => Err(SdlError(get_error())), } } /// Gets device independent resolution for rendering. #[doc(alias = "SDL_GetRenderLogicalPresentation")] - pub fn logical_size( - &self, - ) -> ( - u32, - u32, - sys::render::SDL_RendererLogicalPresentation, - sys::render::SDL_ScaleMode, - ) { + pub fn logical_size(&self) -> (u32, u32, sys::render::SDL_RendererLogicalPresentation) { let mut width = 0; let mut height = 0; let mut mode: sys::render::SDL_RendererLogicalPresentation = sys::render::SDL_RendererLogicalPresentation::SDL_LOGICAL_PRESENTATION_DISABLED; - let mut scale_mode: sys::render::SDL_ScaleMode = - sys::render::SDL_ScaleMode::SDL_SCALEMODE_BEST; unsafe { sys::render::SDL_GetRenderLogicalPresentation( @@ -1077,11 +1065,10 @@ impl Canvas { &mut width, &mut height, &mut mode, - &mut scale_mode, ) }; - (width as u32, height as u32, mode, scale_mode) + (width as u32, height as u32, mode) } /// Sets the drawing area for rendering on the current target. @@ -1161,7 +1148,7 @@ impl Canvas { pub fn draw_point>(&mut self, point: P) -> Result<(), String> { let point = point.into(); let result = unsafe { sys::render::SDL_RenderPoint(self.context.raw, point.x, point.y) }; - if result != 0 { + if !result { Err(get_error()) } else { Ok(()) @@ -1180,7 +1167,7 @@ impl Canvas { points.len() as c_int, ) }; - if result != 0 { + if !result { Err(get_error()) } else { Ok(()) @@ -1200,7 +1187,7 @@ impl Canvas { let result = unsafe { sys::render::SDL_RenderLine(self.context.raw, start.x, start.y, end.x, end.y) }; - if result != 0 { + if !result { Err(get_error()) } else { Ok(()) @@ -1223,7 +1210,7 @@ impl Canvas { points.len() as c_int, ) }; - if result != 0 { + if !result { Err(get_error()) } else { Ok(()) @@ -1235,7 +1222,7 @@ impl Canvas { #[doc(alias = "SDL_RenderRect")] pub fn draw_rect(&mut self, rect: FRect) -> Result<(), String> { let result = unsafe { sys::render::SDL_RenderRect(self.context.raw, &rect.to_ll()) }; - if result != 0 { + if !result { Err(get_error()) } else { Ok(()) @@ -1253,7 +1240,7 @@ impl Canvas { rects.len() as c_int, ) }; - if result != 0 { + if !result { Err(get_error()) } else { Ok(()) @@ -1272,7 +1259,7 @@ impl Canvas { rect.into().map_or(ptr::null(), |r| &r.to_ll()), ) }; - if result != 0 { + if !result { Err(get_error()) } else { Ok(()) @@ -1291,7 +1278,7 @@ impl Canvas { rects.len() as c_int, ) }; - if result != 0 { + if !result { Err(get_error()) } else { Ok(()) @@ -1363,15 +1350,15 @@ impl Canvas { R2: Into>, P: Into>, { - use crate::sys::render::SDL_RendererFlip::*; + use crate::sys::surface::SDL_FlipMode::*; let flip = unsafe { match (flip_horizontal, flip_vertical) { (false, false) => SDL_FLIP_NONE, (true, false) => SDL_FLIP_HORIZONTAL, (false, true) => SDL_FLIP_VERTICAL, - (true, true) => transmute::( - transmute::(SDL_FLIP_HORIZONTAL) - | transmute::(SDL_FLIP_VERTICAL), + (true, true) => transmute::( + transmute::(SDL_FLIP_HORIZONTAL) + | transmute::(SDL_FLIP_VERTICAL), ), } }; @@ -1423,27 +1410,21 @@ impl Canvas { } }; - let pitch = w * format.byte_size_per_pixel(); // calculated pitch + let surface_ptr = sys::render::SDL_RenderReadPixels(self.context.raw, actual_rect); + if surface_ptr.is_null() { + return Err(get_error()); + } + + let surface = SurfaceRef::from_ll(surface_ptr); + let pitch = w * format.byte_size_per_pixel(); let size = format.byte_size_of_pixels(w * h); let mut pixels = Vec::with_capacity(size); pixels.set_len(size); - // Pass the interior of `pixels: Vec` to SDL - let ret = { - sys::render::SDL_RenderReadPixels( - self.context.raw, - actual_rect, - format as u32, - pixels.as_mut_ptr() as *mut c_void, - pitch as c_int, - ) - }; + std::ptr::copy_nonoverlapping(surface.pixels(), pixels.as_mut_ptr(), size); + sys::surface::SDL_DestroySurface(surface_ptr); - if ret == 0 { - Ok(pixels) - } else { - Err(get_error()) - } + Ok(pixels) } } @@ -1578,12 +1559,12 @@ impl Canvas { Texture { raw } } - #[doc(alias = "SDL_RenderFlush")] - pub unsafe fn render_flush(&self) { - let ret = sys::render::SDL_RenderFlush(self.context.raw); + #[doc(alias = "SDL_FlushRenderer")] + pub unsafe fn flush_renderer(&self) { + let ret = sys::render::SDL_FlushRenderer(self.context.raw); if !ret { - panic!("Error setting blend: {}", get_error()) + panic!("Error flushing renderer: {}", get_error()) } } } @@ -1824,32 +1805,50 @@ struct InternalTexture { } impl InternalTexture { - #[doc(alias = "SDL_QueryTexture")] - pub fn query(&self) -> TextureQuery { - let mut format = 0; - let mut access = 0; - let mut width = 0; - let mut height = 0; + #[doc(alias = "SDL_GetTextureProperties")] + pub fn get_properties(&self) -> SDL_PropertiesID { + unsafe { sys::render::SDL_GetTextureProperties(self.raw.into()) } + } - let ret = unsafe { - sys::render::SDL_QueryTexture( - self.raw, - &mut format, - &mut access, - &mut width, - &mut height, + pub fn get_format(&self) -> PixelFormatEnum { + let format = unsafe { + sys::properties::SDL_GetNumberProperty( + self.get_properties(), + sys::render::SDL_PROP_TEXTURE_FORMAT_NUMBER.into(), + 0, ) }; - // Should only fail on an invalid texture - if !ret { - panic!("{}", get_error()) - } else { - TextureQuery { - format: PixelFormatEnum::try_from(format as u32).unwrap(), - access: TextureAccess::try_from(access as u32).unwrap(), - width: width as u32, - height: height as u32, - } + PixelFormatEnum::from(format) + } + + pub fn get_access(&self) -> TextureAccess { + let access = unsafe { + sys::properties::SDL_GetNumberProperty( + self.get_properties(), + sys::render::SDL_PROP_TEXTURE_ACCESS_NUMBER.into(), + 0, + ) + }; + TextureAccess::from(access.into()) + } + + pub fn get_width(&self) -> u32 { + unsafe { + sys::properties::SDL_GetNumberProperty( + self.get_properties(), + sys::render::SDL_PROP_TEXTURE_WIDTH_NUMBER.into(), + 0, + ) as u32 + } + } + + pub fn get_height(&self) -> u32 { + unsafe { + sys::properties::SDL_GetNumberProperty( + self.get_properties(), + sys::render::SDL_PROP_TEXTURE_HEIGHT_NUMBER.into(), + 0, + ) as u32 } } @@ -2157,43 +2156,59 @@ impl InternalTexture { } } - pub unsafe fn gl_bind_texture(&mut self) -> (f32, f32) { - let mut texw = 0.0; - let mut texh = 0.0; - - if sys::render::SDL_GL_BindTexture(self.raw, &mut texw, &mut texh) == 0 { - (texw, texh) - } else { - panic!("OpenGL texture binding not supported"); - } - } - - pub unsafe fn gl_unbind_texture(&mut self) { - if sys::render::SDL_GL_UnbindTexture(self.raw) != 0 { - panic!("OpenGL texture unbinding not supported"); - } - } - - #[doc(alias = "SDL_GL_BindTexture")] - pub fn gl_with_bind R>(&mut self, f: F) -> R { + // not really sure about this! + unsafe fn get_gl_texture_id(&self) -> Sint64 { + let props_id = unsafe { SDL_GetTextureProperties(self.raw) }; unsafe { - let mut texw = 0.0; - let mut texh = 0.0; - - if sys::render::SDL_GL_BindTexture(self.raw, &mut texw, &mut texh) == 0 { - let return_value = f(texw, texh); - - if sys::render::SDL_GL_UnbindTexture(self.raw) == 0 { - return_value - } else { - // This should never happen... - panic!(); - } - } else { - panic!("OpenGL texture binding not supported"); - } + sys::properties::SDL_GetNumberProperty( + props_id, + sys::render::SDL_PROP_TEXTURE_OPENGL_TEXTURE_NUMBER.into(), + 0, + ) } } + + // removed: + // SDL_GL_BindTexture() - use SDL_GetTextureProperties() to get the OpenGL texture ID and bind the texture directly + // SDL_GL_UnbindTexture() - use SDL_GetTextureProperties() to get the OpenGL texture ID and unbind the texture directly + + // pub unsafe fn gl_bind_texture(&mut self) -> (f32, f32) { + // let mut texw = 0.0; + // let mut texh = 0.0; + // + // if sys::render::SDL_GL_BindTexture(self.raw, &mut texw, &mut texh) == 0 { + // (texw, texh) + // } else { + // panic!("OpenGL texture binding not supported"); + // } + // } + // + // pub unsafe fn gl_unbind_texture(&mut self) { + // if sys::render::SDL_GL_UnbindTexture(self.raw) != 0 { + // panic!("OpenGL texture unbinding not supported"); + // } + // } + + // #[doc(alias = "SDL_GL_BindTexture")] + // pub fn gl_with_bind R>(&mut self, f: F) -> R { + // unsafe { + // let mut texw = 0.0; + // let mut texh = 0.0; + // + // if sys::render::SDL_GL_BindTexture(self.raw, &mut texw, &mut texh) == 0 { + // let return_value = f(texw, texh); + // + // if sys::render::SDL_GL_UnbindTexture(self.raw) == 0 { + // return_value + // } else { + // // This should never happen... + // panic!(); + // } + // } else { + // panic!("OpenGL texture binding not supported"); + // } + // } + // } } #[cfg(not(feature = "unsafe_textures"))] @@ -2342,9 +2357,7 @@ impl<'r> Texture<'r> { /// .expect("failed to build window"); /// /// // We get the canvas from which we can get the `TextureCreator`. - /// let mut canvas: Canvas = window.into_canvas() - /// .build() - /// .expect("failed to build window's canvas"); + /// let mut canvas: Canvas = window.into_canvas(); /// let texture_creator = canvas.texture_creator(); /// /// let surface = Surface::new(512, 512, PixelFormatEnum::RGB24).unwrap(); @@ -2376,9 +2389,7 @@ impl<'r> Texture<'r> { /// .expect("failed to build window"); /// /// // We get the canvas from which we can get the `TextureCreator`. - /// let mut canvas: Canvas = window.into_canvas() - /// .build() - /// .expect("failed to build window's canvas"); + /// let mut canvas: Canvas = window.into_canvas(); /// let texture_creator = canvas.texture_creator(); /// /// let surface = Surface::new(512, 512, PixelFormatEnum::RGB24).unwrap(); @@ -2395,10 +2406,28 @@ impl<'r> Texture<'r> { #[cfg(feature = "unsafe_textures")] impl Texture { - /// Queries the attributes of the texture. + /// Get the format of the texture. #[inline] - pub fn query(&self) -> TextureQuery { - InternalTexture { raw: self.raw }.query() + pub fn format(&self) -> PixelFormatEnum { + InternalTexture { raw: self.raw }.get_format() + } + + /// Get the access of the texture. + #[inline] + pub fn access(&self) -> TextureAccess { + InternalTexture { raw: self.raw }.get_access() + } + + /// Get the width of the texture. + #[inline] + pub fn width(&self) -> u32 { + InternalTexture { raw: self.raw }.get_width() + } + + /// Get the height of the texture. + #[inline] + pub fn height(&self) -> u32 { + InternalTexture { raw: self.raw }.get_height() } /// Sets an additional color value multiplied into render copy operations. @@ -2494,24 +2523,26 @@ impl Texture { InternalTexture { raw: self.raw }.with_lock(rect, func) } - /// Binds an OpenGL/ES/ES2 texture to the current - /// context for use with when rendering OpenGL primitives directly. - #[inline] - pub unsafe fn gl_bind_texture(&mut self) -> (f32, f32) { - InternalTexture { raw: self.raw }.gl_bind_texture() - } - - /// Unbinds an OpenGL/ES/ES2 texture from the current context. - #[inline] - pub unsafe fn gl_unbind_texture(&mut self) { - InternalTexture { raw: self.raw }.gl_unbind_texture() - } - - /// Binds and unbinds an OpenGL/ES/ES2 texture from the current context. - #[inline] - pub fn gl_with_bind R>(&mut self, f: F) -> R { - InternalTexture { raw: self.raw }.gl_with_bind(f) - } + // these are not supplied by SDL anymore + // not sure if we should support them since we'd need to pull in OpenGL + // /// Binds an OpenGL/ES/ES2 texture to the current + // /// context for use with when rendering OpenGL primitives directly. + // #[inline] + // pub unsafe fn gl_bind_texture(&mut self) -> (f32, f32) { + // InternalTexture { raw: self.raw }.gl_bind_texture() + // } + // + // /// Unbinds an OpenGL/ES/ES2 texture from the current context. + // #[inline] + // pub unsafe fn gl_unbind_texture(&mut self) { + // InternalTexture { raw: self.raw }.gl_unbind_texture() + // } + // + // /// Binds and unbinds an OpenGL/ES/ES2 texture from the current context. + // #[inline] + // pub fn gl_with_bind R>(&mut self, f: F) -> R { + // InternalTexture { raw: self.raw }.gl_with_bind(f) + // } #[inline] // this can prevent introducing UB until