From 15a09b52d70a242ff10f83815b3bcf27e7706217 Mon Sep 17 00:00:00 2001 From: sawyer bristol Date: Mon, 29 Sep 2025 12:35:54 -0600 Subject: [PATCH] gallery works --- assets/gallery/Sprite-0001.bmp | Bin 0 -> 12342 bytes assets/gallery/Sprite-0002.bmp | Bin 0 -> 12342 bytes assets/gallery/Sprite-0003.bmp | Bin 0 -> 12342 bytes assets/gallery/Sprite-0004.bmp | Bin 0 -> 12342 bytes assets/gallery/Sprite-0005.bmp | Bin 0 -> 12342 bytes kernel/src/abi.rs | 45 ++++++++++++++++++---------- user-apps/gallery/src/main.rs | 53 ++++++++++++++++++++++++++------- user-apps/memory.x | 2 +- 8 files changed, 72 insertions(+), 28 deletions(-) create mode 100644 assets/gallery/Sprite-0001.bmp create mode 100644 assets/gallery/Sprite-0002.bmp create mode 100644 assets/gallery/Sprite-0003.bmp create mode 100644 assets/gallery/Sprite-0004.bmp create mode 100644 assets/gallery/Sprite-0005.bmp diff --git a/assets/gallery/Sprite-0001.bmp b/assets/gallery/Sprite-0001.bmp new file mode 100644 index 0000000000000000000000000000000000000000..8e24bd6c2d3e4cb1152c01351038df2b1c636406 GIT binary patch literal 12342 zcmeH|K@Ng25JhqA&Xq@S>58>+?=?J^*YY+_teG@G$N)2x;v=*f+UC!nM=AG5du_f~ zEB!^}gl9A%us(sRzm%$vsjAJ(My-11?7;s%N?8BIBO?SL zU?EWN37`J0%l&)lSZL>Kyz+YKk literal 0 HcmV?d00001 diff --git a/assets/gallery/Sprite-0002.bmp b/assets/gallery/Sprite-0002.bmp new file mode 100644 index 0000000000000000000000000000000000000000..b2678b5664794b142257b250523dbd2c3e8399e3 GIT binary patch literal 12342 zcmeHFF>+Hu6bm&S6-S`MRceNo;SAKI;T{}{8*mE_f|7?7jo$8hZNJBiXPo(V^t5`C z_9vgeJ{}%kejf4t0iRF*K5ri01K|hf@7~5Ih~xL4-{0^Yr`O-X#}V;R`MPsH3g^Y% zW+G)_Xe0c|D_G=i9;q9##hqnkyXqM}!6?p}okVUCaElB8$sG`jp;QyY5Rg$@T~~gA zxk6xK@WybAmHbUXfGjX(s0SG`I~|T|!{JJhwzy6-u{z`k6Azt9?ud6HvS!9;;!G2~ zDh)$mOpN3&a9*$EQzqu4lgzNZk|!M~&@JHLKYssW5A^{KKYk7$lbtmVn`}DhE>=)p z7kL+wC{Ii#Us>*QWHjX=lZKiM7t!S#fPjpBp;^5ckEEJF_!Ec|@xrYZJ7_m7B9R zL3u>0A!`$~#+93EZN=q5O@`W8aZ_BaEedOA#kE0AZdTaFrqDuLD{Nz7P?MDv#%N4a zZk26ro0+Pt4xii>OeQ;`OFV~Fhh#}yxyi69$RS^ze!bzW=gBJ^em&`PeUr-^X8qx| zz5>cKkryFz0icOGpY&Pu$L{_Wp2aVJk&}rt0oMs;O6Ax6pQXlX-{s+t^3L;mTHJn~&0DVwJeZQ@xU zm8k|ieF#)sf``tmkt6aEnIYgU;xrpx$>dN?oSEB}$!4cbSFpmfbStS_x-yexzJt+M uv~I<8lj&%fE3E*b<{veT%p=?8qZ?v2FMC5bx>vowf%_Y{zkyqS1AhUl#a!6{ literal 0 HcmV?d00001 diff --git a/assets/gallery/Sprite-0003.bmp b/assets/gallery/Sprite-0003.bmp new file mode 100644 index 0000000000000000000000000000000000000000..ee8e1ea3eec87aa07cb2c2e8b0114c663cc9a4e3 GIT binary patch literal 12342 zcmeH}F>b>!3`NtqTc;kOW2ekT_ul_FE@KuSf+bSll43(H4OpPbPx6tlgM9zoKX2=G zm-9pJufO}{_AZuO5`TNuTOD!624VxTf!IK7;Bp&SmSyUhgn#N0X6KieXX^bc{{=>v z{VSfD{{mmZkP%M*HS7G4JJW}}!#xaSuEd^o+sO^feOo1&YCF7+}$?4R;?_aT1J_SzXi*XkS*0A{U0pNGeiR z?5j>~>IfP_7^GU9=ik&!9~%gFrKG(!z?(;_tX4>)ny7xVNSfYbqbc84m8l-K7_fV& z8glv8IU#akGyn`qQGlE%z#ucigBeq(0spfNX*aw@^DGT8 y4Jo_k-OSSP=(N*nj^Ol=Kkw;y0T3IA4a5dw1F?bFKx`m35F3aM#0LJ=27Un;ak{zy literal 0 HcmV?d00001 diff --git a/assets/gallery/Sprite-0004.bmp b/assets/gallery/Sprite-0004.bmp new file mode 100644 index 0000000000000000000000000000000000000000..1988ce5e642074e86efaa4f6695f48ef574c9ffc GIT binary patch literal 12342 zcmeHKJ5B>Z3=K6M6-S_?N{#3_11IJdoPah3SQtHx{2Nauo81jwWk;UpXZzW++9a=U z$LGWEb)@x)?w7y&?(j$!UF3hb=bM3AYXUWan!wr<`22VmpS2au))(#2b~fYM@i*3y zZf6N(?L({jHG!HyP2gWlAbx@GeFSlL>PdCLA2hz*cUvAy|i39YXUWa zn!wT%Fu#VDE*j_mwyrp&_3DmV@2G8Q>0_b_2M92^)$K6S4Ts7uGee+k8CsHKHYH;7 z6*J?_XA?5c-ey!$@;nW{s6!0aM@}v!!)80fAhB7gYp}w>mI`ASVnR1s55yH$&iT zlt-izTQimBa5k&~fn0onY#PKdaSe8}iBw%al@K9ZlmktdsY-($5=hdnjDQTs6GQlU z;VhL`P7Z`$n5`?Qezt(NXq-RxLN)}G{y0QLNCuAd(dtopo$^qc>r yCP6L9L%0j!9nvpiFS7O8PbObozo!#@c?95_Z2<~nBdH$)xv~+9Cok#GwD1E}{AKX~ literal 0 HcmV?d00001 diff --git a/assets/gallery/Sprite-0005.bmp b/assets/gallery/Sprite-0005.bmp new file mode 100644 index 0000000000000000000000000000000000000000..172ddc8988df96902f94986575f2460ff138be4c GIT binary patch literal 12342 zcmeH|F-`)O1{J`NHVS%1k_FCh_bdud*x0 zalT)Ef_Qj5>~}w(1AcGtz5o4Q?5+{vgY~OR`AQ;x(}8p#9Y_b#fpp+h9r*ls>pFU$ z8}R*FbQKrut}VKX7yP$(122Lx11#xSDkU?{Qzw$2P1gj)iO!B+-wWbke&ZzordZ{a z0WXf3VE)3rF*6Bkfsk*@Ut=5R$vIw<%qITVU>4+)f7Uc@5#Iv?ZfE9CfflD!+rVx? z+GR~`@nxFDuC6V*ipxQCid64 zKf3c=I%aZNV4Jf{v)F|eVjc5(Dlt!_r#i;oVk&Ae{L)?XGhP{l@vr2pZI9%id;m2t zXFif2NH~HM%vl!9@1*jVCI75fu;}&qrPGM}5F%1UvaXcEKyY zA5XofCjIxgBsI4G!|?8xVrBYID`o@R|Jm)61*hZx{_AOy&`xg74{Qz_b#nC-_$R^a zB>&jKe>@&H{QtG=+3<8{!B4k|%~Nm1&o@sJvUvh-2S4Hs-;amZr~yA#(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