diff --git a/assets/gallery/Sprite-0001.bmp b/assets/gallery/Sprite-0001.bmp new file mode 100644 index 0000000..8e24bd6 Binary files /dev/null and b/assets/gallery/Sprite-0001.bmp differ diff --git a/assets/gallery/Sprite-0002.bmp b/assets/gallery/Sprite-0002.bmp new file mode 100644 index 0000000..b2678b5 Binary files /dev/null and b/assets/gallery/Sprite-0002.bmp differ diff --git a/assets/gallery/Sprite-0003.bmp b/assets/gallery/Sprite-0003.bmp new file mode 100644 index 0000000..ee8e1ea Binary files /dev/null and b/assets/gallery/Sprite-0003.bmp differ diff --git a/assets/gallery/Sprite-0004.bmp b/assets/gallery/Sprite-0004.bmp new file mode 100644 index 0000000..1988ce5 Binary files /dev/null and b/assets/gallery/Sprite-0004.bmp differ diff --git a/assets/gallery/Sprite-0005.bmp b/assets/gallery/Sprite-0005.bmp new file mode 100644 index 0000000..172ddc8 Binary files /dev/null and b/assets/gallery/Sprite-0005.bmp differ diff --git a/kernel/src/abi.rs b/kernel/src/abi.rs index d181bec..3c31cf2 100644 --- a/kernel/src/abi.rs +++ b/kernel/src/abi.rs @@ -2,7 +2,7 @@ use abi_sys::{ DrawIterAbi, FileLen, GenRand, GetKeyAbi, ListDir, LockDisplay, Modifiers, PrintAbi, ReadFile, RngRequest, SleepAbi, }; -use alloc::{format, vec::Vec}; +use alloc::{string::ToString, vec::Vec}; use core::sync::atomic::Ordering; use embassy_rp::clocks::{RoscRng, clk_sys_freq}; use embedded_graphics::{Pixel, draw_target::DrawTarget, pixelcolor::Rgb565}; @@ -130,23 +130,30 @@ pub extern "C" fn list_dir( wrote } -fn recurse_file(dir: &Dir, dirs: &[&str], mut access: impl FnMut(&mut File) -> T) -> T { +fn recurse_file( + dir: &Dir, + dirs: &[&str], + mut access: impl FnMut(&mut File) -> T, +) -> Result { if dirs.len() == 1 { let mut b = [0_u8; 50]; let mut buf = LfnBuffer::new(&mut b); let mut short_name = None; dir.iterate_dir_lfn(&mut buf, |entry, name| { if let Some(name) = name { - if name == dirs[0] { + if name == dirs[0] || entry.name.to_string().as_str() == dirs[0] { short_name = Some(entry.name.clone()); } } }) .unwrap(); - let mut file = dir - .open_file_in_dir(short_name.unwrap(), embedded_sdmmc::Mode::ReadWriteAppend) - .unwrap(); - return access(&mut file); + if let Some(name) = short_name { + let mut file = dir + .open_file_in_dir(name, embedded_sdmmc::Mode::ReadWriteAppend) + .map_err(|_| ())?; + return Ok(access(&mut file)); + } + return Err(()); } let dir = dir.open_dir(dirs[0]).unwrap(); @@ -161,25 +168,27 @@ pub extern "C" fn read_file( buf: *mut u8, buf_len: usize, ) -> usize { - // SAFETY: caller guarantees `ptr` is valid for `len` bytes - let mut buf = unsafe { core::slice::from_raw_parts_mut(buf, buf_len) }; // SAFETY: caller guarantees `ptr` is valid for `len` bytes let file = unsafe { core::str::from_raw_parts(str, len) }; let file: Vec<&str> = file.split('/').collect(); + // SAFETY: caller guarantees `ptr` is valid for `len` bytes + let mut buf = unsafe { core::slice::from_raw_parts_mut(buf, buf_len) }; - let mut res = 0; + let mut read = 0; let mut guard = SDCARD.get().try_lock().expect("Failed to get sdcard"); let sd = guard.as_mut().unwrap(); if !file.is_empty() { sd.access_root_dir(|root| { - res = recurse_file(&root, &file[1..], |file| { + if let Ok(result) = recurse_file(&root, &file[1..], |file| { file.seek_from_start(start_from as u32).unwrap(); file.read(&mut buf).unwrap() - }); + }) { + read = result + }; }); } - res + read } const _: FileLen = file_len; @@ -188,12 +197,16 @@ pub extern "C" fn file_len(str: *const u8, len: usize) -> usize { let file = unsafe { core::str::from_raw_parts(str, len) }; let file: Vec<&str> = file.split('/').collect(); - let mut res = 0; + let mut len = 0; let mut guard = SDCARD.get().try_lock().expect("Failed to get sdcard"); let sd = guard.as_mut().unwrap(); if !file.is_empty() { - sd.access_root_dir(|root| res = recurse_file(&root, &file[1..], |file| file.length())); + sd.access_root_dir(|root| { + if let Ok(result) = recurse_file(&root, &file[1..], |file| file.length()) { + len = result + } + }); } - res as usize + len as usize } diff --git a/user-apps/gallery/src/main.rs b/user-apps/gallery/src/main.rs index 4d06c76..7422b22 100644 --- a/user-apps/gallery/src/main.rs +++ b/user-apps/gallery/src/main.rs @@ -1,5 +1,6 @@ #![no_std] #![no_main] +#![allow(static_mut_refs)] extern crate alloc; use abi::{ @@ -8,7 +9,7 @@ use abi::{ file_len, get_key, list_dir, lock_display, print, read_file, sleep, }; use alloc::{format, vec::Vec}; -use core::panic::PanicInfo; +use core::{cell::RefCell, panic::PanicInfo}; use embedded_graphics::{Drawable, image::Image, prelude::*}; use tinybmp::Bmp; @@ -29,20 +30,50 @@ pub extern "Rust" fn _start() { pub fn main() { print("Starting Gallery app"); + static mut BMP_BUF: [u8; 100_000] = [0_u8; 100_000]; let mut display = Display; - let file = "/images/ferriseyes_tiny.bmp"; + // Grid parameters + let grid_cols = 3; + let grid_rows = 3; + let cell_width = 64; + let cell_height = 64; - let mut bmp_buf = [0_u8; 3_000]; - let read = read_file(file, 0, &mut bmp_buf); - let bmp = Bmp::from_slice(&bmp_buf[..read]).unwrap(); + let mut images_drawn = 0; - // ensure all draws show up at once - lock_display(true); - Image::new(&bmp, Point::new(10, 20)) - .draw(&mut display) - .unwrap(); - lock_display(false); + let mut files = [const { None }; 18]; + let files_num = list_dir("/images", &mut files); + + for file in &files[2..files_num] { + if images_drawn >= grid_cols * grid_rows { + break; // only draw 3x3 + } + + if let Some(f) = file { + print(&format!("file: {}", f.name)); + if f.name.extension() == b"bmp" || f.name.extension() == b"BMP" { + let file = format!("/images/{}", f.name); + + let read = read_file(&file, 0, &mut unsafe { &mut BMP_BUF[..] }); + if read > 0 { + let bmp = Bmp::from_slice(unsafe { &BMP_BUF }).expect("failed to parse bmp"); + + let row = images_drawn / grid_cols; + let col = images_drawn % grid_cols; + let x = (col * cell_width) as i32 + 10; // 10px margin + let y = (row * cell_height) as i32 + 10; + + lock_display(true); + Image::new(&bmp, Point::new(x, y)) + .draw(&mut display) + .unwrap(); + lock_display(false); + + images_drawn += 1; + } + } + } + } loop { let event = get_key(); diff --git a/user-apps/memory.x b/user-apps/memory.x index 36c9663..5517509 100644 --- a/user-apps/memory.x +++ b/user-apps/memory.x @@ -1,6 +1,6 @@ MEMORY { - RAM : ORIGIN = 0x0, LENGTH = 100K + RAM : ORIGIN = 0x0, LENGTH = 150K } SECTIONS