Browse Source

Merge pull request #5 from FenrirWolf/master

API overhaul and simplification, plus console support
pull/10/head
Ronald Kinard 9 years ago
parent
commit
7337abc701
  1. 9
      3ds.json
  2. 16
      Cargo.toml
  3. 9
      ctru-sys/src/console.rs
  4. 3
      ctru-sys/src/ipc.rs
  5. 9
      ctru-sys/src/lib.rs
  6. 11
      ctru-sys/src/libc.rs
  7. 7
      ctru-sys/src/os.rs
  8. 54
      ctru-sys/src/result.rs
  9. 2
      ctru-sys/src/services/apt.rs
  10. 2
      ctru-sys/src/services/cam.rs
  11. 2
      ctru-sys/src/services/dsp.rs
  12. 29
      ctru-sys/src/services/fs.rs
  13. 2
      ctru-sys/src/services/gspgpu.rs
  14. 2
      ctru-sys/src/services/hb.rs
  15. 2
      ctru-sys/src/services/news.rs
  16. 2
      ctru-sys/src/services/pm.rs
  17. 2
      ctru-sys/src/services/srvpm.rs
  18. 2
      ctru-sys/src/services/y2r.rs
  19. 2
      ctru-sys/src/srv.rs
  20. 2
      ctru-sys/src/svc.rs
  21. 2
      ctru-sys/src/thread.rs
  22. 38
      src/console.rs
  23. 52
      src/gfx.rs
  24. 15
      src/lib.rs
  25. 6
      src/sdmc.rs
  26. 80
      src/services/apt.rs
  27. 18
      src/services/gspgpu.rs
  28. 23
      src/services/hid.rs
  29. 4
      src/services/mod.rs
  30. 2
      src/srv.rs

9
3ds.json

@ -18,12 +18,13 @@
"dynamic-linking": false, "dynamic-linking": false,
"no-compiler-rt": true, "no-compiler-rt": true,
"exe-suffix": ".elf", "exe-suffix": ".elf",
"pre-link-args": ["-specs", "is-like-windows": true,
"function-sections": false,
"pre-link-args": [
"-specs",
"3dsx.specs", "3dsx.specs",
"-march=armv6k", "-march=armv6k",
"-mtune=mpcore", "-mtune=mpcore",
"-mfloat-abi=hard" "-mfloat-abi=hard"
], ]
"is-like-windows": true,
"function-sections": false
} }

16
Cargo.toml

@ -1,15 +1,15 @@
[package] [package]
name = "ctru-rs"
version = "0.2.0"
description = "A safe wrapper around smealum's ctrulib."
authors = ["Ronald Kinard <furyhunter600@gmail.com>"] authors = ["Ronald Kinard <furyhunter600@gmail.com>"]
links = "ctru"
build = "build.rs" build = "build.rs"
description = "A safe wrapper around smealum's ctrulib."
license = "https://en.wikipedia.org/wiki/Zlib_License" license = "https://en.wikipedia.org/wiki/Zlib_License"
links = "ctru"
name = "ctru-rs"
version = "0.3.0"
[dependencies.ctru-sys]
path = "ctru-sys"
[lib] [lib]
name = "ctru"
crate-type = ["rlib"] crate-type = ["rlib"]
name = "ctru"
[dependencies]
ctru-sys = { path = "ctru-sys" }

9
ctru-sys/src/console.rs

