diff --git a/agb/src/number.rs b/agb/src/number.rs index f94c2252..1ff3ab0e 100644 --- a/agb/src/number.rs +++ b/agb/src/number.rs @@ -7,7 +7,7 @@ use core::{ }, }; -pub trait FixedWidthInteger: +pub trait FixedWidthUnsignedInteger: Sized + Copy + PartialOrd @@ -20,7 +20,6 @@ pub trait FixedWidthInteger: + Sub + Not + BitAnd - + Neg + Rem + Div + Mul @@ -31,31 +30,50 @@ pub trait FixedWidthInteger: fn zero() -> Self; fn one() -> Self; fn ten() -> Self; - fn abs(self) -> Self; } -impl FixedWidthInteger for i32 { - fn zero() -> Self { - 0 - } - - fn one() -> Self { - 1 - } - - fn ten() -> Self { - 10 - } - - fn abs(self) -> Self { - self.abs() - } +pub trait FixedWidthSignedInteger: FixedWidthUnsignedInteger + Neg { + fn fixed_abs(self) -> Self; } +macro_rules! fixed_width_unsigned_integer_impl { + ($T: ty) => { + impl FixedWidthUnsignedInteger for $T { + fn zero() -> Self { + 0 + } + fn one() -> Self { + 1 + } + fn ten() -> Self { + 10 + } + } + }; +} + +macro_rules! fixed_width_signed_integer_impl { + ($T: ty) => { + impl FixedWidthSignedInteger for $T { + fn fixed_abs(self) -> Self { + self.abs() + } + } + }; +} + +fixed_width_unsigned_integer_impl!(i16); +fixed_width_unsigned_integer_impl!(u16); +fixed_width_unsigned_integer_impl!(i32); +fixed_width_unsigned_integer_impl!(u32); + +fixed_width_signed_integer_impl!(i16); +fixed_width_signed_integer_impl!(i32); + #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] -pub struct Num(I); +pub struct Num(I); -pub fn change_base( +pub fn change_base( num: Num, ) -> Num { if N < M { @@ -65,7 +83,7 @@ pub fn change_base( } } -impl From for Num { +impl From for Num { fn from(value: I) -> Self { Num(value << N) } @@ -73,7 +91,7 @@ impl From for Num { impl Add for Num where - I: FixedWidthInteger, + I: FixedWidthUnsignedInteger, T: Into>, { type Output = Self; @@ -84,7 +102,7 @@ where impl AddAssign for Num where - I: FixedWidthInteger, + I: FixedWidthUnsignedInteger, T: Into>, { fn add_assign(&mut self, rhs: T) { @@ -94,7 +112,7 @@ where impl Sub for Num where - I: FixedWidthInteger, + I: FixedWidthUnsignedInteger, T: Into>, { type Output = Self; @@ -105,7 +123,7 @@ where impl SubAssign for Num where - I: FixedWidthInteger, + I: FixedWidthUnsignedInteger, T: Into>, { fn sub_assign(&mut self, rhs: T) { @@ -115,7 +133,7 @@ where impl Mul for Num where - I: FixedWidthInteger, + I: FixedWidthUnsignedInteger, T: Into>, { type Output = Self; @@ -126,7 +144,7 @@ where impl MulAssign for Num where - I: FixedWidthInteger, + I: FixedWidthUnsignedInteger, T: Into>, { fn mul_assign(&mut self, rhs: T) { @@ -136,7 +154,7 @@ where impl Div for Num where - I: FixedWidthInteger, + I: FixedWidthUnsignedInteger, T: Into>, { type Output = Self; @@ -147,7 +165,7 @@ where impl DivAssign for Num where - I: FixedWidthInteger, + I: FixedWidthUnsignedInteger, T: Into>, { fn div_assign(&mut self, rhs: T) { @@ -157,7 +175,7 @@ where impl Rem for Num where - I: FixedWidthInteger, + I: FixedWidthUnsignedInteger, T: Into>, { type Output = Self; @@ -168,7 +186,7 @@ where impl RemAssign for Num where - I: FixedWidthInteger, + I: FixedWidthUnsignedInteger, T: Into>, { fn rem_assign(&mut self, modulus: T) { @@ -176,14 +194,14 @@ where } } -impl Neg for Num { +impl Neg for Num { type Output = Self; fn neg(self) -> Self::Output { Num(-self.0) } } -impl Num { +impl Num { pub fn from_raw(n: I) -> Self { Num(n) } @@ -220,8 +238,14 @@ impl Num { self.0 >> N } + pub fn new(integral: I) -> Self { + Self(integral << N) + } +} + +impl Num { pub fn abs(self) -> Self { - Num(self.0.abs()) + Num(self.0.fixed_abs()) } /// domain of [0, 1]. @@ -246,10 +270,6 @@ impl Num { let four: I = 4.into(); (self - one / four).cos() } - - pub fn new(integral: I) -> Self { - Self(integral << N) - } } #[test_case] @@ -380,7 +400,7 @@ fn test_rem_euclid_is_always_positive_and_sensible(_gba: &mut super::Gba) { } } -impl Display for Num { +impl Display for Num { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { let integral = self.0 >> N; let mask: I = (I::one() << N) - I::one(); @@ -402,7 +422,7 @@ impl Display for Num { } } -impl Debug for Num { +impl Debug for Num { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { use core::any::type_name; diff --git a/agb/src/syscall.rs b/agb/src/syscall.rs index 7474eaae..49e1fc53 100644 --- a/agb/src/syscall.rs +++ b/agb/src/syscall.rs @@ -107,8 +107,8 @@ pub fn arc_tan2(x: i16, y: i32) -> i16 { } pub fn affine_matrix( - x_scale: Num, - y_scale: Num, + x_scale: Num, + y_scale: Num, rotation: u8, ) -> AffineMatrixAttributes { let mut result = AffineMatrixAttributes { @@ -129,8 +129,8 @@ pub fn affine_matrix( let rotation_for_input = (rotation as u16) << 8; let input = Input { - y_scale: x_scale.to_raw() as i16, - x_scale: y_scale.to_raw() as i16, + y_scale: x_scale.to_raw(), + x_scale: y_scale.to_raw(), rotation: rotation_for_input, }; @@ -149,9 +149,9 @@ pub fn affine_matrix( #[test_case] fn affine(_gba: &mut crate::Gba) { // expect identity matrix - let one: Num<8> = 1.into(); + let one: Num = 1.into(); let aff = affine_matrix(one, one, 0); - assert_eq!(aff.p_a, one.to_raw() as i16); - assert_eq!(aff.p_d, one.to_raw() as i16); + assert_eq!(aff.p_a, one.to_raw()); + assert_eq!(aff.p_d, one.to_raw()); }