Browse Source

New doc changes and bump bitflags dependency

pull/134/head
Andrea Ciliberti 1 year ago
parent
commit
afc74fdf47
  1. 2
      ctru-rs/Cargo.toml
  2. 116
      ctru-rs/src/applets/mii_selector.rs
  3. 3
      ctru-rs/src/applets/mod.rs
  4. 6
      ctru-rs/src/applets/swkbd.rs
  5. 4
      ctru-rs/src/error.rs
  6. 4
      ctru-rs/src/lib.rs
  7. 6
      ctru-rs/src/services/fs.rs
  8. 13
      ctru-rs/src/services/gfx.rs
  9. 5
      ctru-rs/src/services/hid.rs

2
ctru-rs/Cargo.toml

@ -22,7 +22,7 @@ const-zero = "0.1.0"
shim-3ds = { git = "https://github.com/rust3ds/shim-3ds.git" } shim-3ds = { git = "https://github.com/rust3ds/shim-3ds.git" }
pthread-3ds = { git = "https://github.com/rust3ds/pthread-3ds.git" } pthread-3ds = { git = "https://github.com/rust3ds/pthread-3ds.git" }
libc = "0.2.121" libc = "0.2.121"
bitflags = "1.0.0" bitflags = "2.3.3"
widestring = "0.2.2" widestring = "0.2.2"
[build-dependencies] [build-dependencies]

116
ctru-rs/src/applets/mii_selector.rs

