From 6a96f61be1f2e24f4354a1eadf3b701453758e07 Mon Sep 17 00:00:00 2001 From: Lokathor Date: Mon, 17 Oct 2022 19:13:54 -0600 Subject: [PATCH] fixed point aliases and methods. --- CHANGELOG.md | 5 ++++- src/fixed.rs | 45 +++++++++++++++++++++++++++++++++++++++++++++ src/mmio.rs | 34 +++++++++++++++++----------------- src/prelude.rs | 4 ++-- 4 files changed, 68 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 65298db..5884e62 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/src/fixed.rs b/src/fixed.rs index ac70ad2..5446e1e 100644 --- a/src/fixed.rs +++ b/src/fixed.rs @@ -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; + +/// `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; + // 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); +impl Fixed { + /// 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, + { + 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, const B: u32> $trait_name for Fixed { diff --git a/src/mmio.rs b/src/mmio.rs index ed12cd5..6364bde 100644 --- a/src/mmio.rs +++ b/src/mmio.rs @@ -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; "Background 2 Vertic def_mmio!(0x0400_001C = BG3HOFS: VolAddress; "Background 3 Horizontal Offset (9-bit, text mode)"); def_mmio!(0x0400_001E = BG3VOFS: VolAddress; "Background 3 Vertical Offset (9-bit, text mode)"); -def_mmio!(0x0400_0020 = BG2PA: VolAddress, (), Safe>; "Background 2 Param A (affine mode)"); -def_mmio!(0x0400_0022 = BG2PB: VolAddress, (), Safe>; "Background 2 Param B (affine mode)"); -def_mmio!(0x0400_0024 = BG2PC: VolAddress, (), Safe>; "Background 2 Param C (affine mode)"); -def_mmio!(0x0400_0026 = BG2PD: VolAddress, (), Safe>; "Background 2 Param D (affine mode)"); -def_mmio!(0x0400_0028 = BG2X/["BG2X_L", "BG2X_H"]: VolAddress, (), Safe>; "Background 2 X Reference Point (affine/bitmap modes)"); -def_mmio!(0x0400_002C = BG2Y/["BG2Y_L", "BG2Y_H"]: VolAddress, (), Safe>; "Background 2 Y Reference Point (affine/bitmap modes)"); +def_mmio!(0x0400_0020 = BG2PA: VolAddress; "Background 2 Param A (affine mode)"); +def_mmio!(0x0400_0022 = BG2PB: VolAddress; "Background 2 Param B (affine mode)"); +def_mmio!(0x0400_0024 = BG2PC: VolAddress; "Background 2 Param C (affine mode)"); +def_mmio!(0x0400_0026 = BG2PD: VolAddress; "Background 2 Param D (affine mode)"); +def_mmio!(0x0400_0028 = BG2X/["BG2X_L", "BG2X_H"]: VolAddress; "Background 2 X Reference Point (affine/bitmap modes)"); +def_mmio!(0x0400_002C = BG2Y/["BG2Y_L", "BG2Y_H"]: VolAddress; "Background 2 Y Reference Point (affine/bitmap modes)"); -def_mmio!(0x0400_0030 = BG3PA: VolAddress, (), Safe>; "Background 3 Param A (affine mode)"); -def_mmio!(0x0400_0032 = BG3PB: VolAddress, (), Safe>; "Background 3 Param B (affine mode)"); -def_mmio!(0x0400_0034 = BG3PC: VolAddress, (), Safe>; "Background 3 Param C (affine mode)"); -def_mmio!(0x0400_0036 = BG3PD: VolAddress, (), Safe>; "Background 3 Param D (affine mode)"); -def_mmio!(0x0400_0038 = BG3X/["BG3X_L", "BG3X_H"]: VolAddress, (), Safe>; "Background 3 X Reference Point (affine/bitmap modes)"); -def_mmio!(0x0400_003C = BG3Y/["BG3Y_L", "BG3Y_H"]: VolAddress, (), Safe>; "Background 3 Y Reference Point (affine/bitmap modes)"); +def_mmio!(0x0400_0030 = BG3PA: VolAddress; "Background 3 Param A (affine mode)"); +def_mmio!(0x0400_0032 = BG3PB: VolAddress; "Background 3 Param B (affine mode)"); +def_mmio!(0x0400_0034 = BG3PC: VolAddress; "Background 3 Param C (affine mode)"); +def_mmio!(0x0400_0036 = BG3PD: VolAddress; "Background 3 Param D (affine mode)"); +def_mmio!(0x0400_0038 = BG3X/["BG3X_L", "BG3X_H"]: VolAddress; "Background 3 X Reference Point (affine/bitmap modes)"); +def_mmio!(0x0400_003C = BG3Y/["BG3Y_L", "BG3Y_H"]: VolAddress; "Background 3 Y Reference Point (affine/bitmap modes)"); def_mmio!(0x0400_0040 = WIN0H: VolAddress; "Window 0 Horizontal: high=left, low=(right+1)"); def_mmio!(0x0400_0042 = WIN1H: VolAddress; "Window 1 Horizontal: high=left, low=(right+1)"); @@ -408,7 +408,7 @@ def_mmio!(0x0700_0000 = OBJ_ATTR0: VolSeries()}>; "Object attributes 1."); def_mmio!(0x0700_0004 = OBJ_ATTR2: VolSeries()}>; "Object attributes 2."); -def_mmio!(0x0700_0006 = AFFINE_PARAM_A: VolSeries, Safe, Safe, 32, {size_of::<[u16;16]>()}>; "Affine parameters A."); -def_mmio!(0x0700_000E = AFFINE_PARAM_B: VolSeries, Safe, Safe, 32, {size_of::<[u16;16]>()}>; "Affine parameters B."); -def_mmio!(0x0700_0016 = AFFINE_PARAM_C: VolSeries, Safe, Safe, 32, {size_of::<[u16;16]>()}>; "Affine parameters C."); -def_mmio!(0x0700_001E = AFFINE_PARAM_D: VolSeries, Safe, Safe, 32, {size_of::<[u16;16]>()}>; "Affine parameters D."); +def_mmio!(0x0700_0006 = AFFINE_PARAM_A: VolSeries()}>; "Affine parameters A."); +def_mmio!(0x0700_000E = AFFINE_PARAM_B: VolSeries()}>; "Affine parameters B."); +def_mmio!(0x0700_0016 = AFFINE_PARAM_C: VolSeries()}>; "Affine parameters C."); +def_mmio!(0x0700_001E = AFFINE_PARAM_D: VolSeries()}>; "Affine parameters D."); diff --git a/src/prelude.rs b/src/prelude.rs index d6e25b7..d70b2a9 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -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::*, };