use super::*;
pub use core::time::Duration;
#[derive(Debug)]
#[allow(missing_docs)]
pub struct Bitmap {
pub memory: *mut u8,
pub width: i32,
pub height: i32,
pub pitch: isize,
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
#[repr(C)]
#[allow(missing_docs)]
pub struct StereoI16 {
pub left: i16,
pub right: i16,
}
#[derive(Clone, Default)]
#[allow(missing_docs)]
pub struct SNESController {
pub arrow_up: bool,
pub arrow_down: bool,
pub arrow_left: bool,
pub arrow_right: bool,
pub north: bool,
pub south: bool,
pub east: bool,
pub west: bool,
pub l: bool,
pub r: bool,
pub start: bool,
pub select: bool,
}
impl core::fmt::Debug for SNESController {
#[rustfmt::skip]
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
write!(f, "SNESController {{")?;
if self.arrow_up { write!(f, " arrow_up, ")?; }
if self.arrow_down { write!(f, " arrow_down, ")?; }
if self.arrow_left { write!(f, " arrow_left, ")?; }
if self.arrow_right { write!(f, " arrow_right, ")?; }
if self.north { write!(f, " north, ")?; }
if self.south { write!(f, " south, ")?; }
if self.east { write!(f, " east, ")?; }
if self.west { write!(f, " west, ")?; }
if self.l { write!(f, " l, ")?; }
if self.r { write!(f, " r, ")?; }
if self.start { write!(f, " start, ")?; }
if self.select { write!(f, " select, ")?; }
write!(f, "}}")
}
}
#[derive(Debug, Clone, Default)]
#[allow(missing_docs)]
pub struct GameInput {
pub keyboard: SNESController,
pub gamepads: Vec<SNESController>,
}
#[derive(Debug, Default, Clone)]
#[allow(missing_docs)]
pub struct GameMemory {
pub config: crate::dmg_render::DMGConfig,
pub pal_index: usize,
pub px: u8,
pub py: u8,
pub l_was_down: bool,
pub r_was_down: bool,
pub east_was_down: bool,
pub south_was_down: bool,
pub north_was_down: bool,
pub apu: DMGAPU,
}
#[cfg(feature = "dynamic_link")]
pub type GameUpdateAndRenderFn = extern "C" fn(&mut GameMemory, &GameInput, &mut Bitmap);
#[cfg(not(feature = "dynamic_link"))]
pub type GameUpdateAndRenderFn = fn(&mut GameMemory, &GameInput, &mut Bitmap);
#[cfg(feature = "dynamic_link")]
pub type GameGetSoundSamplesFn = extern "C" fn(&mut GameMemory, i32, &mut [StereoI16]);
#[cfg(not(feature = "dynamic_link"))]
pub type GameGetSoundSamplesFn = fn(&mut GameMemory, i32, &mut [StereoI16]);
#[macro_export]
macro_rules! dump {
($($n:expr),*) => (if cfg!(debug_assertions) {
$(std::println!(concat!("{}:{}> ",stringify!($n),": {:?}"),file!(),line!(),$n);)*
})
}
#[macro_export]
macro_rules! debugln {
($($arg:tt)*) => (if cfg!(debug_assertions) {
std::print!("{}:{}> ",file!(),line!());
std::println!($($arg)*);
})
}
#[macro_export]
macro_rules! tlc_read {
($cell_name:ident) => {
$cell_name.with(Cell::get)
};
}
#[macro_export]
macro_rules! tlc_write {
($cell_name:ident, $new_value:expr) => {
$cell_name.with(|cell| cell.set($new_value));
};
}
#[macro_export]
macro_rules! tlc_modify {
($cell_name:ident, $modify_func:expr) => {
$cell_name.with(|cell| cell.set($modify_func(cell.get())));
};
}
#[macro_export]
macro_rules! newtype {
($(#[$attr:meta])* $new_name:ident, $v:vis $old_name:ty) => {
$(#[$attr])*
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
#[repr(transparent)]
pub struct $new_name($v $old_name);
impl $new_name {
pub const fn new() -> Self {
$new_name(0)
}
}
};
($(#[$attr:meta])* $new_name:ident, $v:vis $old_name:ty, no frills) => {
$(#[$attr])*
#[repr(transparent)]
pub struct $new_name($v $old_name);
};
}
/// Assists in defining a newtype that's an enum.
#[macro_export]
macro_rules! newtype_enum {
(
$(#[$struct_attr:meta])*
$new_name:ident = $old_name:ident,
$($(#[$tag_attr:meta])* $tag_name:ident = $base_value:expr,)*
) => {
$(#[$struct_attr])*
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr($old_name)]
pub enum $new_name {
$(
$(#[$tag_attr])*
$tag_name = $base_value,
)*
}
};
}