2023-10-11 14:55:18 +02:00
|
|
|
//!This is the module to interact with the progmem memory
|
2023-08-07 19:18:34 +02:00
|
|
|
#![allow(unused_imports)]
|
2023-08-15 13:31:46 +02:00
|
|
|
/// Create a space for Progmem variable
|
2023-08-07 19:18:34 +02:00
|
|
|
/// ## Example
|
|
|
|
/// ```
|
|
|
|
/// //for text
|
|
|
|
/// progmem!(
|
|
|
|
/// static text: [u8; _] = *b"I'm a PROGMEM Text\0";
|
|
|
|
/// );
|
|
|
|
/// //for tone sequence
|
|
|
|
/// progmem!(
|
2023-08-15 11:34:37 +02:00
|
|
|
/// static tone: [u16; _] = [
|
2023-08-07 19:18:34 +02:00
|
|
|
/// NOTE_E4, 400, NOTE_D4, 200, NOTE_C4, 400, NOTE_D4, 200, NOTE_C4, 300, NOTE_REST,
|
|
|
|
/// ];
|
|
|
|
/// );
|
|
|
|
/// //for for bitmap
|
|
|
|
/// progmem!(
|
|
|
|
/// static image: [u8; _] = [8, 8, 0x81, 0x00, 0x12, 0x40, 0x04, 0x11, 0x00, 0x04];
|
|
|
|
/// );
|
2023-08-19 19:14:32 +02:00
|
|
|
///
|
|
|
|
/// // for a Vector
|
|
|
|
/// progmem!(
|
|
|
|
/// static mut walls: Vec<Player, 100> = Vec::new();
|
|
|
|
/// );
|
2023-08-07 19:18:34 +02:00
|
|
|
/// ```
|
|
|
|
#[macro_export]
|
|
|
|
macro_rules! progmem {
|
|
|
|
(
|
|
|
|
$( #[$attr:meta] )*
|
|
|
|
$v:vis $id:ident $name:ident: [$ty:ty; _] = $value:expr;
|
|
|
|
$($rest:tt)*
|
|
|
|
) => {
|
|
|
|
$( #[$attr] )*
|
|
|
|
#[link_section = ".progmem.data"]
|
|
|
|
$v $id $name: [$ty; $value.len()] = $value;
|
|
|
|
$crate::progmem!{
|
|
|
|
$($rest)*
|
|
|
|
}
|
|
|
|
};
|
2023-08-19 18:21:14 +02:00
|
|
|
(
|
|
|
|
$( #[$attr:meta] )*
|
|
|
|
$v:vis $id:ident mut $name:ident: [$ty:ty; _] = $value:expr;
|
|
|
|
$($rest:tt)*
|
|
|
|
) => {
|
|
|
|
$( #[$attr] )*
|
|
|
|
#[link_section = ".progmem.data"]
|
|
|
|
$v $id mut $name: [$ty; $value.len()] = $value;
|
|
|
|
$crate::progmem!{
|
|
|
|
$($rest)*
|
|
|
|
}
|
|
|
|
};
|
2023-08-19 19:14:32 +02:00
|
|
|
(
|
|
|
|
$( #[$attr:meta] )*
|
|
|
|
$v:vis $id:ident $name:ident: $ty:ty = $value:expr;
|
|
|
|
$($rest:tt)*
|
|
|
|
) => {
|
|
|
|
$( #[$attr] )*
|
|
|
|
#[link_section = ".progmem.data"]
|
|
|
|
$v $id $name: $ty = $value;
|
|
|
|
$crate::progmem!{
|
|
|
|
$($rest)*
|
|
|
|
}
|
|
|
|
};
|
|
|
|
(
|
|
|
|
$( #[$attr:meta] )*
|
|
|
|
$v:vis $id:ident mut $name:ident: $ty:ty = $value:expr;
|
|
|
|
$($rest:tt)*
|
|
|
|
) => {
|
|
|
|
$( #[$attr] )*
|
|
|
|
#[link_section = ".progmem.data"]
|
|
|
|
$v $id mut $name: $ty = $value;
|
|
|
|
$crate::progmem!{
|
|
|
|
$($rest)*
|
|
|
|
}
|
|
|
|
};
|
2023-08-07 19:18:34 +02:00
|
|
|
() => ()
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(super) use progmem;
|
|
|
|
///Create a `const` raw pointer to a sprite as u8, without creating an intermediate reference.
|
|
|
|
#[macro_export]
|
|
|
|
macro_rules! get_sprite_addr {
|
|
|
|
( $s:expr ) => {
|
2023-08-21 05:24:03 +02:00
|
|
|
unsafe { addr_of!($s) as *const u8 }
|
2023-08-07 19:18:34 +02:00
|
|
|
};
|
|
|
|
}
|
|
|
|
pub(super) use get_sprite_addr;
|
|
|
|
|
2023-09-12 19:20:12 +02:00
|
|
|
///Create a `const` raw pointer to a ardvoice tone as u8, without creating an intermediate reference.
|
|
|
|
#[macro_export]
|
|
|
|
macro_rules! get_ardvoice_tone_addr {
|
|
|
|
( $s:expr ) => {
|
|
|
|
unsafe { addr_of!($s) as *const u8 }
|
|
|
|
};
|
|
|
|
}
|
|
|
|
pub(super) use get_ardvoice_tone_addr;
|
2023-09-12 22:01:54 +02:00
|
|
|
///Create a `const` raw pointer to a tone sequenze as u16, without creating an intermediate reference.
|
2023-08-07 19:18:34 +02:00
|
|
|
#[macro_export]
|
|
|
|
macro_rules! get_tones_addr {
|
|
|
|
( $s:expr ) => {
|
2023-08-21 05:24:03 +02:00
|
|
|
unsafe { addr_of!($s) as *const u16 }
|
2023-08-07 19:18:34 +02:00
|
|
|
};
|
|
|
|
}
|
|
|
|
pub(super) use get_tones_addr;
|
|
|
|
|
|
|
|
///Create a `const` raw pointer to a \[u8;_] that saves text, without creating an intermediate reference.
|
|
|
|
#[macro_export]
|
|
|
|
macro_rules! get_string_addr {
|
|
|
|
( $s:expr ) => {
|
|
|
|
Pstring {
|
2023-08-21 05:24:03 +02:00
|
|
|
pointer: unsafe { addr_of!($s) as *const i8 },
|
2023-08-07 19:18:34 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
pub(super) use get_string_addr;
|
2023-08-07 20:40:06 +02:00
|
|
|
///This is the way to go if you want print some random text
|
|
|
|
///
|
|
|
|
/// This doesn't waste the 2kb ram it saves to progmem (28kb)
|
|
|
|
/// This automatically saves the given text to the Progmem.
|
|
|
|
/// ## Example
|
|
|
|
/// ```
|
2023-08-20 12:31:52 +02:00
|
|
|
/// arduboy.print(f!(b"Random text to print\0"))
|
2023-08-07 20:40:06 +02:00
|
|
|
/// ```
|
|
|
|
#[macro_export]
|
|
|
|
macro_rules! f {
|
|
|
|
($string_literal:literal) => {{
|
|
|
|
progmem!(
|
|
|
|
static local: [u8; _] = *$string_literal;
|
|
|
|
);
|
|
|
|
|
|
|
|
get_string_addr!(local)
|
|
|
|
}};
|
|
|
|
}
|
|
|
|
pub(super) use f;
|
2023-08-08 08:36:49 +02:00
|
|
|
|
|
|
|
/// This struct is important for the Progmem functionality.
|
|
|
|
///
|
|
|
|
/// Typically you will never use this by your self.
|
|
|
|
/// It will be used by the get_string_addr macro in combination with a print command.
|
|
|
|
#[derive(Copy, Clone)]
|
|
|
|
pub struct Pstring {
|
|
|
|
pub pointer: *const i8,
|
|
|
|
}
|