Open mlund opened 9 months ago
I don't think that will be possible, but I also don't think that this is your problem. I'm pretty sure I've successfully used tinytga on a microcontroller with 8 kB of RAM in the past.
Can you provide a bit more information about the system, like what architecture/controller you are working with? Or can you even make the code that you use to draw the image and an example image available?
Thanks for the quick reply. It could be that it's the rust compiler that does something unexpected. The target is a a Commodore 64 8-bit computer using llvm-mos/rust-mos. I'll shortly push the display driver to a crate with instructions how to run this (which involves Docker due to the special toolchain).
Now that's an interesting project, I'm happy to help with that. I had never expected to use any Rust code I've written to run on my C64, but I'll definitely try it when we get this working.
Sounds great - here's preview of what I have so far ;-)
https://github.com/embedded-graphics/tinytga/assets/3248398/07f29486-9954-4d07-ada0-2f316ab70aa8
The retro-display
display driver is out: https://crates.io/crates/retro-display
I had some permission problems with using Podman to run the development container, which made development a little inconvenient, but after some tinkering I was able to display an image using the ImageRaw
type from embedded-graphics:
https://github.com/embedded-graphics/tinytga/assets/226123/5097249a-68aa-498d-b39c-4a3b0ef39251
Here is the code I used to display the image:
#[start]
fn _main(_argc: isize, _argv: *const *const u8) -> isize {
let mut display = PetsciiDisplay {};
display.set_border_color(VicIIPalette::Black);
display.clear(VicIIPalette::Black).unwrap();
let data = include_bytes!("../eg-logo.raw");
let image = ImageRawLE::new(data, 20);
Image::new(&image, Point::new(10, 0))
.draw(&mut display)
.unwrap();
loop {}
}
The generated binary is 1730 bytes with 250 bytes taken up by the image.
There are some minor tweaks which I had to make in the library to get this working. I'll open a PR for these changes when I've sorted out my permission issues. I've also added a set_border_color
method to make the demo look nicer.
The data file was created by a small external program, which uses tinytga
and e-g's Framebuffer
. The code was just a quick hack and is very inflexible with many hardcoded values. A real implementation could map the RGB colors in an image to their closest C64 palette entry.
fn main() {
let logo_data = include_bytes!("../assets/eg-logo.tga");
let logo = Tga::<Gray4>::from_slice(logo_data).unwrap();
let mut fb =
Framebuffer::<Gray4, _, LittleEndian, 20, 25, { buffer_size::<Gray4>(20, 25) }>::new();
Image::new(&logo, Point::zero()).draw(&mut fb).unwrap();
for p in fb.bounding_box().points() {
let c = fb.pixel(p).unwrap();
let c64_c = match c.into_storage() {
8 => 6,
15 => 14,
_ => 0,
};
fb.set_pixel(p, Gray4::new(c64_c));
}
std::fs::write("/tmp/eg-logo.raw", fb.data()).unwrap();
}
This is great, and 2K is not bad at all. Yes, I started looking into conversion from RGB by calculating the color difference and realised that this can be done in many ways. There are crates available, but I didn't continue investigating.
Description of the problem/feature request/other
I'm experimenting with embedded-graphics on a very restricted system with only 40 kB available RAM, and while it does work with primitives like circles, fonts etc., using tinytga, the size grows up to 80 kB bytes or so while loading a 2 kB file. I therefore wonder if
fn from_slice()
could be madeconst
so that image processing is done at compile-time? I realise that this could be an elaborate task due to the limitations of constant expressions.