fixed point aliases and methods.

This commit is contained in:
Lokathor 2022-10-17 19:13:54 -06:00
parent c82c3bf7fe
commit 6a96f61be1
4 changed files with 68 additions and 20 deletions

View file

@ -1,6 +1,9 @@
# Changelog
* **0.9.0:** (unreleased)
* **0.9.1:**
* Adds some randomization support directly into the crate.
* Added more methods to the `Fixed` type.
* **0.9.0:**
* **MSRV:** The crate now requires `compiler_builtins-0.1.81` to build. You
will need a Nightly from 2022-10-15 or later.
* **Break:** Quite a bit of the video interface has been replaced, but it

View file

@ -1,10 +1,55 @@
use core::ops::*;
/// `i16` with 8 bits of fixed-point fraction.
///
/// This is used by the affine matrix entries.
#[allow(non_camel_case_types)]
pub type i16fx8 = Fixed<i16, 8>;
/// `i32` with 8 bits of fixed-point fraction.
///
/// This is used by the background reference point entries.
#[allow(non_camel_case_types)]
pub type i32fx8 = Fixed<i32, 8>;
// TODO: this derived Debug impl prints the wrong thing, but it's fine for now.
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct Fixed<I, const B: u32>(I);
impl<I, const B: u32> Fixed<I, B> {
/// Converts a base typed value into the fixed-point form.
///
/// This involves left-shifting the input by `B` bits. If the input is large
/// enough then bits will shift off of the left edge. The resulting value is
/// thus "wrapped" into the numeric range of this fixed point type.
#[inline]
#[must_use]
pub fn wrapping_from(i: I) -> Self
where
I: Shl<u32, Output = I>,
{
Self(i << B)
}
/// Makes a `Fixed` from a raw inner value.
#[inline]
#[must_use]
pub const fn from_raw(i: I) -> Self {
Self(i)
}
/// Unwraps the inner value back into the base type.
#[inline]
#[must_use]
pub const fn into_raw(self) -> I
where
I: Copy,
{
self.0
}
}
macro_rules! impl_passthrough_self_rhs {
($trait_name:ident, $method_name:ident) => {
impl<I: $trait_name<Output = I>, const B: u32> $trait_name for Fixed<I, B> {

View file

@ -37,7 +37,7 @@ use crate::{
sound::{
SweepControl, TonePattern, ToneFrequency, WaveBank, WaveLenVolume, WaveFrequency, NoiseLenEnvelope, NoiseFrequency, LeftRightVolume, SoundMix, SoundEnable, SoundBias
},
timers::TimerControl, keys::{KeyInput, KeyControl}, mgba::MgbaMessageLevel, fixed::Fixed,
timers::TimerControl, keys::{KeyInput, KeyControl}, mgba::MgbaMessageLevel, fixed::{i16fx8, i32fx8},
};
// Note(Lokathor): This macro lets us stick each address at the start of the
@ -78,19 +78,19 @@ def_mmio!(0x0400_001A = BG2VOFS: VolAddress<u16, (), Safe>; "Background 2 Vertic
def_mmio!(0x0400_001C = BG3HOFS: VolAddress<u16, (), Safe>; "Background 3 Horizontal Offset (9-bit, text mode)");
def_mmio!(0x0400_001E = BG3VOFS: VolAddress<u16, (), Safe>; "Background 3 Vertical Offset (9-bit, text mode)");
def_mmio!(0x0400_0020 = BG2PA: VolAddress<Fixed<i16, 8>, (), Safe>; "Background 2 Param A (affine mode)");
def_mmio!(0x0400_0022 = BG2PB: VolAddress<Fixed<i16, 8>, (), Safe>; "Background 2 Param B (affine mode)");
def_mmio!(0x0400_0024 = BG2PC: VolAddress<Fixed<i16, 8>, (), Safe>; "Background 2 Param C (affine mode)");
def_mmio!(0x0400_0026 = BG2PD: VolAddress<Fixed<i16, 8>, (), Safe>; "Background 2 Param D (affine mode)");
def_mmio!(0x0400_0028 = BG2X/["BG2X_L", "BG2X_H"]: VolAddress<Fixed<i32, 8>, (), Safe>; "Background 2 X Reference Point (affine/bitmap modes)");
def_mmio!(0x0400_002C = BG2Y/["BG2Y_L", "BG2Y_H"]: VolAddress<Fixed<i32, 8>, (), Safe>; "Background 2 Y Reference Point (affine/bitmap modes)");
def_mmio!(0x0400_0020 = BG2PA: VolAddress<i16fx8, (), Safe>; "Background 2 Param A (affine mode)");
def_mmio!(0x0400_0022 = BG2PB: VolAddress<i16fx8, (), Safe>; "Background 2 Param B (affine mode)");
def_mmio!(0x0400_0024 = BG2PC: VolAddress<i16fx8, (), Safe>; "Background 2 Param C (affine mode)");
def_mmio!(0x0400_0026 = BG2PD: VolAddress<i16fx8, (), Safe>; "Background 2 Param D (affine mode)");
def_mmio!(0x0400_0028 = BG2X/["BG2X_L", "BG2X_H"]: VolAddress<i32fx8, (), Safe>; "Background 2 X Reference Point (affine/bitmap modes)");
def_mmio!(0x0400_002C = BG2Y/["BG2Y_L", "BG2Y_H"]: VolAddress<i32fx8, (), Safe>; "Background 2 Y Reference Point (affine/bitmap modes)");
def_mmio!(0x0400_0030 = BG3PA: VolAddress<Fixed<i16, 8>, (), Safe>; "Background 3 Param A (affine mode)");
def_mmio!(0x0400_0032 = BG3PB: VolAddress<Fixed<i16, 8>, (), Safe>; "Background 3 Param B (affine mode)");
def_mmio!(0x0400_0034 = BG3PC: VolAddress<Fixed<i16, 8>, (), Safe>; "Background 3 Param C (affine mode)");
def_mmio!(0x0400_0036 = BG3PD: VolAddress<Fixed<i16, 8>, (), Safe>; "Background 3 Param D (affine mode)");
def_mmio!(0x0400_0038 = BG3X/["BG3X_L", "BG3X_H"]: VolAddress<Fixed<i32, 8>, (), Safe>; "Background 3 X Reference Point (affine/bitmap modes)");
def_mmio!(0x0400_003C = BG3Y/["BG3Y_L", "BG3Y_H"]: VolAddress<Fixed<i32, 8>, (), Safe>; "Background 3 Y Reference Point (affine/bitmap modes)");
def_mmio!(0x0400_0030 = BG3PA: VolAddress<i16fx8, (), Safe>; "Background 3 Param A (affine mode)");
def_mmio!(0x0400_0032 = BG3PB: VolAddress<i16fx8, (), Safe>; "Background 3 Param B (affine mode)");
def_mmio!(0x0400_0034 = BG3PC: VolAddress<i16fx8, (), Safe>; "Background 3 Param C (affine mode)");
def_mmio!(0x0400_0036 = BG3PD: VolAddress<i16fx8, (), Safe>; "Background 3 Param D (affine mode)");
def_mmio!(0x0400_0038 = BG3X/["BG3X_L", "BG3X_H"]: VolAddress<i32fx8, (), Safe>; "Background 3 X Reference Point (affine/bitmap modes)");
def_mmio!(0x0400_003C = BG3Y/["BG3Y_L", "BG3Y_H"]: VolAddress<i32fx8, (), Safe>; "Background 3 Y Reference Point (affine/bitmap modes)");
def_mmio!(0x0400_0040 = WIN0H: VolAddress<u8x2, (), Safe>; "Window 0 Horizontal: high=left, low=(right+1)");
def_mmio!(0x0400_0042 = WIN1H: VolAddress<u8x2, (), Safe>; "Window 1 Horizontal: high=left, low=(right+1)");
@ -408,7 +408,7 @@ def_mmio!(0x0700_0000 = OBJ_ATTR0: VolSeries<ObjAttr0, Safe, Safe, 128, {size_of
def_mmio!(0x0700_0002 = OBJ_ATTR1: VolSeries<ObjAttr1, Safe, Safe, 128, {size_of::<[u16;4]>()}>; "Object attributes 1.");
def_mmio!(0x0700_0004 = OBJ_ATTR2: VolSeries<ObjAttr2, Safe, Safe, 128, {size_of::<[u16;4]>()}>; "Object attributes 2.");
def_mmio!(0x0700_0006 = AFFINE_PARAM_A: VolSeries<Fixed<i16, 8>, Safe, Safe, 32, {size_of::<[u16;16]>()}>; "Affine parameters A.");
def_mmio!(0x0700_000E = AFFINE_PARAM_B: VolSeries<Fixed<i16, 8>, Safe, Safe, 32, {size_of::<[u16;16]>()}>; "Affine parameters B.");
def_mmio!(0x0700_0016 = AFFINE_PARAM_C: VolSeries<Fixed<i16, 8>, Safe, Safe, 32, {size_of::<[u16;16]>()}>; "Affine parameters C.");
def_mmio!(0x0700_001E = AFFINE_PARAM_D: VolSeries<Fixed<i16, 8>, Safe, Safe, 32, {size_of::<[u16;16]>()}>; "Affine parameters D.");
def_mmio!(0x0700_0006 = AFFINE_PARAM_A: VolSeries<i16fx8, Safe, Safe, 32, {size_of::<[u16;16]>()}>; "Affine parameters A.");
def_mmio!(0x0700_000E = AFFINE_PARAM_B: VolSeries<i16fx8, Safe, Safe, 32, {size_of::<[u16;16]>()}>; "Affine parameters B.");
def_mmio!(0x0700_0016 = AFFINE_PARAM_C: VolSeries<i16fx8, Safe, Safe, 32, {size_of::<[u16;16]>()}>; "Affine parameters C.");
def_mmio!(0x0700_001E = AFFINE_PARAM_D: VolSeries<i16fx8, Safe, Safe, 32, {size_of::<[u16;16]>()}>; "Affine parameters D.");

View file

@ -1,6 +1,6 @@
//! A module that just re-exports all the other modules of the crate.
pub use crate::{
asm_runtime::*, bios::*, builtin_art::*, dma::*, gba_cell::*, interrupts::*,
keys::*, mmio::*, sound::*, timers::*, video::*,
asm_runtime::*, bios::*, builtin_art::*, dma::*, fixed::*, gba_cell::*,
interrupts::*, keys::*, mmio::*, sound::*, timers::*, video::*,
};