Ronald Kinard
10 years ago
8 changed files with 341 additions and 23 deletions
@ -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(); |
||||||
|
} |
||||||
|
} |
@ -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(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -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); |
||||||
|
} |
||||||
|
} |
@ -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; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue