aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRonald Kinard <[email protected]>2015-06-11 23:00:34 -0500
committerRonald Kinard <[email protected]>2015-06-11 23:00:34 -0500
commitd5fb1a9b7dd51d43c99f4d1995edd9de6fda4773 (patch)
treeb86110cd0b1a9571260d2d3fc82d22a6f1ca367a /src
parentAdd bindings for several more services. (diff)
downloadctru-rs-d5fb1a9b7dd51d43c99f4d1995edd9de6fda4773.tar.xz
ctru-rs-d5fb1a9b7dd51d43c99f4d1995edd9de6fda4773.zip
Make idiomatic interfaces to a few functions.
Diffstat (limited to 'src')
-rw-r--r--src/gfx.rs31
-rw-r--r--src/lib.rs21
-rw-r--r--src/raw/services/gsp.rs6
-rw-r--r--src/services/apt.rs110
-rw-r--r--src/services/gsp.rs46
-rw-r--r--src/services/hid.rs134
-rw-r--r--src/services/mod.rs3
-rw-r--r--src/srv.rs13
8 files changed, 341 insertions, 23 deletions
diff --git a/src/gfx.rs b/src/gfx.rs
new file mode 100644
index 0000000..c767cf5
--- /dev/null
+++ b/src/gfx.rs
@@ -0,0 +1,31 @@
+use ::raw::gfx;
+
+pub fn init_default() -> () {
+ unsafe {
+ gfx::gfxInitDefault();
+ }
+}
+
+pub fn exit() -> () {
+ unsafe {
+ gfx::gfxExit();
+ }
+}
+
+pub fn set_3d_enabled(enabled: bool) -> () {
+ unsafe {
+ gfx::gfxSet3D(match enabled { true => 1u8, false => 0u8 });
+ }
+}
+
+pub fn flush_buffers() -> () {
+ unsafe {
+ gfx::gfxFlushBuffers();
+ }
+}
+
+pub fn swap_buffers() -> () {
+ unsafe {
+ gfx::gfxSwapBuffers();
+ }
+}
diff --git a/src/lib.rs b/src/lib.rs
index 98bd1ef..b652b63 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -11,21 +11,6 @@ pub mod raw;
pub type Result = i32;
pub type Handle = u32;
-pub mod srv {
- use super::Result;
- use super::raw::srv;
- pub fn init() -> Result {
- unsafe {
- return srv::srvInit();
- }
- }
- pub fn exit() -> Result {
- unsafe {
- return srv::srvExit();
- }
- }
-
- pub fn awesome() -> i32 {
- 0
- }
-}
+pub mod srv;
+pub mod gfx;
+pub mod services;
diff --git a/src/raw/services/gsp.rs b/src/raw/services/gsp.rs
index 6518978..3420186 100644
--- a/src/raw/services/gsp.rs
+++ b/src/raw/services/gsp.rs
@@ -9,7 +9,7 @@ pub fn GSP_REBASE_REG(r: u32) {
}
#[repr(C)]
-#[derive(Copy)]
+#[derive(Clone, Copy)]
pub struct GSP_FramebufferInfo {
active_framebuf: u32, //"0=first, 1=second"
framebuf0_vaddr: *mut u32, //"Framebuffer virtual address, for the main screen this is the 3D left framebuffer"
@@ -20,10 +20,6 @@ pub struct GSP_FramebufferInfo {
unk: u32 //"?"
}
-impl Clone for GSP_FramebufferInfo {
- fn clone(&self) -> Self { *self }
-}
-
#[repr(C)]
pub enum GSP_FramebufferFormats {
GSP_RGBA8_OES=0, //pixel_size = 4-bytes
diff --git a/src/services/apt.rs b/src/services/apt.rs
new file mode 100644
index 0000000..a1eee94
--- /dev/null
+++ b/src/services/apt.rs
@@ -0,0 +1,110 @@
+use ::Result;
+
+use core::ops::Fn;
+
+use ::raw::services::apt;
+
+pub enum AppStatus {
+ NotInitialized,
+ Running,
+ Suspended,
+ Exiting,
+ Suspending,
+ SleepMode,
+ PrepareSleepMode,
+ AppletStarted,
+ AppletClosed
+}
+
+
+fn to_raw_appstatus(status: AppStatus) -> apt::APP_STATUS {
+ use self::AppStatus::*;
+ match status {
+ NotInitialized => apt::APP_STATUS::APP_NOTINITIALIZED,
+ Running => apt::APP_STATUS::APP_RUNNING,
+ Suspended => apt::APP_STATUS::APP_SUSPENDED,
+ Exiting => apt::APP_STATUS::APP_EXITING,
+ Suspending => apt::APP_STATUS::APP_SUSPENDING,
+ SleepMode => apt::APP_STATUS::APP_SLEEPMODE,
+ PrepareSleepMode => apt::APP_STATUS::APP_PREPARE_SLEEPMODE,
+ AppletStarted => apt::APP_STATUS::APP_APPLETSTARTED,
+ AppletClosed => apt::APP_STATUS::APP_APPLETCLOSED,
+ }
+}
+
+fn from_raw_appstatus(status: apt::APP_STATUS) -> AppStatus {
+ use self::AppStatus::*;
+ match status {
+ apt::APP_STATUS::APP_NOTINITIALIZED => NotInitialized,
+ apt::APP_STATUS::APP_RUNNING => Running,
+ apt::APP_STATUS::APP_SUSPENDED => Suspended,
+ apt::APP_STATUS::APP_EXITING => Exiting,
+ apt::APP_STATUS::APP_SUSPENDING => Suspending,
+ apt::APP_STATUS::APP_SLEEPMODE => SleepMode,
+ apt::APP_STATUS::APP_PREPARE_SLEEPMODE => PrepareSleepMode,
+ apt::APP_STATUS::APP_APPLETSTARTED => AppletStarted,
+ apt::APP_STATUS::APP_APPLETCLOSED => AppletClosed
+ }
+}
+
+pub fn init() -> Result {
+ unsafe {
+ return apt::aptInit();
+ }
+}
+
+pub fn exit() -> () {
+ unsafe {
+ apt::aptExit();
+ }
+}
+
+pub fn get_status() -> AppStatus {
+ unsafe {
+ return from_raw_appstatus(apt::aptGetStatus());
+ }
+}
+
+pub fn set_status(status: AppStatus) -> () {
+ unsafe {
+ apt::aptSetStatus(to_raw_appstatus(status));
+ }
+}
+
+/// Return to the home menu.
+///
+/// When `get_status` returns `AppStatus::Suspending`, you should call this,
+/// otherwise the app will be left stuck in that state.
+///
+/// The program will not return from this function until the system returns
+/// to the application, or when the status changes to `AppStatus::Exiting`.
+///
+/// # Examples
+///
+/// ```
+/// if get_status() == Suspending {
+/// return_to_menu();
+/// }
+/// ```
+pub fn return_to_menu() -> () {
+ unsafe {
+ apt::aptReturnToMenu();
+ }
+}
+
+/// Execute a function repeatedly until the apt main loop is over.
+///
+/// # Examples
+///
+/// ```
+/// main_loop(|| {
+/// // do things here
+/// });
+/// ```
+pub fn main_loop<F>(f: F) -> () where F : Fn() -> () {
+ unsafe {
+ while apt::aptMainLoop() != 0 {
+ f();
+ }
+ }
+}
diff --git a/src/services/gsp.rs b/src/services/gsp.rs
new file mode 100644
index 0000000..90ed3b2
--- /dev/null
+++ b/src/services/gsp.rs
@@ -0,0 +1,46 @@
+use ::Result;
+
+use ::raw::services::gsp;
+
+pub enum Event {
+ Psc0,
+ Psc1,
+ VBlank0,
+ VBlank1,
+ PPF,
+ P3D,
+ DMA
+}
+
+fn to_raw_event(ev: Event) -> gsp::GSP_Event {
+ use ::raw::services::gsp::GSP_Event::*;
+ use self::Event::*;
+
+ match ev {
+ Psc0 => GSPEVENT_PSC0,
+ Psc1 => GSPEVENT_PSC1,
+ VBlank0 => GSPEVENT_VBlank0,
+ VBlank1 => GSPEVENT_VBlank1,
+ PPF => GSPEVENT_PPF,
+ P3D => GSPEVENT_P3D,
+ DMA => GSPEVENT_DMA
+ }
+}
+
+/// Sleep until GSP event fires.
+///
+/// # Examples
+///
+/// Wait for VBlank.
+///
+/// ```
+/// use ctru::services::apt;
+/// apt::main_loop(|| {
+/// wait_for_event(Event::VBlank0);
+/// });
+pub fn wait_for_event(ev: Event) -> () {
+ unsafe {
+ // TODO second argument?
+ gsp::gspWaitForEvent(to_raw_event(ev), 0);
+ }
+}
diff --git a/src/services/hid.rs b/src/services/hid.rs
new file mode 100644
index 0000000..03c9c4e
--- /dev/null
+++ b/src/services/hid.rs
@@ -0,0 +1,134 @@
+use ::Result;
+
+use ::raw::services::hid;
+
+pub enum PadKey {
+ A,
+ B,
+ Select,
+ Start,
+ DPadRight,
+ DPadLeft,
+ DPadUp,
+ DPadDown,
+ R,
+ L,
+ X,
+ Y,
+ ZL,
+ ZR,
+ Touch,
+ CSRight,
+ CSLeft,
+ CSUp,
+ CSDown,
+ CRight,
+ CLeft,
+ CUp,
+ CDown,
+
+ // convenience catch-all for dpad and cpad
+ Up,
+ Down,
+ Left,
+ Right
+}
+
+fn to_raw_padkey(key: PadKey) -> u32 {
+ use ::raw::services::hid::PAD_KEY::*;
+ use self::PadKey::*;
+
+ match key {
+ Up => KEY_DUP as u32 | KEY_CPAD_UP as u32,
+ Down => KEY_DDOWN as u32 | KEY_CPAD_DOWN as u32,
+ Left => KEY_DLEFT as u32 | KEY_CPAD_LEFT as u32,
+ Right => KEY_DRIGHT as u32 | KEY_CPAD_RIGHT as u32,
+
+ A => KEY_A as u32,
+ B => KEY_B as u32,
+ X => KEY_X as u32,
+ Y => KEY_Y as u32,
+ L => KEY_L as u32,
+ R => KEY_R as u32,
+ ZL => KEY_ZL as u32,
+ ZR => KEY_ZR as u32,
+ Start => KEY_START as u32,
+ Select => KEY_SELECT as u32,
+ Touch => KEY_TOUCH as u32,
+ CSRight => KEY_CSTICK_RIGHT as u32,
+ CSLeft => KEY_CSTICK_LEFT as u32,
+ CSUp => KEY_CSTICK_UP as u32,
+ CSDown => KEY_CSTICK_DOWN as u32,
+ CRight => KEY_CPAD_RIGHT as u32,
+ CLeft => KEY_CPAD_LEFT as u32,
+ CDown => KEY_CPAD_DOWN as u32,
+ CUp => KEY_CPAD_UP as u32,
+ DPadLeft => KEY_DLEFT as u32,
+ DPadRight => KEY_DRIGHT as u32,
+ DPadUp => KEY_DUP as u32,
+ DPadDown => KEY_DDOWN as u32
+ }
+}
+
+pub fn init() -> Result {
+ unsafe {
+ // TODO allow sharedMem argument?
+ return hid::hidInit(0 as *mut u32);
+ }
+}
+
+pub fn exit() -> () {
+ unsafe {
+ hid::hidExit();
+ }
+}
+
+/// Update ctrulib's button states.
+///
+/// # Examples
+///
+/// ```
+/// use ctru::service::apt;
+///
+/// apt::main_loop(|| {
+/// scan_input();
+/// if key_down(PadKey::A) {
+/// apt::set_status(apt::AppStatus::Exiting);
+/// }
+/// });
+/// ```
+pub fn scan_input() -> () {
+ unsafe {
+ hid::hidScanInput();
+ }
+}
+
+pub fn key_down(key: PadKey) -> bool {
+ unsafe {
+ if hid::hidKeysDown() & to_raw_padkey(key) != 0 {
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
+
+pub fn key_held(key: PadKey) -> bool {
+ unsafe {
+ if hid::hidKeysHeld() & to_raw_padkey(key) != 0 {
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
+
+pub fn key_up(key: PadKey) -> bool {
+ unsafe {
+ if hid::hidKeysUp() & to_raw_padkey(key) != 0 {
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
diff --git a/src/services/mod.rs b/src/services/mod.rs
new file mode 100644
index 0000000..1bdeae7
--- /dev/null
+++ b/src/services/mod.rs
@@ -0,0 +1,3 @@
+pub mod apt;
+pub mod hid;
+pub mod gsp;
diff --git a/src/srv.rs b/src/srv.rs
new file mode 100644
index 0000000..44fb956
--- /dev/null
+++ b/src/srv.rs
@@ -0,0 +1,13 @@
+use ::Result;
+use ::raw::srv;
+
+pub fn init() -> Result {
+ unsafe {
+ return srv::srvInit();
+ }
+}
+pub fn exit() -> Result {
+ unsafe {
+ return srv::srvExit();
+ }
+}