Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve documentation and examples #134

Merged
merged 39 commits into from
Aug 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
243863c
Fixed wrong type quotations
Meziu May 6, 2023
f497a1f
General setup for the new documentation
Meziu Jul 6, 2023
cd7a041
error module documentation
Meziu Jul 7, 2023
9b97e90
Renew manifests and fix warnings
Meziu Jul 7, 2023
39829e1
Am, Apt and refactoring to streamline the API and docs
Meziu Jul 8, 2023
d315ebd
doc(alias) everywhere
Meziu Jul 8, 2023
61e20fa
Enum variants documentation + ide files ignored
Meziu Jul 8, 2023
4124df8
Fixed all compiler warnings for docs
Meziu Jul 9, 2023
73d3f40
Publish-ready Cargo manifests
Meziu Jul 16, 2023
4a1c695
Fixed only doc lint
Meziu Jul 16, 2023
10f70aa
New READMEs and fixed package labeling
Meziu Jul 19, 2023
9662b87
Fmt
Meziu Jul 19, 2023
afc74fd
New doc changes and bump bitflags dependency
Meziu Jul 19, 2023
fafe3c3
Finish MiiSelector applet documentation
Meziu Jul 19, 2023
ab8a440
Finalize applets
Meziu Jul 19, 2023
127eafd
Small changes and finalized AM service
Meziu Jul 22, 2023
30c3fb0
Small example fmt
Meziu Jul 22, 2023
fde168c
Finish up SSLC, SOC, ROMFS and PS
Meziu Jul 22, 2023
db2bb7c
Finished HID and CFGU
Meziu Jul 22, 2023
1245860
Finish up GFX
Meziu Jul 22, 2023
3085b3e
Docs-rs rules for ctru-sys
Meziu Jul 25, 2023
ef4860c
Finalize NDSP and Wave
Meziu Jul 25, 2023
3d3a59a
Finalize CAM service
Meziu Jul 26, 2023
ccb0676
More generic doc changes
Meziu Jul 26, 2023
acb1d3f
Finalize Mii module
Meziu Jul 26, 2023
a184e7a
Finalize Console docs
Meziu Jul 27, 2023
9c95544
Finalize examples
Meziu Jul 27, 2023
2af0268
Fix examples after thorough testing
Meziu Jul 28, 2023
99d1b91
Fixed clippy warnings
Meziu Jul 28, 2023
1640e20
Finishing touches after complete revision
Meziu Jul 28, 2023
8328721
Fmt
Meziu Jul 28, 2023
354b9e3
Change Actions minimum nightly
Meziu Jul 28, 2023
47e3a73
Fix typo in play_shutter_sound docs
Meziu Jul 29, 2023
79e0d04
Update ctru-rs/examples/file-explorer.rs
Meziu Aug 4, 2023
f260e94
Update ctru-rs/examples/gfx-3d-mode.rs
Meziu Aug 4, 2023
fde132a
Apply suggestions from code review
Meziu Aug 5, 2023
414b760
Easy fixes to review suggestions
Meziu Aug 5, 2023
00f264b
Module doc aliases
Meziu Aug 5, 2023
869cd50
Fixed romfs suggestions
Meziu Aug 5, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
matrix:
toolchain:
# Run against a "known good" nightly
- nightly-2023-01-13
- nightly-2023-05-31
# Check for breakage on latest nightly
- nightly

Expand Down Expand Up @@ -57,7 +57,7 @@ jobs:
strategy:
matrix:
toolchain:
- nightly-2023-01-13
- nightly-2023-05-31
- nightly
continue-on-error: ${{ matrix.toolchain == 'nightly' }}
runs-on: ubuntu-latest
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ Cargo.lock

# IDE files
.idea
.vscode
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[workspace]
members = ["ctru-rs", "ctru-sys", "ctru-sys/bindgen-ctru-sys"]
default-members = ["ctru-rs", "ctru-sys"]
resolver = "2"

