Andrea Ciliberti
2 years ago
9 changed files with 273 additions and 103 deletions
@ -0,0 +1,46 @@ |
|||||||
|
name: Setup |
||||||
|
description: Set up CI environment for Rust + 3DS development |
||||||
|
|
||||||
|
inputs: |
||||||
|
toolchain: |
||||||
|
description: The Rust toolchain to use for the steps |
||||||
|
required: true |
||||||
|
default: nightly |
||||||
|
|
||||||
|
runs: |
||||||
|
using: composite |
||||||
|
steps: |
||||||
|
# https://github.com/nektos/act/issues/917#issuecomment-1074421318 |
||||||
|
- if: ${{ env.ACT }} |
||||||
|
shell: bash |
||||||
|
name: Hack container for local development |
||||||
|
run: | |
||||||
|
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash - |
||||||
|
sudo apt-get install -y nodejs |
||||||
|
|
||||||
|
- name: Setup default Rust toolchain |
||||||
|
# Use this helper action so we get matcher support |
||||||
|
# https://github.com/actions-rust-lang/setup-rust-toolchain/pull/15 |
||||||
|
uses: actions-rust-lang/setup-rust-toolchain@v1 |
||||||
|
with: |
||||||
|
components: clippy, rustfmt, rust-src |
||||||
|
toolchain: ${{ inputs.toolchain }} |
||||||
|
|
||||||
|
- name: Install build tools for host |
||||||
|
shell: bash |
||||||
|
run: sudo apt-get update && sudo apt-get install -y build-essential |
||||||
|
|
||||||
|
- name: Install cargo-3ds |
||||||
|
uses: actions-rs/cargo@v1 |
||||||
|
with: |
||||||
|
command: install |
||||||
|
# TODO: this should probably just be a released version from crates.io |
||||||
|
# once cargo-3ds gets published somewhere... |
||||||
|
args: >- |
||||||
|
--git https://github.com/rust3ds/cargo-3ds |
||||||
|
--rev 78a652fdfb01e2614a792d1a56b10c980ee1dae9 |
||||||
|
|
||||||
|
- name: Set PATH to include devkitARM |
||||||
|
shell: bash |
||||||
|
# For some reason devkitARM/bin is not part of the default PATH in the container |
||||||
|
run: echo "${DEVKITARM}/bin" >> $GITHUB_PATH |
@ -0,0 +1,57 @@ |
|||||||
|
use ctru::prelude::*; |
||||||
|
use ctru::services::gfx::Screen; |
||||||
|
|
||||||
|
/// Ferris image taken from <https://rustacean.net> and scaled down to 320x240px.
|
||||||
|
/// To regenerate the data, you will need to install `imagemagick` and run this
|
||||||
|
/// command from the `examples` directory:
|
||||||
|
///
|
||||||
|
/// ```sh
|
||||||
|
/// magick assets/ferris.png -channel-fx "red<=>blue" -rotate 90 assets/ferris.rgb
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// This creates an image appropriate for the default frame buffer format of
|
||||||
|
/// [`Bgr8`](ctru::services::gspgpu::FramebufferFormat::Bgr8)
|
||||||
|
/// and rotates the image 90° to account for the portrait mode screen.
|
||||||
|
static IMAGE: &[u8] = include_bytes!("assets/ferris.rgb"); |
||||||
|
|
||||||
|
fn main() { |
||||||
|
ctru::use_panic_handler(); |
||||||
|
|
||||||
|
let gfx = Gfx::new().expect("Couldn't obtain GFX controller"); |
||||||
|
let mut hid = Hid::new().expect("Couldn't obtain HID controller"); |
||||||
|
let apt = Apt::new().expect("Couldn't obtain APT controller"); |
||||||
|
let _console = Console::new(gfx.top_screen.borrow_mut()); |
||||||
|
|
||||||
|
println!("\x1b[21;16HPress Start to exit."); |
||||||
|
|
||||||
|
let mut bottom_screen = gfx.bottom_screen.borrow_mut(); |
||||||
|
|
||||||
|
// We don't need double buffering in this example.
|
||||||
|
// In this way we can draw our image only once on screen.
|
||||||
|
bottom_screen.set_double_buffering(false); |
||||||
|
|
||||||
|
// We assume the image is the correct size already, so we drop width + height.
|
||||||
|
let frame_buffer = bottom_screen.raw_framebuffer(); |
||||||
|
|
||||||
|
// Copy the image into the frame buffer
|
||||||
|
unsafe { |
||||||
|
frame_buffer.ptr.copy_from(IMAGE.as_ptr(), IMAGE.len()); |
||||||
|
} |
||||||
|
|
||||||
|
// Main loop
|
||||||
|
while apt.main_loop() { |
||||||
|
//Scan all the inputs. This should be done once for each frame
|
||||||
|
hid.scan_input(); |
||||||
|
|
||||||
|
if hid.keys_down().contains(KeyPad::START) { |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
// Flush and swap framebuffers
|
||||||
|
bottom_screen.flush_buffer(); |
||||||
|
bottom_screen.swap_buffers(); |
||||||
|
|
||||||
|
//Wait for VBlank
|
||||||
|
gfx.wait_for_vblank(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,49 @@ |
|||||||
|
use ctru::prelude::*; |
||||||
|
|
||||||
|
fn main() { |
||||||
|
ctru::use_panic_handler(); |
||||||
|
|
||||||
|
let gfx = Gfx::new().expect("Couldn't obtain GFX controller"); |
||||||
|
let mut hid = Hid::new().expect("Couldn't obtain HID controller"); |
||||||
|
let apt = Apt::new().expect("Couldn't obtain APT controller"); |
||||||
|
|
||||||
|
let console = Console::new(gfx.top_screen.borrow_mut()); |
||||||
|
|
||||||
|
// We'll hold the previous touch position for comparison.
|
||||||
|
let mut old_touch: (u16, u16) = (0, 0); |
||||||
|
|
||||||
|
println!("\x1b[29;16HPress Start to exit"); |
||||||
|
|
||||||
|
while apt.main_loop() { |
||||||
|
hid.scan_input(); |
||||||
|
|
||||||
|
if hid.keys_down().contains(KeyPad::START) { |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
// Get X and Y coordinates of the touch point.
|
||||||
|
// The touch screen is 320x240.
|
||||||
|
let touch: (u16, u16) = hid.touch_position(); |
||||||
|
|
||||||
|
// We only want to print the position when it's different
|
||||||
|
// from what it was on the previous frame
|
||||||
|
if touch != old_touch { |
||||||
|
// Special case for when the user lifts the stylus/finger from the screen.
|
||||||
|
// This is done to avoid some screen tearing.
|
||||||
|
if touch == (0, 0) { |
||||||
|
console.clear(); |
||||||
|
|
||||||
|
// Print again because we just cleared the screen
|
||||||
|
println!("\x1b[29;16HPress Start to exit"); |
||||||
|
} |
||||||
|
|
||||||
|
// Move the cursor back to the top of the screen and print the coordinates
|
||||||
|
print!("\x1b[1;1HTouch Screen position: {:#?}", touch); |
||||||
|
} |
||||||
|
|
||||||
|
// Save our current touch position for the next frame
|
||||||
|
old_touch = touch; |
||||||
|
|
||||||
|
gfx.wait_for_vblank(); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue