From acf521e8ac7337a76ae741251df45eeb35f0ce9a Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Sat, 1 Jul 2023 04:09:54 +0000 Subject: [PATCH] cube: add example --- Makefile | 1 + math/fp.hpp | 69 ++++++++----- math/mat4x4.hpp | 124 ++++++++++++++++++++++ math/vec.hpp | 160 ----------------------------- math/vec3.hpp | 149 +++++++++++++++++++++++++++ math/vec4.hpp | 155 ++++++++++++++++++++++++++++ vdp1/cos.hpp | 268 ++++++++++++++++++++++++++++++++++++++++++++++++ vdp1/cube.cpp | 196 +++++++++++++++++++++++++++++++++++ 8 files changed, 935 insertions(+), 187 deletions(-) create mode 100644 math/mat4x4.hpp create mode 100644 math/vec3.hpp create mode 100644 math/vec4.hpp create mode 100644 vdp1/cos.hpp create mode 100644 vdp1/cube.cpp diff --git a/Makefile b/Makefile index 74f44b1..b0183c2 100644 --- a/Makefile +++ b/Makefile @@ -44,6 +44,7 @@ raytracing/raytracing.elf: raytracing/main-saturn.o raytracing/raytracing.o sh/l vdp2/nbg0.elf: vdp2/nbg0.o res/butterfly.data.o res/butterfly.data.pal.o vdp1/polygon.elf: vdp1/polygon.o +vdp1/cube.elf: vdp1/cube.o $(LIBGCC) vdp1/normal_sprite.elf: vdp1/normal_sprite.o res/mai00.data.o res/mai.data.pal.o vdp1/normal_sprite_color_bank.elf: vdp1/normal_sprite_color_bank.o res/mai00.data.o res/mai.data.pal.o diff --git a/math/fp.hpp b/math/fp.hpp index c0cc874..8f9c9ab 100644 --- a/math/fp.hpp +++ b/math/fp.hpp @@ -1,32 +1,47 @@ #pragma once -#include +#include +#include + #include "div.hpp" struct fp_raw_tag {}; +template +constexpr inline int fp_fractional(std::floating_point auto n) +{ + return (n - static_cast(n)) * (1 << B); +} + +template +constexpr inline int fp_integral(std::floating_point auto n) +{ + return static_cast(n) << B; +} + template struct fp { T value; - constexpr inline fp() noexcept - : value(0) - {} - - constexpr inline fp(T n) noexcept + constexpr inline fp(std::integral auto n) : value(n * (1 << B)) {} - constexpr inline fp(T n, T d) noexcept - : value(n * (1 << B) + d) + consteval inline fp(std::floating_point auto n) + : value(fp_integral(n) + fp_fractional(n)) {} - constexpr inline explicit fp(T n, struct fp_raw_tag) noexcept + constexpr inline explicit fp(T n, struct fp_raw_tag) : value(n) {} - constexpr inline fp operator-() const noexcept + constexpr inline explicit operator int() const + { + return value >> 16; + } + + constexpr inline fp operator-() { return fp(-value, fp_raw_tag{}); } @@ -69,40 +84,40 @@ inline constexpr fp& fp::operator*=(fp const& v) } template -constexpr inline fp operator+(const fp& a, const fp& b) noexcept +constexpr inline fp operator+(const fp& a, const fp& b) { return fp(a.value + b.value, fp_raw_tag{}); } template -constexpr inline fp operator-(const fp& a, const fp& b) noexcept +constexpr inline fp operator-(const fp& a, const fp& b) { return fp(a.value - b.value, fp_raw_tag{}); } template -constexpr inline fp operator*(const fp& a, const fp& b) noexcept +constexpr inline fp operator*(const fp& a, const fp& b) { - I p = (static_cast(a.value) * static_cast(b.value)); + const I p = (static_cast(a.value) * static_cast(b.value)); return fp(static_cast(p >> B), fp_raw_tag{}); } template -constexpr inline fp operator*(const fp& a, T b) noexcept +constexpr inline fp operator*(const fp& a, T b) { I p = (static_cast(a.value) * static_cast(b)); return fp(static_cast(p), fp_raw_tag{}); } template -constexpr inline fp operator*(T b, const fp& a) noexcept +constexpr inline fp operator*(T b, const fp& a) { I p = (static_cast(a.value) * static_cast(b)); return fp(static_cast(p), fp_raw_tag{}); } template -constexpr inline fp operator/(const fp& a, const fp& b) noexcept +constexpr inline fp operator/(const fp& a, const fp& b) { //T p = (static_cast(a.value) * ) / static_cast(b.value); //T p = static_cast(a.value) / static_cast(b.value); @@ -114,37 +129,37 @@ constexpr inline fp operator/(const fp& a, const fp& // comparison template -constexpr inline bool operator==(const fp& a, const fp& b) noexcept +constexpr inline bool operator==(const fp& a, const fp& b) { return a.value == b.value; } template -constexpr inline bool operator!=(const fp& a, const fp& b) noexcept +constexpr inline bool operator!=(const fp& a, const fp& b) { return a.value != b.value; } template -constexpr inline bool operator<(const fp& a, const fp& b) noexcept +constexpr inline bool operator<(const fp& a, const fp& b) { return a.value < b.value; } template -constexpr inline bool operator>(const fp& a, const fp& b) noexcept +constexpr inline bool operator>(const fp& a, const fp& b) { return a.value > b.value; } template -constexpr inline bool operator<=(const fp& a, const fp& b) noexcept +constexpr inline bool operator<=(const fp& a, const fp& b) { return a.value <= b.value; } template -constexpr inline bool operator>=(const fp& a, const fp& b) noexcept +constexpr inline bool operator>=(const fp& a, const fp& b) { return a.value >= b.value; } @@ -157,12 +172,12 @@ struct fp_limits; template struct fp_limits> { - static constexpr fp min() noexcept + static constexpr fp min() { return fp(-(1 << (2 * B - 1)), fp_raw_tag{}); } - static constexpr fp max() noexcept + static constexpr fp max() { return fp((static_cast(1) << (2 * B - 1)) - 1, fp_raw_tag{}); } @@ -171,7 +186,7 @@ struct fp_limits> // functions template -constexpr inline fp pow(fp a, fp b) noexcept +constexpr inline fp pow(fp a, fp b) { while (b > fp(1)) { a *= a; @@ -184,7 +199,7 @@ constexpr inline fp pow(fp a, fp b) noexcept using fp16_16 = fp; -constexpr inline fp16_16 sqrt(const fp16_16& n) noexcept +constexpr inline fp16_16 sqrt(const fp16_16& n) { int32_t x = n.value; int32_t c = 0; diff --git a/math/mat4x4.hpp b/math/mat4x4.hpp new file mode 100644 index 0000000..1a5c25e --- /dev/null +++ b/math/mat4x4.hpp @@ -0,0 +1,124 @@ +#pragma once + +#include + +template +struct mat; + +// +// mat4x4 +// + +template +struct mat<4, 4, T> +{ + typedef vec<4, T> row_type; + typedef vec<4, T> col_type; + +private: + row_type value[4]; + +public: + inline constexpr mat(); + + inline constexpr mat + ( + T const& a00, T const& a01, T const& a02, T const& a03, + T const& a10, T const& a11, T const& a12, T const& a13, + T const& a20, T const& a21, T const& a22, T const& a23, + T const& a30, T const& a31, T const& a32, T const& a33 + ); + + inline static constexpr int length() { return 4; } + + inline constexpr typename mat<4, 4, T>::row_type const & + operator[](int i) const; + + void operator=(const mat<4, 4, T>&) = delete; + +}; + + +template +inline constexpr mat<4, 4, T>::mat() + : value{std::move(row_type(1, 0, 0, 0)), + std::move(row_type(0, 1, 0, 0)), + std::move(row_type(0, 0, 1, 0)), + std::move(row_type(0, 0, 0, 1))} +{ } + +template +inline constexpr mat<4, 4, T>::mat +( + T const& a00, T const& a01, T const& a02, T const& a03, + T const& a10, T const& a11, T const& a12, T const& a13, + T const& a20, T const& a21, T const& a22, T const& a23, + T const& a30, T const& a31, T const& a32, T const& a33 +) + : value{std::move(row_type(a00, a01, a02, a03)), + std::move(row_type(a10, a11, a12, a13)), + std::move(row_type(a20, a21, a22, a23)), + std::move(row_type(a30, a31, a32, a33))} +{ } + +template +inline constexpr typename mat<4, 4, T>::row_type const & +mat<4, 4, T>::operator[](int i) const +{ + switch (i) + { + default: [[fallthrough]]; + case 0: + return value[0]; + case 1: + return value[1]; + case 2: + return value[2]; + case 3: + return value[3]; + } +} + +template +inline constexpr mat<4, 4, T> operator*(mat<4, 4, T> const& m1, mat<4, 4, T> const& m2) +{ +#define c(i, j) ( \ + m1[i][0] * m2[0][j] \ + + m1[i][1] * m2[1][j] \ + + m1[i][2] * m2[2][j] \ + + m1[i][3] * m2[3][j] ) + + return mat<4, 4, T>(c(0,0), c(0,1), c(0,2), c(0,3), + c(1,0), c(1,1), c(1,2), c(1,3), + c(2,0), c(2,1), c(2,2), c(2,3), + c(3,0), c(3,1), c(3,2), c(3,3)); +#undef c +} + +template +inline constexpr typename mat<4, 4, T>::row_type operator* +( + mat<4, 4, T> const& m, + typename mat<4, 4, T>::col_type const& v +) +{ +#define c(i) ( \ + m[i][0] * v[0] \ + + m[i][1] * v[1] \ + + m[i][2] * v[2] \ + + m[i][3] * v[3] ) + + return typename mat<4, 4, T>::row_type(c(0), c(1), c(2), c(3)); +#undef c +} + +template +inline constexpr mat<4, 4, T> transpose(mat<4, 4, T> const& m) +{ + return mat<4, 4, T>( + m[0][0], m[1][0], m[2][0], m[3][0], + m[0][1], m[1][1], m[2][1], m[3][1], + m[0][2], m[1][2], m[2][2], m[3][2], + m[0][3], m[1][3], m[2][3], m[3][3] + ); +} diff --git a/math/vec.hpp b/math/vec.hpp index 1a69ad5..a63d225 100644 --- a/math/vec.hpp +++ b/math/vec.hpp @@ -1,164 +1,4 @@ #pragma once -#include "math.hpp" - template struct vec; - -// -// vec3 -// - -template -struct vec<3, T> -{ - union - { - struct { T x, y, z; }; - struct { T r, g, b; }; - struct { T s, t, p; }; - }; - - inline constexpr vec(); - inline constexpr vec(T scalar); - inline constexpr vec(T _x, T _y, T _z); - - inline constexpr T const& operator[](int i) const; - - constexpr inline vec<3, T> operator-() const noexcept - { - return vec<3, T>(-x, -y, -z); - } - - inline constexpr vec<3, T>& operator=(vec<3, T> const& v); - - inline constexpr vec<3, T>& operator+=(vec<3, T> const& v); - - inline constexpr vec<3, T>& operator-=(vec<3, T> const& v); -}; - -template -inline constexpr vec<3, T>::vec() - : x(0), y(0), z(0) -{} - -template -inline constexpr vec<3, T>::vec(T scalar) - : x(scalar), y(scalar), z(scalar) -{} - -template -inline constexpr vec<3, T>::vec(T _x, T _y, T _z) - : x(_x), y(_y), z(_z) -{} - -template -inline constexpr T const& vec<3, T>::operator[](int i) const -{ - switch(i) - { - default: - case 0: - return x; - case 1: - return y; - case 2: - return z; - } -} - -template -inline constexpr vec<3, T>& vec<3, T>::operator=(vec<3, T> const& v) -{ - this->x = static_cast(v.x); - this->y = static_cast(v.y); - this->z = static_cast(v.z); - return *this; -} - -template -inline constexpr vec<3, T>& vec<3, T>::operator+=(vec<3, T> const& v) -{ - *this = *this + vec<3, T>(v); - return *this; -} - -template -inline constexpr vec<3, T>& vec<3, T>::operator-=(vec<3, T> const& v) -{ - *this = *this + vec<3, T>(v); - return *this; -} - -template -inline constexpr vec<3, T> operator+(vec<3, T> const& v1, vec<3, T> const& v2) -{ - return vec<3, T>(v1.x + v2.x, - v1.y + v2.y, - v1.z + v2.z); -} - -template -inline constexpr vec<3, T> operator-(vec<3, T> const& v1, vec<3, T> const& v2) -{ - return vec<3, T>(v1.x - v2.x, - v1.y - v2.y, - v1.z - v2.z); -} - -template -inline constexpr vec<3, T> operator*(vec<3, T> const& v1, vec<3, T> const& v2) -{ - return vec<3, T>(v1.x * v2.x, - v1.y * v2.y, - v1.z * v2.z); -} - -/* -template -inline constexpr vec<3, T> operator/(vec<3, T> const& v1, vec<3, T> const& v2) -{ - return vec<3, T>(v1.x / v2.x, - v1.y / v2.y, - v1.z / v2.z); -} -*/ - -template -inline constexpr vec<3, T> operator*(vec<3, T> const& v1, T const& scalar) -{ - return v1 * vec<3, T>(scalar); -} - -/* -template -inline constexpr vec<3, T> operator/(vec<3, T> const& v1, T const& scalar) -{ - return v1 / vec<3, T>(scalar); -} -*/ - -template -inline constexpr T dot(vec<3, T> const& v1, vec<3, T> const& v2) -{ - vec<3, T> tmp(v1 * v2); - return tmp.x + tmp.y + tmp.z; -} - -template -inline constexpr vec<3, T> functor1(T (&func) (T const& x), vec<3, T> const& v) -{ - return vec<3, T>(func(v.x), func(v.y), func(v.z)); -} - -template -inline constexpr vec<3, U> functor1(U (&func) (T const& x), vec<3, T> const& v) -{ - return vec<3, U>(func(v.x), func(v.y), func(v.z)); -} - -template -inline constexpr T length(vec<3, T> const& v) -{ - return sqrt(dot(v, v)); -} diff --git a/math/vec3.hpp b/math/vec3.hpp new file mode 100644 index 0000000..7383cee --- /dev/null +++ b/math/vec3.hpp @@ -0,0 +1,149 @@ +#pragma once + +#include "math.hpp" +#include "vec.hpp" + +// +// vec3 +// + +template +struct vec<3, T> +{ + T x, y, z; + + inline constexpr vec(); + inline constexpr vec(T scalar); + inline constexpr vec(T _x, T _y, T _z); + + constexpr inline vec<3, T> operator-() const; + inline constexpr T const& operator[](int i) const; + inline constexpr vec<3, T>& operator=(vec<3, T> const& v); + inline constexpr vec<3, T>& operator+=(vec<3, T> const& v); + inline constexpr vec<3, T>& operator-=(vec<3, T> const& v); +}; + +template +inline constexpr vec<3, T>::vec() + : x(0), y(0), z(0) +{} + +template +inline constexpr vec<3, T>::vec(T scalar) + : x(scalar), y(scalar), z(scalar) +{} + +template +inline constexpr vec<3, T>::vec(T _x, T _y, T _z) + : x(_x), y(_y), z(_z) +{} + +template +constexpr inline vec<3, T> vec<3, T>::operator-() const +{ + return vec<3, T>(-x, -y, -z); +} + +template +inline constexpr T const& vec<3, T>::operator[](int i) const +{ + switch(i) + { + default: [[fallthrough]]; + case 0: return x; + case 1: return y; + case 2: return z; + } +} + +template +inline constexpr vec<3, T>& vec<3, T>::operator=(vec<3, T> const& v) +{ + this->x = static_cast(v.x); + this->y = static_cast(v.y); + this->z = static_cast(v.z); + return *this; +} + +template +inline constexpr vec<3, T>& vec<3, T>::operator+=(vec<3, T> const& v) +{ + *this = *this + vec<3, T>(v); + return *this; +} + +template +inline constexpr vec<3, T>& vec<3, T>::operator-=(vec<3, T> const& v) +{ + *this = *this - vec<3, T>(v); + return *this; +} + +template +inline constexpr vec<3, T> operator+(vec<3, T> const& v1, vec<3, T> const& v2) +{ + return vec<3, T>(v1.x + v2.x, + v1.y + v2.y, + v1.z + v2.z); +} + +template +inline constexpr vec<3, T> operator-(vec<3, T> const& v1, vec<3, T> const& v2) +{ + return vec<3, T>(v1.x - v2.x, + v1.y - v2.y, + v1.z - v2.z); +} + +template +inline constexpr vec<3, T> operator*(vec<3, T> const& v1, vec<3, T> const& v2) +{ + return vec<3, T>(v1.x * v2.x, + v1.y * v2.y, + v1.z * v2.z); +} + +template +inline constexpr vec<3, T> operator*(vec<3, T> const& v1, T const& scalar) +{ + return v1 * vec<3, T>(scalar); +} + +template +inline constexpr vec<3, T> operator/(vec<3, T> const& v1, vec<3, T> const& v2) +{ + return vec<3, T>(v1.x / v2.x, + v1.y / v2.y, + v1.z / v2.z); +} + +template +inline constexpr vec<3, T> operator/(vec<3, T> const& v1, T const& scalar) +{ + return v1 / vec<3, T>(scalar); +} + +template +inline constexpr T dot(vec<3, T> const& v1, vec<3, T> const& v2) +{ + vec<3, T> tmp(v1 * v2); + return tmp.x + tmp.y + tmp.z; +} + +template +inline constexpr vec<3, T> functor1(T (&func) (T const& x), vec<3, T> const& v) +{ + return vec<3, T>(func(v.x), func(v.y), func(v.z)); +} + +template +inline constexpr vec<3, U> functor1(U (&func) (T const& x), vec<3, T> const& v) +{ + return vec<3, U>(func(v.x), func(v.y), func(v.z)); +} + +template +inline constexpr T length(vec<3, T> const& v) +{ + return sqrt(dot(v, v)); +} diff --git a/math/vec4.hpp b/math/vec4.hpp new file mode 100644 index 0000000..2ec8b45 --- /dev/null +++ b/math/vec4.hpp @@ -0,0 +1,155 @@ +#pragma once + +#include "math.hpp" +#include "vec.hpp" + +// +// vec4 +// + +template +struct vec<4, T> +{ + T x, y, z, w; + + inline constexpr vec(); + inline constexpr vec(T scalar); + inline constexpr vec(T _x, T _y, T _z, T _w); + + constexpr inline vec<4, T> operator-() const; + inline constexpr T const& operator[](int i) const; + inline constexpr vec<4, T>& operator=(vec<4, T> const& v); + inline constexpr vec<4, T>& operator+=(vec<4, T> const& v); + inline constexpr vec<4, T>& operator-=(vec<4, T> const& v); +}; + +template +inline constexpr vec<4, T>::vec() + : x(0), y(0), z(0), w(0) +{} + +template +inline constexpr vec<4, T>::vec(T scalar) + : x(scalar), y(scalar), z(scalar), w(scalar) +{} + +template +inline constexpr vec<4, T>::vec(T _x, T _y, T _z, T _w) + : x(_x), y(_y), z(_z), w(_w) +{} + +template +constexpr inline vec<4, T> vec<4, T>::operator-() const +{ + return vec<4, T>(-x, -y, -z, -w); +} + +template +inline constexpr T const& vec<4, T>::operator[](int i) const +{ + switch(i) + { + default: [[fallthrough]]; + case 0: return x; + case 1: return y; + case 2: return z; + case 3: return w; + } +} + +template +inline constexpr vec<4, T>& vec<4, T>::operator=(vec<4, T> const& v) +{ + this->x = static_cast(v.x); + this->y = static_cast(v.y); + this->z = static_cast(v.z); + this->w = static_cast(v.w); + return *this; +} + +template +inline constexpr vec<4, T>& vec<4, T>::operator+=(vec<4, T> const& v) +{ + *this = *this + vec<4, T>(v); + return *this; +} + +template +inline constexpr vec<4, T>& vec<4, T>::operator-=(vec<4, T> const& v) +{ + *this = *this - vec<4, T>(v); + return *this; +} + +template +inline constexpr vec<4, T> operator+(vec<4, T> const& v1, vec<4, T> const& v2) +{ + return vec<4, T>(v1.x + v2.x, + v1.y + v2.y, + v1.z + v2.z, + v1.w + v2.w); +} + +template +inline constexpr vec<4, T> operator-(vec<4, T> const& v1, vec<4, T> const& v2) +{ + return vec<4, T>(v1.x - v2.x, + v1.y - v2.y, + v1.z - v2.z, + v1.w - v2.w); +} + +template +inline constexpr vec<4, T> operator*(vec<4, T> const& v1, vec<4, T> const& v2) +{ + return vec<4, T>(v1.x * v2.x, + v1.y * v2.y, + v1.z * v2.z, + v1.w * v2.w); +} + +template +inline constexpr vec<4, T> operator*(vec<4, T> const& v1, T const& scalar) +{ + return v1 * vec<4, T>(scalar); +} + +template +inline constexpr vec<4, T> operator/(vec<4, T> const& v1, vec<4, T> const& v2) +{ + return vec<4, T>(v1.x / v2.x, + v1.y / v2.y, + v1.z / v2.z, + v1.w / v2.w); +} + +template +inline constexpr vec<4, T> operator/(vec<4, T> const& v1, T const& scalar) +{ + return v1 / vec<4, T>(scalar); +} + +template +inline constexpr T dot(vec<4, T> const& v1, vec<4, T> const& v2) +{ + vec<4, T> tmp(v1 * v2); + return tmp.x + tmp.y + tmp.z + tmp.w; +} + +template +inline constexpr vec<4, T> functor1(T (&func) (T const& x), vec<4, T> const& v) +{ + return vec<4, T>(func(v.x), func(v.y), func(v.z), func(v.w)); +} + +template +inline constexpr vec<4, U> functor1(U (&func) (T const& x), vec<4, T> const& v) +{ + return vec<4, U>(func(v.x), func(v.y), func(v.z), func(v.w)); +} + +template +inline constexpr T length(vec<4, T> const& v) +{ + return sqrt(dot(v, v)); +} diff --git a/vdp1/cos.hpp b/vdp1/cos.hpp new file mode 100644 index 0000000..6ab5a87 --- /dev/null +++ b/vdp1/cos.hpp @@ -0,0 +1,268 @@ +static constexpr fp16_16 _cos[256] = { + 1.0, + 0.9996988186962042, + 0.9987954562051724, + 0.9972904566786902, + 0.9951847266721969, + 0.99247953459871, + 0.989176509964781, + 0.9852776423889412, + 0.9807852804032304, + 0.9757021300385286, + 0.970031253194544, + 0.9637760657954398, + 0.9569403357322088, + 0.9495281805930367, + 0.9415440651830208, + 0.932992798834739, + 0.9238795325112867, + 0.9142097557035307, + 0.9039892931234433, + 0.8932243011955153, + 0.881921264348355, + 0.8700869911087115, + 0.8577286100002721, + 0.8448535652497071, + 0.8314696123025452, + 0.8175848131515837, + 0.8032075314806449, + 0.7883464276266063, + 0.773010453362737, + 0.7572088465064846, + 0.7409511253549591, + 0.724247082951467, + 0.7071067811865476, + 0.6895405447370669, + 0.6715589548470183, + 0.6531728429537768, + 0.6343932841636455, + 0.6152315905806268, + 0.5956993044924335, + 0.5758081914178453, + 0.5555702330196023, + 0.5349976198870973, + 0.5141027441932217, + 0.4928981922297841, + 0.4713967368259978, + 0.4496113296546066, + 0.4275550934302822, + 0.40524131400498986, + 0.38268343236508984, + 0.3598950365349883, + 0.33688985339222005, + 0.3136817403988916, + 0.29028467725446233, + 0.2667127574748984, + 0.24298017990326398, + 0.21910124015686977, + 0.19509032201612833, + 0.17096188876030136, + 0.14673047445536175, + 0.12241067519921628, + 0.09801714032956077, + 0.07356456359966745, + 0.049067674327418126, + 0.024541228522912264, + 6.123233995736766e-17, + -0.024541228522912142, + -0.04906767432741801, + -0.07356456359966733, + -0.09801714032956065, + -0.12241067519921615, + -0.14673047445536164, + -0.17096188876030124, + -0.1950903220161282, + -0.21910124015686966, + -0.24298017990326387, + -0.2667127574748983, + -0.29028467725446216, + -0.3136817403988914, + -0.33688985339221994, + -0.35989503653498817, + -0.3826834323650897, + -0.40524131400498975, + -0.42755509343028186, + -0.4496113296546067, + -0.4713967368259977, + -0.492898192229784, + -0.5141027441932217, + -0.534997619887097, + -0.555570233019602, + -0.5758081914178453, + -0.5956993044924334, + -0.6152315905806267, + -0.6343932841636454, + -0.6531728429537765, + -0.6715589548470184, + -0.6895405447370669, + -0.7071067811865475, + -0.7242470829514668, + -0.7409511253549589, + -0.7572088465064846, + -0.773010453362737, + -0.7883464276266062, + -0.8032075314806448, + -0.8175848131515836, + -0.8314696123025453, + -0.8448535652497071, + -0.857728610000272, + -0.8700869911087113, + -0.8819212643483549, + -0.8932243011955152, + -0.9039892931234433, + -0.9142097557035307, + -0.9238795325112867, + -0.9329927988347388, + -0.9415440651830207, + -0.9495281805930367, + -0.9569403357322088, + -0.9637760657954398, + -0.970031253194544, + -0.9757021300385285, + -0.9807852804032304, + -0.9852776423889412, + -0.989176509964781, + -0.99247953459871, + -0.9951847266721968, + -0.9972904566786902, + -0.9987954562051724, + -0.9996988186962042, + -1.0, + -0.9996988186962042, + -0.9987954562051724, + -0.9972904566786902, + -0.9951847266721969, + -0.99247953459871, + -0.989176509964781, + -0.9852776423889413, + -0.9807852804032304, + -0.9757021300385286, + -0.970031253194544, + -0.96377606579544, + -0.9569403357322089, + -0.9495281805930368, + -0.9415440651830208, + -0.932992798834739, + -0.9238795325112868, + -0.9142097557035307, + -0.9039892931234434, + -0.8932243011955153, + -0.881921264348355, + -0.8700869911087115, + -0.8577286100002721, + -0.8448535652497072, + -0.8314696123025455, + -0.8175848131515837, + -0.8032075314806449, + -0.7883464276266063, + -0.7730104533627371, + -0.7572088465064848, + -0.7409511253549591, + -0.724247082951467, + -0.7071067811865477, + -0.689540544737067, + -0.6715589548470187, + -0.6531728429537771, + -0.6343932841636459, + -0.6152315905806273, + -0.5956993044924331, + -0.5758081914178452, + -0.5555702330196022, + -0.5349976198870973, + -0.5141027441932218, + -0.4928981922297842, + -0.47139673682599786, + -0.44961132965460693, + -0.4275550934302825, + -0.40524131400499036, + -0.38268343236509034, + -0.35989503653498794, + -0.33688985339221994, + -0.31368174039889146, + -0.29028467725446244, + -0.26671275747489853, + -0.24298017990326412, + -0.2191012401568701, + -0.19509032201612866, + -0.1709618887603017, + -0.1467304744553623, + -0.12241067519921596, + -0.09801714032956045, + -0.07356456359966736, + -0.04906767432741803, + -0.02454122852291239, + -1.8369701987210297e-16, + 0.02454122852291202, + 0.04906767432741766, + 0.07356456359966698, + 0.09801714032956009, + 0.1224106751992156, + 0.14673047445536194, + 0.17096188876030133, + 0.1950903220161283, + 0.21910124015686974, + 0.24298017990326376, + 0.2667127574748982, + 0.29028467725446205, + 0.31368174039889113, + 0.3368898533922196, + 0.3598950365349876, + 0.38268343236509, + 0.40524131400499, + 0.42755509343028214, + 0.4496113296546066, + 0.4713967368259976, + 0.49289819222978387, + 0.5141027441932216, + 0.5349976198870969, + 0.5555702330196018, + 0.5758081914178449, + 0.5956993044924329, + 0.615231590580627, + 0.6343932841636456, + 0.6531728429537768, + 0.6715589548470183, + 0.6895405447370668, + 0.7071067811865474, + 0.7242470829514667, + 0.7409511253549589, + 0.7572088465064842, + 0.7730104533627367, + 0.7883464276266059, + 0.803207531480645, + 0.8175848131515837, + 0.8314696123025452, + 0.844853565249707, + 0.857728610000272, + 0.8700869911087113, + 0.8819212643483548, + 0.8932243011955151, + 0.9039892931234431, + 0.9142097557035305, + 0.9238795325112865, + 0.932992798834739, + 0.9415440651830208, + 0.9495281805930367, + 0.9569403357322088, + 0.9637760657954398, + 0.970031253194544, + 0.9757021300385285, + 0.9807852804032303, + 0.9852776423889411, + 0.9891765099647809, + 0.99247953459871, + 0.9951847266721969, + 0.9972904566786902, + 0.9987954562051724, + 0.9996988186962042, +}; + +constexpr fp16_16 cos(int x) +{ + return _cos[x & 255]; +} + +constexpr fp16_16 sin(int x) +{ + return _cos[(x + 64) & 255]; +} diff --git a/vdp1/cube.cpp b/vdp1/cube.cpp new file mode 100644 index 0000000..7380a22 --- /dev/null +++ b/vdp1/cube.cpp @@ -0,0 +1,196 @@ +#include +#include "vdp2.h" +#include "vdp1.h" + +#include + +#include "../common/vdp2_func.hpp" + +#include "../math/fp.hpp" +#include "../math/vec4.hpp" +#include "../math/vec3.hpp" +#include "../math/mat4x4.hpp" + +#include "cos.hpp" + +// |-- +// | +// | + +using vec4 = vec<4, fp16_16>; +using vec3 = vec<3, fp16_16>; +using mat4x4 = mat<4, 4, fp16_16>; + +static vec4 vertices[8] = { + {-0.5, -0.5, 0.5, 1.0}, // top left front + { 0.5, -0.5, 0.5, 1.0}, // top right front + { 0.5, 0.5, 0.5, 1.0}, // bottom right front + {-0.5, 0.5, 0.5, 1.0}, // bottom left front + + {-0.5, -0.5, -0.5, 1.0}, // top left back + { 0.5, -0.5, -0.5, 1.0}, // top right back + { 0.5, 0.5, -0.5, 1.0}, // bottom right back + {-0.5, 0.5, -0.5, 1.0}, // bottom left back +}; + +static uint32_t faces[6][4] = { + {0, 1, 2, 3}, // front clockwise + {5, 4, 7, 6}, // back clockwise + {0, 4, 5, 1}, // top clockwise + {3, 2, 6, 7}, // bottom clockwise + {4, 0, 3, 7}, // left clockwise + {1, 5, 6, 2}, // right clockwise +}; + +struct canvas { + fp16_16 width; + fp16_16 height; +}; + +constexpr struct canvas canvas = { 240, 240 }; + +template +vec<3, T> viewport_to_canvas(T x, T y) +{ + return vec<3, T>(x * canvas.width, y * canvas.height, T(1)); +} + +template +inline constexpr vec<3, T> project_vertex(vec<4, T> const& v) +{ + // / (v.z - T(5)) + // / (v.z - T(5)) + return viewport_to_canvas((v.x * T(0.5) + T(2.0/3.0)), + (v.y * T(0.5) + T(0.5))); +} + +constexpr inline uint16_t rgb15(int32_t r, int32_t g, int32_t b) +{ + return ((b & 31) << 10) | ((g & 31) << 5) | ((r & 31) << 0); +} + +constexpr uint16_t colors[] = { + rgb15(31, 0, 0), // red + rgb15( 0, 31, 0), // green + rgb15( 0, 0, 31), // blue + rgb15(31, 0, 31), // magenta + rgb15( 0, 31, 31), // cyan + rgb15(31, 31, 0), // yellow +}; + +static int32_t tick = 0; + +void +render() +{ + tick++; + int ix = 2; + + const int rx = tick >> 2; + const mat4x4 rotationX { + 1, 0, 0, 0, + 0, cos(rx), sin(rx), 0, + 0, -sin(rx), cos(rx), 0, + 0, 0, 0, 1, + }; + + const int ry = tick >> 2; + const mat4x4 rotationY { + cos(ry), 0, -sin(ry), 0, + 0, 1, 0, 0, + sin(ry), 0, cos(ry), 0, + 0, 0, 0, 1, + }; + + const mat4x4 transform = rotationX * rotationY; + + for (int i = 0; i < 6; i++) { + + const uint32_t * face = faces[i]; + + vdp1.vram.cmd[ix].CTRL = CTRL__JP__JUMP_NEXT | CTRL__COMM__POLYLINE; + vdp1.vram.cmd[ix].LINK = 0; + vdp1.vram.cmd[ix].PMOD = PMOD__ECD | PMOD__SPD; + vdp1.vram.cmd[ix].COLR = COLR__RGB | colors[i]; + + for (int p = 0; p < 4; p++) { + const vec4& v0 = vertices[face[p]]; + + const vec4 v1 = transform * v0; + + const vec3& v2 = project_vertex(v1); + + vdp1.vram.cmd[ix].point[p].X = static_cast(v2.x); + vdp1.vram.cmd[ix].point[p].Y = static_cast(v2.y); + } + + ix++; + } + + vdp1.vram.cmd[ix].CTRL = CTRL__END; +} + +void main() +{ + v_blank_in(); + + // DISP: Please make sure to change this bit from 0 to 1 during V blank. + vdp2.reg.TVMD = ( TVMD__DISP | TVMD__LSMD__NON_INTERLACE + | TVMD__VRESO__240 | TVMD__HRESO__NORMAL_320); + + // VDP2 User's Manual: + // "When sprite data is in an RGB format, sprite register 0 is selected" + // "When the value of a priority number is 0h, it is read as transparent" + // + // The power-on value of PRISA is zero. Set the priority for sprite register 0 + // to some number greater than zero, so that the color data is not interpreted + // as "transparent". + vdp2.reg.PRISA = PRISA__S0PRIN(1); // Sprite register 0 Priority Number + + /* TVM settings must be performed from the second H-blank IN interrupt after the + V-blank IN interrupt to the H-blank IN interrupt immediately after the V-blank + OUT interrupt. */ + // "normal" display resolution, 16 bits per pixel, 512x256 framebuffer + vdp1.reg.TVMR = TVMR__TVM__NORMAL; + + // swap framebuffers every 1 cycle; non-interlace + vdp1.reg.FBCR = 0; + + // during a framebuffer erase cycle, write the color "black" to each pixel + constexpr uint16_t black = 0x0000; + vdp1.reg.EWDR = black; + + // the EWLR/EWRR macros use somewhat nontrivial math for the X coordinates + // erase upper-left coordinate + vdp1.reg.EWLR = EWLR__16BPP_X1(0) | EWLR__Y1(0); + + // erase lower-right coordinate + vdp1.reg.EWRR = EWRR__16BPP_X3(319) | EWRR__Y3(239); + + vdp1.vram.cmd[0].CTRL = CTRL__JP__JUMP_NEXT | CTRL__COMM__SYSTEM_CLIP_COORDINATES; + vdp1.vram.cmd[0].LINK = 0; + vdp1.vram.cmd[0].XC = 319; + vdp1.vram.cmd[0].YC = 239; + + vdp1.vram.cmd[1].CTRL = CTRL__JP__JUMP_NEXT | CTRL__COMM__LOCAL_COORDINATE; + vdp1.vram.cmd[1].LINK = 0; + vdp1.vram.cmd[1].XA = 0; + vdp1.vram.cmd[1].YA = 0; + + vdp1.vram.cmd[2].CTRL = CTRL__END; + + // start drawing (execute the command list) on every frame + vdp1.reg.PTMR = PTMR__PTM__FRAME_CHANGE; + + while (true) { + v_blank_in(); + render(); + } +} + +extern "C" +void start(void) +{ + main(); + while (1) {} +}