@ -1,4 +1,4 @@
use c_void; use libc::c_void;
use super::gfx::*; use super::gfx::*;
@ -54,7 +54,12 @@ pub enum debugDevice {
extern "C" { extern "C" {
pub fn consoleSetFont(console: *mut PrintConsole, font: *mut ConsoleFont) -> (); pub fn consoleSetFont(console: *mut PrintConsole, font: *mut ConsoleFont) -> ();
pub fn consoleSetWindow(console: *mut PrintConsole, x: i32, y: i32, width: i32, height: i32) -> (); pub fn consoleSetWindow(console: *mut PrintConsole,
x: i32,
y: i32,
width: i32,
height: i32)
-> ();
pub fn consoleGetDefault() -> *mut PrintConsole; pub fn consoleGetDefault() -> *mut PrintConsole;
pub fn consoleSelect(console: *mut PrintConsole) -> *mut PrintConsole; pub fn consoleSelect(console: *mut PrintConsole) -> *mut PrintConsole;
pub fn consoleInit(screen: gfxScreen_t, console: *mut PrintConsole) -> *mut PrintConsole; pub fn consoleInit(screen: gfxScreen_t, console: *mut PrintConsole) -> *mut PrintConsole;

3
ctru-sys/src/ipc.rs

@ -1,4 +1,4 @@
//TODO: Implement static inline functions + solve the anonymous enum enigma //TODO: Implement static inline functions
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
#[repr(C)] #[repr(C)]
@ -7,4 +7,3 @@ pub enum IPC_BufferRights {
IPC_BUFFER_W = 4, IPC_BUFFER_W = 4,
IPC_BUFFER_RW = 6, IPC_BUFFER_RW = 6,
} }

9
ctru-sys/src/lib.rs

@ -14,6 +14,7 @@ pub mod gfx;
pub mod gpu; pub mod gpu;
pub mod ipc; pub mod ipc;
pub mod lock; pub mod lock;
pub mod libc;
pub mod os; pub mod os;
pub mod sdmc; pub mod sdmc;
pub mod srv; pub mod srv;
@ -29,10 +30,4 @@ pub use self::types::*;
pub type Result = i32; pub type Result = i32;
pub type Handle = u32; pub type Handle = u32;
#[repr(u8)] pub type ThreadFunc = Option<extern "C" fn(arg1: *mut libc::c_void) -> ()>;
pub enum c_void {
__variant1,
__variant2,
}
pub type ThreadFunc = Option<extern "C" fn(arg1: *mut c_void) -> ()>;

11
ctru-sys/src/libc.rs

@ -0,0 +1,11 @@
pub const STDOUT_FILENO: i32 = 1;
#[repr(u8)]
pub enum c_void {
__variant1,
__variant2,
}
extern "C" {
pub fn write(fd: i32, buf: *const c_void, count: usize) -> isize;
}

7
ctru-sys/src/os.rs

@ -1,6 +1,7 @@
//TODO: Fix Bindgen's issues again. //TODO: Fix Bindgen's issues again.
use ::Result; use ::Result;
use libc::c_void;
use types::*; use types::*;
#[inline] #[inline]
@ -35,9 +36,9 @@ impl ::core::default::Default for Struct_Unnamed2 {
} }
pub type OS_VersionBin = Struct_Unnamed2; pub type OS_VersionBin = Struct_Unnamed2;
extern "C" { extern "C" {
pub fn osConvertVirtToPhys(vaddr: *const ::c_void) -> u32; pub fn osConvertVirtToPhys(vaddr: *const c_void) -> u32;
pub fn osConvertOldLINEARMemToNew(vaddr: *const ::c_void) pub fn osConvertOldLINEARMemToNew(vaddr: *const c_void)
-> *mut ::c_void; -> *mut c_void;
pub fn osStrError(error: u32) -> *const u8; pub fn osStrError(error: u32) -> *const u8;
pub fn osGetMemRegionUsed(region: MemRegion) -> s64; pub fn osGetMemRegionUsed(region: MemRegion) -> s64;
pub fn osGetTime() -> u64; pub fn osGetTime() -> u64;

54
ctru-sys/src/result.rs

@ -0,0 +1,54 @@
//TODO: Implement C macro functions? Maybe?
//Result code level values
pub const RL_SUCCESS :i32 = 0;
pub const RL_INFO :i32 = 1;
pub const RL_FATAL :i32 = 31;
pub const RL_RESET :i32 = 30;
pub const RL_REINITIALIZE :i32 = 29;
pub const RL_USAGE :i32 = 28;
pub const RL_PERMANENT :i32 = 27;
pub const RL_TEMPORARY :i32 = 26;
pub const RL_STATUS :i32 = 25;
//Result code summary values
pub const RS_SUCCESS :i32 = 0;
pub const RS_NOP :i32 = 1;
pub const RS_WOULDBLOCK :i32 = 2;
pub const RS_OUTOFRESOURCE :i32 = 3;
pub const RS_NOTFOUND :i32 = 4;
pub const RS_INVALIDSTATE :i32 = 5;
pub const RS_NOTSUPPORTED :i32 = 6;
pub const RS_INVALIDARG :i32 = 7;
pub const RS_WRONGARG :i32 = 8;
pub const RS_CANCELED :i32 = 9;
pub const RS_STATUSCHANGED :i32 = 10;
pub const RS_INTERNAL :i32 = 11;
pub const RS_INVALIDRESVAL :i32 = 63;
//Result code generic description values
pub const RD_SUCCESS :i32 = 0;
pub const RD_INVALID_RESULT_VALUE :i32 = 1023;
pub const RD_TIMEOUT :i32 = 1022;
pub const RD_OUT_OF_RANGE :i32 = 1021;
pub const RD_ALREADY_EXISTS :i32 = 1020;
pub const RD_CANCEL_REQUESTED :i32 = 1019;
pub const RD_NOT_FOUND :i32 = 1018;
pub const RD_ALREADY_INITIALIZED :i32 = 1017;
pub const RD_NOT_INITIALIZED :i32 = 1016;
pub const RD_INVALID_HANDLE :i32 = 1015;
pub const RD_INVALID_POINTER :i32 = 1014;
pub const RD_INVALID_ADDRESS :i32 = 1013;
pub const RD_NOT_IMPLEMENTED :i32 = 1012;
pub const RD_OUT_OF_MEMORY :i32 = 1011;
pub const RD_MISALIGNED_SIZE :i32 = 1010;
pub const RD_MISALIGNED_ADDRESS :i32 = 1009;
pub const RD_BUSY :i32 = 1008;
pub const RD_NO_DATA :i32 = 1007;
pub const RD_INVALID_COMBINATION :i32 = 1006;
pub const RD_INVALID_ENUM_VALUE :i32 = 1005;
pub const RD_INVALID_SIZE :i32 = 1004;
pub const RD_ALREADY_DONE :i32 = 1003;
pub const RD_NOT_AUTHORIZED :i32 = 1002;
pub const RD_TOO_LARGE :i32 = 1001;
pub const RD_INVALID_SELECTION :i32 = 1000;

2
ctru-sys/src/services/apt.rs

@ -1,5 +1,5 @@
use ::{Result, Handle}; use ::{Result, Handle};
use ::c_void; use ::libc::c_void;
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy)] #[derive(Clone, Copy)]

2
ctru-sys/src/services/cam.rs

@ -1,7 +1,7 @@
// TODO: Determine if anonymous enums are properly represented (they probably aren't) // TODO: Determine if anonymous enums are properly represented (they probably aren't)
use ::{Handle, Result}; use ::{Handle, Result};
use ::c_void; use libc::c_void;
use ::types::*; use ::types::*;
#[derive(Clone, Copy)] #[derive(Clone, Copy)]

2
ctru-sys/src/services/dsp.rs

@ -1,5 +1,5 @@
use ::{Handle, Result}; use ::{Handle, Result};
use ::c_void; use ::libc::c_void;
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy)] #[derive(Clone, Copy)]

