Meziu
2 years ago
committed by
GitHub
3 changed files with 91 additions and 0 deletions
@ -0,0 +1,46 @@ |
|||||||
|
#![feature(allocator_api)] |
||||||
|
|
||||||
|
use ctru::linear::LinearAllocator; |
||||||
|
use ctru::prelude::*; |
||||||
|
|
||||||
|
fn main() { |
||||||
|
ctru::init(); |
||||||
|
let gfx = Gfx::init().expect("Couldn't obtain GFX controller"); |
||||||
|
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()); |
||||||
|
|
||||||
|
let linear_space_before = LinearAllocator::free_space(); |
||||||
|
|
||||||
|
// Normal `Box` on the heap
|
||||||
|
let heap_box = Box::new(1492); |
||||||
|
// `Box` living on the linear memory sector
|
||||||
|
let linear_box: Box<i32, LinearAllocator> = Box::new_in(2022, LinearAllocator); |
||||||
|
|
||||||
|
println!("This value is from the heap: {heap_box}"); |
||||||
|
println!("This value is from the LINEAR memory: {linear_box}"); |
||||||
|
|
||||||
|
println!("\nLINEAR space free before allocation: {linear_space_before}"); |
||||||
|
println!( |
||||||
|
"LINEAR space free after allocation: {}", |
||||||
|
LinearAllocator::free_space() |
||||||
|
); |
||||||
|
|
||||||
|
println!("\x1b[29;16HPress Start to exit"); |
||||||
|
|
||||||
|
// 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::KEY_START) { |
||||||
|
break; |
||||||
|
} |
||||||
|
// Flush and swap framebuffers
|
||||||
|
gfx.flush_buffers(); |
||||||
|
gfx.swap_buffers(); |
||||||
|
|
||||||
|
//Wait for VBlank
|
||||||
|
gfx.wait_for_vblank(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,42 @@ |
|||||||
|
//! Linear memory allocator
|
||||||
|
//!
|
||||||
|
//! Linear memory is a sector of the 3DS' RAM that binds virtual addresses exactly to the physical address.
|
||||||
|
//! As such, it is used for fast and safe memory sharing between services (and is especially needed for GPU and DSP).
|
||||||
|
//!
|
||||||
|
//! Resources:<br>
|
||||||
|
//! <https://github.com/devkitPro/libctru/blob/master/libctru/source/allocator/linear.cpp><br>
|
||||||
|
//! <https://www.3dbrew.org/wiki/Memory_layout>
|
||||||
|
|
||||||
|
use std::alloc::{AllocError, Allocator, Layout}; |
||||||
|
use std::ptr::NonNull; |
||||||
|
|
||||||
|
// Implementing an `std::alloc::Allocator` type is the best way to handle this case, since it gives
|
||||||
|
// us full control over the normal `std` implementations (like `Box`). The only issue is that this is another unstable feature to add.
|
||||||
|
// Sadly the linear memory allocator included in `libctru` doesn't implement `linearRealloc` at the time of these additions,
|
||||||
|
// but the default fallback of the `std` will take care of that for us.
|
||||||
|
|
||||||
|
/// [`std::alloc::Allocator`] struct for LINEAR memory
|
||||||
|
/// To use this struct the main crate must activate the `allocator_api` unstable feature.
|
||||||
|
pub struct LinearAllocator; |
||||||
|
|
||||||
|
impl LinearAllocator { |
||||||
|
/// Returns the amount of free space left in the LINEAR sector
|
||||||
|
pub fn free_space() -> u32 { |
||||||
|
unsafe { ctru_sys::linearSpaceFree() } |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
unsafe impl Allocator for LinearAllocator { |
||||||
|
fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> { |
||||||
|
let pointer = |
||||||
|
unsafe { ctru_sys::linearMemAlign(layout.size() as u32, layout.align() as u32) }; |
||||||
|
|
||||||
|
NonNull::new(pointer.cast()) |
||||||
|
.map(|ptr| NonNull::slice_from_raw_parts(ptr, layout.size())) |
||||||
|
.ok_or(AllocError) |
||||||
|
} |
||||||
|
|
||||||
|
unsafe fn deallocate(&self, ptr: NonNull<u8>, _layout: Layout) { |
||||||
|
ctru_sys::linearFree(ptr.as_ptr().cast()); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue