From 5fdfcf88c497fbcad69ad8e1f409776a13961462 Mon Sep 17 00:00:00 2001 From: ZennCode Date: Mon, 7 Aug 2023 16:28:11 +0200 Subject: [PATCH] added support for printing out of progmem --- Cargo.lock | 100 ++++++++++++++++++ Project/game/Cargo.toml | 1 + Project/game/src/lib.rs | 15 ++- .../src/library/arduboy/arduboy.cpp | 4 + Wrapper-Project/src/library/arduboy/arduboy.h | 1 + arduboy-rust/Cargo.toml | 1 + arduboy-rust/src/lib.rs | 2 +- arduboy-rust/src/library/arduboy.rs | 8 ++ arduboy-rust/src/prelude.rs | 4 +- arduboy-rust/src/print.rs | 25 +++++ 10 files changed, 157 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 674ce8e..3f5ad6c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6,9 +6,27 @@ version = 3 name = "arduboy-rust" version = "1.0.0" dependencies = [ + "avr-progmem", "panic-halt", ] +[[package]] +name = "avr-progmem" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4026b5cfd2368953bed46ffaa1acc7e4ea398bb7a610743d11895a5187498076" +dependencies = [ + "cfg-if", + "derivative", + "ufmt", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + [[package]] name = "demo2" version = "0.1.0" @@ -44,6 +62,17 @@ dependencies = [ "arduboy-rust", ] +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "eeprom-demo" version = "0.1.0" @@ -56,6 +85,7 @@ name = "game" version = "0.1.0" dependencies = [ "arduboy-rust", + "avr-progmem", ] [[package]] @@ -71,6 +101,30 @@ dependencies = [ "arduboy-rust", ] +[[package]] +name = "proc-macro-hack" +version = "0.5.20+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" + +[[package]] +name = "proc-macro2" +version = "1.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" +dependencies = [ + "proc-macro2", +] + [[package]] name = "rustacean" version = "0.1.0" @@ -85,9 +139,55 @@ dependencies = [ "arduboy-rust", ] +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "tone" version = "0.1.0" dependencies = [ "arduboy-rust", ] + +[[package]] +name = "ufmt" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31d3c0c63312dfc9d8e5c71114d617018a19f6058674003c0da29ee8d8036cdd" +dependencies = [ + "proc-macro-hack", + "ufmt-macros", + "ufmt-write", +] + +[[package]] +name = "ufmt-macros" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4ab6c92f30c996394a8bd525aef9f03ce01d0d7ac82d81902968057e37dd7d9" +dependencies = [ + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "ufmt-write" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e87a2ed6b42ec5e28cc3b94c09982969e9227600b2e3dcbc1db927a84c06bd69" + +[[package]] +name = "unicode-ident" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" diff --git a/Project/game/Cargo.toml b/Project/game/Cargo.toml index b916457..2bc60a8 100644 --- a/Project/game/Cargo.toml +++ b/Project/game/Cargo.toml @@ -7,4 +7,5 @@ edition = "2021" crate-type = ["staticlib"] [dependencies] +avr-progmem = "0.3.3" arduboy-rust = { path = "../../arduboy-rust" } diff --git a/Project/game/src/lib.rs b/Project/game/src/lib.rs index dce1d8c..d9f4d07 100644 --- a/Project/game/src/lib.rs +++ b/Project/game/src/lib.rs @@ -1,16 +1,29 @@ #![no_std] #![allow(non_upper_case_globals)] +#![feature(const_trait_impl)] +use core::cell::LazyCell; + //Include the Arduboy Library //Initialize the arduboy object #[allow(unused_imports)] use arduboy_rust::prelude::*; -//#[link_section = ".progmem.data"] +#[link_section = ".progmem.data"] +static lol2: [u8; 29] = [ + 0x54, 0x68, 0x61, 0x6E, 0x6B, 0x73, 0x20, 0x61, 0x20, 0x6C, 0x6F, 0x74, 0x0A, 0x79, 0x6F, 0x75, + 0x20, 0x61, 0x72, 0x65, 0x20, 0x61, 0x20, 0x0A, 0x48, 0x65, 0x72, 0x6F, 0x00, +]; +#[link_section = ".progmem.data"] +static lol1: [u8; 10] = LazyCell::new(|| "hallowelt\0".as_bytes().try_into().unwrap()); // The setup() function runs once when you turn your Arduboy on #[no_mangle] pub unsafe extern "C" fn setup() { // put your setup code here, to run once: + arduboy.begin(); + arduboy.clear(); + arduboy.print(get_string_addr!(lol1)); + arduboy.display(); } // The loop() function repeats forever after setup() is done #[no_mangle] diff --git a/Wrapper-Project/src/library/arduboy/arduboy.cpp b/Wrapper-Project/src/library/arduboy/arduboy.cpp index 93f6ec1..f71bade 100644 --- a/Wrapper-Project/src/library/arduboy/arduboy.cpp +++ b/Wrapper-Project/src/library/arduboy/arduboy.cpp @@ -81,6 +81,10 @@ void arduboy_print_chars(const char *cstr) { arduboy.print(cstr); } +size_t arduboy_print_chars_progmem(const char *cstr) +{ + return arduboy.print(reinterpret_cast(cstr)); +} size_t arduboy_print_char(char c) { return arduboy.print(c); diff --git a/Wrapper-Project/src/library/arduboy/arduboy.h b/Wrapper-Project/src/library/arduboy/arduboy.h index 710ab79..2b80fa6 100644 --- a/Wrapper-Project/src/library/arduboy/arduboy.h +++ b/Wrapper-Project/src/library/arduboy/arduboy.h @@ -24,6 +24,7 @@ extern "C" bool arduboy_pressed(uint8_t buttons); void arduboy_print_chars(const char *cstr); size_t arduboy_print_char(char c); + size_t arduboy_print_chars_progmem(const char *); size_t arduboy_print_int(int n, int base); size_t arduboy_print_long(long n, int base); size_t arduboy_print_unsigned_char(unsigned char n, int base); diff --git a/arduboy-rust/Cargo.toml b/arduboy-rust/Cargo.toml index b08ad4f..c209aaa 100644 --- a/arduboy-rust/Cargo.toml +++ b/arduboy-rust/Cargo.toml @@ -13,4 +13,5 @@ categories = ["game-engines", "games", "api-bindings"] [dependencies] +avr-progmem = "0.3.3" panic-halt = "0.2.0" diff --git a/arduboy-rust/src/lib.rs b/arduboy-rust/src/lib.rs index acc73c5..aec4c1e 100644 --- a/arduboy-rust/src/lib.rs +++ b/arduboy-rust/src/lib.rs @@ -6,7 +6,7 @@ mod hardware; mod library; pub mod prelude; mod print; -pub use crate::library::arduboy::{Arduboy, Color, FONT_SIZE, HEIGHT, WIDTH}; +pub use crate::library::arduboy::{Arduboy, Color, Pstring, FONT_SIZE, HEIGHT, WIDTH}; pub use crate::library::arduboy_tone::Sound; pub use crate::library::eeprom::EEPROM; pub use crate::library::{arduboy_tone_pitch, c, sprites}; diff --git a/arduboy-rust/src/library/arduboy.rs b/arduboy-rust/src/library/arduboy.rs index 58637f0..ee07e2e 100644 --- a/arduboy-rust/src/library/arduboy.rs +++ b/arduboy-rust/src/library/arduboy.rs @@ -20,6 +20,11 @@ pub const WIDTH: u8 = 128; /// /// this is to calculate with it. pub const HEIGHT: u8 = 64; + +#[derive(Copy, Clone)] +pub struct Pstring { + pub pointer: *const i8, +} /// This item is to chose between Black or White #[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] #[repr(u8)] @@ -411,6 +416,9 @@ extern "C" { #[link_name = "arduboy_print_chars"] pub fn print_chars(cstr: *const c_char); + #[link_name = "arduboy_print_chars_progmem"] + pub fn print_chars_progmem(pstring: *const c_char); + // #[link_name = "arduboy_print_char"] // fn print_char(c: c_char) -> c_size_t; diff --git a/arduboy-rust/src/prelude.rs b/arduboy-rust/src/prelude.rs index 36e2b02..37136f6 100644 --- a/arduboy-rust/src/prelude.rs +++ b/arduboy-rust/src/prelude.rs @@ -12,14 +12,14 @@ pub const arduboy: Arduboy = Arduboy {}; #[allow(non_upper_case_globals)] pub const sound: Sound = Sound {}; pub use crate::hardware::buttons::*; -pub use crate::library::arduboy::{Color, Point, Rect, FONT_SIZE, HEIGHT, WIDTH}; +pub use crate::library::arduboy::{Color, Point, Pstring, Rect, FONT_SIZE, HEIGHT, WIDTH}; pub use crate::library::arduboy_tone::*; pub use crate::library::arduino::*; pub use crate::library::c::*; pub use crate::library::eeprom::EEPROM; pub use crate::library::sprites; pub use crate::print::*; -pub use crate::{get_sprite_addr, get_tones_addr}; +pub use crate::{get_sprite_addr, get_string_addr, get_tones_addr}; use core::cmp; pub fn constrain(x: T, a: T, b: T) -> T { diff --git a/arduboy-rust/src/print.rs b/arduboy-rust/src/print.rs index 4bf8211..69a36fd 100644 --- a/arduboy-rust/src/print.rs +++ b/arduboy-rust/src/print.rs @@ -1,5 +1,18 @@ use core::ffi::c_int; +#[macro_export] +macro_rules! get_string_addr { + ( $s:expr ) => { + Pstring { + pointer: addr_of!($s) as *const i8, + } + }; +} +#[allow(unused_imports)] +pub(super) use get_string_addr; + +use crate::Pstring; + #[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] pub enum Base { Bin = 2, @@ -101,3 +114,15 @@ impl Printable for &str { fn default_parameters() -> Self::Parameters {} } + +impl Printable for Pstring { + type Parameters = (); + + fn print_2(self, _params: Self::Parameters) { + unsafe { + crate::library::arduboy::print_chars_progmem(self.pointer); + } + } + + fn default_parameters() -> Self::Parameters {} +}