pub struct Num<I, const N: usize>(/* private fields */)
where
I: FixedWidthUnsignedInteger;
Expand description
A fixed point number represented using I
with N
bits of fractional precision
Implementations§
source§impl<I, const N: usize> Num<I, N>where
I: FixedWidthUnsignedInteger,
impl<I, const N: usize> Num<I, N>where
I: FixedWidthUnsignedInteger,
sourcepub fn change_base<J, const M: usize>(self) -> Num<J, M>where
J: FixedWidthUnsignedInteger + From<I>,
pub fn change_base<J, const M: usize>(self) -> Num<J, M>where
J: FixedWidthUnsignedInteger + From<I>,
Performs the conversion between two integer types and between two different fractional precisions
sourcepub fn try_change_base<J, const M: usize>(self) -> Option<Num<J, M>>where
J: FixedWidthUnsignedInteger + TryFrom<I>,
pub fn try_change_base<J, const M: usize>(self) -> Option<Num<J, M>>where
J: FixedWidthUnsignedInteger + TryFrom<I>,
Attempts to perform the conversion between two integer types and between two different fractional precisions
let a: Num<i32, 8> = 1.into();
let b: Option<Num<u8, 4>> = a.try_change_base();
assert_eq!(b, Some(1.into()));
let a: Num<i32, 8> = 18.into();
let b: Option<Num<u8, 4>> = a.try_change_base();
assert_eq!(b, None);
Examples found in repository?
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
fn main(mut gba: agb::Gba) -> ! {
let (gfx, mut vram) = gba.display.video.tiled0();
let mut map = gfx.background(
agb::display::Priority::P0,
RegularBackgroundSize::Background32x32,
TileFormat::FourBpp,
);
let mut window = gba.display.window.get();
window
.win_in(WinIn::Win0)
.set_background_enable(map.background(), true)
.set_position(&Rect::new((10, 10).into(), (64, 64).into()))
.enable();
window
.win_out()
.enable()
.set_background_enable(map.background(), true)
.set_blend_enable(true);
example_logo::display_logo(&mut map, &mut vram);
let mut blend = gba.display.blend.get();
blend
.set_background_enable(Layer::Top, map.background(), true)
.set_backdrop_enable(Layer::Bottom, true)
.set_blend_mode(BlendMode::Normal);
let mut pos: Vector2D<FNum> = (10, 10).into();
let mut velocity: Vector2D<FNum> = Vector2D::new(1.into(), 1.into());
let mut blend_amount: Num<i32, 8> = num!(0.5);
let mut blend_velocity: Num<i32, 8> = Num::new(1) / 128;
let vblank = VBlank::get();
loop {
pos += velocity;
if pos.x.floor() > WIDTH - 64 || pos.x.floor() < 0 {
velocity.x *= -1;
}
if pos.y.floor() > HEIGHT - 64 || pos.y.floor() < 0 {
velocity.y *= -1;
}
blend_amount += blend_velocity;
if blend_amount > num!(0.75) || blend_amount < num!(0.25) {
blend_velocity *= -1;
}
blend_amount = blend_amount.clamp(0.into(), 1.into());
blend.set_blend_weight(Layer::Top, blend_amount.try_change_base().unwrap());
window
.win_in(WinIn::Win0)
.set_position(&Rect::new(pos.floor(), (64, 64).into()));
vblank.wait_for_vblank();
window.commit();
blend.commit();
}
}
sourcepub fn from_f32(input: f32) -> Num<I, N>
pub fn from_f32(input: f32) -> Num<I, N>
Lossily transforms an f32 into a fixed point representation. This is not const
because you cannot currently do floating point operations in const contexts, so
you should use the num!
macro from agb-macros if you want a const from_f32/f64
sourcepub fn from_f64(input: f64) -> Num<I, N>
pub fn from_f64(input: f64) -> Num<I, N>
Lossily transforms an f64 into a fixed point representation. This is not const
because you cannot currently do floating point operations in const contexts, so
you should use the num!
macro from agb-macros if you want a const from_f32/f64
sourcepub fn trunc(self) -> I
pub fn trunc(self) -> I
Truncates the fixed point number returning the integral part
let n: Num<i32, 8> = num!(5.67);
assert_eq!(n.trunc(), 5);
let n: Num<i32, 8> = num!(-5.67);
assert_eq!(n.trunc(), -5);
sourcepub fn rem_euclid(self, rhs: Num<I, N>) -> Num<I, N>
pub fn rem_euclid(self, rhs: Num<I, N>) -> Num<I, N>
Performs the equivalent to the integer rem_euclid, which is modulo numbering.
let n: Num<i32, 8> = num!(5.67);
let r: Num<i32, 8> = num!(4.);
assert_eq!(n.rem_euclid(r), num!(1.67));
let n: Num<i32, 8> = num!(-1.5);
let r: Num<i32, 8> = num!(4.);
assert_eq!(n.rem_euclid(r), num!(2.5));
sourcepub fn floor(self) -> I
pub fn floor(self) -> I
Performs rounding towards negative infinity
let n: Num<i32, 8> = num!(5.67);
assert_eq!(n.floor(), 5);
let n: Num<i32, 8> = num!(-5.67);
assert_eq!(n.floor(), -6);
Examples found in repository?
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
fn main(mut gba: agb::Gba) -> ! {
let (gfx, mut vram) = gba.display.video.tiled0();
let mut map = gfx.background(
agb::display::Priority::P0,
RegularBackgroundSize::Background32x32,
TileFormat::FourBpp,
);
let mut window = gba.display.window.get();
window
.win_in(WinIn::Win0)
.set_background_enable(map.background(), true)
.set_position(&Rect::new((10, 10).into(), (64, 64).into()))
.enable();
window
.win_out()
.enable()
.set_background_enable(map.background(), true)
.set_blend_enable(true);
example_logo::display_logo(&mut map, &mut vram);
let mut blend = gba.display.blend.get();
blend
.set_background_enable(Layer::Top, map.background(), true)
.set_backdrop_enable(Layer::Bottom, true)
.set_blend_mode(BlendMode::Normal);
let mut pos: Vector2D<FNum> = (10, 10).into();
let mut velocity: Vector2D<FNum> = Vector2D::new(1.into(), 1.into());
let mut blend_amount: Num<i32, 8> = num!(0.5);
let mut blend_velocity: Num<i32, 8> = Num::new(1) / 128;
let vblank = VBlank::get();
loop {
pos += velocity;
if pos.x.floor() > WIDTH - 64 || pos.x.floor() < 0 {
velocity.x *= -1;
}
if pos.y.floor() > HEIGHT - 64 || pos.y.floor() < 0 {
velocity.y *= -1;
}
blend_amount += blend_velocity;
if blend_amount > num!(0.75) || blend_amount < num!(0.25) {
blend_velocity *= -1;
}
blend_amount = blend_amount.clamp(0.into(), 1.into());
blend.set_blend_weight(Layer::Top, blend_amount.try_change_base().unwrap());
window
.win_in(WinIn::Win0)
.set_position(&Rect::new(pos.floor(), (64, 64).into()));
vblank.wait_for_vblank();
window.commit();
blend.commit();
}
}
More examples
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
fn main(mut gba: agb::Gba) -> ! {
let (gfx, mut vram) = gba.display.video.tiled0();
let mut map = gfx.background(
agb::display::Priority::P0,
RegularBackgroundSize::Background32x32,
TileFormat::FourBpp,
);
let mut window = gba.display.window.get();
window
.win_in(WinIn::Win0)
.set_background_enable(map.background(), true)
.set_position(&Rect::new((10, 10).into(), (64, 64).into()))
.enable();
let dmas = gba.dma.dma();
example_logo::display_logo(&mut map, &mut vram);
let mut pos: Vector2D<FNum> = (10, 10).into();
let mut velocity: Vector2D<FNum> = Vector2D::new(1.into(), 1.into());
let vblank = VBlank::get();
let circle: Box<[_]> = (1..64i32)
.map(|i| {
let y = 32 - i;
let x = (32 * 32 - y * y).isqrt();
let x1 = 32 - x;
let x2 = 32 + x;
((x1 as u16) << 8) | (x2 as u16)
})
.collect();
let mut circle_poses = vec![0; 160];
loop {
pos += velocity;
if pos.x.floor() > WIDTH - 64 || pos.x.floor() < 0 {
velocity.x *= -1;
}
if pos.y.floor() > HEIGHT - 64 || pos.y.floor() < 0 {
velocity.y *= -1;
}
let x_pos = pos.x.floor().max(0) as u16;
let y_pos = pos.y.floor().max(0);
let x_adjustment = x_pos << 8 | x_pos;
for (i, value) in circle_poses.iter_mut().enumerate() {
let i = i as i32;
if i <= y_pos || i >= y_pos + 64 {
*value = 0;
continue;
}
*value = circle[(i - y_pos) as usize - 1] + x_adjustment;
}
window
.win_in(WinIn::Win0)
.set_position(&Rect::new(pos.floor(), (64, 65).into()));
window.commit();
let dma_controllable = window.win_in(WinIn::Win0).horizontal_position_dma();
let _transfer = unsafe { dmas.dma0.hblank_transfer(&dma_controllable, &circle_poses) };
vblank.wait_for_vblank();
}
}
sourcepub fn frac(self) -> I
pub fn frac(self) -> I
Returns the fractional component of a number as it’s integer representation
let n: Num<i32, 8> = num!(5.5);
assert_eq!(n.frac(), 1 << 7);
sourcepub fn new(integral: I) -> Num<I, N>
pub fn new(integral: I) -> Num<I, N>
Creates an integer represented by a fixed point number
let n: Num<i32, 8> = Num::new(5);
assert_eq!(n.frac(), 0); // no fractional component
assert_eq!(n, num!(5.)); // just equals the number 5
Examples found in repository?
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
fn main(mut gba: agb::Gba) -> ! {
let (gfx, mut vram) = gba.display.video.tiled0();
let mut map = gfx.background(
agb::display::Priority::P0,
RegularBackgroundSize::Background32x32,
TileFormat::FourBpp,
);
let mut window = gba.display.window.get();
window
.win_in(WinIn::Win0)
.set_background_enable(map.background(), true)
.set_position(&Rect::new((10, 10).into(), (64, 64).into()))
.enable();
window
.win_out()
.enable()
.set_background_enable(map.background(), true)
.set_blend_enable(true);
example_logo::display_logo(&mut map, &mut vram);
let mut blend = gba.display.blend.get();
blend
.set_background_enable(Layer::Top, map.background(), true)
.set_backdrop_enable(Layer::Bottom, true)
.set_blend_mode(BlendMode::Normal);
let mut pos: Vector2D<FNum> = (10, 10).into();
let mut velocity: Vector2D<FNum> = Vector2D::new(1.into(), 1.into());
let mut blend_amount: Num<i32, 8> = num!(0.5);
let mut blend_velocity: Num<i32, 8> = Num::new(1) / 128;
let vblank = VBlank::get();
loop {
pos += velocity;
if pos.x.floor() > WIDTH - 64 || pos.x.floor() < 0 {
velocity.x *= -1;
}
if pos.y.floor() > HEIGHT - 64 || pos.y.floor() < 0 {
velocity.y *= -1;
}
blend_amount += blend_velocity;
if blend_amount > num!(0.75) || blend_amount < num!(0.25) {
blend_velocity *= -1;
}
blend_amount = blend_amount.clamp(0.into(), 1.into());
blend.set_blend_weight(Layer::Top, blend_amount.try_change_base().unwrap());
window
.win_in(WinIn::Win0)
.set_position(&Rect::new(pos.floor(), (64, 64).into()));
vblank.wait_for_vblank();
window.commit();
blend.commit();
}
}
source§impl<I, const N: usize> Num<I, N>where
I: FixedWidthSignedInteger,
impl<I, const N: usize> Num<I, N>where
I: FixedWidthSignedInteger,
sourcepub fn abs(self) -> Num<I, N>
pub fn abs(self) -> Num<I, N>
Returns the absolute value of a fixed point number
let n: Num<i32, 8> = num!(5.5);
assert_eq!(n.abs(), num!(5.5));
let n: Num<i32, 8> = num!(-5.5);
assert_eq!(n.abs(), num!(5.5));
sourcepub fn cos(self) -> Num<I, N>
pub fn cos(self) -> Num<I, N>
Calculates the cosine of a fixed point number with the domain of [0, 1]. Uses a fifth order polynomial.
let n: Num<i32, 8> = num!(0.); // 0 radians
assert_eq!(n.cos(), num!(1.));
let n: Num<i32, 8> = num!(0.25); // pi / 2 radians
assert_eq!(n.cos(), num!(0.));
let n: Num<i32, 8> = num!(0.5); // pi radians
assert_eq!(n.cos(), num!(-1.));
let n: Num<i32, 8> = num!(0.75); // 3pi/2 radians
assert_eq!(n.cos(), num!(0.));
let n: Num<i32, 8> = num!(1.); // 2 pi radians (whole rotation)
assert_eq!(n.cos(), num!(1.));
sourcepub fn sin(self) -> Num<I, N>
pub fn sin(self) -> Num<I, N>
Calculates the sine of a number with domain of [0, 1].
let n: Num<i32, 8> = num!(0.); // 0 radians
assert_eq!(n.sin(), num!(0.));
let n: Num<i32, 8> = num!(0.25); // pi / 2 radians
assert_eq!(n.sin(), num!(1.));
let n: Num<i32, 8> = num!(0.5); // pi radians
assert_eq!(n.sin(), num!(0.));
let n: Num<i32, 8> = num!(0.75); // 3pi/2 radians
assert_eq!(n.sin(), num!(-1.));
let n: Num<i32, 8> = num!(1.); // 2 pi radians (whole rotation)
assert_eq!(n.sin(), num!(0.));
Trait Implementations§
source§impl<I, T, const N: usize> Add<T> for Num<I, N>where
I: FixedWidthUnsignedInteger,
T: Into<Num<I, N>>,
impl<I, T, const N: usize> Add<T> for Num<I, N>where
I: FixedWidthUnsignedInteger,
T: Into<Num<I, N>>,
source§impl<I, T, const N: usize> AddAssign<T> for Num<I, N>where
I: FixedWidthUnsignedInteger,
T: Into<Num<I, N>>,
impl<I, T, const N: usize> AddAssign<T> for Num<I, N>where
I: FixedWidthUnsignedInteger,
T: Into<Num<I, N>>,
source§fn add_assign(&mut self, rhs: T)
fn add_assign(&mut self, rhs: T)
+=
operation. Read moresource§impl<I, const N: usize> Clone for Num<I, N>where
I: Clone + FixedWidthUnsignedInteger,
impl<I, const N: usize> Clone for Num<I, N>where
I: Clone + FixedWidthUnsignedInteger,
source§impl<I, const N: usize> Debug for Num<I, N>where
I: FixedWidthUnsignedInteger,
impl<I, const N: usize> Debug for Num<I, N>where
I: FixedWidthUnsignedInteger,
source§impl<I, const N: usize> Default for Num<I, N>where
I: FixedWidthUnsignedInteger,
impl<I, const N: usize> Default for Num<I, N>where
I: FixedWidthUnsignedInteger,
source§impl<I, const N: usize> Display for Num<I, N>where
I: FixedWidthUnsignedInteger,
impl<I, const N: usize> Display for Num<I, N>where
I: FixedWidthUnsignedInteger,
source§impl<I, const N: usize> Div<I> for Num<I, N>where
I: FixedWidthUnsignedInteger,
impl<I, const N: usize> Div<I> for Num<I, N>where
I: FixedWidthUnsignedInteger,
source§impl<I, const N: usize> Div for Num<I, N>where
I: FixedWidthUnsignedInteger,
impl<I, const N: usize> Div for Num<I, N>where
I: FixedWidthUnsignedInteger,
source§impl<I, T, const N: usize> DivAssign<T> for Num<I, N>
impl<I, T, const N: usize> DivAssign<T> for Num<I, N>
source§fn div_assign(&mut self, rhs: T)
fn div_assign(&mut self, rhs: T)
/=
operation. Read moresource§impl<I, const N: usize> From<I> for Num<I, N>where
I: FixedWidthUnsignedInteger,
impl<I, const N: usize> From<I> for Num<I, N>where
I: FixedWidthUnsignedInteger,
source§impl<I, const N: usize> Hash for Num<I, N>where
I: Hash + FixedWidthUnsignedInteger,
impl<I, const N: usize> Hash for Num<I, N>where
I: Hash + FixedWidthUnsignedInteger,
source§impl<I, const N: usize> Mul<I> for Num<I, N>where
I: FixedWidthUnsignedInteger,
impl<I, const N: usize> Mul<I> for Num<I, N>where
I: FixedWidthUnsignedInteger,
source§impl<I, const N: usize> Mul for Num<I, N>where
I: FixedWidthUnsignedInteger,
impl<I, const N: usize> Mul for Num<I, N>where
I: FixedWidthUnsignedInteger,
source§impl<I, T, const N: usize> MulAssign<T> for Num<I, N>
impl<I, T, const N: usize> MulAssign<T> for Num<I, N>
source§fn mul_assign(&mut self, rhs: T)
fn mul_assign(&mut self, rhs: T)
*=
operation. Read moresource§impl<I, const N: usize> Neg for Num<I, N>where
I: FixedWidthSignedInteger,
impl<I, const N: usize> Neg for Num<I, N>where
I: FixedWidthSignedInteger,
source§impl<I, const N: usize> Num for Num<I, N>where
I: FixedWidthUnsignedInteger + Num,
impl<I, const N: usize> Num for Num<I, N>where
I: FixedWidthUnsignedInteger + Num,
type FromStrRadixErr = <f64 as Num>::FromStrRadixErr
source§fn from_str_radix(
str: &str,
radix: u32
) -> Result<Num<I, N>, <Num<I, N> as Num>::FromStrRadixErr>
fn from_str_radix( str: &str, radix: u32 ) -> Result<Num<I, N>, <Num<I, N> as Num>::FromStrRadixErr>
2..=36
). Read moresource§impl<I, const N: usize> One for Num<I, N>where
I: FixedWidthUnsignedInteger,
impl<I, const N: usize> One for Num<I, N>where
I: FixedWidthUnsignedInteger,
source§impl<I, const N: usize> Ord for Num<I, N>where
I: Ord + FixedWidthUnsignedInteger,
impl<I, const N: usize> Ord for Num<I, N>where
I: Ord + FixedWidthUnsignedInteger,
source§impl<I, const N: usize> PartialEq for Num<I, N>where
I: PartialEq + FixedWidthUnsignedInteger,
impl<I, const N: usize> PartialEq for Num<I, N>where
I: PartialEq + FixedWidthUnsignedInteger,
source§impl<I, const N: usize> PartialOrd for Num<I, N>where
I: PartialOrd + FixedWidthUnsignedInteger,
impl<I, const N: usize> PartialOrd for Num<I, N>where
I: PartialOrd + FixedWidthUnsignedInteger,
source§impl<I, T, const N: usize> Rem<T> for Num<I, N>where
I: FixedWidthUnsignedInteger,
T: Into<Num<I, N>>,
impl<I, T, const N: usize> Rem<T> for Num<I, N>where
I: FixedWidthUnsignedInteger,
T: Into<Num<I, N>>,
source§impl<I, T, const N: usize> RemAssign<T> for Num<I, N>where
I: FixedWidthUnsignedInteger,
T: Into<Num<I, N>>,
impl<I, T, const N: usize> RemAssign<T> for Num<I, N>where
I: FixedWidthUnsignedInteger,
T: Into<Num<I, N>>,
source§fn rem_assign(&mut self, modulus: T)
fn rem_assign(&mut self, modulus: T)
%=
operation. Read moresource§impl<I, T, const N: usize> Sub<T> for Num<I, N>where
I: FixedWidthUnsignedInteger,
T: Into<Num<I, N>>,
impl<I, T, const N: usize> Sub<T> for Num<I, N>where
I: FixedWidthUnsignedInteger,
T: Into<Num<I, N>>,
source§impl<I, T, const N: usize> SubAssign<T> for Num<I, N>where
I: FixedWidthUnsignedInteger,
T: Into<Num<I, N>>,
impl<I, T, const N: usize> SubAssign<T> for Num<I, N>where
I: FixedWidthUnsignedInteger,
T: Into<Num<I, N>>,
source§fn sub_assign(&mut self, rhs: T)
fn sub_assign(&mut self, rhs: T)
-=
operation. Read more