Meziu
2 years ago
committed by
GitHub
3 changed files with 91 additions and 0 deletions
@ -0,0 +1,46 @@
@@ -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 @@
@@ -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