Steve Cook
2 years ago
3 changed files with 247 additions and 0 deletions
@ -0,0 +1,34 @@
@@ -0,0 +1,34 @@
|
||||
use ctru::console::Console; |
||||
use ctru::gfx::Gfx; |
||||
use ctru::services::apt::Apt; |
||||
use ctru::services::hid::{Hid, KeyPad}; |
||||
use ctru::services::cfgu::Cfgu; |
||||
|
||||
fn main() { |
||||
ctru::init(); |
||||
let gfx = Gfx::init().expect("Couldn't obtain GFX controller"); |
||||
let hid = Hid::init().expect("Couldn't obtain HID controller"); |
||||
let apt = Apt::init().expect("Couldn't obtain APT controller"); |
||||
let cfgu = Cfgu::init().expect("Couldn't obtain CFGU controller"); |
||||
let _console = Console::init(gfx.top_screen.borrow_mut()); |
||||
|
||||
println!("\x1b[0;0H{}", format!("Region: {:?}", cfgu.get_region().unwrap())); |
||||
println!("\x1b[10;0H{}", format!("Language: {:?}", cfgu.get_language().unwrap())); |
||||
println!("\x1b[20;0H{}", format!("Model: {:?}", cfgu.get_model().unwrap())); |
||||
|
||||
// Main loop
|
||||
while apt.main_loop() { |
||||
//Scan all the inputs. This should be done once for each frame
|
||||
hid.scan_input(); |
||||
|
||||
if hid.keys_down().contains(KeyPad::KEY_START) { |
||||
break; |
||||
} |
||||
// Flush and swap framebuffers
|
||||
gfx.flush_buffers(); |
||||
gfx.swap_buffers(); |
||||
|
||||
//Wait for VBlank
|
||||
gfx.wait_for_vblank(); |
||||
} |
||||
} |
@ -0,0 +1,212 @@
@@ -0,0 +1,212 @@
|
||||
//! Configuration service
|
||||
//!
|
||||
//! This module contains basic methods to retrieve and change configuration from the console.
|
||||
|
||||
#[derive(Copy, Clone, Debug)] |
||||
#[repr(u32)] |
||||
pub enum Region { |
||||
Japan = ctru_sys::CFG_REGION_JPN, |
||||
USA = ctru_sys::CFG_REGION_USA, |
||||
Europe = ctru_sys::CFG_REGION_EUR, |
||||
Australia = ctru_sys::CFG_REGION_AUS, |
||||
China = ctru_sys::CFG_REGION_CHN, |
||||
Korea = ctru_sys::CFG_REGION_KOR, |
||||
Taiwan = ctru_sys::CFG_REGION_TWN, |
||||
} |
||||
|
||||
#[derive(Copy, Clone, Debug)] |
||||
#[repr(u32)] |
||||
pub enum Language { |
||||
Japanese = ctru_sys::CFG_LANGUAGE_JP, |
||||
English = ctru_sys::CFG_LANGUAGE_EN, |
||||
French = ctru_sys::CFG_LANGUAGE_FR, |
||||
German = ctru_sys::CFG_LANGUAGE_DE, |
||||
Italian = ctru_sys::CFG_LANGUAGE_IT, |
||||
Spanish = ctru_sys::CFG_LANGUAGE_ES, |
||||
SimplifiedChinese = ctru_sys::CFG_LANGUAGE_ZH, |
||||
Korean = ctru_sys::CFG_LANGUAGE_KO, |
||||
Dutch = ctru_sys::CFG_LANGUAGE_NL, |
||||
Portuguese = ctru_sys::CFG_LANGUAGE_PT, |
||||
Russian = ctru_sys::CFG_LANGUAGE_RU, |
||||
TraditionalChinese = ctru_sys::CFG_LANGUAGE_TW, |
||||
} |
||||
|
||||
#[derive(Copy, Clone, Debug)] |
||||
#[repr(u32)] |
||||
pub enum SystemModel { |
||||
Model3DS = ctru_sys::CFG_MODEL_3DS, |
||||
Model3DSXL = ctru_sys::CFG_MODEL_3DSXL, |
||||
ModelNew3DS = ctru_sys::CFG_MODEL_N3DS, |
||||
Model2DS = ctru_sys::CFG_MODEL_2DS, |
||||
ModelNew3DSXL = ctru_sys::CFG_MODEL_N3DSXL, |
||||
ModelNew2DSXL = ctru_sys::CFG_MODEL_N2DSXL, |
||||
} |
||||
|
||||
/// Represents the configuration service. No actions can be performed
|
||||
/// until an instance of this struct is created.
|
||||
///
|
||||
/// The service exits when all instances of this struct go out of scope.
|
||||
pub struct Cfgu(()); |
||||
|
||||
impl Cfgu { |
||||
/// Initializes the CFGU service.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// This function will return Err if there was an error initializing the
|
||||
/// CFGU service.
|
||||
///
|
||||
/// ctrulib services are reference counted, so this function may be called
|
||||
/// as many times as desired and the service will not exit until all
|
||||
/// instances of Cfgu drop out of scope.
|
||||
pub fn init() -> crate::Result<Cfgu> { |
||||
unsafe { |
||||
let r = ctru_sys::cfguInit(); |
||||
if r < 0 { |
||||
Err(r.into()) |
||||
} else { |
||||
Ok(Cfgu(())) |
||||
} |
||||
} |
||||
} |
||||
|
||||
/// Gets system region from secure info
|
||||
pub fn get_region(&self) -> crate::Result<Region> { |
||||
let mut region: u8 = 0; |
||||
|
||||
let r = unsafe { ctru_sys::CFGU_SecureInfoGetRegion(&mut region) }; |
||||
if r < 0 { |
||||
Err(r.into()) |
||||
} else { |
||||
// The system shouldn't give an invalid value
|
||||
Ok(Region::try_from(region).unwrap()) |
||||
} |
||||
} |
||||
|
||||
/// Gets system's model
|
||||
pub fn get_model(&self) -> crate::Result<SystemModel> { |
||||
let mut model: u8 = 0; |
||||
|
||||
let r = unsafe { ctru_sys::CFGU_GetSystemModel(&mut model) }; |
||||
if r < 0 { |
||||
Err(r.into()) |
||||
} else { |
||||
// The system shouldn't give an invalid value
|
||||
Ok(SystemModel::try_from(model).unwrap()) |
||||
} |
||||
} |
||||
|
||||
/// Gets system's language
|
||||
pub fn get_language(&self) -> crate::Result<Language> { |
||||
let mut language: u8 = 0; |
||||
|
||||
let r = unsafe { ctru_sys::CFGU_GetSystemLanguage(&mut language) }; |
||||
if r < 0 { |
||||
Err(r.into()) |
||||
} else { |
||||
// The system shouldn't give an invalid value
|
||||
Ok(Language::try_from(language).unwrap()) |
||||
} |
||||
} |
||||
|
||||
/// Checks if NFC is supported by the console
|
||||
pub fn is_nfc_supported(&self) -> crate::Result<bool> { |
||||
let mut supported: bool = false; |
||||
|
||||
let r = unsafe { ctru_sys::CFGU_IsNFCSupported(&mut supported) }; |
||||
if r < 0 { |
||||
Err(r.into()) |
||||
} else { |
||||
Ok(supported) |
||||
} |
||||
} |
||||
|
||||
/// Check if the console is from the 2DS family (2DS, New2DS, New2DSXL)
|
||||
pub fn is_2ds_family(&self) -> crate::Result<bool> { |
||||
let mut is_2ds_family: u8 = 0; |
||||
|
||||
let r = unsafe { ctru_sys::CFGU_GetModelNintendo2DS(&mut is_2ds_family) }; |
||||
if r < 0 { |
||||
Err(r.into()) |
||||
} else { |
||||
Ok(is_2ds_family == 0) |
||||
} |
||||
} |
||||
} |
||||
|
||||
impl Drop for Cfgu { |
||||
fn drop(&mut self) { |
||||
unsafe { |
||||
ctru_sys::cfguExit(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
macro_rules! from_type_to_u8 { |
||||
($from_type:ty) => { |
||||
impl From<$from_type> for u8 { |
||||
fn from(v: $from_type) -> Self { |
||||
v as u8 |
||||
} |
||||
} |
||||
}; |
||||
} |
||||
|
||||
from_type_to_u8!(Region); |
||||
from_type_to_u8!(Language); |
||||
from_type_to_u8!(SystemModel); |
||||
|
||||
impl TryFrom<u8> for Region { |
||||
type Error = (); |
||||
|
||||
fn try_from(value: u8) -> Result<Self, Self::Error> { |
||||
match value as u32 { |
||||
ctru_sys::CFG_REGION_JPN => Ok(Region::Japan), |
||||
ctru_sys::CFG_REGION_USA => Ok(Region::USA), |
||||
ctru_sys::CFG_REGION_EUR => Ok(Region::Europe), |
||||
ctru_sys::CFG_REGION_AUS => Ok(Region::Australia), |
||||
ctru_sys::CFG_REGION_CHN => Ok(Region::China), |
||||
ctru_sys::CFG_REGION_KOR => Ok(Region::Korea), |
||||
ctru_sys::CFG_REGION_TWN => Ok(Region::Taiwan), |
||||
_ => Err(()), |
||||
} |
||||
} |
||||
} |
||||
|
||||
impl TryFrom<u8> for Language { |
||||
type Error = (); |
||||
|
||||
fn try_from(value: u8) -> Result<Self, Self::Error> { |
||||
match value as u32 { |
||||
ctru_sys::CFG_LANGUAGE_JP => Ok(Language::Japanese), |
||||
ctru_sys::CFG_LANGUAGE_EN => Ok(Language::English), |
||||
ctru_sys::CFG_LANGUAGE_FR => Ok(Language::French), |
||||
ctru_sys::CFG_LANGUAGE_DE => Ok(Language::German), |
||||
ctru_sys::CFG_LANGUAGE_IT => Ok(Language::Italian), |
||||
ctru_sys::CFG_LANGUAGE_ES => Ok(Language::Spanish), |
||||
ctru_sys::CFG_LANGUAGE_ZH => Ok(Language::SimplifiedChinese), |
||||
ctru_sys::CFG_LANGUAGE_KO => Ok(Language::Korean), |
||||
ctru_sys::CFG_LANGUAGE_NL => Ok(Language::Dutch), |
||||
ctru_sys::CFG_LANGUAGE_PT => Ok(Language::Portuguese), |
||||
ctru_sys::CFG_LANGUAGE_RU => Ok(Language::Russian), |
||||
ctru_sys::CFG_LANGUAGE_TW => Ok(Language::TraditionalChinese), |
||||
_ => Err(()), |
||||
} |
||||
} |
||||
} |
||||
|
||||
impl TryFrom<u8> for SystemModel { |
||||
type Error = (); |
||||
|
||||
fn try_from(value: u8) -> Result<Self, Self::Error> { |
||||
match value as u32 { |
||||
ctru_sys::CFG_MODEL_3DS => Ok(SystemModel::Model3DS), |
||||
ctru_sys::CFG_MODEL_3DSXL => Ok(SystemModel::Model3DSXL), |
||||
ctru_sys::CFG_MODEL_N3DS => Ok(SystemModel::ModelNew3DS), |
||||
ctru_sys::CFG_MODEL_2DS => Ok(SystemModel::Model2DS), |
||||
ctru_sys::CFG_MODEL_N3DSXL => Ok(SystemModel::ModelNew3DSXL), |
||||
ctru_sys::CFG_MODEL_N2DSXL => Ok(SystemModel::ModelNew2DSXL), |
||||
_ => Err(()), |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue