Browse Source

Update to latest libctru

Includes fixes from vivlim and Meziu, such as two static libraries that
fix missing symbols during linking.
pull/10/head
AzureMarker 3 years ago
parent
commit
82d0055b22
No known key found for this signature in database
GPG Key ID: 47A133F3BF9D03D3
  1. 30
      ctru-rs/src/applets/swkbd.rs
  2. 10
      ctru-rs/src/lib.rs
  3. 4
      ctru-rs/src/sdmc.rs
  4. 6
      ctru-rs/src/services/gspgpu.rs
  5. 41
      ctru-rs/src/thread.rs
  6. 13
      ctru-sys/Cargo.toml
  7. 11
      ctru-sys/bindgen.sh
  8. 28
      ctru-sys/build.rs
  9. BIN
      ctru-sys/liblinker_fix_3ds.a
  10. BIN
      ctru-sys/libpthread_3ds.a
  11. 7539
      ctru-sys/src/bindings.rs
  12. 5
      ctru-sys/src/lib.rs

30
ctru-rs/src/applets/swkbd.rs

@ -1,9 +1,11 @@
use std::convert::TryInto;
use std::iter::once; use std::iter::once;
use std::mem; use std::mem;
use std::str; use std::str;
use libctru::{self, SwkbdState, swkbdInit, swkbdSetFeatures, swkbdSetHintText, swkbdInputText, use libctru::{
swkbdSetButton}; self, swkbdInit, swkbdInputText, swkbdSetButton, swkbdSetFeatures, swkbdSetHintText, SwkbdState,
};
use libc; use libc;
@ -127,7 +129,11 @@ impl Swkbd {
/// the output will be truncated but should still be well-formed UTF-8 /// the output will be truncated but should still be well-formed UTF-8
pub fn get_bytes(&mut self, buf: &mut [u8]) -> Result<Button, Error> { pub fn get_bytes(&mut self, buf: &mut [u8]) -> Result<Button, Error> {
unsafe { unsafe {
match swkbdInputText(self.state.as_mut(), buf.as_mut_ptr(), buf.len()) { match swkbdInputText(
self.state.as_mut(),
buf.as_mut_ptr(),
buf.len().try_into().unwrap(),
) {
libctru::SWKBD_BUTTON_NONE => Err(self.parse_swkbd_error()), libctru::SWKBD_BUTTON_NONE => Err(self.parse_swkbd_error()),
libctru::SWKBD_BUTTON_LEFT => Ok(Button::Left), libctru::SWKBD_BUTTON_LEFT => Ok(Button::Left),
libctru::SWKBD_BUTTON_MIDDLE => Ok(Button::Middle), libctru::SWKBD_BUTTON_MIDDLE => Ok(Button::Middle),
@ -139,14 +145,11 @@ impl Swkbd {
/// Sets special features for this keyboard /// Sets special features for this keyboard
pub fn set_features(&mut self, features: Features) { pub fn set_features(&mut self, features: Features) {
unsafe { unsafe { swkbdSetFeatures(self.state.as_mut(), features.bits) }
swkbdSetFeatures(self.state.as_mut(), features.bits)
}
} }
/// Configures input validation for this keyboard /// Configures input validation for this keyboard
pub fn set_validation(&mut self, validation: ValidInput, pub fn set_validation(&mut self, validation: ValidInput, filters: Filters) {
filters: Filters) {
self.state.valid_input = validation as i32; self.state.valid_input = validation as i32;
self.state.filter_flags = filters.bits; self.state.filter_flags = filters.bits;
} }
@ -157,7 +160,7 @@ impl Swkbd {
self.state.max_digits = digits; self.state.max_digits = digits;
} }
/// Sets the hint text for this software keyboard (that is, the help text that is displayed /// Sets the hint text for this software keyboard (that is, the help text that is displayed
/// when the textbox is empty) /// when the textbox is empty)
pub fn set_hint_text(&mut self, text: &str) { pub fn set_hint_text(&mut self, text: &str) {
unsafe { unsafe {
@ -175,13 +178,18 @@ impl Swkbd {
pub fn configure_button(&mut self, button: Button, text: &str, submit: bool) { pub fn configure_button(&mut self, button: Button, text: &str, submit: bool) {
unsafe { unsafe {
let nul_terminated: String = text.chars().chain(once('\0')).collect(); let nul_terminated: String = text.chars().chain(once('\0')).collect();
swkbdSetButton(self.state.as_mut(), button as u32, nul_terminated.as_ptr(), submit); swkbdSetButton(
self.state.as_mut(),
button as u32,
nul_terminated.as_ptr(),
submit,
);
} }
} }
/// Configures the maximum number of UTF-16 code units that can be entered into the software /// Configures the maximum number of UTF-16 code units that can be entered into the software
/// keyboard. By default the limit is 0xFDE8 code units. /// keyboard. By default the limit is 0xFDE8 code units.
/// ///
/// Note that keyboard input is converted from UTF-16 to UTF-8 before being handed to Rust, /// Note that keyboard input is converted from UTF-16 to UTF-8 before being handed to Rust,
/// so this code point limit does not necessarily equal the max number of UTF-8 code points /// so this code point limit does not necessarily equal the max number of UTF-8 code points
/// receivable by the `get_utf8` and `get_bytes` functions. /// receivable by the `get_utf8` and `get_bytes` functions.

10
ctru-rs/src/lib.rs

@ -1,8 +1,6 @@
#![crate_type = "rlib"] #![crate_type = "rlib"]
#![crate_name = "ctru"] #![crate_name = "ctru"]
#![feature(fnbox)]
#[macro_use] #[macro_use]
extern crate bitflags; extern crate bitflags;
extern crate libc; extern crate libc;
@ -13,14 +11,14 @@ extern crate ctru_sys as libctru;
pub mod applets; pub mod applets;
pub mod console; pub mod console;
pub mod error; pub mod error;
pub mod srv;
pub mod gfx; pub mod gfx;
pub mod services;
pub mod sdmc; pub mod sdmc;
pub mod services;
pub mod srv;
pub mod thread; pub mod thread;
pub use error::{Result, Error}; pub use error::{Error, Result};
pub use srv::Srv;
pub use gfx::Gfx; pub use gfx::Gfx;
pub use sdmc::Sdmc; pub use sdmc::Sdmc;
pub use srv::Srv;

4
ctru-rs/src/sdmc.rs

@ -3,7 +3,7 @@ pub struct Sdmc(());
impl Sdmc { impl Sdmc {
pub fn init() -> ::Result<Sdmc> { pub fn init() -> ::Result<Sdmc> {
unsafe { unsafe {
let r = ::libctru::sdmcInit(); let r = ::libctru::archiveMountSdmc();
if r < 0 { if r < 0 {
Err(r.into()) Err(r.into())
} else { } else {
@ -15,6 +15,6 @@ impl Sdmc {
impl Drop for Sdmc { impl Drop for Sdmc {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { ::libctru::sdmcExit() }; unsafe { ::libctru::archiveUnmountAll() };
} }
} }

6
ctru-rs/src/services/gspgpu.rs

@ -51,8 +51,8 @@ pub fn wait_for_event(ev: Event, discard_current: bool) {
} }
} }
impl From<::libctru::GSPGPU_FramebufferFormats> for FramebufferFormat { impl From<::libctru::GSPGPU_FramebufferFormat> for FramebufferFormat {
fn from(g: ::libctru::GSPGPU_FramebufferFormats) -> Self { fn from(g: ::libctru::GSPGPU_FramebufferFormat) -> Self {
use self::FramebufferFormat::*; use self::FramebufferFormat::*;
match g { match g {
::libctru::GSP_RGBA8_OES => Rgba8, ::libctru::GSP_RGBA8_OES => Rgba8,
@ -65,7 +65,7 @@ impl From<::libctru::GSPGPU_FramebufferFormats> for FramebufferFormat {
} }
} }
impl From<FramebufferFormat> for ::libctru::GSPGPU_FramebufferFormats { impl From<FramebufferFormat> for ::libctru::GSPGPU_FramebufferFormat {
fn from(g: FramebufferFormat) -> Self { fn from(g: FramebufferFormat) -> Self {
use self::FramebufferFormat::*; use self::FramebufferFormat::*;
match g { match g {

41
ctru-rs/src/thread.rs

@ -37,9 +37,9 @@ use std::cell::UnsafeCell;
use std::fmt; use std::fmt;
use std::io; use std::io;
use std::panic; use std::panic;
use std::sync::{Arc, Condvar, Mutex};
use std::sync::atomic::AtomicUsize; use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering::SeqCst; use std::sync::atomic::Ordering::SeqCst;
use std::sync::{Arc, Condvar, Mutex};
use std::thread as std_thread; use std::thread as std_thread;
use std::time::Duration; use std::time::Duration;
@ -200,12 +200,10 @@ impl Builder {
let my_packet: Arc<UnsafeCell<Option<Result<T>>>> = Arc::new(UnsafeCell::new(None)); let my_packet: Arc<UnsafeCell<Option<Result<T>>>> = Arc::new(UnsafeCell::new(None));
let their_packet = my_packet.clone(); let their_packet = my_packet.clone();
let main = move || { let main = move || unsafe {
unsafe { thread_info::set(their_thread);
thread_info::set(their_thread); let try_result = panic::catch_unwind(panic::AssertUnwindSafe(f));
let try_result = panic::catch_unwind(panic::AssertUnwindSafe(f)); *their_packet.get() = Some(try_result);
*their_packet.get() = Some(try_result);
}
}; };
Ok(JoinHandle(JoinInner { Ok(JoinHandle(JoinInner {
@ -635,7 +633,8 @@ impl Thread {
/// [park]: fn.park.html /// [park]: fn.park.html
pub fn unpark(&self) { pub fn unpark(&self) {
loop { loop {
match self.inner match self
.inner
.state .state
.compare_exchange(EMPTY, NOTIFIED, SeqCst, SeqCst) .compare_exchange(EMPTY, NOTIFIED, SeqCst, SeqCst)
{ {
@ -647,7 +646,8 @@ impl Thread {
// Coordinate wakeup through the mutex and a condvar notification // Coordinate wakeup through the mutex and a condvar notification
let _lock = self.inner.lock.lock().unwrap(); let _lock = self.inner.lock.lock().unwrap();
match self.inner match self
.inner
.state .state
.compare_exchange(PARKED, NOTIFIED, SeqCst, SeqCst) .compare_exchange(PARKED, NOTIFIED, SeqCst, SeqCst)
{ {
@ -886,8 +886,9 @@ fn _assert_sync_and_send() {
} }
mod imp { mod imp {
use std::boxed::FnBox; use std::boxed::Box;
use std::cmp; use std::cmp;
use std::convert::TryInto;
use std::io; use std::io;
use std::mem; use std::mem;
use std::ptr; use std::ptr;
@ -895,8 +896,10 @@ mod imp {
use libc; use libc;
use libctru::{Thread as ThreadHandle, svcSleepThread, svcGetThreadId, svcGetThreadPriority, use libctru::{
svcGetProcessorID, threadCreate, threadDetach, threadFree, threadJoin}; svcGetProcessorID, svcGetThreadId, svcGetThreadPriority, svcSleepThread, threadCreate,
threadDetach, threadFree, threadJoin, Thread as ThreadHandle,
};
pub struct Thread { pub struct Thread {
handle: ThreadHandle, handle: ThreadHandle,
@ -912,7 +915,7 @@ mod imp {
stack: usize, stack: usize,
priority: i32, priority: i32,
affinity: i32, affinity: i32,
p: Box<FnBox() + 'a>, p: Box<dyn FnOnce() + 'a>,
) -> io::Result<Thread> { ) -> io::Result<Thread> {
let p = Box::new(p); let p = Box::new(p);
let stack_size = cmp::max(stack, DEFAULT_MIN_STACK_SIZE); let stack_size = cmp::max(stack, DEFAULT_MIN_STACK_SIZE);
@ -920,7 +923,7 @@ mod imp {
let handle = threadCreate( let handle = threadCreate(
Some(thread_func), Some(thread_func),
&*p as *const _ as *mut _, &*p as *const _ as *mut _,
stack_size, stack_size.try_into().unwrap(),
priority, priority,
affinity, affinity,
false, false,
@ -955,13 +958,11 @@ mod imp {
} }
pub fn affinity() -> i32 { pub fn affinity() -> i32 {
unsafe { unsafe { svcGetProcessorID() }
svcGetProcessorID()
}
} }
unsafe fn _start_thread(main: *mut u8) { unsafe fn _start_thread(main: *mut u8) {
Box::from_raw(main as *mut Box<FnBox()>)() Box::from_raw(main as *mut Box<dyn FnOnce()>)()
} }
pub fn yield_now() { pub fn yield_now() {
@ -970,7 +971,8 @@ mod imp {
pub fn sleep(dur: Duration) { pub fn sleep(dur: Duration) {
unsafe { unsafe {
let nanos = dur.as_secs() let nanos = dur
.as_secs()
.saturating_mul(1_000_000_000) .saturating_mul(1_000_000_000)
.saturating_add(dur.subsec_nanos() as u64); .saturating_add(dur.subsec_nanos() as u64);
svcSleepThread(nanos as i64) svcSleepThread(nanos as i64)
@ -986,7 +988,6 @@ mod imp {
} }
} }
#[allow(dead_code)] #[allow(dead_code)]
pub fn handle(&self) -> ThreadHandle { pub fn handle(&self) -> ThreadHandle {
self.handle self.handle

13
ctru-sys/Cargo.toml

@ -4,14 +4,5 @@ version = "0.4.0"
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"
[dependencies.libc] [dependencies]
version = "0.2" libc = { version = "0.2", default-features = false }
default-features = false
optional = true
[features]
default = ["libc"]
# This is a dummy feature that only exists to work around a Xargo issue.
# User code should not enable it.
stdbuild = []

11
ctru-sys/bindgen.sh

@ -1,14 +1,5 @@
#!/usr/bin/env bash #!/usr/bin/env bash
clang_version=$1
if [ -z "$clang_version" ]; then
echo " usage: ./bindgen.sh <clang_version>"
echo "example: ./bindgen.sh 5.0.0"
echo "Check your current version with \`clang -v\`."
exit 1
fi
set -euxo pipefail set -euxo pipefail
bindgen "$DEVKITPRO/libctru/include/3ds.h" \ bindgen "$DEVKITPRO/libctru/include/3ds.h" \
@ -23,11 +14,11 @@ bindgen "$DEVKITPRO/libctru/include/3ds.h" \
--blacklist-type "u(8|16|32|64)" \ --blacklist-type "u(8|16|32|64)" \
--blacklist-type "__builtin_va_list" \ --blacklist-type "__builtin_va_list" \
--blacklist-type "__va_list" \ --blacklist-type "__va_list" \
--opaque-type "MiiData" \
-- \ -- \
--target=arm-none-eabi \ --target=arm-none-eabi \
--sysroot=$DEVKITARM/arm-none-eabi \ --sysroot=$DEVKITARM/arm-none-eabi \
-isystem$DEVKITARM/arm-none-eabi/include \ -isystem$DEVKITARM/arm-none-eabi/include \
-isystem/usr/lib/clang/$clang_version/include \
-I$DEVKITPRO/libctru/include \ -I$DEVKITPRO/libctru/include \
-mfloat-abi=hard \ -mfloat-abi=hard \
-march=armv6k \ -march=armv6k \

28
ctru-sys/build.rs

@ -2,10 +2,30 @@ use std::env;
fn main() { fn main() {
let dkp_path = env::var("DEVKITPRO").unwrap(); let dkp_path = env::var("DEVKITPRO").unwrap();
let manifest_path = env::var("CARGO_MANIFEST_DIR").unwrap();
let profile = env::var("PROFILE").unwrap();
println!("cargo:rustc-link-search=native={}/libctru/lib", dkp_path); println!("cargo:rustc-link-search=native={}/libctru/lib", dkp_path);
println!("cargo:rustc-link-lib=static={}", match env::var("PROFILE").unwrap().as_str() { println!("cargo:rustc-link-search=native={}", manifest_path);
"debug" => "ctrud", println!(
_ => "ctru", "cargo:rustc-link-search=native={}/devkitARM/arm-none-eabi/lib/armv6k/fpu",
}); dkp_path
);
println!(
"cargo:rustc-link-search=native={}/devkitARM/lib/gcc/arm-none-eabi/11.1.0/armv6k/fpu",
dkp_path
);
println!(
"cargo:rustc-link-lib=static={}",
match profile.as_str() {
"debug" => "ctrud",
_ => "ctru",
}
);
println!("cargo:rustc-link-lib=static=gcc");
println!("cargo:rustc-link-lib=static=sysbase");
println!("cargo:rustc-link-lib=static=c");
println!("cargo:rustc-link-lib=static=pthread_3ds");
println!("cargo:rustc-link-lib=static=linker_fix_3ds");
} }

BIN
ctru-sys/liblinker_fix_3ds.a

Binary file not shown.

BIN
ctru-sys/libpthread_3ds.a

Binary file not shown.

7539
ctru-sys/src/bindings.rs

File diff suppressed because it is too large Load Diff

5
ctru-sys/src/lib.rs

@ -1,13 +1,8 @@
#![allow(non_upper_case_globals)] #![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)] #![allow(non_camel_case_types)]
#![allow(non_snake_case)] #![allow(non_snake_case)]
#![feature(const_fn)]
#![no_std] #![no_std]
#![cfg_attr(feature = "stdbuild", feature(libc))]
extern crate libc; extern crate libc;
include!("bindings.rs"); include!("bindings.rs");

Loading…
Cancel
Save