@ -1,11 +1,11 @@
//! Mii Selector applet. //! Mii Selector applet.
//! //!
//! This applet opens a window on the console's bottom screen which lets the player/user choose a Mii from the ones present on their console. //! This applet opens a window on the console's bottom screen which lets the player/user choose a Mii from the ones present on their console.
//! The application can access the selected Mii's data via the use of the [`mii`](crate::mii) module. //! The selected Mii is readable as a [`MiiData`](crate::mii::MiiData).
use crate::mii::MiiData; use crate::mii::MiiData;
use bitflags::bitflags; use bitflags::bitflags;
use std::ffi::CString; use std::{ffi::CString, error::Error, fmt};
/// Index of a Mii used to configure some parameters of the Mii Selector. /// Index of a Mii used to configure some parameters of the Mii Selector.
#[derive(Debug, Clone, Copy, Eq, PartialEq)] #[derive(Debug, Clone, Copy, Eq, PartialEq)]
@ -16,7 +16,7 @@ pub enum Index {
All, All,
} }
/// The type of a Mii with their respective data /// The type of a Mii.
#[derive(Debug, Clone, Eq, PartialEq)] #[derive(Debug, Clone, Eq, PartialEq)]
pub enum MiiType { pub enum MiiType {
/// Guest Mii. /// Guest Mii.
@ -31,29 +31,56 @@ pub enum MiiType {
} }
bitflags! { bitflags! {
/// Options for the Mii Selector /// Options to configure the [MiiSelector].
///
/// <h1>Example</h1>
///
/// ```no_run
/// # use std::error::Error;
/// # fn main() -> Result<(), Box<dyn Error>> {
/// #
/// use ctru::applets::mii_selector::{MiiSelector, Options};
///
/// // Setup a `MiiSelector` that can be cancelled and that makes Guest Miis available to select.
/// let opts = Options::ENABLE_CANCEL & Options::ENABLE_GUESTS;
///
/// let mut mii_selector = MiiSelector::new();
/// mii_selector.set_options(opts);
///
/// let result = mii_selector.launch()?;
/// #
/// # Ok(())
/// # }
/// ```
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)]
pub struct Options: u32 { pub struct Options: u32 {
/// Show the cancel button /// Show the cancel button.
const MII_SELECTOR_CANCEL = ctru_sys::MIISELECTOR_CANCEL; const ENABLE_CANCEL = ctru_sys::MIISELECTOR_CANCEL;
/// Make guest Miis selectable /// Make guest Miis available to select.
const MII_SELECTOR_GUESTS = ctru_sys::MIISELECTOR_GUESTS; const ENABLE_GUESTS = ctru_sys::MIISELECTOR_GUESTS;
/// Show on the top screen /// Show on the top screen.
const MII_SELECTOR_TOP = ctru_sys::MIISELECTOR_TOP; const USE_TOP_SCREEN = ctru_sys::MIISELECTOR_TOP;
/// Start on the guest's page /// Start on the guests' page. Requires [Options::ENABLE_GUESTS].
const MII_SELECTOR_GUEST_START = ctru_sys::MIISELECTOR_GUESTSTART; const START_WITH_GUESTS = ctru_sys::MIISELECTOR_GUESTSTART;
} }
} }
/// An instance of the Mii Selector /// Configuration object to setup the Mii Selector applet.
/// ///
/// # Example /// # Example
/// ``` /// ```no_run
/// # use std::error::Error;
/// # fn main() -> Result<(), Box<dyn Error>> {
/// #
/// use ctru::applets::mii_selector::MiiSelector; /// use ctru::applets::mii_selector::MiiSelector;
/// ///
/// let mut mii_selector = MiiSelector::new(); /// let mut mii_selector = MiiSelector::new();
/// mii_selector.set_title("Example Mii selector"); /// mii_selector.set_title("Example Mii Selector");
/// ///
/// let result = mii_selector.launch().unwrap(); /// let result = mii_selector.launch()?;
/// #
/// # Ok(())
/// # }
/// ``` /// ```
#[doc(alias = "MiiSelectorConf")] #[doc(alias = "MiiSelectorConf")]
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
@ -61,27 +88,27 @@ pub struct MiiSelector {
config: Box<ctru_sys::MiiSelectorConf>, config: Box<ctru_sys::MiiSelectorConf>,
} }
/// Return value from a MiiSelector's launch /// Return value of a successful [MiiSelector::launch()].
#[non_exhaustive] #[non_exhaustive]
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct SelectionResult { pub struct Selection {
/// Data regarding the selected Mii. /// Data of the selected Mii.
pub mii_data: MiiData, pub mii_data: MiiData,
/// Type of the selected Mii. /// Type of the selected Mii.
pub mii_type: MiiType, pub mii_type: MiiType,
} }
/// Error type for the Mii selector /// Error returned by an unsuccessful [MiiSelector::launch()].
#[derive(Copy, Clone, Debug, Eq, PartialEq)] #[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum LaunchError { pub enum LaunchError {
/// The selected Mii's data is corrupt in some way /// The selected Mii's data is corrupt in some way.
InvalidChecksum, InvalidChecksum,
/// Either the user cancelled the selection (see [Options::MII_SELECTOR_CANCEL]), or no valid Miis were available to select /// Either the user cancelled the selection (see [Options::ENABLE_CANCEL]), or no valid Miis were available to select.
NoMiiSelected, NoMiiSelected,
} }
impl MiiSelector { impl MiiSelector {
/// Initializes a Mii Selector /// Initialize a new configuration for the Mii Selector applet.
#[doc(alias = "miiSelectorInit")] #[doc(alias = "miiSelectorInit")]
pub fn new() -> Self { pub fn new() -> Self {
let mut config = Box::<ctru_sys::MiiSelectorConf>::default(); let mut config = Box::<ctru_sys::MiiSelectorConf>::default();
@ -91,9 +118,9 @@ impl MiiSelector {
Self { config } Self { config }
} }
/// Set the title of the Mii Selector. /// Set the title of the Mii Selector window.
/// ///
/// This function would panic if the given ``&str`` contains NUL bytes. /// This function will panic if the given `&str` contains NUL bytes.
#[doc(alias = "miiSelectorSetTitle")] #[doc(alias = "miiSelectorSetTitle")]
pub fn set_title(&mut self, text: &str) { pub fn set_title(&mut self, text: &str) {
// This can only fail if the text contains NUL bytes in the string... which seems // This can only fail if the text contains NUL bytes in the string... which seems
@ -104,13 +131,15 @@ impl MiiSelector {
} }
} }
/// Set the options of the Mii Selector /// Set the options of the Mii Selector.
///
/// This will overwrite any previously saved options.
#[doc(alias = "miiSelectorSetOptions")] #[doc(alias = "miiSelectorSetOptions")]
pub fn set_options(&mut self, options: Options) { pub fn set_options(&mut self, options: Options) {
unsafe { ctru_sys::miiSelectorSetOptions(self.config.as_mut(), options.bits) } unsafe { ctru_sys::miiSelectorSetOptions(self.config.as_mut(), options.bits()) }
} }
/// Whitelist a guest Mii /// Whitelist a guest Mii based on its index.
#[doc(alias = "miiSelectorWhitelistGuestMii")] #[doc(alias = "miiSelectorWhitelistGuestMii")]
pub fn whitelist_guest_mii(&mut self, mii_index: Index) { pub fn whitelist_guest_mii(&mut self, mii_index: Index) {
let index = match mii_index { let index = match mii_index {
@ -121,7 +150,7 @@ impl MiiSelector {
unsafe { ctru_sys::miiSelectorWhitelistGuestMii(self.config.as_mut(), index) } unsafe { ctru_sys::miiSelectorWhitelistGuestMii(self.config.as_mut(), index) }
} }
/// Blacklist a guest Mii /// Blacklist a guest Mii based on its index.
#[doc(alias = "miiSelectorBlacklistGuestMii")] #[doc(alias = "miiSelectorBlacklistGuestMii")]
pub fn blacklist_guest_mii(&mut self, mii_index: Index) { pub fn blacklist_guest_mii(&mut self, mii_index: Index) {
let index = match mii_index { let index = match mii_index {
@ -132,7 +161,7 @@ impl MiiSelector {
unsafe { ctru_sys::miiSelectorBlacklistGuestMii(self.config.as_mut(), index) } unsafe { ctru_sys::miiSelectorBlacklistGuestMii(self.config.as_mut(), index) }
} }
/// Whitelist a user Mii /// Whitelist a user Mii based on its index.
#[doc(alias = "miiSelectorWhitelistUserMii")] #[doc(alias = "miiSelectorWhitelistUserMii")]
pub fn whitelist_user_mii(&mut self, mii_index: Index) { pub fn whitelist_user_mii(&mut self, mii_index: Index) {
let index = match mii_index { let index = match mii_index {
@ -143,7 +172,7 @@ impl MiiSelector {
unsafe { ctru_sys::miiSelectorWhitelistUserMii(self.config.as_mut(), index) } unsafe { ctru_sys::miiSelectorWhitelistUserMii(self.config.as_mut(), index) }
} }
/// Blacklist a user Mii /// Blacklist a user Mii based on its index.
#[doc(alias = "miiSelectorBlacklistUserMii")] #[doc(alias = "miiSelectorBlacklistUserMii")]
pub fn blacklist_user_mii(&mut self, mii_index: Index) { pub fn blacklist_user_mii(&mut self, mii_index: Index) {
let index = match mii_index { let index = match mii_index {
@ -154,8 +183,9 @@ impl MiiSelector {
unsafe { ctru_sys::miiSelectorBlacklistUserMii(self.config.as_mut(), index) } unsafe { ctru_sys::miiSelectorBlacklistUserMii(self.config.as_mut(), index) }
} }
/// Set where the cursor will be. /// Set where the cursor will start at.
/// If there's no Mii at that index, the cursor will start at the Mii with the index 0 ///
/// If there's no Mii at that index, the cursor will start at the Mii with the index 0.
pub fn set_initial_index(&mut self, index: usize) { pub fn set_initial_index(&mut self, index: usize) {
// This function is static inline in libctru // This function is static inline in libctru
// https://github.com/devkitPro/libctru/blob/af5321c78ee5c72a55b526fd2ed0d95ca1c05af9/libctru/include/3ds/applets/miiselector.h#L155 // https://github.com/devkitPro/libctru/blob/af5321c78ee5c72a55b526fd2ed0d95ca1c05af9/libctru/include/3ds/applets/miiselector.h#L155
@ -163,9 +193,10 @@ impl MiiSelector {
} }
/// Launch the Mii Selector. /// Launch the Mii Selector.
/// Returns an error when the checksum of the Mii is invalid. ///
/// Depending on the configuration, the Mii Selector window will appear either on the bottom screen (default behaviour) or the top screen (see [Options::USE_TOP_SCREEN]).
#[doc(alias = "miiSelectorLaunch")] #[doc(alias = "miiSelectorLaunch")]
pub fn launch(&mut self) -> Result<SelectionResult, LaunchError> { pub fn launch(&mut self) -> Result<Selection, LaunchError> {
let mut return_val = Box::<ctru_sys::MiiSelectorReturn>::default(); let mut return_val = Box::<ctru_sys::MiiSelectorReturn>::default();
unsafe { ctru_sys::miiSelectorLaunch(self.config.as_mut(), return_val.as_mut()) } unsafe { ctru_sys::miiSelectorLaunch(self.config.as_mut(), return_val.as_mut()) }
@ -187,12 +218,23 @@ impl Default for MiiSelector {
} }
} }
impl From<ctru_sys::MiiSelectorReturn> for SelectionResult { impl fmt::Display for LaunchError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::InvalidChecksum => write!(f, "selected mii has invalid checksum"),
Self::NoMiiSelected => write!(f, "no mii was selected"),
}
}
}
impl Error for LaunchError {}
impl From<ctru_sys::MiiSelectorReturn> for Selection {
fn from(ret: ctru_sys::MiiSelectorReturn) -> Self { fn from(ret: ctru_sys::MiiSelectorReturn) -> Self {
let raw_mii_data = ret.mii; let raw_mii_data = ret.mii;
let mut guest_mii_name = ret.guest_mii_name; let mut guest_mii_name = ret.guest_mii_name;
SelectionResult { Selection {
mii_data: raw_mii_data.into(), mii_data: raw_mii_data.into(),
mii_type: if ret.guest_mii_index != 0xFFFFFFFF { mii_type: if ret.guest_mii_index != 0xFFFFFFFF {
MiiType::Guest { MiiType::Guest {

3
ctru-rs/src/applets/mod.rs

@ -2,6 +2,9 @@
//! //!
//! Applets are small integrated programs that the OS makes available to the developer to streamline commonly needed functionality. //! Applets are small integrated programs that the OS makes available to the developer to streamline commonly needed functionality.
//! Thanks to these integrations the developer can avoid wasting time re-implementing common features and instead use a more reliable base for their application. //! Thanks to these integrations the developer can avoid wasting time re-implementing common features and instead use a more reliable base for their application.
//!
//! Unlike [services](crate::services), applets aren't accessed via a system subprocess (which would require obtaining a special handle at runtime).
//! Instead, the user builds a configuration storing the various parameters which is then used to "launch" the applet.
pub mod mii_selector; pub mod mii_selector;
pub mod swkbd; pub mod swkbd;

6
ctru-rs/src/applets/swkbd.rs

@ -89,6 +89,7 @@ pub enum ValidInput {
bitflags! { bitflags! {
/// Keyboard feature flags. /// Keyboard feature flags.
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)]
pub struct Features: u32 { pub struct Features: u32 {
/// Parental PIN mode. /// Parental PIN mode.
const PARENTAL_PIN = ctru_sys::SWKBD_PARENTAL; const PARENTAL_PIN = ctru_sys::SWKBD_PARENTAL;
@ -111,6 +112,7 @@ bitflags! {
} }
/// Keyboard input filtering flags /// Keyboard input filtering flags
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)]
pub struct Filters: u32 { pub struct Filters: u32 {
/// Disallows the usage of numerical digits. /// Disallows the usage of numerical digits.
const DIGITS = ctru_sys::SWKBD_FILTER_DIGITS; const DIGITS = ctru_sys::SWKBD_FILTER_DIGITS;
@ -183,13 +185,13 @@ impl Swkbd {
/// Sets special features for this keyboard /// Sets special features for this keyboard
#[doc(alias = "swkbdSetFeatures")] #[doc(alias = "swkbdSetFeatures")]
pub fn set_features(&mut self, features: Features) { pub fn set_features(&mut self, features: Features) {
unsafe { swkbdSetFeatures(self.state.as_mut(), features.bits) } unsafe { swkbdSetFeatures(self.state.as_mut(), features.bits()) }
} }
/// Configures input validation for this keyboard /// Configures input validation for this keyboard
pub fn set_validation(&mut self, validation: ValidInput, filters: Filters) { pub fn set_validation(&mut self, validation: ValidInput, filters: Filters) {
self.state.valid_input = validation.into(); self.state.valid_input = validation.into();
self.state.filter_flags = filters.bits; self.state.filter_flags = filters.bits();
} }
/// Configures the maximum number of digits that can be entered in the keyboard when the /// Configures the maximum number of digits that can be entered in the keyboard when the

4
ctru-rs/src/error.rs

@ -21,7 +21,9 @@ pub type Result<T> = ::std::result::Result<T, Error>;
/// # Example /// # Example
/// ///
/// ```no_run /// ```no_run
/// pub fn hid_init() -> crate::Result<()> { /// use ctru::error::{Result, ResultCode};
///
/// pub fn hid_init() -> Result<()> {
/// // We run an unsafe function which returns a `ctru_sys::Result`. /// // We run an unsafe function which returns a `ctru_sys::Result`.
/// let result: ctru_sys::Result = unsafe { ctru_sys::hidInit() }; /// let result: ctru_sys::Result = unsafe { ctru_sys::hidInit() };
/// ///

4
ctru-rs/src/lib.rs

@ -14,10 +14,6 @@
//! Read thoroughly the official [`ctru-rs` wiki](https://github.com/rust3ds/ctru-rs/wiki) which guides you through the setup needed to install the required toolchain and helpful tools. //! Read thoroughly the official [`ctru-rs` wiki](https://github.com/rust3ds/ctru-rs/wiki) which guides you through the setup needed to install the required toolchain and helpful tools.
//! After following the guide and understanding the many quirks of the Nintendo 3DS homebrew development environment, you can create a new project by including this crate as a dependency //! After following the guide and understanding the many quirks of the Nintendo 3DS homebrew development environment, you can create a new project by including this crate as a dependency
//! of your project in your `Cargo.toml` manifest and build your binaries either manually (for the `armv6k-nintendo-3ds` target) or via [`cargo-3ds`](https://github.com/rust3ds/cargo-3ds). //! of your project in your `Cargo.toml` manifest and build your binaries either manually (for the `armv6k-nintendo-3ds` target) or via [`cargo-3ds`](https://github.com/rust3ds/cargo-3ds).
//!
//! # Examples
//!
//! You can check out the examples provided with this crate which dive into most of the implemented functionality.
#![crate_type = "rlib"] #![crate_type = "rlib"]
#![crate_name = "ctru"] #![crate_name = "ctru"]

6
ctru-rs/src/services/fs.rs

@ -17,20 +17,20 @@ use std::sync::Arc;
use widestring::{WideCStr, WideCString}; use widestring::{WideCStr, WideCString};
bitflags! { bitflags! {
#[derive(Default)] #[derive(Default, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)]
struct FsOpen: u32 { struct FsOpen: u32 {
const FS_OPEN_READ = 1; const FS_OPEN_READ = 1;
const FS_OPEN_WRITE = 2; const FS_OPEN_WRITE = 2;
const FS_OPEN_CREATE = 4; const FS_OPEN_CREATE = 4;
} }
#[derive(Default)] #[derive(Default, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)]
struct FsWrite: u32 { struct FsWrite: u32 {
const FS_WRITE_FLUSH = 1; const FS_WRITE_FLUSH = 1;
const FS_WRITE_UPDATE_TIME = 256; const FS_WRITE_UPDATE_TIME = 256;
} }
#[derive(Default)] #[derive(Default, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)]
struct FsAttribute: u32 { struct FsAttribute: u32 {
const FS_ATTRIBUTE_DIRECTORY = 1; const FS_ATTRIBUTE_DIRECTORY = 1;
const FS_ATTRIBUTE_HIDDEN = 256; const FS_ATTRIBUTE_HIDDEN = 256;

13
ctru-rs/src/services/gfx.rs

@ -222,8 +222,17 @@ impl Gfx {
/// Creates a new [`Gfx`] instance with default init values /// Creates a new [`Gfx`] instance with default init values
/// It's the same as calling: /// It's the same as calling:
/// ///
/// ``` /// ```no_run
/// Gfx::with_formats(FramebufferFormat::Bgr8, FramebufferFormat::Bgr8, false) /// # use std::error::Error;
/// # fn main() -> Result<(), Box<dyn Error>> {
/// #
/// # use ctru::services::gfx::Gfx;
/// use ctru::services::gspgpu::FramebufferFormat;
///
/// Gfx::with_formats(FramebufferFormat::Bgr8, FramebufferFormat::Bgr8, false);
/// #
/// # Ok(())
/// # }
/// ``` /// ```
#[doc(alias = "gfxInit")] #[doc(alias = "gfxInit")]
pub fn new() -> Result<Self> { pub fn new() -> Result<Self> {

5
ctru-rs/src/services/hid.rs

@ -5,9 +5,12 @@
//! the accelerometer, and the gyroscope. //! the accelerometer, and the gyroscope.
use crate::error::ResultCode; use crate::error::ResultCode;
bitflags::bitflags! { use bitflags::bitflags;
bitflags! {
/// A set of flags corresponding to the button and directional pad /// A set of flags corresponding to the button and directional pad
/// inputs on the 3DS /// inputs on the 3DS
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)]
pub struct KeyPad: u32 { pub struct KeyPad: u32 {
/// A button. /// A button.
const A = ctru_sys::KEY_A; const A = ctru_sys::KEY_A;

Loading…
Cancel
Save