mirror of
https://github.com/italicsjenga/agb.git
synced 2025-02-02 12:36:35 +11:00
commit
cdba323b39
7 changed files with 58 additions and 10 deletions
|
@ -9,10 +9,13 @@ use core::{
|
|||
},
|
||||
};
|
||||
|
||||
#[doc(hidden)]
|
||||
pub use agb_macros::num as num_inner;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! num {
|
||||
($value:literal) => {{
|
||||
$crate::Num::new_from_parts(agb_macros::num!($value))
|
||||
$crate::Num::new_from_parts($crate::num_inner!($value))
|
||||
}};
|
||||
}
|
||||
|
||||
|
|
|
@ -115,7 +115,7 @@ pub fn include_aseprite_inner(input: TokenStream) -> TokenStream {
|
|||
|
||||
for frame in frames {
|
||||
let width = frame.width();
|
||||
assert!(width == frame.height() && width.is_power_of_two() && width <= 32);
|
||||
assert!(width == frame.height() && width.is_power_of_two() && width <= 64);
|
||||
|
||||
let image = Image::load_from_dyn_image(frame);
|
||||
add_to_optimiser(
|
||||
|
@ -154,7 +154,7 @@ pub fn include_aseprite_inner(input: TokenStream) -> TokenStream {
|
|||
quote! {
|
||||
Sprite::new(
|
||||
&PALETTES[#assignment],
|
||||
#data,
|
||||
align_bytes!(u16, #data),
|
||||
Size::from_width_height(#width, #height)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -135,11 +135,32 @@ pub enum Size {
|
|||
S32x64 = 0b10_11,
|
||||
}
|
||||
|
||||
#[repr(C)] // guarantee 'bytes' comes after '_align'
|
||||
pub struct AlignedAs<Align, Bytes: ?Sized> {
|
||||
pub _align: [Align; 0],
|
||||
pub bytes: Bytes,
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! align_bytes {
|
||||
($align_ty:ty, $data:literal) => {{
|
||||
use $crate::display::object::AlignedAs;
|
||||
|
||||
const ALIGNED: &AlignedAs<$align_ty, [u8]> = &AlignedAs {
|
||||
_align: [],
|
||||
bytes: *$data,
|
||||
};
|
||||
|
||||
&ALIGNED.bytes
|
||||
}};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! include_aseprite {
|
||||
($($aseprite_path: expr),*) => {{
|
||||
use $crate::display::object::{Size, Sprite, Tag, TagMap, Graphics};
|
||||
use $crate::display::palette16::Palette16;
|
||||
use $crate::align_bytes;
|
||||
|
||||
$crate::include_aseprite_inner!($($aseprite_path),*);
|
||||
|
||||
|
@ -249,8 +270,11 @@ impl Tag {
|
|||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn sprite(&self, idx: usize) -> &'static Sprite {
|
||||
&self.sprites()[idx]
|
||||
pub const fn sprite(&self, idx: usize) -> &'static Sprite {
|
||||
if idx >= self.len {
|
||||
panic!("out of bounds access to sprite");
|
||||
}
|
||||
unsafe { &*self.sprites.add(idx) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
@ -17,7 +17,7 @@ const PALETTE_BACKGROUND: MemoryMapped1DArray<u16, 256> =
|
|||
|
||||
static TILE_ALLOCATOR: BlockAllocator = unsafe {
|
||||
BlockAllocator::new(StartEnd {
|
||||
start: || TILE_RAM_START,
|
||||
start: || TILE_RAM_START + 8 * 8,
|
||||
end: || TILE_RAM_START + 0x8000,
|
||||
})
|
||||
};
|
||||
|
|
|
@ -95,10 +95,12 @@ agb_arm_func agb_rs__mixer_add_stereo
|
|||
@ Arguments
|
||||
@ r0 - pointer to the data to be copied (u8 array)
|
||||
@ r1 - pointer to the sound buffer (i16 array which will alternate left and right channels, 32-bit aligned)
|
||||
@ r2 - volume to play the sound at
|
||||
@
|
||||
@ The sound buffer must be SOUND_BUFFER_SIZE * 2 in size = 176 * 2
|
||||
push {r4-r8}
|
||||
push {r4-r9}
|
||||
|
||||
mov r9, r2
|
||||
ldr r5, =0x00000FFF
|
||||
|
||||
ldr r8, =agb_rs__buffer_size
|
||||
|
@ -128,7 +130,7 @@ agb_arm_func agb_rs__mixer_add_stereo
|
|||
lsl r6, r6, #24 @ r6 = | R | 0 | 0 | 0 | drop everything except the right sample
|
||||
orr r6, r7, r6, asr #8 @ r6 = | 1 | R | 1 | L | now we have it perfectly set up
|
||||
|
||||
add r4, r4, r6, lsl #4 @ r4 += r6 << 4 (calculating both the left and right samples together)
|
||||
mla r4, r6, r9, r4 @ r4 += r6 * r9 (calculating both the left and right samples together)
|
||||
|
||||
str r4, [r1], #4 @ store the new value, and increment the pointer
|
||||
.endr
|
||||
|
@ -136,7 +138,7 @@ agb_arm_func agb_rs__mixer_add_stereo
|
|||
subs r8, r8, #4 @ loop counter
|
||||
bne 1b @ jump back if we're done with the loop
|
||||
|
||||
pop {r4-r8}
|
||||
pop {r4-r9}
|
||||
bx lr
|
||||
|
||||
agb_arm_end agb_rs__mixer_add_stereo
|
||||
|
|
|
@ -375,4 +375,18 @@ impl SoundChannel {
|
|||
pub fn stop(&mut self) {
|
||||
self.is_done = true;
|
||||
}
|
||||
|
||||
/// Gets how far along the sound has played.
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn pos(&self) -> Num<usize, 8> {
|
||||
self.pos
|
||||
}
|
||||
|
||||
/// Sets the playback position
|
||||
#[inline]
|
||||
pub fn set_pos(&mut self, pos: impl Into<Num<usize, 8>>) -> &mut Self {
|
||||
self.pos = pos.into();
|
||||
self
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,11 @@ extern "C" {
|
|||
right_amount: Num<i16, 4>,
|
||||
);
|
||||
|
||||
fn agb_rs__mixer_add_stereo(sound_data: *const u8, sound_buffer: *mut Num<i16, 4>);
|
||||
fn agb_rs__mixer_add_stereo(
|
||||
sound_data: *const u8,
|
||||
sound_buffer: *mut Num<i16, 4>,
|
||||
volume: Num<i16, 4>,
|
||||
);
|
||||
|
||||
fn agb_rs__mixer_collapse(sound_buffer: *mut i8, input_buffer: *const Num<i16, 4>);
|
||||
}
|
||||
|
@ -447,6 +451,7 @@ impl MixerBuffer {
|
|||
agb_rs__mixer_add_stereo(
|
||||
channel.data.as_ptr().add(channel.pos.floor()),
|
||||
buffer.as_mut_ptr(),
|
||||
channel.volume,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
|
|
Loading…
Add table
Reference in a new issue