29
ctru-sys/src/services/fs.rs

@ -1,6 +1,7 @@
// TODO: Determine if anonymous enums are properly represented (they probably aren't) // TODO: Determine if anonymous enums are properly represented (they probably aren't)
use ::{Handle, Result}; use ::{Handle, Result};
use ::libc::c_void;
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
#[repr(C)] #[repr(C)]
@ -276,7 +277,7 @@ pub type FS_DeviceMoveContext = Struct_Unnamed24;
pub struct Struct_Unnamed25 { pub struct Struct_Unnamed25 {
pub _type: FS_PathType, pub _type: FS_PathType,
pub size: u32, pub size: u32,
pub data: *const ::c_void, pub data: *const c_void,
} }
impl ::core::clone::Clone for Struct_Unnamed25 { impl ::core::clone::Clone for Struct_Unnamed25 {
fn clone(&self) -> Self { *self } fn clone(&self) -> Self { *self }
@ -305,12 +306,12 @@ extern "C" {
pub fn fsExit(); pub fn fsExit();
pub fn fsUseSession(session: Handle, sdmc: u8); pub fn fsUseSession(session: Handle, sdmc: u8);
pub fn fsEndUseSession(); pub fn fsEndUseSession();
pub fn fsMakePath(_type: FS_PathType, path: *const ::c_void) pub fn fsMakePath(_type: FS_PathType, path: *const c_void)
-> FS_Path; -> FS_Path;
pub fn fsGetSessionHandle() -> *mut Handle; pub fn fsGetSessionHandle() -> *mut Handle;
pub fn FSUSER_Control(action: FS_Action, pub fn FSUSER_Control(action: FS_Action,
input: *mut ::c_void, inputSize: u32, input: *mut c_void, inputSize: u32,
output: *mut ::c_void, output: *mut c_void,
outputSize: u32) -> Result; outputSize: u32) -> Result;
pub fn FSUSER_Initialize(session: Handle) -> Result; pub fn FSUSER_Initialize(session: Handle) -> Result;
pub fn FSUSER_OpenFile(out: *mut Handle, archive: FS_Archive, pub fn FSUSER_OpenFile(out: *mut Handle, archive: FS_Archive,
@ -339,9 +340,9 @@ extern "C" {
pub fn FSUSER_OpenArchive(archive: *mut FS_Archive) -> Result; pub fn FSUSER_OpenArchive(archive: *mut FS_Archive) -> Result;
pub fn FSUSER_ControlArchive(archive: FS_Archive, pub fn FSUSER_ControlArchive(archive: FS_Archive,
action: FS_ArchiveAction, action: FS_ArchiveAction,
input: *mut ::c_void, input: *mut c_void,
inputSize: u32, inputSize: u32,
output: *mut ::c_void, output: *mut c_void,
outputSize: u32) -> Result; outputSize: u32) -> Result;
pub fn FSUSER_CloseArchive(archive: *mut FS_Archive) -> Result; pub fn FSUSER_CloseArchive(archive: *mut FS_Archive) -> Result;
pub fn FSUSER_GetFreeBytes(freeBytes: *mut u64, archive: FS_Archive) pub fn FSUSER_GetFreeBytes(freeBytes: *mut u64, archive: FS_Archive)
@ -495,22 +496,22 @@ extern "C" {
titleUniqueId: u32, titleUniqueId: u32,
titleVariation: u8) -> Result; titleVariation: u8) -> Result;
pub fn FSUSER_ControlSecureSave(action: FS_SecureSaveAction, pub fn FSUSER_ControlSecureSave(action: FS_SecureSaveAction,
input: *mut ::c_void, input: *mut c_void,
inputSize: u32, inputSize: u32,
output: *mut ::c_void, output: *mut c_void,
outputSize: u32) -> Result; outputSize: u32) -> Result;
pub fn FSUSER_GetMediaType(mediaType: *mut FS_MediaType) -> Result; pub fn FSUSER_GetMediaType(mediaType: *mut FS_MediaType) -> Result;
pub fn FSFILE_Control(handle: Handle, action: FS_FileAction, pub fn FSFILE_Control(handle: Handle, action: FS_FileAction,
input: *mut ::c_void, inputSize: u32, input: *mut c_void, inputSize: u32,
output: *mut ::c_void, output: *mut c_void,
outputSize: u32) -> Result; outputSize: u32) -> Result;
pub fn FSFILE_OpenSubFile(handle: Handle, subFile: *mut Handle, pub fn FSFILE_OpenSubFile(handle: Handle, subFile: *mut Handle,
offset: u64, size: u64) -> Result; offset: u64, size: u64) -> Result;
pub fn FSFILE_Read(handle: Handle, bytesRead: *mut u32, offset: u64, pub fn FSFILE_Read(handle: Handle, bytesRead: *mut u32, offset: u64,
buffer: *mut ::c_void, size: u32) buffer: *mut c_void, size: u32)
-> Result; -> Result;
pub fn FSFILE_Write(handle: Handle, bytesWritten: *mut u32, offset: u64, pub fn FSFILE_Write(handle: Handle, bytesWritten: *mut u32, offset: u64,
buffer: *const ::c_void, size: u32, buffer: *const c_void, size: u32,
flags: u32) -> Result; flags: u32) -> Result;
pub fn FSFILE_GetSize(handle: Handle, size: *mut u64) -> Result; pub fn FSFILE_GetSize(handle: Handle, size: *mut u64) -> Result;
pub fn FSFILE_SetSize(handle: Handle, size: u64) -> Result; pub fn FSFILE_SetSize(handle: Handle, size: u64) -> Result;
@ -524,8 +525,8 @@ extern "C" {
pub fn FSFILE_OpenLinkFile(handle: Handle, linkFile: *mut Handle) pub fn FSFILE_OpenLinkFile(handle: Handle, linkFile: *mut Handle)
-> Result; -> Result;
pub fn FSDIR_Control(handle: Handle, action: FS_DirectoryAction, pub fn FSDIR_Control(handle: Handle, action: FS_DirectoryAction,
input: *mut ::c_void, inputSize: u32, input: *mut c_void, inputSize: u32,
output: *mut ::c_void, output: *mut c_void,
outputSize: u32) -> Result; outputSize: u32) -> Result;
pub fn FSDIR_Read(handle: Handle, entriesRead: *mut u32, pub fn FSDIR_Read(handle: Handle, entriesRead: *mut u32,
entryCount: u32, entries: *mut FS_DirectoryEntry) entryCount: u32, entries: *mut FS_DirectoryEntry)

2
ctru-sys/src/services/gspgpu.rs

@ -1,5 +1,5 @@
use ::{Handle, Result}; use ::{Handle, Result};
use ::c_void; use ::libc::c_void;
use ::types::*; use ::types::*;
#[inline] #[inline]

2
ctru-sys/src/services/hb.rs

@ -1,5 +1,5 @@
use ::Result; use ::Result;
use ::c_void; use ::libc::c_void;
extern "C" { extern "C" {

2
ctru-sys/src/services/news.rs

@ -1,5 +1,5 @@
use ::Result; use ::Result;
use ::c_void; use ::libc::c_void;
extern "C" { extern "C" {
pub fn newsInit() -> Result; pub fn newsInit() -> Result;

2
ctru-sys/src/services/pm.rs

@ -1,5 +1,5 @@
use ::{Handle, Result}; use ::{Handle, Result};
use ::c_void; use ::libc::c_void;
extern "C" { extern "C" {
pub fn pmInit() -> Result; pub fn pmInit() -> Result;

2
ctru-sys/src/services/srvpm.rs

@ -1,5 +1,5 @@
use ::{Handle, Result}; use ::{Handle, Result};
use ::c_void; use ::libc::c_void;
extern "C" { extern "C" {
pub fn srvPmInit() -> Result; pub fn srvPmInit() -> Result;

2
ctru-sys/src/services/y2r.rs

@ -1,5 +1,5 @@
use ::{Handle, Result}; use ::{Handle, Result};
use ::c_void; use ::libc::c_void;
use ::types::*; use ::types::*;
#[derive(Clone, Copy)] #[derive(Clone, Copy)]

2
ctru-sys/src/srv.rs

@ -1,5 +1,5 @@
use {Result, Handle}; use {Result, Handle};
use c_void; use libc::c_void;
extern "C" { extern "C" {
pub fn srvInit() -> Result; pub fn srvInit() -> Result;

2
ctru-sys/src/svc.rs

@ -1,7 +1,7 @@
//TODO: Implement static functions //TODO: Implement static functions
use {Handle, Result}; use {Handle, Result};
use c_void; use libc::c_void;
use ThreadFunc; use ThreadFunc;
use types::*; use types::*;

2
ctru-sys/src/thread.rs

@ -1,5 +1,5 @@
use {Handle, Result}; use {Handle, Result};
use c_void; use libc::c_void;
use ThreadFunc; use ThreadFunc;
pub enum Struct_Thread_tag { } pub enum Struct_Thread_tag { }

38
src/console.rs

@ -0,0 +1,38 @@
use libctru::console::{consoleInit, consoleClear};
use libctru::gfx;
use libctru::libc;
use core::fmt::{self, Write};
use core::default::Default;
use core::marker::PhantomData;
use core::ptr;
pub struct Console {
pd: PhantomData<()>,
}
impl Console {
pub fn clear(&mut self) {
unsafe { consoleClear() }
}
}
impl Default for Console {
fn default() -> Self {
unsafe {
consoleInit(gfx::gfxScreen_t::GFX_TOP, ptr::null_mut());
}
Console { pd: PhantomData }
}
}
impl Write for Console {
fn write_str(&mut self, s: &str) -> fmt::Result {
let ret = unsafe { libc::write(libc::STDOUT_FILENO, s.as_ptr() as *const _, s.len()) };
if ret == s.len() as isize {
Ok(())
} else {
Err(fmt::Error)
}
}
}

52
src/gfx.rs

@ -4,65 +4,69 @@ use core::default::Default;
use core::marker::PhantomData; use core::marker::PhantomData;
use core::ops::Drop; use core::ops::Drop;
use ::services::gsp::FramebufferFormat; use services::gspgpu::FramebufferFormat;
pub struct Gfx { pub struct Gfx {
// we do this to prevent people from making a Gfx struct manually // we do this to prevent people from making a Gfx struct manually
pd: PhantomData<i32> pd: PhantomData<i32>,
} }
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub enum Screen { pub enum Screen {
Top, Top,
Bottom Bottom,
} }
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub enum Side { pub enum Side {
Left, Left,
Right Right,
} }
impl From<gfx::gfxScreen_t> for Screen { impl From<gfx::gfxScreen_t> for Screen {
#[inline] fn from(g: gfx::gfxScreen_t) -> Screen { #[inline]
fn from(g: gfx::gfxScreen_t) -> Screen {
use libctru::gfx::gfxScreen_t::*; use libctru::gfx::gfxScreen_t::*;
use self::Screen::*; use self::Screen::*;
match g { match g {
GFX_TOP => Top, GFX_TOP => Top,
GFX_BOTTOM => Bottom GFX_BOTTOM => Bottom,
} }
} }
} }
impl From<Screen> for gfx::gfxScreen_t { impl From<Screen> for gfx::gfxScreen_t {
#[inline] fn from(g: Screen) -> gfx::gfxScreen_t { #[inline]
fn from(g: Screen) -> gfx::gfxScreen_t {
use libctru::gfx::gfxScreen_t::*; use libctru::gfx::gfxScreen_t::*;
use self::Screen::*; use self::Screen::*;
match g { match g {
Top => GFX_TOP, Top => GFX_TOP,
Bottom => GFX_BOTTOM Bottom => GFX_BOTTOM,
} }
} }
} }
impl From<gfx::gfx3dSide_t> for Side { impl From<gfx::gfx3dSide_t> for Side {
#[inline] fn from(s: gfx::gfx3dSide_t) -> Side { #[inline]
fn from(s: gfx::gfx3dSide_t) -> Side {
use libctru::gfx::gfx3dSide_t::*; use libctru::gfx::gfx3dSide_t::*;
use self::Side::*; use self::Side::*;
match s { match s {
GFX_LEFT => Left, GFX_LEFT => Left,
GFX_RIGHT => Right GFX_RIGHT => Right,
} }
} }
} }
impl From<Side> for gfx::gfx3dSide_t { impl From<Side> for gfx::gfx3dSide_t {
#[inline] fn from(s: Side) -> gfx::gfx3dSide_t { #[inline]
fn from(s: Side) -> gfx::gfx3dSide_t {
use libctru::gfx::gfx3dSide_t::*; use libctru::gfx::gfx3dSide_t::*;
use self::Side::*; use self::Side::*;
match s { match s {
Left => GFX_LEFT, Left => GFX_LEFT,
Right => GFX_RIGHT Right => GFX_RIGHT,
} }
} }
} }
@ -70,7 +74,10 @@ impl From<Side> for gfx::gfx3dSide_t {
impl Gfx { impl Gfx {
pub fn set_3d_enabled(&mut self, enabled: bool) { pub fn set_3d_enabled(&mut self, enabled: bool) {
unsafe { unsafe {
gfx::gfxSet3D(match enabled { true => 1u8, false => 0u8 }); gfx::gfxSet3D(match enabled {
true => 1u8,
false => 0u8,
});
} }
} }
@ -81,7 +88,10 @@ impl Gfx {
let mut w: u16 = 0; let mut w: u16 = 0;
let mut h: u16 = 0; let mut h: u16 = 0;
let buf: *mut u8 = gfx::gfxGetFramebuffer(screen.into(), side.into(), &mut w as *mut u16, &mut h as &mut u16); let buf: *mut u8 = gfx::gfxGetFramebuffer(screen.into(),
side.into(),
&mut w as *mut u16,
&mut h as &mut u16);
let fbfmt = self.get_framebuffer_format(screen); let fbfmt = self.get_framebuffer_format(screen);
@ -103,21 +113,21 @@ impl Gfx {
pub fn get_framebuffer_format(&self, screen: Screen) -> FramebufferFormat { pub fn get_framebuffer_format(&self, screen: Screen) -> FramebufferFormat {
use core::convert::Into; use core::convert::Into;
unsafe { unsafe { gfx::gfxGetScreenFormat(screen.into()).into() }
gfx::gfxGetScreenFormat(screen.into()).into()
}
} }
pub fn set_framebuffer_format(&mut self, screen: Screen, fmt: FramebufferFormat) { pub fn set_framebuffer_format(&mut self, screen: Screen, fmt: FramebufferFormat) {
use core::convert::Into; use core::convert::Into;
unsafe { unsafe { gfx::gfxSetScreenFormat(screen.into(), fmt.into()) }
gfx::gfxSetScreenFormat(screen.into(), fmt.into())
}
} }
pub fn set_double_buffering(&mut self, screen: Screen, enabled: bool) { pub fn set_double_buffering(&mut self, screen: Screen, enabled: bool) {
unsafe { unsafe {
gfx::gfxSetDoubleBuffering(screen.into(), match enabled { true => 1u8, false => 0u8 }) gfx::gfxSetDoubleBuffering(screen.into(),
match enabled {
true => 1u8,
false => 0u8,
})
}; };
} }
} }

15
src/lib.rs

@ -1,10 +1,15 @@
#![feature(lang_items, alloc, collections, macro_reexport, allow_internal_unstable)]
#![no_std] #![no_std]
#![feature(lang_items)]
#![crate_type = "rlib"] #![crate_type = "rlib"]
#![crate_name = "ctru"] #![crate_name = "ctru"]
extern crate alloc;
#[macro_reexport(format, vec)]
extern crate collections;
extern crate ctru_sys as libctru; extern crate ctru_sys as libctru;
pub mod console;
pub mod srv; pub mod srv;
pub mod gfx; pub mod gfx;
pub mod sdmc; pub mod sdmc;
@ -15,5 +20,9 @@ pub use srv::Srv;
pub use gfx::Gfx; pub use gfx::Gfx;
pub use sdmc::Sdmc; pub use sdmc::Sdmc;
#[lang = "eh_personality"] extern fn eh_personality() {} #[lang = "eh_personality"]
#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} } extern "C" fn eh_personality() {}
#[lang = "panic_fmt"]
fn panic_fmt() -> ! {
loop {}
}

6
src/sdmc.rs

@ -3,7 +3,7 @@ use core::marker::PhantomData;
use libctru::sdmc::*; use libctru::sdmc::*;
pub struct Sdmc { pub struct Sdmc {
pd: PhantomData<i32> pd: PhantomData<i32>,
} }
impl Sdmc { impl Sdmc {
@ -21,8 +21,6 @@ impl Sdmc {
impl Drop for Sdmc { impl Drop for Sdmc {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe { sdmcExit() };
sdmcExit()
};
} }
} }

80
src/services/apt.rs

@ -11,22 +11,23 @@ pub enum AppStatus {
SleepMode, SleepMode,
PrepareSleepMode, PrepareSleepMode,
AppletStarted, AppletStarted,
AppletClosed AppletClosed,
} }
impl From<AppStatus> for apt::APT_AppStatus { impl From<AppStatus> for apt::APT_AppStatus {
fn from(a: AppStatus) -> apt::APT_AppStatus { fn from(a: AppStatus) -> apt::APT_AppStatus {
use self::AppStatus::*; use self::AppStatus::*;
use libctru::services::apt::APT_AppStatus::*;
match a { match a {
NotInitialized => apt::APT_AppStatus::APP_NOTINITIALIZED, NotInitialized => APP_NOTINITIALIZED,
Running => apt::APT_AppStatus::APP_RUNNING, Running => APP_RUNNING,
Suspended => apt::APT_AppStatus::APP_SUSPENDED, Suspended => APP_SUSPENDED,
Exiting => apt::APT_AppStatus::APP_EXITING, Exiting => APP_EXITING,
Suspending => apt::APT_AppStatus::APP_SUSPENDING, Suspending => APP_SUSPENDING,
SleepMode => apt::APT_AppStatus::APP_SLEEPMODE, SleepMode => APP_SLEEPMODE,
PrepareSleepMode => apt::APT_AppStatus::APP_PREPARE_SLEEPMODE, PrepareSleepMode => APP_PREPARE_SLEEPMODE,
AppletStarted => apt::APT_AppStatus::APP_APPLETSTARTED, AppletStarted => APP_APPLETSTARTED,
AppletClosed => apt::APT_AppStatus::APP_APPLETCLOSED, AppletClosed => APP_APPLETCLOSED,
} }
} }
} }
@ -34,34 +35,28 @@ impl From<AppStatus> for apt::APT_AppStatus {
impl From<apt::APT_AppStatus> for AppStatus { impl From<apt::APT_AppStatus> for AppStatus {
fn from(a: apt::APT_AppStatus) -> AppStatus { fn from(a: apt::APT_AppStatus) -> AppStatus {
use self::AppStatus::*; use self::AppStatus::*;
use libctru::services::apt::APT_AppStatus::*;
match a { match a {
apt::APT_AppStatus::APP_NOTINITIALIZED => NotInitialized, APP_NOTINITIALIZED => NotInitialized,
apt::APT_AppStatus::APP_RUNNING => Running, APP_RUNNING => Running,
apt::APT_AppStatus::APP_SUSPENDED => Suspended, APP_SUSPENDED => Suspended,
apt::APT_AppStatus::APP_EXITING => Exiting, APP_EXITING => Exiting,
apt::APT_AppStatus::APP_SUSPENDING => Suspending, APP_SUSPENDING => Suspending,
apt::APT_AppStatus::APP_SLEEPMODE => SleepMode, APP_SLEEPMODE => SleepMode,
apt::APT_AppStatus::APP_PREPARE_SLEEPMODE => PrepareSleepMode, APP_PREPARE_SLEEPMODE => PrepareSleepMode,
apt::APT_AppStatus::APP_APPLETSTARTED => AppletStarted, APP_APPLETSTARTED => AppletStarted,
apt::APT_AppStatus::APP_APPLETCLOSED => AppletClosed APP_APPLETCLOSED => AppletClosed,
} }
} }
} }
pub struct Apt { pub struct Apt {
pd: PhantomData<()> pd: PhantomData<()>,
} }
impl Apt { impl Apt {
pub fn new() -> Result<Apt, i32> { pub fn new() -> Apt {
unsafe { Apt { pd: PhantomData }
let r = apt::aptInit();
if r < 0 {
Err(r)
} else {
Ok(Apt { pd: PhantomData })
}
}
} }
pub fn get_status(&self) -> AppStatus { pub fn get_status(&self) -> AppStatus {
@ -80,31 +75,16 @@ impl Apt {
/// The program will not return from this function until the system returns /// The program will not return from this function until the system returns
/// to the application, or when the status changes to `AppStatus::Exiting`. /// to the application, or when the status changes to `AppStatus::Exiting`.
pub fn return_to_menu(&mut self) { pub fn return_to_menu(&mut self) {
unsafe { apt::aptReturnToMenu() }; unsafe { apt::aptReturnToMenu() }
} }
pub fn main_loop(&mut self, app: &mut Application) { pub fn main_loop(&mut self) -> bool {
unsafe { unsafe {
while apt::aptMainLoop() != 0 { match apt::aptMainLoop() {
app.main_loop(self); 1 => true,
if app.ready_to_quit() { 0 => false,
self.set_status(AppStatus::Exiting) _ => unreachable!(),
} }
} }
};
} }
} }
impl Drop for Apt {
fn drop(&mut self) {
unsafe { apt::aptExit() };
}
}
pub trait Application {
/// Program app loop body.
fn main_loop(&mut self, apt: &mut Apt);
/// True if the application is ready to quit.
fn ready_to_quit(&self) -> bool;
}

18
src/services/gsp.rs → src/services/gspgpu.rs

@ -9,7 +9,7 @@ pub enum Event {
VBlank1, VBlank1,
PPF, PPF,
P3D, P3D,
DMA DMA,
} }
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
@ -18,7 +18,7 @@ pub enum FramebufferFormat {
Bgr8, Bgr8,
Rgb565, Rgb565,
Rgb5A1, Rgb5A1,
Rgba4 Rgba4,
} }
impl FramebufferFormat { impl FramebufferFormat {
@ -29,13 +29,14 @@ impl FramebufferFormat {
Bgr8 => 3usize, Bgr8 => 3usize,
Rgb565 => 2usize, Rgb565 => 2usize,
Rgb5A1 => 2usize, Rgb5A1 => 2usize,
Rgba4 => 2usize Rgba4 => 2usize,
} }
} }
} }
impl From<gspgpu::GSPGPU_FramebufferFormats> for FramebufferFormat { impl From<gspgpu::GSPGPU_FramebufferFormats> for FramebufferFormat {
#[inline] fn from(g: gspgpu::GSPGPU_FramebufferFormats) -> FramebufferFormat { #[inline]
fn from(g: gspgpu::GSPGPU_FramebufferFormats) -> FramebufferFormat {
use libctru::services::gspgpu::GSPGPU_FramebufferFormats::*; use libctru::services::gspgpu::GSPGPU_FramebufferFormats::*;
use self::FramebufferFormat::*; use self::FramebufferFormat::*;
match g { match g {
@ -43,13 +44,14 @@ impl From<gspgpu::GSPGPU_FramebufferFormats> for FramebufferFormat {
GSP_BGR8_OES => Bgr8, GSP_BGR8_OES => Bgr8,
GSP_RGB565_OES => Rgb565, GSP_RGB565_OES => Rgb565,
GSP_RGB5_A1_OES => Rgb5A1, GSP_RGB5_A1_OES => Rgb5A1,
GSP_RGBA4_OES => Rgba4 GSP_RGBA4_OES => Rgba4,
} }
} }
} }
impl From<FramebufferFormat> for gspgpu::GSPGPU_FramebufferFormats { impl From<FramebufferFormat> for gspgpu::GSPGPU_FramebufferFormats {
#[inline] fn from(g: FramebufferFormat) -> gspgpu::GSPGPU_FramebufferFormats { #[inline]
fn from(g: FramebufferFormat) -> gspgpu::GSPGPU_FramebufferFormats {
use libctru::services::gspgpu::GSPGPU_FramebufferFormats::*; use libctru::services::gspgpu::GSPGPU_FramebufferFormats::*;
use self::FramebufferFormat::*; use self::FramebufferFormat::*;
match g { match g {
@ -57,7 +59,7 @@ impl From<FramebufferFormat> for gspgpu::GSPGPU_FramebufferFormats {
Bgr8 => GSP_BGR8_OES, Bgr8 => GSP_BGR8_OES,
Rgb565 => GSP_RGB565_OES, Rgb565 => GSP_RGB565_OES,
Rgb5A1 => GSP_RGB5_A1_OES, Rgb5A1 => GSP_RGB5_A1_OES,
Rgba4 => GSP_RGBA4_OES Rgba4 => GSP_RGBA4_OES,
} }
} }
} }
@ -73,7 +75,7 @@ fn to_raw_event(ev: Event) -> gspgpu::GSPGPU_Event {
VBlank1 => GSPGPU_EVENT_VBlank1, VBlank1 => GSPGPU_EVENT_VBlank1,
PPF => GSPGPU_EVENT_PPF, PPF => GSPGPU_EVENT_PPF,
P3D => GSPGPU_EVENT_P3D, P3D => GSPGPU_EVENT_P3D,
DMA => GSPGPU_EVENT_DMA DMA => GSPGPU_EVENT_DMA,
} }
} }

23
src/services/hid.rs

@ -32,7 +32,7 @@ pub enum PadKey {
Up, Up,
Down, Down,
Left, Left,
Right Right,
} }
impl From<PadKey> for u32 { impl From<PadKey> for u32 {
@ -68,25 +68,18 @@ impl From<PadKey> for u32 {
DPadLeft => KEY_DLEFT as u32, DPadLeft => KEY_DLEFT as u32,
DPadRight => KEY_DRIGHT as u32, DPadRight => KEY_DRIGHT as u32,
DPadUp => KEY_DUP as u32, DPadUp => KEY_DUP as u32,
DPadDown => KEY_DDOWN as u32 DPadDown => KEY_DDOWN as u32,
} }
} }
} }
pub struct Hid { pub struct Hid {
pd: PhantomData<i32> pd: PhantomData<()>,
} }
impl Hid { impl Hid {
pub fn new() -> Result<Hid, i32> { pub fn new() -> Hid {
unsafe { Hid { pd: PhantomData }
let r = hid::hidInit();
if r < 0 {
Err(r)
} else {
Ok(Hid { pd: PhantomData })
}
}
} }
pub fn scan_input(&mut self) { pub fn scan_input(&mut self) {
@ -126,9 +119,3 @@ impl Hid {
} }
} }
} }
impl Drop for Hid {
fn drop(&mut self) {
unsafe { hid::hidExit() };
}
}

4
src/services/mod.rs

@ -1,6 +1,6 @@
pub mod apt; pub mod apt;
pub mod hid; pub mod hid;
pub mod gsp; pub mod gspgpu;
pub use self::hid::Hid; pub use self::hid::Hid;
pub use self::apt::{Apt, Application}; pub use self::apt::Apt;

2
src/srv.rs

@ -3,7 +3,7 @@ use libctru::srv::*;
use core::marker::PhantomData; use core::marker::PhantomData;
pub struct Srv { pub struct Srv {
pd: PhantomData<i32> pd: PhantomData<i32>,
} }
impl Srv { impl Srv {

Loading…
Cancel
Save