use bitflags::bitflags;
use vex_sdk::vexSystemLinkAddrGet;
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
#[repr(u32)]
#[non_exhaustive]
pub enum ProgramType {
User = 0,
}
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
#[repr(u32)]
pub enum ProgramOwner {
System = 0,
Vex = 1,
Partner = 2,
}
bitflags! {
#[derive(Default, Debug, Clone, Copy, Eq, PartialEq)]
pub struct ProgramOptions: u32 {
const INVERT_DEFAULT_GRAPHICS = 1 << 0;
const KILL_TASKS_ON_EXIT = 1 << 1;
const THEMED_DEFAULT_GRAPHICS = 1 << 2;
}
}
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
#[repr(C)]
pub struct CodeSignature(vex_sdk::vcodesig, [u32; 4]);
impl CodeSignature {
#[must_use]
pub const fn new(
program_type: ProgramType,
owner: ProgramOwner,
options: ProgramOptions,
) -> Self {
Self(
vex_sdk::vcodesig {
magic: vex_sdk::V5_SIG_MAGIC,
r#type: program_type as _,
owner: owner as _,
options: options.bits(),
},
[0; 4],
)
}
#[must_use]
pub const fn owner(&self) -> ProgramOwner {
match self.0.owner {
0 => ProgramOwner::System,
1 => ProgramOwner::Vex,
2 => ProgramOwner::Partner,
_ => unreachable!(),
}
}
#[must_use]
pub const fn program_type(&self) -> ProgramType {
match self.0.r#type {
0 => ProgramType::User,
_ => unreachable!(),
}
}
#[must_use]
pub const fn options(&self) -> ProgramOptions {
ProgramOptions::from_bits_retain(self.0.options)
}
}
#[inline]
#[must_use]
pub fn code_signature() -> CodeSignature {
#[cfg(target_os = "vexos")]
{
unsafe extern "C" {
static __user_ram_start: CodeSignature;
}
unsafe { core::ptr::read(&raw const __user_ram_start) }
}
#[cfg(not(target_os = "vexos"))]
{
unsafe extern "C" {
safe static __VEXIDE_CODE_SIGNATURE: CodeSignature;
}
__VEXIDE_CODE_SIGNATURE
}
}
#[inline]
#[must_use]
pub fn linked_file() -> *mut () {
unsafe { vexSystemLinkAddrGet() as *mut () }
}