Browse Source

Merge remote-tracking branch 'upstream/master' into testing/custom-test-framework

pull/41/head
Ian Chamberlain 3 years ago
parent
commit
b839fc3330
No known key found for this signature in database
GPG Key ID: AE5484D09405AA60
  1. 3
      .gitignore
  2. 8
      Cargo.toml
  3. 2
      ctru-rs/Cargo.toml
  4. 73
      ctru-rs/examples/futures-basic.rs
  5. 72
      ctru-rs/examples/futures-tokio.rs
  6. 39
      ctru-rs/examples/hashmaps.rs
  7. 66
      ctru-rs/examples/thread-locals.rs
  8. 56
      ctru-rs/src/services/ps.rs
  9. 7
      ctru-rs/src/thread.rs
  10. 3
      ctru-sys/Cargo.toml
  11. 2
      ctru-sys/bindgen.sh
  12. 114
      ctru-sys/src/bindings.rs

3
.gitignore vendored

@ -1,3 +1,6 @@
target target
Cargo.lock Cargo.lock
.cargo .cargo
# IDE files
.idea

8
Cargo.toml

@ -1,2 +1,10 @@
[workspace] [workspace]
members = ["ctru-rs", "ctru-sys"] members = ["ctru-rs", "ctru-sys"]
[patch.crates-io]
# We have some changes not in the upstream
libc = { git = "https://github.com/Meziu/libc.git" }
[patch.'https://github.com/Meziu/ctru-rs']
# Make sure all dependencies use the local ctru-sys package
ctru-sys = { path = "ctru-sys" }

2
ctru-rs/Cargo.toml

@ -25,7 +25,9 @@ toml = "0.5"
[dev-dependencies] [dev-dependencies]
ferris-says = "0.2.1" ferris-says = "0.2.1"
futures = "0.3"
time = "0.3.7" time = "0.3.7"
tokio = { version = "1.16", features = ["rt", "time", "sync", "macros"] }
[features] [features]
default = ["romfs"] default = ["romfs"]

73
ctru-rs/examples/futures-basic.rs

@ -0,0 +1,73 @@
//! This example runs a basic future executor from the `futures` library.
//! Every 60 frames (about 1 second) it prints "Tick" to the console.
//! The executor runs on a separate thread. Internally it yields when it has no more work to do,
//! allowing other threads to run.
//! The example also implements clean shutdown by using a oneshot channel to end the future, thus
//! ending the executor and the thread it runs on.
use ctru::console::Console;
use ctru::services::hid::KeyPad;
use ctru::services::{Apt, Hid};
use ctru::Gfx;
use futures::StreamExt;
fn main() {
ctru::init();
let gfx = Gfx::default();
let hid = Hid::init().expect("Couldn't obtain HID controller");
let apt = Apt::init().expect("Couldn't obtain APT controller");
let _console = Console::init(gfx.top_screen.borrow_mut());
// Give ourselves up to 30% of the system core's time
apt.set_app_cpu_time_limit(30)
.expect("Failed to enable system core");
println!("Starting executor...");
let (exit_sender, mut exit_receiver) = futures::channel::oneshot::channel();
let (mut timer_sender, mut timer_receiver) = futures::channel::mpsc::channel(0);
let executor_thread = ctru::thread::Builder::new()
.affinity(1)
.spawn(move || {
let mut executor = futures::executor::LocalPool::new();
executor.run_until(async move {
loop {
futures::select! {
_ = exit_receiver => break,
_ = timer_receiver.next() => {
println!("Tick");
}
}
}
});
})
.expect("Failed to create executor thread");
println!("Executor started!");
let mut frame_count = 0;
while apt.main_loop() {
hid.scan_input();
if hid.keys_down().contains(KeyPad::KEY_START) {
println!("Shutting down...");
let _ = exit_sender.send(());
let _ = executor_thread.join();
break;
}
frame_count += 1;
if frame_count == 60 {
if let Err(e) = timer_sender.try_send(()) {
println!("Error sending timer message: {e}");
}
frame_count = 0;
}
gfx.flush_buffers();
gfx.swap_buffers();
gfx.wait_for_vblank();
}
}

72
ctru-rs/examples/futures-tokio.rs

@ -0,0 +1,72 @@
use ctru::console::Console;
use ctru::services::hid::KeyPad;
use ctru::services::ps::Ps;
use ctru::services::{Apt, Hid};
use ctru::Gfx;
use std::time::Duration;
fn main() {
ctru::init();
let gfx = Gfx::default();
let hid = Hid::init().expect("Couldn't obtain HID controller");
let apt = Apt::init().expect("Couldn't obtain APT controller");
let _ps = Ps::init().expect("Couldn't initialize PS service");
let _console = Console::init(gfx.top_screen.borrow_mut());
// Give ourselves up to 30% of the system core's time
apt.set_app_cpu_time_limit(30)
.expect("Failed to enable system core");
println!("Starting runtime...");
let (exit_sender, mut exit_receiver) = tokio::sync::oneshot::channel();
let runtime = tokio::runtime::Builder::new_current_thread()
.enable_time()
.build()
.expect("Couldn't build runtime");
let runtime_thread = ctru::thread::Builder::new()
// Run on the system core
.affinity(1)
// Use a bigger stack size. Default is 0x1000 but we'd easily overflow that.
.stack_size(0x200000)
.spawn(move || {
runtime.block_on(async move {
let mut wake_time = tokio::time::Instant::now() + Duration::from_secs(1);
let mut iteration = 0;
loop {
let sleep_future = tokio::time::sleep_until(wake_time);
tokio::select! {
// Use the first available future instead of randomizing
biased;
_ = sleep_future => {
println!("Tick {}", iteration);
iteration += 1;
wake_time += Duration::from_secs(1);
}
_ = &mut exit_receiver => break,
}
}
});
})
.expect("Failed to create runtime thread");
println!("Runtime started!");
while apt.main_loop() {
hid.scan_input();
if hid.keys_down().contains(KeyPad::KEY_START) {
println!("Shutting down...");
let _ = exit_sender.send(());
let _ = runtime_thread.join();
break;
}
gfx.flush_buffers();
gfx.swap_buffers();
gfx.wait_for_vblank();
}
}

39
ctru-rs/examples/hashmaps.rs

@ -0,0 +1,39 @@
use ctru::console::Console;
use ctru::gfx::Gfx;
use ctru::services::apt::Apt;
use ctru::services::hid::{Hid, KeyPad};
use ctru::services::ps::Ps;
fn main() {
// Initialize services
ctru::init();
let apt = Apt::init().unwrap();
let hid = Hid::init().unwrap();
let gfx = Gfx::default();
let _console = Console::init(gfx.top_screen.borrow_mut());
// HashMaps generate hashes thanks to the 3DS' criptografically secure generator.
// Sadly, this generator is only active when activating the `Ps` service.
// To do this, we have to make sure the `Ps` service handle is alive for the whole
// run time (or at least, when `HashMaps` are used).
// Not having a living `Ps` instance when using `HashMap`s results in a panic
let _ps = Ps::init().unwrap();
let mut map = std::collections::HashMap::new();
map.insert("A Key!", 102);
map.insert("Another key?", 543);
map.remove("A Key!");
println!("{:#?}", map);
while apt.main_loop() {
gfx.flush_buffers();
gfx.swap_buffers();
gfx.wait_for_vblank();
hid.scan_input();
if hid.keys_down().contains(KeyPad::KEY_START) {
break;
}
}
}

66
ctru-rs/examples/thread-locals.rs

@ -0,0 +1,66 @@
use ctru::console::Console;
use ctru::services::hid::KeyPad;
use ctru::services::{Apt, Hid};
use ctru::Gfx;
use std::cell::RefCell;
std::thread_local! {
static MY_LOCAL: RefCell<&'static str> = RefCell::new("initial value");
}
fn main() {
ctru::init();
let gfx = Gfx::default();
gfx.top_screen.borrow_mut().set_wide_mode(true);
let hid = Hid::init().expect("Couldn't obtain HID controller");
let apt = Apt::init().expect("Couldn't obtain APT controller");
let _console = Console::init(gfx.top_screen.borrow_mut());
// Give ourselves up to 30% of the system core's time
apt.set_app_cpu_time_limit(30)
.expect("Failed to enable system core");
MY_LOCAL.with(|local| {
println!("Initial value on main thread: {}", local.borrow());
*local.borrow_mut() = "second value";
});
MY_LOCAL.with(|local| {
println!("Value on main thread after mutation: {}", local.borrow());
});
ctru::thread::Builder::new()
.affinity(1)
.spawn(move || {
MY_LOCAL.with(|local| {
println!("Initial value on second thread: {}", local.borrow());
*local.borrow_mut() = "third value";
});
MY_LOCAL.with(|local| {
println!("Value on second thread after mutation: {}", local.borrow());
});
})
.expect("Failed to create thread")
.join()
.expect("Failed to join on thread");
MY_LOCAL.with(|local| {
println!(
"Value on main thread after second thread exits: {}",
local.borrow()
);
});
println!("Press Start to exit");
while apt.main_loop() {
hid.scan_input();
if hid.keys_down().contains(KeyPad::KEY_START) {
break;
}
gfx.flush_buffers();
gfx.swap_buffers();
gfx.wait_for_vblank();
}
}

