Nugget
Bare-metal libraries and examples for the original PlayStation
Loading...
Searching...
No Matches
fixedmath.hh
Go to the documentation of this file.
1/*
2
3MIT License
4
5Copyright (c) 2026 PCSX-Redux authors
6
7Permission is hereby granted, free of charge, to any person obtaining a copy
8of this software and associated documentation files (the "Software"), to deal
9in the Software without restriction, including without limitation the rights
10to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11copies of the Software, and to permit persons to whom the Software is
12furnished to do so, subject to the following conditions:
13
14The above copyright notice and this permission notice shall be included in all
15copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23SOFTWARE.
24
25*/
26
27#pragma once
28
29#include <concepts>
30#include <stdint.h>
31
32#include "psyqo/fixed-point.hh"
34#include "psyqo/trigonometry.hh"
35#include "psyqo/vector.hh"
36
37// The OpenBIOS shell does all of its 3D in a bespoke 8.24 fixed point format,
38// with ONE == 2^24, angles measured in units of 2048 to the full turn, and a
39// cosine table seeded by the same recurrence psyqo's Trig uses. That maps
40// exactly onto psyqo's templated fixed point: FixedPoint<24> is the 8.24 type,
41// Trig<24> produces bit-identical cosine values, and Angle (FixedPoint<10>,
42// fractions of Pi) measures 2048 raw to the full turn just like the shell's
43// DC_2PI. We deliberately stay off the GTE: this is the same software pipeline
44// the original used, expressed through psyqo's types.
45
46namespace shello {
47
48// 8.24 fixed point. ONE (the original's 16777216) is Fixed(1.0).
49typedef psyqo::FixedPoint<24> Fixed;
53
54enum class Axis { X, Y, Z };
55
56// A 3x3 matrix whose rows are vs[0..2], matching the original Matrix3D layout
57// (vs[i] is the i-th row, so vs[0].x/y/z is the first row).
58struct Matrix3D {
59 Vec3 vs[3];
60};
61
62// The shell stores rotation phase in the 8.24 domain ([0, ONE) == one full
63// turn) and feeds the rotation routines an angle pre-shifted to DC units via
64// `phase >> 13` (since ONE / 2048 == 2^13). That DC value is exactly the raw
65// value of a psyqo Angle (FixedPoint<10>, 2048 raw to the turn).
66static inline psyqo::Angle dcToAngle(int32_t dc) { return psyqo::Angle(dc, psyqo::Angle::RAW); }
67static inline psyqo::Angle phaseToAngle(Fixed phase) { return dcToAngle(phase.raw() >> 13); }
68
70void multiplyMatrix3D(const Matrix3D *m1, const Matrix3D *m2, Matrix3D *out);
72void matrixVertexMul3D(const Matrix3D *m, const Vec3 *v, Vec3 *out);
73void matrixVertexMul3Dxy(const Matrix3D *m, const Vec3 *v, Vec2 *out);
74Fixed matrixVertexMul3Dz(const Matrix3D *m, const Vec3 *v);
75
76static inline void rotationMatrix2D(Matrix3D *m, psyqo::Angle t, const Trig &trig) {
77 Fixed c = trig.cos(t);
78 Fixed s = trig.sin(t);
79 m->vs[0].x = c;
80 m->vs[0].y = s;
81 m->vs[1].x = -s;
82 m->vs[1].y = c;
83}
84
85// 2x2 transform (rotation/scale) applied to a 2D vector, packed into the top
86// two rows of a Matrix3D's x/y, mirroring the original Matrix2D usage.
87static inline void matrixVertexMul2D(const Matrix3D *m, Vec2 *v) {
88 Fixed x = v->x;
89 Fixed y = v->y;
90 v->x = x * m->vs[0].x + y * m->vs[0].y;
91 v->y = x * m->vs[1].x + y * m->vs[1].y;
92}
93
94// Linear interpolation. p is in [0, 256] for integers and colors, and in
95// [0, 1] for Fixed.
96template <std::integral T>
97static inline T lerp(T s, T d, unsigned p) {
98 return (s * T(256 - p) + d * T(p)) >> 8;
99}
100static inline Fixed lerp(Fixed s, Fixed d, Fixed p) {
101 Fixed one(1.0);
102 return s * (one - p) + d * p;
103}
104static inline psyqo::Color lerp(psyqo::Color s, psyqo::Color d, unsigned p) {
106 r.r = lerp<uint32_t>(s.r, d.r, p);
107 r.g = lerp<uint32_t>(s.g, d.g, p);
108 r.b = lerp<uint32_t>(s.b, d.b, p);
109 return r;
110}
111
112} // namespace shello
A trigonometry table.
Definition trigonometry.hh:74
uint32_t t
Definition cop0.c:79
uint32_t r
Definition cpu.c:222
uint32_t out
Definition cpu.c:62
Axis
Definition math.h:59
one(pat, name)
Definition gentable.py:66
m
Definition gentable.py:52
FixedPoint< 10 > Angle
A fixed point angle.
Definition trigonometry.hh:48
Definition cdcheck.cpp:31
psyqo::Vector< 3, 24 > Vec3
Definition fixedmath.hh:50
void multiplyMatrix3D(const Matrix3D *m1, const Matrix3D *m2, Matrix3D *out)
Definition fixedmath.cpp:78
void generateRotationMatrix3D(Matrix3D *m, psyqo::Angle t, Axis a, const Trig &trig)
Definition fixedmath.cpp:36
void matrixVertexMul3D(const Matrix3D *m, const Vec3 *v, Vec3 *out)
Definition fixedmath.cpp:108
psyqo::Vector< 2, 24 > Vec2
Definition fixedmath.hh:51
psyqo::Trig< 24 > Trig
Definition fixedmath.hh:52
Axis
Definition fixedmath.hh:54
Fixed matrixVertexMul3Dz(const Matrix3D *m, const Vec3 *v)
Definition fixedmath.cpp:125
void matrixVertexMul3Dxy(const Matrix3D *m, const Vec3 *v, Vec2 *out)
Definition fixedmath.cpp:117
psyqo::FixedPoint< 24 > Fixed
Definition fixedmath.hh:49
void scaleMatrix3D(Matrix3D *m, Fixed s)
Definition fixedmath.cpp:100
char * s
Definition string.c:48
Definition math.h:55
Definition vector.hh:47
Definition fixedmath.hh:58
Vec3 vs[3]
Definition fixedmath.hh:59
static int c
Definition syscalls.h:122
The Color struct.
Definition common.hh:91
uint8_t g
Definition common.hh:93
uint8_t b
Definition common.hh:93
uint8_t r
Definition common.hh:93