Skip to main content
← PSoXide SDK guides and examples · SDK f2fec1c301f1 · All Cargo features enabled; check feature gates before use.

Crate psx_math

Crate psx_math 

Source
Expand description

Fixed-point math primitives for the PS1 SDK.

The PS1 has no FPU. Games that want sine-driven animation, camera rotation, pseudo-3D, or smoothed HUDs all reach for the same toolbox: a Q-format fixed-point type, a sin/cos LUT, and a couple of vector/matrix helpers. This crate owns those primitives once so every downstream crate (psx-font, a future psx-gte-wrapper, a future psx-ui, gameplay code) shares the same representation.

§What’s here today

  • sincos – Q0.12 angle type + 256-entry Q1.12 sine LUT + interpolated sin_q12 / cos_q12 lookups, and the matching octant-linear atan2_q12.
  • int32 – saturating 32-bit scalar helpers: abs_i32 / abs_i16, clamp_i16, square_i32_saturating, isqrt_i32, mul_q12_i32, plus the 64-bit-free wide forms mul_div_i32, mul_shr_i32, mul_shr_trunc_i32, mul_div_u32, isqrt_u64 and div_u64_by_u32.
  • fmt – integer-to-decimal ASCII without core::fmt, for HUD/score text drawn with psx-font.

§What’s planned (same crate, future modules)

  • fixed – Q3.12 and Q16.16 wrappers with operator overloads and saturating / wrapping arithmetic.
  • vec – Vec2 / Vec3 over integer and fixed-point types with dot / cross / length² / normalise.
  • mat – 2×2 / 3×3 / GTE-shape matrices, chosen to match how the GTE’s RTPS / MVMVA instructions consume data.
  • ease – sinusoidal / quadratic / cubic easing helpers for timeline animation.
  • lerp – generic linear interpolation.

These modules land as concrete consumer code needs them – no premature abstractions. The crate ships empty apart from the documented scope so reviewers can see where new primitives should go.

§Q-format refresher

Qm.n means m integer bits + n fractional bits in a signed integer. Arithmetic rules:

  • Add / sub: same as ordinary integer add / sub.
  • Multiply: (a * b) >> n – two Q_.n values produce a Q._2n intermediate that must be shifted back.
  • Divide: (a << n) / b – scale up the numerator by n bits first so the quotient is in Qm.n.

Conventions the PS1 SDK uses:

  • Q0.12 angle: u16 in [0, 4096) maps to [0°, 360°). Matches the GTE’s angle resolution. 4096 = one full revolution. Overflow wraps naturally in u16.
  • Q1.12 trig values: i16 in [-4096, 4096]. 4096 = +1.0, -4096 = -1.0. Multiplying a Q_.12 input by a Q1.12 coefficient produces a Q._24 intermediate; shift right 12 to land back in the original format.
  • Q3.12 transforms (future): i16 with range ±7.999…. Used by psx-font’s affine matrices today; planned as a proper Mat2 type here.
  • Q16.16 positions (future): i32 in ±32767 with 16 fractional bits – standard precision for sub-pixel positions, accumulated velocities, etc.

Re-exports§

pub use sincos::atan2_q12;
pub use sincos::cos_q12;
pub use sincos::sin_q12;
pub use sincos::SIN_TABLE;

Modules§

attributed_clip
Allocation-free convex clipping shared by the PS1 renderers.
color
RGB arithmetic with explicit rounding contracts.
fmt
Integer-to-decimal ASCII without core::fmt.
int32
Saturating 32-bit integer scalar helpers.
sincos
Compact sin/cos lookup for Q0.12 angles.