56
ctru-rs/src/services/ps.rs

@ -8,6 +8,30 @@
#[non_exhaustive] #[non_exhaustive]
pub struct Ps; pub struct Ps;
#[repr(u32)]
pub enum AESAlgorithm {
CbcEnc,
CbcDec,
CtrEnc,
CtrDec,
CcmEnc,
CcmDec,
}
#[repr(u32)]
pub enum AESKeyType {
Keyslot0D,
Keyslot2D,
Keyslot31,
Keyslot38,
Keyslot32,
Keyslot39Dlp,
Keyslot2E,
KeyslotInvalid,
Keyslot36,
Keyslot39Nfc,
}
impl Ps { impl Ps {
/// Initialize the PS module. /// Initialize the PS module.
pub fn init() -> crate::Result<Self> { pub fn init() -> crate::Result<Self> {
@ -18,6 +42,38 @@ impl Ps {
Ok(Self) Ok(Self)
} }
} }
pub fn local_friend_code_seed(&self) -> crate::Result<u64> {
let mut seed: u64 = 0;
let r = unsafe { ctru_sys::PS_GetLocalFriendCodeSeed(&mut seed) };
if r < 0 {
Err(r.into())
} else {
Ok(seed)
}
}
pub fn device_id(&self) -> crate::Result<u32> {
let mut id: u32 = 0;
let r = unsafe { ctru_sys::PS_GetDeviceId(&mut id) };
if r < 0 {
Err(r.into())
} else {
Ok(id)
}
}
pub fn generate_random_bytes(&self, out: &mut [u8]) -> crate::Result<()> {
let r =
unsafe { ctru_sys::PS_GenerateRandomBytes(out as *mut _ as *mut _, out.len() as u32) };
if r < 0 {
Err(r.into())
} else {
Ok(())
}
}
} }
impl Drop for Ps { impl Drop for Ps {

7
ctru-rs/src/thread.rs

@ -1040,7 +1040,10 @@ mod thread_info {
} }
pub fn set(thread: Thread) { pub fn set(thread: Thread) {
CTRU_THREAD_INFO.with(|c| assert!(c.borrow().is_none())); CTRU_THREAD_INFO.with(move |c| {
CTRU_THREAD_INFO.with(move |c| *c.borrow_mut() = Some(ThreadInfo { thread })); let mut thread_info = c.borrow_mut();
assert!(thread_info.is_none());
*thread_info = Some(ThreadInfo { thread });
});
} }
} }

3
ctru-sys/Cargo.toml

@ -1,8 +1,9 @@
[package] [package]
name = "ctru-sys" name = "ctru-sys"
version = "0.4.0" version = "0.4.1"
authors = ["Ronald Kinard <furyhunter600@gmail.com>"] authors = ["Ronald Kinard <furyhunter600@gmail.com>"]
license = "https://en.wikipedia.org/wiki/Zlib_License" license = "https://en.wikipedia.org/wiki/Zlib_License"
links = "ctru"
edition = "2021" edition = "2021"
[dependencies] [dependencies]

2
ctru-sys/bindgen.sh

@ -26,5 +26,5 @@ bindgen "$DEVKITPRO/libctru/include/3ds.h" \
-mtune=mpcore \ -mtune=mpcore \
-mfpu=vfp \ -mfpu=vfp \
-DARM11 \ -DARM11 \
-D_3DS \ -D__3DS__ \
> src/bindings.rs > src/bindings.rs

114
ctru-sys/src/bindings.rs