[patch.'https://github.com/rust3ds/ctru-rs']
# Make sure all dependencies use the local ctru-sys package
Expand Down
32 changes: 13 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,33 +1,27 @@
# ctru-rs

A Rust wrapper library for smealum's [ctrulib](https://github.com/smealum/ctrulib).
This repository is home of the `ctru-rs` project, which aims to bring full control of the Nintendo 3DS console to homebrew developers using Rust.

## Structure

This repository is organized as follows:

* `ctru-rs`: Safe, idiomatic wrapper around `ctru-sys`
* [`ctru-rs`](./ctru-rs/) - Safe, idiomatic wrapper around [`ctru-sys`](./ctru-sys/).
* [`ctru-sys`](./ctru-sys/) - Low-level, unsafe bindings to [`libctru`](https://github.com/devkitPro/libctru).

* `ctru-sys`: Low-level, unsafe bindings to ctrulib.
## Getting Started

This crate's version changes according to the version of `libctru`
used to generate the bindings, with the following convention:

* `libctru` version `X.Y.Z-W`
* `ctru-sys` version `XY.Z.P+X.Y.Z-W`

where `P` is usually 0 but may be incremented for fixes in e.g.
binding generation, `libc` dependency bump, etc.

It may be possible to build this crate against a different version of `libctru`,
but you may encounter linker errors or ABI issues. A build-time Cargo warning
(displayed when built with `-vv`) will be issued if the build script detects
a mismatch or is unable to check the installed `libctru` version.
Specific information about how to use the crates is present in the individual README for each package.
Have a look at `ctru-rs`' [README.md](./ctru-rs/README.md) for a broad overview.

## Original version

This project is based on the efforts the original authors:
* [Eidolon](https://github.com/HybridEidolon)
* [FenrirWolf](https://github.com/FenrirWolf)
This project is based on the efforts of the original authors:
* [Eidolon](https://github.com/HybridEidolon)
* [FenrirWolf](https://github.com/FenrirWolf)

The old version is archived [here](https://github.com/rust3ds/ctru-rs-old).

## License

This project is distributed under the Zlib license.
19 changes: 14 additions & 5 deletions ctru-rs/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
[package]
authors = ["Rust3DS Org", "Ronald Kinard <[email protected]>"]
description = "A safe wrapper around smealum's ctrulib."
license = "Zlib"
name = "ctru-rs"
version = "0.7.1"
authors = ["Rust3DS Org", "Ronald Kinard <[email protected]>"]
description = "A safe wrapper around libctru"
repository = "https://github.com/rust3ds/ctru-rs"
keywords = ["3ds", "libctru"]
Meziu marked this conversation as resolved.
Show resolved Hide resolved
categories = ["os", "api-bindings", "hardware-support"]
exclude = ["examples"]
Meziu marked this conversation as resolved.
Show resolved Hide resolved
license = "Zlib"
edition = "2021"
rust-version = "1.64"
rust-version = "1.70"

[lib]
crate-type = ["rlib"]
Expand All @@ -18,7 +22,7 @@ const-zero = "0.1.0"
shim-3ds = { git = "https://github.com/rust3ds/shim-3ds.git" }
pthread-3ds = { git = "https://github.com/rust3ds/pthread-3ds.git" }
libc = "0.2.121"
bitflags = "1.0.0"
bitflags = "2.3.3"
widestring = "0.2.2"

[build-dependencies]
Expand All @@ -45,6 +49,11 @@ std-threads = []
[package.metadata.cargo-3ds]
romfs_dir = "examples/romfs"

[package.metadata.docs.rs]
default-target = "armv6k-nintendo-3ds"
targets = []
cargo-args = ["-Z", "build-std"]
Meziu marked this conversation as resolved.
Show resolved Hide resolved

[[example]]
name = "thread-basic"
required-features = ["std-threads"]
Expand Down
22 changes: 22 additions & 0 deletions ctru-rs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# ctru-rs

Safe and idiomatic Rust wrapper around [`libctru`](https://github.com/devkitPro/libctru).

## Getting Started

Thoroughly read the [`ctru-rs` wiki](https://github.com/rust3ds/ctru-rs/wiki/Getting-Started) to meet the requirements
and to understand what it takes to develop homebrew software on the Nintendo 3DS family of consoles.
After that, you can simply add the crate as a dependency to your project and build your final binary by using [`cargo-3ds`](https://github.com/rust3ds/cargo-3ds)
or by manually compiling for the `armv6k-nintendo-3ds` target.

## Examples

Many examples to demonstrate the `ctru-rs` functionality are available in the [`examples`](./examples/) folder. Simply run them via

```bash
cargo 3ds run --example <example-name>
```

## License

This project is distributed under the Zlib license.
39 changes: 28 additions & 11 deletions ctru-rs/examples/audio-filters.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,30 @@
//! Audio Filters example.
//!
//! This example showcases basic audio functionality using [`Ndsp`].

#![feature(allocator_api)]

use std::f32::consts::PI;

use ctru::linear::LinearAllocator;
use ctru::prelude::*;
use ctru::services::ndsp::{
wave::{Wave, WaveStatus},
wave::{Status, Wave},
AudioFormat, AudioMix, InterpolationType, Ndsp, OutputMode,
};

// Configuration for the NDSP process and channels.
const SAMPLE_RATE: usize = 22050;
const SAMPLES_PER_BUF: usize = SAMPLE_RATE / 10; // 2205
const BYTES_PER_SAMPLE: usize = AudioFormat::PCM16Stereo.size();
const AUDIO_WAVE_LENGTH: usize = SAMPLES_PER_BUF * BYTES_PER_SAMPLE;

// Note Frequencies
// Note frequencies.
const NOTEFREQ: [f32; 7] = [220., 440., 880., 1760., 3520., 7040., 14080.];

// The audio format is Stereo PCM16
// As such, a sample is made up of 2 "Mono" samples (2 * i16 = u32), one for each channel (left and right)
fn fill_buffer(audio_data: &mut [u8], frequency: f32) {
// The audio format is Stereo PCM16.
// As such, a sample is made up of 2 "Mono" samples (2 * i16), one for each channel (left and right).
let formatted_data = bytemuck::cast_slice_mut::<_, [i16; 2]>(audio_data);

for (i, chunk) in formatted_data.iter_mut().enumerate() {
Expand All @@ -44,8 +49,7 @@ fn main() {

let mut note: usize = 4;

// Filters

// Filter names to display.
let filter_names = [
"None",
"Low-Pass",
Expand All @@ -60,19 +64,26 @@ fn main() {
// We set up two wave buffers and alternate between the two,
// effectively streaming an infinitely long sine wave.

// We create a buffer on the LINEAR memory that will hold our audio data.
// It's necessary for the buffer to live on the LINEAR memory sector since it needs to be accessed by the DSP processor.
let mut audio_data1 = Box::new_in([0u8; AUDIO_WAVE_LENGTH], LinearAllocator);

// Fill the buffer with the first set of data. This simply writes a sine wave into the buffer.
fill_buffer(audio_data1.as_mut_slice(), NOTEFREQ[4]);

// Clone the original buffer to obtain an equal buffer on the LINEAR memory used for double buffering.
let audio_data2 = audio_data1.clone();

// Setup two wave info objects with the correct configuration and ownership of the audio data.
let mut wave_info1 = Wave::new(audio_data1, AudioFormat::PCM16Stereo, false);
let mut wave_info2 = Wave::new(audio_data2, AudioFormat::PCM16Stereo, false);

let mut ndsp = Ndsp::new().expect("Couldn't obtain NDSP controller");
// Setup the NDSP service and its configuration.

// This line isn't needed since the default NDSP configuration already sets the output mode to `Stereo`
let mut ndsp = Ndsp::new().expect("Couldn't obtain NDSP controller");
ndsp.set_output_mode(OutputMode::Stereo);

// Channel configuration. We use channel zero but any channel would do just fine.
let mut channel_zero = ndsp.channel(0).unwrap();
channel_zero.set_interpolation(InterpolationType::Linear);
channel_zero.set_sample_rate(SAMPLE_RATE as f32);
Expand All @@ -82,6 +93,7 @@ fn main() {
let mix = AudioMix::default();
channel_zero.set_mix(&mix);

// First set of queueing for the two buffers. The second one will only play after the first one has ended.
channel_zero.queue_wave(&mut wave_info1).unwrap();
channel_zero.queue_wave(&mut wave_info2).unwrap();

Expand All @@ -93,6 +105,8 @@ fn main() {
filter_names[filter as usize]
);

println!("\x1b[29;16HPress Start to exit");

let mut altern = true; // true is wave_info1, false is wave_info2

while apt.main_loop() {
Expand All @@ -101,14 +115,16 @@ fn main() {

if keys_down.contains(KeyPad::START) {
break;
} // break in order to return to hbmenu
}

// Note frequency controller using the buttons.
if keys_down.intersects(KeyPad::DOWN) {
note = note.saturating_sub(1);
} else if keys_down.intersects(KeyPad::UP) {
note = std::cmp::min(note + 1, NOTEFREQ.len() - 1);
}

// Filter controller using the buttons.
let mut update_params = false;
if keys_down.intersects(KeyPad::LEFT) {
filter -= 1;
Expand Down Expand Up @@ -139,22 +155,23 @@ fn main() {
}
}

// Double buffer alternation depending on the one used.
let current: &mut Wave = if altern {
&mut wave_info1
} else {
&mut wave_info2
};

// If the current buffer has finished playing, we can refill it with new data and re-queue it.
let status = current.status();
if let WaveStatus::Done = status {
if let Status::Done = status {
fill_buffer(current.get_buffer_mut().unwrap(), NOTEFREQ[note]);

channel_zero.queue_wave(current).unwrap();

altern = !altern;
}

//Wait for VBlank
gfx.wait_for_vblank();
}
}
24 changes: 14 additions & 10 deletions ctru-rs/examples/buttons.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
//! Buttons example.
//!
//! This example showcases how to retrieve button inputs from the console's HID.

use ctru::prelude::*;

fn main() {
Expand All @@ -18,28 +22,28 @@ fn main() {
// Scan for user input on the current frame.
hid.scan_input();

// Get information about which keys were held down on this frame
// Get information about which keys were held down on this frame.
let keys = hid.keys_held();

// We only want to print when the keys we're holding now are different
// from what they were on the previous frame
// from what they were on the previous frame.
if keys != old_keys {
// Clear the screen
// Clear the screen.
console.clear();

// We print these again because we just cleared the screen above
// We print these again because we just cleared the screen above.
println!("Hi there! Try pressing a button");
println!("\x1b[29;16HPress Start to exit");

// Move the cursor back to the top of the screen
// Move the cursor back to the top of the screen.
println!("\x1b[3;0H");

// Print to the screen depending on which keys were held.
//
// The .contains() method checks for all of the provided keys,
// and the .intersects() method checks for any of the provided keys.
// The `.contains()` method checks for all of the provided keys,
// and the `.intersects()` method checks for any of the provided keys.
//
// You can also use the .bits() method to do direct comparisons on
// You can also use the `.bits()` method to do direct comparisons on
// the underlying bits

if keys.contains(KeyPad::A) {
Expand All @@ -54,13 +58,13 @@ fn main() {
if keys.intersects(KeyPad::L | KeyPad::R | KeyPad::ZL | KeyPad::ZR) {
println!("You held a shoulder button!");
}
if keys.intersects(KeyPad::START) {
if keys.contains(KeyPad::START) {
println!("See ya!");
break;
}
}

// Save our current key presses for the next frame
// Save our current key presses for the next frame.
old_keys = keys;

gfx.wait_for_vblank();
Expand Down
Loading