mirror of
https://github.com/italicsjenga/agb.git
synced 2024-12-23 08:11:33 +11:00
Upcast multiply (#436)
- [ ] Changelog updated / no changelog update needed
This commit is contained in:
commit
53937b4fa8
|
@ -79,6 +79,8 @@ pub trait FixedWidthUnsignedInteger:
|
||||||
fn ten() -> Self;
|
fn ten() -> Self;
|
||||||
/// Converts an i32 to it's own representation, panics on failure
|
/// Converts an i32 to it's own representation, panics on failure
|
||||||
fn from_as_i32(v: i32) -> Self;
|
fn from_as_i32(v: i32) -> Self;
|
||||||
|
/// Returns (a * b) >> N
|
||||||
|
fn upcast_multiply(a: Self, b: Self, n: usize) -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Trait for an integer that includes negation
|
/// Trait for an integer that includes negation
|
||||||
|
@ -89,7 +91,7 @@ pub trait FixedWidthSignedInteger: FixedWidthUnsignedInteger + Neg<Output = Self
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! fixed_width_unsigned_integer_impl {
|
macro_rules! fixed_width_unsigned_integer_impl {
|
||||||
($T: ty) => {
|
($T: ty, $Upcast: ty) => {
|
||||||
impl FixedWidthUnsignedInteger for $T {
|
impl FixedWidthUnsignedInteger for $T {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn zero() -> Self {
|
fn zero() -> Self {
|
||||||
|
@ -107,6 +109,10 @@ macro_rules! fixed_width_unsigned_integer_impl {
|
||||||
fn from_as_i32(v: i32) -> Self {
|
fn from_as_i32(v: i32) -> Self {
|
||||||
v as $T
|
v as $T
|
||||||
}
|
}
|
||||||
|
#[inline(always)]
|
||||||
|
fn upcast_multiply(a: Self, b: Self, n: usize) -> Self {
|
||||||
|
(((a as $Upcast) * (b as $Upcast)) >> n) as $T
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -122,12 +128,11 @@ macro_rules! fixed_width_signed_integer_impl {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fixed_width_unsigned_integer_impl!(u8);
|
fixed_width_unsigned_integer_impl!(u8, u32);
|
||||||
fixed_width_unsigned_integer_impl!(i16);
|
fixed_width_unsigned_integer_impl!(i16, i32);
|
||||||
fixed_width_unsigned_integer_impl!(u16);
|
fixed_width_unsigned_integer_impl!(u16, u32);
|
||||||
fixed_width_unsigned_integer_impl!(i32);
|
fixed_width_unsigned_integer_impl!(i32, i64);
|
||||||
fixed_width_unsigned_integer_impl!(u32);
|
fixed_width_unsigned_integer_impl!(u32, u64);
|
||||||
fixed_width_unsigned_integer_impl!(usize);
|
|
||||||
|
|
||||||
fixed_width_signed_integer_impl!(i16);
|
fixed_width_signed_integer_impl!(i16);
|
||||||
fixed_width_signed_integer_impl!(i32);
|
fixed_width_signed_integer_impl!(i32);
|
||||||
|
@ -204,9 +209,7 @@ where
|
||||||
{
|
{
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
fn mul(self, rhs: Num<I, N>) -> Self::Output {
|
fn mul(self, rhs: Num<I, N>) -> Self::Output {
|
||||||
Num(((self.floor() * rhs.floor()) << N)
|
Num(I::upcast_multiply(self.0, rhs.0, N))
|
||||||
+ (self.floor() * rhs.frac() + rhs.floor() * self.frac())
|
|
||||||
+ ((self.frac() * rhs.frac()) >> N))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ fn main(mut gba: Gba) -> ! {
|
||||||
{
|
{
|
||||||
if let Some(channel) = mixer.channel(&channel_id) {
|
if let Some(channel) = mixer.channel(&channel_id) {
|
||||||
let half: Num<i16, 4> = num!(0.5);
|
let half: Num<i16, 4> = num!(0.5);
|
||||||
let half_usize: Num<usize, 8> = num!(0.5);
|
let half_usize: Num<u32, 8> = num!(0.5);
|
||||||
match input.x_tri() {
|
match input.x_tri() {
|
||||||
Tri::Negative => channel.panning(-half),
|
Tri::Negative => channel.panning(-half),
|
||||||
Tri::Zero => channel.panning(0),
|
Tri::Zero => channel.panning(0),
|
||||||
|
|
|
@ -224,10 +224,10 @@ impl Frequency {
|
||||||
/// ```
|
/// ```
|
||||||
pub struct SoundChannel {
|
pub struct SoundChannel {
|
||||||
data: &'static [u8],
|
data: &'static [u8],
|
||||||
pos: Num<usize, 8>,
|
pos: Num<u32, 8>,
|
||||||
should_loop: bool,
|
should_loop: bool,
|
||||||
|
|
||||||
playback_speed: Num<usize, 8>,
|
playback_speed: Num<u32, 8>,
|
||||||
volume: Num<i16, 4>, // between 0 and 1
|
volume: Num<i16, 4>, // between 0 and 1
|
||||||
|
|
||||||
panning: Num<i16, 4>, // between -1 and 1
|
panning: Num<i16, 4>, // between -1 and 1
|
||||||
|
@ -336,7 +336,7 @@ impl SoundChannel {
|
||||||
/// Note that this only works for mono sounds. Stereo sounds will not change
|
/// Note that this only works for mono sounds. Stereo sounds will not change
|
||||||
/// how fast they play.
|
/// how fast they play.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn playback(&mut self, playback_speed: impl Into<Num<usize, 8>>) -> &mut Self {
|
pub fn playback(&mut self, playback_speed: impl Into<Num<u32, 8>>) -> &mut Self {
|
||||||
self.playback_speed = playback_speed.into();
|
self.playback_speed = playback_speed.into();
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -392,13 +392,13 @@ impl SoundChannel {
|
||||||
/// Gets how far along the sound has played.
|
/// Gets how far along the sound has played.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn pos(&self) -> Num<usize, 8> {
|
pub fn pos(&self) -> Num<u32, 8> {
|
||||||
self.pos
|
self.pos
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the playback position
|
/// Sets the playback position
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_pos(&mut self, pos: impl Into<Num<usize, 8>>) -> &mut Self {
|
pub fn set_pos(&mut self, pos: impl Into<Num<u32, 8>>) -> &mut Self {
|
||||||
self.pos = pos.into();
|
self.pos = pos.into();
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ extern "C" {
|
||||||
fn agb_rs__mixer_add(
|
fn agb_rs__mixer_add(
|
||||||
sound_data: *const u8,
|
sound_data: *const u8,
|
||||||
sound_buffer: *mut Num<i16, 4>,
|
sound_buffer: *mut Num<i16, 4>,
|
||||||
playback_speed: Num<usize, 8>,
|
playback_speed: Num<u32, 8>,
|
||||||
left_amount: Num<i16, 4>,
|
left_amount: Num<i16, 4>,
|
||||||
right_amount: Num<i16, 4>,
|
right_amount: Num<i16, 4>,
|
||||||
);
|
);
|
||||||
|
@ -415,8 +415,8 @@ impl MixerBuffer {
|
||||||
channel.playback_speed
|
channel.playback_speed
|
||||||
};
|
};
|
||||||
|
|
||||||
if (channel.pos + playback_speed * self.frequency.buffer_size()).floor()
|
if (channel.pos + playback_speed * self.frequency.buffer_size() as u32).floor()
|
||||||
>= channel.data.len()
|
>= channel.data.len() as u32
|
||||||
{
|
{
|
||||||
// TODO: This should probably play what's left rather than skip the last bit
|
// TODO: This should probably play what's left rather than skip the last bit
|
||||||
if channel.should_loop {
|
if channel.should_loop {
|
||||||
|
@ -431,7 +431,7 @@ impl MixerBuffer {
|
||||||
if channel.is_stereo {
|
if channel.is_stereo {
|
||||||
unsafe {
|
unsafe {
|
||||||
agb_rs__mixer_add_stereo(
|
agb_rs__mixer_add_stereo(
|
||||||
channel.data.as_ptr().add(channel.pos.floor()),
|
channel.data.as_ptr().add(channel.pos.floor() as usize),
|
||||||
working_buffer.as_mut_ptr(),
|
working_buffer.as_mut_ptr(),
|
||||||
channel.volume,
|
channel.volume,
|
||||||
);
|
);
|
||||||
|
@ -442,7 +442,7 @@ impl MixerBuffer {
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
agb_rs__mixer_add(
|
agb_rs__mixer_add(
|
||||||
channel.data.as_ptr().add(channel.pos.floor()),
|
channel.data.as_ptr().add(channel.pos.floor() as usize),
|
||||||
working_buffer.as_mut_ptr(),
|
working_buffer.as_mut_ptr(),
|
||||||
playback_speed,
|
playback_speed,
|
||||||
left_amount,
|
left_amount,
|
||||||
|
@ -452,7 +452,7 @@ impl MixerBuffer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
channel.pos += playback_speed * self.frequency.buffer_size();
|
channel.pos += playback_speed * self.frequency.buffer_size() as u32;
|
||||||
}
|
}
|
||||||
|
|
||||||
let write_buffer = free(|cs| self.state.borrow(cs).borrow_mut().active_advanced());
|
let write_buffer = free(|cs| self.state.borrow(cs).borrow_mut().active_advanced());
|
||||||
|
|
Loading…
Reference in a new issue