@ -215,8 +215,12 @@ pub const CUR_PROCESS_HANDLE: u32 = 4294934529;
pub const ARBITRATION_SIGNAL_ALL: i32 = -1; pub const ARBITRATION_SIGNAL_ALL: i32 = -1;
pub const CUR_THREAD_HANDLE: u32 = 4294934528; pub const CUR_THREAD_HANDLE: u32 = 4294934528;
pub const SYSCLOCK_SOC: u32 = 16756991; pub const SYSCLOCK_SOC: u32 = 16756991;
pub const SYSCLOCK_SYS: u32 = 33513982;
pub const SYSCLOCK_SDMMC: u32 = 67027964;
pub const SYSCLOCK_ARM9: u32 = 134055928; pub const SYSCLOCK_ARM9: u32 = 134055928;
pub const SYSCLOCK_ARM11: u32 = 268111856; pub const SYSCLOCK_ARM11: u32 = 268111856;
pub const SYSCLOCK_ARM11_LGR1: u32 = 536223712;
pub const SYSCLOCK_ARM11_LGR2: u32 = 804335568;
pub const SYSCLOCK_ARM11_NEW: u32 = 804335568; pub const SYSCLOCK_ARM11_NEW: u32 = 804335568;
pub const CPU_TICKS_PER_MSEC: f64 = 268111.856; pub const CPU_TICKS_PER_MSEC: f64 = 268111.856;
pub const CPU_TICKS_PER_USEC: f64 = 268.111856; pub const CPU_TICKS_PER_USEC: f64 = 268.111856;
@ -277,6 +281,8 @@ pub const CONSOLE_BLINK_FAST: u32 = 32;
pub const CONSOLE_COLOR_REVERSE: u32 = 64; pub const CONSOLE_COLOR_REVERSE: u32 = 64;
pub const CONSOLE_CONCEAL: u32 = 128; pub const CONSOLE_CONCEAL: u32 = 128;
pub const CONSOLE_CROSSED_OUT: u32 = 256; pub const CONSOLE_CROSSED_OUT: u32 = 256;
pub const CONSOLE_FG_CUSTOM: u32 = 512;
pub const CONSOLE_BG_CUSTOM: u32 = 1024;
pub const __GNUCLIKE_ASM: u32 = 3; pub const __GNUCLIKE_ASM: u32 = 3;
pub const __GNUCLIKE___TYPEOF: u32 = 1; pub const __GNUCLIKE___TYPEOF: u32 = 1;
pub const __GNUCLIKE___OFFSETOF: u32 = 1; pub const __GNUCLIKE___OFFSETOF: u32 = 1;
@ -1216,6 +1222,7 @@ pub const MIISELECTOR_GUESTMII_SLOTS: u32 = 6;
pub const MIISELECTOR_USERMII_SLOTS: u32 = 100; pub const MIISELECTOR_USERMII_SLOTS: u32 = 100;
pub const MIISELECTOR_GUESTMII_NAME_LEN: u32 = 12; pub const MIISELECTOR_GUESTMII_NAME_LEN: u32 = 12;
pub const ARCHIVE_DIRITER_MAGIC: u32 = 1751347809; pub const ARCHIVE_DIRITER_MAGIC: u32 = 1751347809;
pub const LINK3DS_COMM_PORT: u32 = 17491;
pub type __int8_t = ::libc::c_schar; pub type __int8_t = ::libc::c_schar;
pub type __uint8_t = ::libc::c_uchar; pub type __uint8_t = ::libc::c_uchar;
pub type __int16_t = ::libc::c_short; pub type __int16_t = ::libc::c_short;
@ -3446,7 +3453,10 @@ extern "C" {
fb_b: *const ::libc::c_void, fb_b: *const ::libc::c_void,
stride: u32_, stride: u32_,
mode: u32_, mode: u32_,
); ) -> bool;
}
extern "C" {
pub fn gspIsPresentPending(screen: ::libc::c_uint) -> bool;
} }
extern "C" { extern "C" {
pub fn gspSetEventCallback( pub fn gspSetEventCallback(
@ -3628,8 +3638,8 @@ pub struct PrintConsole {
pub windowWidth: ::libc::c_int, pub windowWidth: ::libc::c_int,
pub windowHeight: ::libc::c_int, pub windowHeight: ::libc::c_int,
pub tabSize: ::libc::c_int, pub tabSize: ::libc::c_int,
pub fg: ::libc::c_int, pub fg: u16_,
pub bg: ::libc::c_int, pub bg: u16_,
pub flags: ::libc::c_int, pub flags: ::libc::c_int,
pub PrintChar: ConsolePrint, pub PrintChar: ConsolePrint,
pub consoleInitialised: bool, pub consoleInitialised: bool,
@ -4040,12 +4050,26 @@ extern "C" {
extern "C" { extern "C" {
pub fn mappableFree(mem: *mut ::libc::c_void); pub fn mappableFree(mem: *mut ::libc::c_void);
} }
pub const VRAM_ALLOC_A: vramAllocPos = 1;
pub const VRAM_ALLOC_B: vramAllocPos = 2;
pub const VRAM_ALLOC_ANY: vramAllocPos = 3;
pub type vramAllocPos = ::libc::c_uint;
extern "C" { extern "C" {
pub fn vramAlloc(size: size_t) -> *mut ::libc::c_void; pub fn vramAlloc(size: size_t) -> *mut ::libc::c_void;
} }
extern "C" {
pub fn vramAllocAt(size: size_t, pos: vramAllocPos) -> *mut ::libc::c_void;
}
extern "C" { extern "C" {
pub fn vramMemAlign(size: size_t, alignment: size_t) -> *mut ::libc::c_void; pub fn vramMemAlign(size: size_t, alignment: size_t) -> *mut ::libc::c_void;
} }
extern "C" {
pub fn vramMemAlignAt(
size: size_t,
alignment: size_t,
pos: vramAllocPos,
) -> *mut ::libc::c_void;
}
extern "C" { extern "C" {
pub fn vramRealloc(mem: *mut ::libc::c_void, size: size_t) -> *mut ::libc::c_void; pub fn vramRealloc(mem: *mut ::libc::c_void, size: size_t) -> *mut ::libc::c_void;
} }
@ -4414,6 +4438,13 @@ impl Default for FS_Path {
} }
} }
} }
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct FS_SdMmcSpeedInfo {
pub highSpeedModeEnabled: bool,
pub usesHighestClockRate: bool,
pub sdClkCtrl: u16_,
}
pub type FS_Archive = u64_; pub type FS_Archive = u64_;
extern "C" { extern "C" {
pub fn fsInit() -> Result; pub fn fsInit() -> Result;
@ -4553,10 +4584,10 @@ extern "C" {
pub fn FSUSER_GetNandCid(out: *mut u8_, length: u32_) -> Result; pub fn FSUSER_GetNandCid(out: *mut u8_, length: u32_) -> Result;
} }
extern "C" { extern "C" {
pub fn FSUSER_GetSdmcSpeedInfo(speedInfo: *mut u32_) -> Result; pub fn FSUSER_GetSdmcSpeedInfo(speedInfo: *mut FS_SdMmcSpeedInfo) -> Result;
} }
extern "C" { extern "C" {
pub fn FSUSER_GetNandSpeedInfo(speedInfo: *mut u32_) -> Result; pub fn FSUSER_GetNandSpeedInfo(speedInfo: *mut FS_SdMmcSpeedInfo) -> Result;
} }
extern "C" { extern "C" {
pub fn FSUSER_GetSdmcLog(out: *mut u8_, length: u32_) -> Result; pub fn FSUSER_GetSdmcLog(out: *mut u8_, length: u32_) -> Result;
@ -5027,6 +5058,19 @@ pub struct AM_TWLPartitionInfo {
pub titlesCapacity: u64_, pub titlesCapacity: u64_,
pub titlesFreeSpace: u64_, pub titlesFreeSpace: u64_,
} }
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct AM_ContentInfo {
pub index: u16_,
pub type_: u16_,
pub contentId: u32_,
pub size: u64_,
pub flags: u8_,
pub padding: [u8_; 7usize],
}
pub const AM_CONTENT_DOWNLOADED: AM_ContentInfoFlags = 1;
pub const AM_CONTENT_OWNED: AM_ContentInfoFlags = 2;
pub type AM_ContentInfoFlags = ::libc::c_uint;
extern "C" { extern "C" {
pub fn amInit() -> Result; pub fn amInit() -> Result;
} }
@ -5325,6 +5369,23 @@ extern "C" {
extern "C" { extern "C" {
pub fn AM_DeleteAllTwlTitles() -> Result; pub fn AM_DeleteAllTwlTitles() -> Result;
} }
extern "C" {
pub fn AMAPP_GetDLCContentInfoCount(
count: *mut u32_,
mediatype: FS_MediaType,
titleID: u64_,
) -> Result;
}
extern "C" {
pub fn AMAPP_ListDLCContentInfos(
contentInfoRead: *mut u32_,
mediatype: FS_MediaType,
titleID: u64_,
contentInfoCount: u32_,
offset: u32_,
contentInfos: *mut AM_ContentInfo,
) -> Result;
}
extern "C" { extern "C" {
pub fn ampxiInit(servhandle: Handle) -> Result; pub fn ampxiInit(servhandle: Handle) -> Result;
} }
@ -7305,10 +7366,10 @@ extern "C" {
pub fn FSPXI_GetNandCid(serviceHandle: Handle, out: *mut ::libc::c_void, size: u32_) -> Result; pub fn FSPXI_GetNandCid(serviceHandle: Handle, out: *mut ::libc::c_void, size: u32_) -> Result;
} }
extern "C" { extern "C" {
pub fn FSPXI_GetSdmcSpeedInfo(serviceHandle: Handle, out: *mut u32_) -> Result; pub fn FSPXI_GetSdmcSpeedInfo(serviceHandle: Handle, out: *mut FS_SdMmcSpeedInfo) -> Result;
} }
extern "C" { extern "C" {
pub fn FSPXI_GetNandSpeedInfo(serviceHandle: Handle, out: *mut u32_) -> Result; pub fn FSPXI_GetNandSpeedInfo(serviceHandle: Handle, out: *mut FS_SdMmcSpeedInfo) -> Result;
} }
extern "C" { extern "C" {
pub fn FSPXI_GetSdmcLog(serviceHandle: Handle, out: *mut ::libc::c_void, size: u32_) -> Result; pub fn FSPXI_GetSdmcLog(serviceHandle: Handle, out: *mut ::libc::c_void, size: u32_) -> Result;
@ -10314,6 +10375,9 @@ extern "C" {
extern "C" { extern "C" {
pub fn ptmuExit(); pub fn ptmuExit();
} }
extern "C" {
pub fn ptmuGetSessionHandle() -> *mut Handle;
}
extern "C" { extern "C" {
pub fn PTMU_GetShellState(out: *mut u8_) -> Result; pub fn PTMU_GetShellState(out: *mut u8_) -> Result;
} }
@ -10361,6 +10425,9 @@ extern "C" {
extern "C" { extern "C" {
pub fn ptmSysmExit(); pub fn ptmSysmExit();
} }
extern "C" {
pub fn ptmSysmGetSessionHandle() -> *mut Handle;
}
extern "C" { extern "C" {
pub fn PTMSYSM_RequestSleep() -> Result; pub fn PTMSYSM_RequestSleep() -> Result;
} }
@ -10379,6 +10446,9 @@ extern "C" {
extern "C" { extern "C" {
pub fn PTMSYSM_Awaken() -> Result; pub fn PTMSYSM_Awaken() -> Result;
} }
extern "C" {
pub fn PTMSYSM_SetUserTime(msY2k: s64) -> Result;
}
extern "C" { extern "C" {
pub fn PTMSYSM_InvalidateSystemTime() -> Result; pub fn PTMSYSM_InvalidateSystemTime() -> Result;
} }
@ -10400,6 +10470,30 @@ extern "C" {
extern "C" { extern "C" {
pub fn PTMSYSM_RebootAsync(timeout: u64_) -> Result; pub fn PTMSYSM_RebootAsync(timeout: u64_) -> Result;
} }
extern "C" {
pub fn ptmGetsInit() -> Result;
}
extern "C" {
pub fn ptmGetsExit();
}
extern "C" {
pub fn ptmGetsGetSessionHandle() -> *mut Handle;
}
extern "C" {
pub fn PTMGETS_GetSystemTime(outMsY2k: *mut s64) -> Result;
}
extern "C" {
pub fn ptmSetsInit() -> Result;
}
extern "C" {
pub fn ptmSetsExit();
}
extern "C" {
pub fn ptmSetsGetSessionHandle() -> *mut Handle;
}
extern "C" {
pub fn PTMSETS_SetSystemTime(msY2k: s64) -> Result;
}
pub const WAIT_NONE: PXIDEV_WaitType = 0; pub const WAIT_NONE: PXIDEV_WaitType = 0;
pub const WAIT_SLEEP: PXIDEV_WaitType = 1; pub const WAIT_SLEEP: PXIDEV_WaitType = 1;
pub const WAIT_IREQ_RETURN: PXIDEV_WaitType = 2; pub const WAIT_IREQ_RETURN: PXIDEV_WaitType = 2;
@ -13543,3 +13637,9 @@ extern "C" {
extern "C" { extern "C" {
pub fn gdbHioDevSystem(command: *const ::libc::c_char) -> ::libc::c_int; pub fn gdbHioDevSystem(command: *const ::libc::c_char) -> ::libc::c_int;
} }
extern "C" {
pub static mut __3dslink_host: in_addr;
}
extern "C" {
pub fn link3dsConnectToHost(redirStdout: bool, redirStderr: bool) -> ::libc::c_int;
}

Loading…
Cancel
Save