mirror of
https://github.com/italicsjenga/agb.git
synced 2025-01-09 08:31:33 +11:00
use new affine stuff in map
This commit is contained in:
parent
c69fdd7bec
commit
ed1e8bcbdc
|
@ -688,6 +688,17 @@ impl<I: FixedWidthUnsignedInteger, const N: usize> Vector2D<Num<I, N>> {
|
|||
y: self.y.floor(),
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
/// Attempts to change the base returning None if the numbers cannot be represented
|
||||
pub fn try_change_base<J: FixedWidthUnsignedInteger + TryFrom<I>, const M: usize>(
|
||||
self,
|
||||
) -> Option<Vector2D<Num<J, M>>> {
|
||||
Some(Vector2D::new(
|
||||
self.x.try_change_base()?,
|
||||
self.y.try_change_base()?,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> Vector2D<Num<i32, N>> {
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
use agb::{
|
||||
display::{
|
||||
affine::{AffineMatrix, AffineMatrixBackground},
|
||||
tiled::{AffineBackgroundSize, TileFormat, TileSet, TiledMap},
|
||||
Priority,
|
||||
},
|
||||
|
@ -32,8 +33,8 @@ fn main(mut gba: agb::Gba) -> ! {
|
|||
bg.commit(&mut vram);
|
||||
bg.show();
|
||||
|
||||
let mut rotation: Num<u16, 8> = num!(0.);
|
||||
let rotation_increase = num!(1.);
|
||||
let mut rotation = num!(0.);
|
||||
let rotation_increase: Num<i32, 16> = num!(0.01);
|
||||
|
||||
let mut input = agb::input::ButtonController::new();
|
||||
|
||||
|
@ -45,14 +46,19 @@ fn main(mut gba: agb::Gba) -> ! {
|
|||
scroll_x += input.x_tri() as i32;
|
||||
scroll_y += input.y_tri() as i32;
|
||||
|
||||
let scroll_pos = (scroll_x as i16, scroll_y as i16);
|
||||
bg.set_scroll_pos(scroll_pos.into());
|
||||
bg.set_transform((0, 0), (1, 1), rotation);
|
||||
let scroll_pos = (scroll_x, scroll_y).into();
|
||||
|
||||
rotation += rotation_increase;
|
||||
if rotation >= num!(255.) {
|
||||
rotation = 0.into();
|
||||
}
|
||||
rotation = rotation.rem_euclid(1.into());
|
||||
|
||||
let transformation = AffineMatrixBackground::from_scale_rotation_position(
|
||||
(0, 0).into(),
|
||||
(1, 1).into(),
|
||||
rotation,
|
||||
scroll_pos,
|
||||
);
|
||||
|
||||
bg.set_transform(transformation);
|
||||
|
||||
vblank.wait_for_vblank();
|
||||
bg.commit(&mut vram);
|
||||
|
|
|
@ -62,7 +62,7 @@ impl AffineMatrix {
|
|||
#[must_use]
|
||||
/// Generates the matrix that represents a rotation
|
||||
pub fn from_rotation<const N: usize>(angle: Num<i32, N>) -> Self {
|
||||
fn from_rotation(angle: Num<i32, 28>) -> AffineMatrix {
|
||||
fn from_rotation(angle: Num<i32, 8>) -> AffineMatrix {
|
||||
let cos = angle.cos().change_base();
|
||||
let sin = angle.sin().change_base();
|
||||
|
||||
|
@ -71,8 +71,8 @@ impl AffineMatrix {
|
|||
// space rather than how you might conventionally think of it.
|
||||
AffineMatrix {
|
||||
a: cos,
|
||||
b: sin,
|
||||
c: -sin,
|
||||
b: -sin,
|
||||
c: sin,
|
||||
d: cos,
|
||||
x: 0.into(),
|
||||
y: 0.into(),
|
||||
|
@ -90,15 +90,15 @@ impl AffineMatrix {
|
|||
b: 0.into(),
|
||||
c: 0.into(),
|
||||
d: 1.into(),
|
||||
x: position.x,
|
||||
y: position.y,
|
||||
x: -position.x,
|
||||
y: -position.y,
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
/// The position fields of the matrix
|
||||
pub fn position(&self) -> Vector2D<Num<i32, 8>> {
|
||||
(self.x, self.y).into()
|
||||
(-self.x, -self.y).into()
|
||||
}
|
||||
|
||||
/// Attempts to convert the matrix to one which can be used in affine
|
||||
|
@ -150,6 +150,20 @@ impl AffineMatrix {
|
|||
d: Num::from_raw(self.d.to_raw() as i16),
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
/// Creates an affine matrix from a given (x, y) scaling. This will scale by
|
||||
/// the inverse, ie (2, 2) will produce half the size.
|
||||
pub fn from_scale(scale: Vector2D<Num<i32, 8>>) -> AffineMatrix {
|
||||
AffineMatrix {
|
||||
a: scale.x,
|
||||
b: 0.into(),
|
||||
c: 0.into(),
|
||||
d: scale.y,
|
||||
x: 0.into(),
|
||||
y: 0.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for AffineMatrix {
|
||||
|
@ -198,6 +212,35 @@ impl AffineMatrixBackground {
|
|||
y: self.y,
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
/// Creates a transformation matrix using GBA specific syscalls.
|
||||
/// This can be done using the standard transformation matricies like
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// use agb::display::affine::AffineMatrix;
|
||||
/// # #![no_std]
|
||||
/// # #![no_main]
|
||||
/// # fn something() {
|
||||
/// let A = AffineMatrix::from_translation(-transform_origin)
|
||||
/// * AffineMatrix::from_scale(scale)
|
||||
/// * AffineMatrix::from_rotation(rotation)
|
||||
/// * AffineMatrix::from_translation(position);
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn from_scale_rotation_position(
|
||||
transform_origin: Vector2D<Num<i32, 8>>,
|
||||
scale: Vector2D<Num<i32, 8>>,
|
||||
rotation: Num<i32, 16>,
|
||||
position: Vector2D<Num<i32, 8>>,
|
||||
) -> Self {
|
||||
crate::syscall::bg_affine_matrix(
|
||||
transform_origin,
|
||||
position.try_change_base::<i16, 8>().unwrap().floor(),
|
||||
scale.try_change_base().unwrap(),
|
||||
rotation.rem_euclid(1.into()).try_change_base().unwrap(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AffineMatrixBackground> for AffineMatrix {
|
||||
|
|
|
@ -344,16 +344,8 @@ impl AffineMap {
|
|||
*self.tiles_dirty() = true;
|
||||
}
|
||||
|
||||
pub fn set_transform(
|
||||
&mut self,
|
||||
transform_origin: impl Into<Vector2D<Num<i32, 8>>>,
|
||||
scale: impl Into<Vector2D<Num<i16, 8>>>,
|
||||
rotation: impl Into<Num<u16, 8>>,
|
||||
) {
|
||||
let scale = scale.into();
|
||||
let rotation = rotation.into();
|
||||
self.transform =
|
||||
crate::syscall::bg_affine_matrix(transform_origin.into(), self.scroll, scale, rotation);
|
||||
pub fn set_transform(&mut self, transformation: impl Into<AffineMatrixBackground>) {
|
||||
self.transform = transformation.into();
|
||||
}
|
||||
|
||||
fn bg_affine_matrix(&self) -> MemoryMapped<AffineMatrixBackground> {
|
||||
|
|
|
@ -145,20 +145,26 @@ pub fn bg_affine_matrix(
|
|||
bg_center: Vector2D<Num<i32, 8>>,
|
||||
display_center: Vector2D<i16>,
|
||||
scale: Vector2D<Num<i16, 8>>,
|
||||
rotation: Num<u16, 8>,
|
||||
rotation: Num<u16, 16>,
|
||||
) -> AffineMatrixBackground {
|
||||
#[repr(C, packed(4))]
|
||||
struct Input {
|
||||
bg_center: Vector2D<Num<i32, 8>>,
|
||||
display_center: Vector2D<i16>,
|
||||
scale: Vector2D<Num<i16, 8>>,
|
||||
rotation: Num<u16, 8>,
|
||||
bg_center_x: Num<i32, 8>,
|
||||
bg_center_y: Num<i32, 8>,
|
||||
display_center_x: i16,
|
||||
display_center_y: i16,
|
||||
scale_x: Num<i16, 8>,
|
||||
scale_y: Num<i16, 8>,
|
||||
rotation: Num<u16, 16>,
|
||||
}
|
||||
|
||||
let input = Input {
|
||||
bg_center,
|
||||
display_center,
|
||||
scale,
|
||||
bg_center_x: bg_center.x,
|
||||
bg_center_y: bg_center.y,
|
||||
display_center_x: display_center.x,
|
||||
display_center_y: display_center.y,
|
||||
scale_x: scale.x,
|
||||
scale_y: scale.y,
|
||||
rotation,
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue