mirror of
https://github.com/italicsjenga/agb.git
synced 2025-01-10 09:01:34 +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(),
|
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>> {
|
impl<const N: usize> Vector2D<Num<i32, N>> {
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
use agb::{
|
use agb::{
|
||||||
display::{
|
display::{
|
||||||
|
affine::{AffineMatrix, AffineMatrixBackground},
|
||||||
tiled::{AffineBackgroundSize, TileFormat, TileSet, TiledMap},
|
tiled::{AffineBackgroundSize, TileFormat, TileSet, TiledMap},
|
||||||
Priority,
|
Priority,
|
||||||
},
|
},
|
||||||
|
@ -32,8 +33,8 @@ fn main(mut gba: agb::Gba) -> ! {
|
||||||
bg.commit(&mut vram);
|
bg.commit(&mut vram);
|
||||||
bg.show();
|
bg.show();
|
||||||
|
|
||||||
let mut rotation: Num<u16, 8> = num!(0.);
|
let mut rotation = num!(0.);
|
||||||
let rotation_increase = num!(1.);
|
let rotation_increase: Num<i32, 16> = num!(0.01);
|
||||||
|
|
||||||
let mut input = agb::input::ButtonController::new();
|
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_x += input.x_tri() as i32;
|
||||||
scroll_y += input.y_tri() as i32;
|
scroll_y += input.y_tri() as i32;
|
||||||
|
|
||||||
let scroll_pos = (scroll_x as i16, scroll_y as i16);
|
let scroll_pos = (scroll_x, scroll_y).into();
|
||||||
bg.set_scroll_pos(scroll_pos.into());
|
|
||||||
bg.set_transform((0, 0), (1, 1), rotation);
|
|
||||||
|
|
||||||
rotation += rotation_increase;
|
rotation += rotation_increase;
|
||||||
if rotation >= num!(255.) {
|
rotation = rotation.rem_euclid(1.into());
|
||||||
rotation = 0.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();
|
vblank.wait_for_vblank();
|
||||||
bg.commit(&mut vram);
|
bg.commit(&mut vram);
|
||||||
|
|
|
@ -62,7 +62,7 @@ impl AffineMatrix {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
/// Generates the matrix that represents a rotation
|
/// Generates the matrix that represents a rotation
|
||||||
pub fn from_rotation<const N: usize>(angle: Num<i32, N>) -> Self {
|
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 cos = angle.cos().change_base();
|
||||||
let sin = angle.sin().change_base();
|
let sin = angle.sin().change_base();
|
||||||
|
|
||||||
|
@ -71,8 +71,8 @@ impl AffineMatrix {
|
||||||
// space rather than how you might conventionally think of it.
|
// space rather than how you might conventionally think of it.
|
||||||
AffineMatrix {
|
AffineMatrix {
|
||||||
a: cos,
|
a: cos,
|
||||||
b: sin,
|
b: -sin,
|
||||||
c: -sin,
|
c: sin,
|
||||||
d: cos,
|
d: cos,
|
||||||
x: 0.into(),
|
x: 0.into(),
|
||||||
y: 0.into(),
|
y: 0.into(),
|
||||||
|
@ -90,15 +90,15 @@ impl AffineMatrix {
|
||||||
b: 0.into(),
|
b: 0.into(),
|
||||||
c: 0.into(),
|
c: 0.into(),
|
||||||
d: 1.into(),
|
d: 1.into(),
|
||||||
x: position.x,
|
x: -position.x,
|
||||||
y: position.y,
|
y: -position.y,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
/// The position fields of the matrix
|
/// The position fields of the matrix
|
||||||
pub fn position(&self) -> Vector2D<Num<i32, 8>> {
|
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
|
/// 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),
|
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 {
|
impl Default for AffineMatrix {
|
||||||
|
@ -198,6 +212,35 @@ impl AffineMatrixBackground {
|
||||||
y: self.y,
|
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 {
|
impl From<AffineMatrixBackground> for AffineMatrix {
|
||||||
|
|
|
@ -344,16 +344,8 @@ impl AffineMap {
|
||||||
*self.tiles_dirty() = true;
|
*self.tiles_dirty() = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_transform(
|
pub fn set_transform(&mut self, transformation: impl Into<AffineMatrixBackground>) {
|
||||||
&mut self,
|
self.transform = transformation.into();
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bg_affine_matrix(&self) -> MemoryMapped<AffineMatrixBackground> {
|
fn bg_affine_matrix(&self) -> MemoryMapped<AffineMatrixBackground> {
|
||||||
|
|
|
@ -145,20 +145,26 @@ pub fn bg_affine_matrix(
|
||||||
bg_center: Vector2D<Num<i32, 8>>,
|
bg_center: Vector2D<Num<i32, 8>>,
|
||||||
display_center: Vector2D<i16>,
|
display_center: Vector2D<i16>,
|
||||||
scale: Vector2D<Num<i16, 8>>,
|
scale: Vector2D<Num<i16, 8>>,
|
||||||
rotation: Num<u16, 8>,
|
rotation: Num<u16, 16>,
|
||||||
) -> AffineMatrixBackground {
|
) -> AffineMatrixBackground {
|
||||||
#[repr(C, packed(4))]
|
#[repr(C, packed(4))]
|
||||||
struct Input {
|
struct Input {
|
||||||
bg_center: Vector2D<Num<i32, 8>>,
|
bg_center_x: Num<i32, 8>,
|
||||||
display_center: Vector2D<i16>,
|
bg_center_y: Num<i32, 8>,
|
||||||
scale: Vector2D<Num<i16, 8>>,
|
display_center_x: i16,
|
||||||
rotation: Num<u16, 8>,
|
display_center_y: i16,
|
||||||
|
scale_x: Num<i16, 8>,
|
||||||
|
scale_y: Num<i16, 8>,
|
||||||
|
rotation: Num<u16, 16>,
|
||||||
}
|
}
|
||||||
|
|
||||||
let input = Input {
|
let input = Input {
|
||||||
bg_center,
|
bg_center_x: bg_center.x,
|
||||||
display_center,
|
bg_center_y: bg_center.y,
|
||||||
scale,
|
display_center_x: display_center.x,
|
||||||
|
display_center_y: display_center.y,
|
||||||
|
scale_x: scale.x,
|
||||||
|
scale_y: scale.y,
|
||||||
rotation,
|
rotation,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue