mirror of
https://github.com/LNH-team/pico-launcher.git
synced 2026-06-02 09:06:54 +02:00
Initial commit
This commit is contained in:
93
arm9/source/core/math/ColorConverter.h
Normal file
93
arm9/source/core/math/ColorConverter.h
Normal file
@@ -0,0 +1,93 @@
|
||||
#pragma once
|
||||
#include "Rgb.h"
|
||||
|
||||
class Rgb8To5Table
|
||||
{
|
||||
u8 _table[256];
|
||||
|
||||
public:
|
||||
constexpr Rgb8To5Table()
|
||||
: _table()
|
||||
{
|
||||
for (u32 i = 0; i < 256; i++)
|
||||
{
|
||||
u32 value5 = (i * 63 + 255) / (255 * 2);
|
||||
if (value5 > 31)
|
||||
value5 = 31;
|
||||
_table[i] = value5;
|
||||
}
|
||||
}
|
||||
|
||||
constexpr u8 Rgb8ToRgb5(u32 rgb8) const { return _table[rgb8]; }
|
||||
};
|
||||
|
||||
class Rgb8To6Table
|
||||
{
|
||||
u8 _table[256];
|
||||
|
||||
public:
|
||||
constexpr Rgb8To6Table()
|
||||
: _table()
|
||||
{
|
||||
for (u32 i = 0; i < 256; i++)
|
||||
_table[i] = (i * 63 + 128) / 255;
|
||||
}
|
||||
|
||||
constexpr u8 Rgb8ToRgb6(u32 rgb8) const { return _table[rgb8]; }
|
||||
};
|
||||
|
||||
class ColorConverter
|
||||
{
|
||||
static constexpr Rgb8To5Table sRgb8To5Table { };
|
||||
static constexpr Rgb8To6Table sRgb8To6Table { };
|
||||
public:
|
||||
/// @brief Unpacks a 15 bit color with format xbbb bbgg gggr rrrr.
|
||||
/// @param color The packed color.
|
||||
/// @return The unpacked color.
|
||||
static Rgb<5, 5, 5> FromXBGR555(u16 color)
|
||||
{
|
||||
return Rgb<5, 5, 5>(color & 0x1F, (color >> 5) & 0x1F, (color >> 10) & 0x1F);
|
||||
}
|
||||
|
||||
/// @brief Packs a 15 bit color with format xbbb bbgg gggr rrrr.
|
||||
/// Note that the color components are not clamped or masked.
|
||||
/// @param color The color to pack.
|
||||
/// @return The packed color.
|
||||
static u16 ToXBGR555(const Rgb<5, 5, 5>& color)
|
||||
{
|
||||
return color.r | (color.g << 5) | (color.b << 10);
|
||||
}
|
||||
|
||||
/// @brief Unpacks a 16 bit color with format Gbbb bbgg gggr rrrr.
|
||||
/// With G an additional lsb of green forming a 6 bit value together with ggggg.
|
||||
/// @param color The packed color.
|
||||
/// @return The unpacked color.
|
||||
static Rgb<5, 6, 5> FromGBGR565(u16 color)
|
||||
{
|
||||
return Rgb<5, 6, 5>(color & 0x1F, ((color >> 4) & 0x3E) | (color >> 15), (color >> 10) & 0x1F);
|
||||
}
|
||||
|
||||
/// @brief Packs a 16 bit color with format Gbbb bbgg gggr rrrr.
|
||||
/// With G an additional lsb of green forming a 6 bit value together with ggggg.
|
||||
/// Note that the color components are not clamped or masked.
|
||||
/// @param color The color to pack.
|
||||
/// @return The packed color.
|
||||
static u16 ToGBGR565(const Rgb<5, 6, 5>& color)
|
||||
{
|
||||
return color.r | ((color.g >> 1) << 5) | (color.b << 10) | (color.g << 15);
|
||||
}
|
||||
|
||||
/// @brief Packs a 16 bit color with format Gbbb bbgg gggr rrrr.
|
||||
/// With G an additional lsb of green forming a 6 bit value together with ggggg.
|
||||
/// Note that the color components are not clamped or masked.
|
||||
/// @param color The color to pack.
|
||||
/// @return The packed color.
|
||||
static u16 ToGBGR565(const Rgb<8, 8, 8>& color)
|
||||
{
|
||||
u32 r = sRgb8To5Table.Rgb8ToRgb5(color.r);
|
||||
u32 g = sRgb8To6Table.Rgb8ToRgb6(color.g);
|
||||
u32 b = sRgb8To5Table.Rgb8ToRgb5(color.b);
|
||||
|
||||
return r | ((g >> 1) << 5) | (b << 10) | (g << 15);
|
||||
}
|
||||
};
|
||||
18
arm9/source/core/math/Point.h
Normal file
18
arm9/source/core/math/Point.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
struct Point
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
|
||||
constexpr Point()
|
||||
: x(0), y(0) { }
|
||||
|
||||
constexpr Point(int x, int y)
|
||||
: x(x), y(y) { }
|
||||
|
||||
constexpr s64 DistanceSquaredTo(const Point& other) const
|
||||
{
|
||||
return (s64)(other.x - x) * (other.x - x) + (s64)(other.y - y) * (other.y - y);
|
||||
}
|
||||
};
|
||||
74
arm9/source/core/math/Rectangle.h
Normal file
74
arm9/source/core/math/Rectangle.h
Normal file
@@ -0,0 +1,74 @@
|
||||
#pragma once
|
||||
#include "Point.h"
|
||||
|
||||
/// @brief Class representing a 2d rectangle.
|
||||
class Rectangle
|
||||
{
|
||||
int _x;
|
||||
int _y;
|
||||
int _width;
|
||||
int _height;
|
||||
|
||||
public:
|
||||
constexpr Rectangle(const Point& point, int width, int height)
|
||||
: _x(point.x), _y(point.y), _width(width), _height(height) { }
|
||||
|
||||
constexpr Rectangle(const Point& topLeft, const Point& bottomRight)
|
||||
: _x(topLeft.x), _y(topLeft.y)
|
||||
, _width(bottomRight.x - topLeft.x), _height(bottomRight.y - topLeft.y) { }
|
||||
|
||||
constexpr Rectangle(int x, int y, int width, int height)
|
||||
: _x(x), _y(y), _width(width), _height(height) { }
|
||||
|
||||
constexpr int GetX() const { return _x; }
|
||||
constexpr int GetY() const { return _y; }
|
||||
constexpr int GetWidth() const { return _width; }
|
||||
constexpr int GetHeight() const { return _height; }
|
||||
|
||||
constexpr int GetLeft() const { return _x; }
|
||||
constexpr int GetRight() const { return _x + _width; }
|
||||
constexpr int GetTop() const { return _y; }
|
||||
constexpr int GetBottom() const { return _y + _height; }
|
||||
|
||||
constexpr Point GetTopLeft() const { return Point(_x, _y); }
|
||||
constexpr Point GetBottomRight() const { return Point(_x + _width, _y + _height); }
|
||||
|
||||
constexpr Point GetTopCenter() const { return Point(_x + (_width >> 1), _y); }
|
||||
constexpr Point GetCenter() const { return Point(_x + (_width >> 1), _y + (_height >> 1)); }
|
||||
constexpr Point GetBottomCenter() const { return Point(_x + (_width >> 1), _y); }
|
||||
|
||||
/// @brief Checks if the given rectangle overlaps with this rectangle.
|
||||
/// @param other The rectangle to check.
|
||||
/// @return True if the given rectangle overlaps with this rectangle,
|
||||
/// or false otherwise.
|
||||
constexpr bool OverlapsWith(const Rectangle& other) const
|
||||
{
|
||||
return GetLeft() < other.GetRight() && other.GetLeft() < GetRight()
|
||||
&& GetTop() < other.GetBottom() && other.GetTop() < GetBottom();
|
||||
}
|
||||
|
||||
/// @brief Checks if the given point is contained in this rectangle.
|
||||
/// @param point The point to check.
|
||||
/// @return True if the given point is contained in this rectangle,
|
||||
/// or false otherwise.
|
||||
constexpr bool Contains(const Point& point) const
|
||||
{
|
||||
return point.x >= GetLeft() && point.x < GetRight()
|
||||
&& point.y >= GetTop() && point.y < GetBottom();
|
||||
}
|
||||
|
||||
/// @brief Checks if the given rectangle is fully contained in this rectangle.
|
||||
/// @param other The rectangle to check.
|
||||
/// @return True if the given rectangle is fully contained in this rectangle,
|
||||
/// or false otherwise.
|
||||
constexpr bool Contains(const Rectangle& other) const
|
||||
{
|
||||
return other.GetLeft() >= GetLeft() && other.GetRight() <= GetRight()
|
||||
&& other.GetTop() >= GetTop() && other.GetBottom() <= GetBottom();
|
||||
}
|
||||
|
||||
constexpr Rectangle OffsetBy(const Point& point) const
|
||||
{
|
||||
return Rectangle(_x + point.x, _y + point.y, _width, _height);
|
||||
}
|
||||
};
|
||||
77
arm9/source/core/math/Rgb.h
Normal file
77
arm9/source/core/math/Rgb.h
Normal file
@@ -0,0 +1,77 @@
|
||||
#pragma once
|
||||
#include <algorithm>
|
||||
#include "common.h"
|
||||
|
||||
template <u32 RBits, u32 GBits, u32 BBits>
|
||||
class Rgb
|
||||
{
|
||||
public:
|
||||
u8 r, g, b;
|
||||
|
||||
constexpr Rgb()
|
||||
: r(0), g(0), b(0) { }
|
||||
|
||||
constexpr Rgb(u32 red, u32 green, u32 blue)
|
||||
: r(red), g(green), b(blue) { }
|
||||
|
||||
constexpr Rgb(const Rgb<RBits, GBits, BBits>& rgb)
|
||||
: r(rgb.r), g(rgb.g), b(rgb.b) { }
|
||||
|
||||
template <u32 RBits2, u32 GBits2, u32 BBits2>
|
||||
explicit constexpr Rgb(const Rgb<RBits2, GBits2, BBits2>& rgb)
|
||||
// {
|
||||
// if (RBits2 > RBits)
|
||||
// r = rgb.r >> (RBits2 - RBits);
|
||||
// else if (RBits2 < RBits)
|
||||
// r = rgb.r << (RBits - RBits2);
|
||||
// else
|
||||
// r = rgb.r;
|
||||
|
||||
// if (GBits2 > GBits)
|
||||
// g = rgb.g >> (GBits2 - GBits);
|
||||
// else if (GBits2 < GBits)
|
||||
// g = rgb.g << (GBits - GBits2);
|
||||
// else
|
||||
// g = rgb.g;
|
||||
|
||||
// if (BBits2 > BBits)
|
||||
// b = rgb.b >> (BBits2 - BBits);
|
||||
// else if (BBits2 < BBits)
|
||||
// b = rgb.b << (BBits - BBits2);
|
||||
// else
|
||||
// b = rgb.b;
|
||||
// }
|
||||
: r((rgb.r * ((1 << RBits) - 1) + ((1 << RBits2) >> 1)) / ((1 << RBits2) - 1))
|
||||
, g((rgb.g * ((1 << GBits) - 1) + ((1 << GBits2) >> 1)) / ((1 << GBits2) - 1))
|
||||
, b((rgb.b * ((1 << BBits) - 1) + ((1 << BBits2) >> 1)) / ((1 << BBits2) - 1)) { }
|
||||
|
||||
/// @brief Returns this color with its components clamped to their allowed range.
|
||||
/// @return The clamped color.
|
||||
constexpr Rgb Clamped() const
|
||||
{
|
||||
return Rgb(
|
||||
std::clamp<u32>(r, 0, (1 << RBits) - 1),
|
||||
std::clamp<u32>(g, 0, (1 << GBits) - 1),
|
||||
std::clamp<u32>(b, 0, (1 << BBits) - 1));
|
||||
}
|
||||
|
||||
/// @brief Adds the \p other color and clamps the resulting rgb values to their allowed range.
|
||||
/// @param other The color to add.
|
||||
/// @return The result of adding the colors and clamping the result.
|
||||
constexpr Rgb operator+(const Rgb& other) const
|
||||
{
|
||||
return Rgb(
|
||||
std::clamp<u32>(r + other.r, 0, (1 << RBits) - 1),
|
||||
std::clamp<u32>(g + other.g, 0, (1 << GBits) - 1),
|
||||
std::clamp<u32>(b + other.b, 0, (1 << BBits) - 1));
|
||||
}
|
||||
|
||||
/// @brief Adds the \p other color and without clamping the resulting rgb values.
|
||||
/// Note that this can cause an overflow.
|
||||
/// @param other The color to add.
|
||||
/// @return The result of adding the colors.
|
||||
constexpr Rgb AddUnclamped(const Rgb& other) const
|
||||
{
|
||||
return Rgb(r + other.r, g + other.g, b + other.b);
|
||||
}
|
||||
};
|
||||
26
arm9/source/core/math/RgbMixer.h
Normal file
26
arm9/source/core/math/RgbMixer.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
#include "Rgb.h"
|
||||
#include "fixed.h"
|
||||
#include "ColorConverter.h"
|
||||
|
||||
class RgbMixer
|
||||
{
|
||||
public:
|
||||
template <u32 RBits, u32 GBits, u32 BBits>
|
||||
static Rgb<RBits, GBits, BBits> Lerp(const Rgb<RBits, GBits, BBits>& from, const Rgb<RBits, GBits, BBits>& to, int t, int tMax)
|
||||
{
|
||||
return Rgb<RBits, GBits, BBits>(
|
||||
(u32)((from.r * (tMax - t) + to.r * t) + (tMax >> 1)) / tMax,
|
||||
(u32)((from.g * (tMax - t) + to.g * t) + (tMax >> 1)) / tMax,
|
||||
(u32)((from.b * (tMax - t) + to.b * t) + (tMax >> 1)) / tMax);
|
||||
}
|
||||
|
||||
static void MakeGradientPalette(u16* palette, const Rgb<8, 8, 8>& from, const Rgb<8, 8, 8>& to)
|
||||
{
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
auto newColor = Lerp(from, to, i, 15);
|
||||
palette[i] = ColorConverter::ToGBGR565(newColor);
|
||||
}
|
||||
}
|
||||
};
|
||||
29
arm9/source/core/math/SinTable.h
Normal file
29
arm9/source/core/math/SinTable.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
#include <cmath>
|
||||
#include "fixed.h"
|
||||
|
||||
template<int N>
|
||||
class SinTable
|
||||
{
|
||||
struct sin_cos_t
|
||||
{
|
||||
fix16<14> sin = 0;
|
||||
fix16<14> cos = 0;
|
||||
};
|
||||
|
||||
sin_cos_t _table[N];
|
||||
|
||||
public:
|
||||
constexpr SinTable()
|
||||
: _table()
|
||||
{
|
||||
for (auto i = 0; i < N; i++)
|
||||
_table[i] = { sin(i * 2 * M_PI / N), cos(i * 2 * M_PI / N) };
|
||||
}
|
||||
|
||||
constexpr fix16<14> Sin(u16 angle) const { return _table[(angle * N) >> 16].sin; }
|
||||
constexpr fix16<14> Cos(u16 angle) const { return _table[(angle * N) >> 16].cos; }
|
||||
constexpr const sin_cos_t& SinCos(u16 angle) const { return _table[(angle * N) >> 16]; }
|
||||
};
|
||||
|
||||
constexpr SinTable<4096> gSinTable = SinTable<4096>();
|
||||
479
arm9/source/core/math/fixed.h
Normal file
479
arm9/source/core/math/fixed.h
Normal file
@@ -0,0 +1,479 @@
|
||||
#pragma once
|
||||
#include <libtwl/math/mathDiv.h>
|
||||
|
||||
template <typename T, u32 FractionBits>
|
||||
class fixed
|
||||
{
|
||||
protected:
|
||||
T _value;
|
||||
|
||||
constexpr fixed(T rawValue, int dummy)
|
||||
: _value(rawValue) { }
|
||||
|
||||
public:
|
||||
constexpr fixed() { }
|
||||
|
||||
template <typename T2>
|
||||
constexpr fixed(fixed<T2, FractionBits> value)
|
||||
: _value(value.GetRawValue()) { }
|
||||
|
||||
template <typename T2, u32 OtherFractionBits>
|
||||
explicit constexpr fixed(fixed<T2, OtherFractionBits> value)
|
||||
{
|
||||
if (FractionBits == OtherFractionBits)
|
||||
_value = value.GetRawValue();
|
||||
else if (OtherFractionBits < FractionBits)
|
||||
_value = value.GetRawValue() << (FractionBits - OtherFractionBits);
|
||||
else
|
||||
{
|
||||
const T2 rounding = (T2)(1ULL << ((OtherFractionBits - FractionBits) - 1));
|
||||
const int shift = OtherFractionBits - FractionBits;
|
||||
_value = (value.GetRawValue() + rounding) >> shift;
|
||||
}
|
||||
}
|
||||
|
||||
constexpr fixed(int value)
|
||||
: _value(value << FractionBits) { }
|
||||
|
||||
constexpr fixed(s64 value)
|
||||
: _value(value << FractionBits) { }
|
||||
|
||||
constexpr fixed(float value)
|
||||
: _value(std::round(value * (1 << FractionBits))) { }
|
||||
|
||||
constexpr fixed(double value)
|
||||
: _value(std::round(value * (1 << FractionBits))) { }
|
||||
|
||||
constexpr fixed(long double value)
|
||||
: _value(std::round(value * (1 << FractionBits))) { }
|
||||
|
||||
constexpr T Int() const
|
||||
{
|
||||
return _value >> FractionBits;
|
||||
}
|
||||
|
||||
constexpr T GetRawValue() const { return _value; }
|
||||
};
|
||||
|
||||
template <u32 FractionBits>
|
||||
class fix32;
|
||||
|
||||
template <u32 FractionBits>
|
||||
class fix64;
|
||||
|
||||
template <u32 FractionBits>
|
||||
class fix16 : public fixed<s16, FractionBits>
|
||||
{
|
||||
constexpr fix16(s16 rawValue, int dummy)
|
||||
: fixed<s16, FractionBits>(rawValue, dummy) { }
|
||||
|
||||
public:
|
||||
constexpr fix16() { }
|
||||
|
||||
constexpr fix16(const fix16<FractionBits>& value)
|
||||
: fixed<s16, FractionBits>(value) { }
|
||||
|
||||
template <typename T2, u32 OtherFractionBits>
|
||||
explicit constexpr fix16(const fixed<T2, OtherFractionBits>& value)
|
||||
: fixed<s16, FractionBits>(value) { }
|
||||
|
||||
constexpr fix16(s16 value)
|
||||
: fixed<s16, FractionBits>(value) { }
|
||||
|
||||
constexpr fix16(int value)
|
||||
: fixed<s16, FractionBits>(value) { }
|
||||
|
||||
constexpr fix16(float value)
|
||||
: fixed<s16, FractionBits>(value) { }
|
||||
|
||||
constexpr fix16(double value)
|
||||
: fixed<s16, FractionBits>(value) { }
|
||||
|
||||
constexpr fix16(long double value)
|
||||
: fixed<s16, FractionBits>(value) { }
|
||||
|
||||
constexpr bool operator<(const fix16& other) const
|
||||
{
|
||||
return this->_value < other._value;
|
||||
}
|
||||
|
||||
constexpr bool operator<=(const fix16& other) const
|
||||
{
|
||||
return this->_value <= other._value;
|
||||
}
|
||||
|
||||
constexpr bool operator>(const fix16& other) const
|
||||
{
|
||||
return this->_value > other._value;
|
||||
}
|
||||
|
||||
constexpr bool operator>=(const fix16& other) const
|
||||
{
|
||||
return this->_value >= other._value;
|
||||
}
|
||||
|
||||
constexpr fix16 operator-() const
|
||||
{
|
||||
return FromRawValue(-this->_value);
|
||||
}
|
||||
|
||||
constexpr fix16 operator+(const fix16& other) const
|
||||
{
|
||||
return FromRawValue(this->_value + other._value);
|
||||
}
|
||||
|
||||
template <typename TOther>
|
||||
constexpr fix16 operator+(TOther other) const
|
||||
{
|
||||
return FromRawValue(this->_value + fix16(other)._value);
|
||||
}
|
||||
|
||||
template <typename TLhs>
|
||||
constexpr friend fix16 operator+(TLhs lhs, const fix16& rhs)
|
||||
{
|
||||
return FromRawValue(fix16(lhs)._value + rhs._value);
|
||||
}
|
||||
|
||||
constexpr fix16 operator-(const fix16& other) const
|
||||
{
|
||||
return FromRawValue(this->_value - other._value);
|
||||
}
|
||||
|
||||
template <typename TOther>
|
||||
constexpr fix16 operator-(TOther other) const
|
||||
{
|
||||
return FromRawValue(this->_value - fix16(other)._value);
|
||||
}
|
||||
|
||||
template <typename TLhs>
|
||||
constexpr friend fix16 operator-(TLhs lhs, fix16 rhs)
|
||||
{
|
||||
return FromRawValue(fix16(lhs)._value - rhs._value);
|
||||
}
|
||||
|
||||
constexpr fix16 operator<<(int rhs) const
|
||||
{
|
||||
return FromRawValue(this->_value << rhs);
|
||||
}
|
||||
|
||||
constexpr fix16 operator>>(int rhs) const
|
||||
{
|
||||
return FromRawValue(this->_value >> rhs);
|
||||
}
|
||||
|
||||
constexpr fix16 abs() const
|
||||
{
|
||||
return FromRawValue(std::abs(this->_value));
|
||||
}
|
||||
|
||||
template <u32 OtherFractionBits>
|
||||
constexpr fix32<FractionBits + OtherFractionBits> LongMul(const fix16<OtherFractionBits>& other) const
|
||||
{
|
||||
return fix32<FractionBits + OtherFractionBits>::FromRawValue(this->_value * other.GetRawValue());
|
||||
}
|
||||
|
||||
template <u32 OtherFractionBits>
|
||||
constexpr fix64<FractionBits + OtherFractionBits> LongMul(const fix32<OtherFractionBits>& other) const
|
||||
{
|
||||
return fix64<FractionBits + OtherFractionBits>::FromRawValue(this->_value * (s64)other._value);
|
||||
}
|
||||
|
||||
template <u32 OtherFractionBits>
|
||||
constexpr fix16 operator*(const fix16<OtherFractionBits>& other) const
|
||||
{
|
||||
return fix16(LongMul(other));
|
||||
}
|
||||
|
||||
template <u32 OtherFractionBits>
|
||||
constexpr fix16 operator*(const fix32<OtherFractionBits>& other) const
|
||||
{
|
||||
return fix16(LongMul(other));
|
||||
}
|
||||
|
||||
constexpr fix16 operator*(s16 other) const
|
||||
{
|
||||
return FromRawValue(this->_value * other);
|
||||
}
|
||||
|
||||
constexpr friend fix16 operator*(s16 lhs, const fix16& rhs)
|
||||
{
|
||||
return FromRawValue(lhs * rhs.GetRawValue());
|
||||
}
|
||||
|
||||
template <u32 OtherFractionBits>
|
||||
constexpr fix16 operator/(const fix16<OtherFractionBits>& other) const
|
||||
{
|
||||
s32 lhs = (s32)this->_value << 16;
|
||||
s32 rhs = other.GetRawValue();
|
||||
s32 divResult;
|
||||
if (std::is_constant_evaluated())
|
||||
divResult = lhs / rhs;
|
||||
else
|
||||
divResult = math_div32(lhs, rhs);
|
||||
return fix16(fix32<FractionBits + 16 - OtherFractionBits>::FromRawValue(divResult));
|
||||
}
|
||||
|
||||
static constexpr fix16 FromRawValue(s16 value)
|
||||
{
|
||||
return fix16(value, 0);
|
||||
}
|
||||
};
|
||||
|
||||
template <u32 FractionBits>
|
||||
class fix32 : public fixed<int, FractionBits>
|
||||
{
|
||||
constexpr fix32(int rawValue, int dummy)
|
||||
: fixed<int, FractionBits>(rawValue, dummy) { }
|
||||
|
||||
public:
|
||||
constexpr fix32() { }
|
||||
|
||||
constexpr fix32(const fix16<FractionBits>& value)
|
||||
: fixed<int, FractionBits>(value) { }
|
||||
|
||||
constexpr fix32(const fix32<FractionBits>& value)
|
||||
: fixed<int, FractionBits>(value) { }
|
||||
|
||||
template <typename T2, u32 OtherFractionBits>
|
||||
explicit constexpr fix32(const fixed<T2, OtherFractionBits>& value)
|
||||
: fixed<int, FractionBits>(value) { }
|
||||
|
||||
constexpr fix32(int value)
|
||||
: fixed<int, FractionBits>(value) { }
|
||||
|
||||
constexpr fix32(float value)
|
||||
: fixed<int, FractionBits>(value) { }
|
||||
|
||||
constexpr fix32(double value)
|
||||
: fixed<int, FractionBits>(value) { }
|
||||
|
||||
constexpr fix32(long double value)
|
||||
: fixed<int, FractionBits>(value) { }
|
||||
|
||||
constexpr bool operator==(const fix32& other) const
|
||||
{
|
||||
return this->_value == other._value;
|
||||
}
|
||||
|
||||
constexpr bool operator!=(const fix32& other) const
|
||||
{
|
||||
return this->_value != other._value;
|
||||
}
|
||||
|
||||
constexpr bool operator<(const fix32& other) const
|
||||
{
|
||||
return this->_value < other._value;
|
||||
}
|
||||
|
||||
constexpr bool operator<=(const fix32& other) const
|
||||
{
|
||||
return this->_value <= other._value;
|
||||
}
|
||||
|
||||
constexpr bool operator>(const fix32& other) const
|
||||
{
|
||||
return this->_value > other._value;
|
||||
}
|
||||
|
||||
constexpr bool operator>=(const fix32& other) const
|
||||
{
|
||||
return this->_value >= other._value;
|
||||
}
|
||||
|
||||
constexpr fix32 operator-() const
|
||||
{
|
||||
return FromRawValue(-this->_value);
|
||||
}
|
||||
|
||||
constexpr fix32 operator+(const fix32& other) const
|
||||
{
|
||||
return FromRawValue(this->_value + other._value);
|
||||
}
|
||||
|
||||
template <typename TOther>
|
||||
constexpr fix32 operator+(TOther other) const
|
||||
{
|
||||
return FromRawValue(this->_value + fix32(other)._value);
|
||||
}
|
||||
|
||||
template <typename TLhs>
|
||||
constexpr friend fix32 operator+(TLhs lhs, const fix32& rhs)
|
||||
{
|
||||
return FromRawValue(fix32(lhs)._value + rhs._value);
|
||||
}
|
||||
|
||||
constexpr fix32 operator-(const fix32& other) const
|
||||
{
|
||||
return FromRawValue(this->_value - other._value);
|
||||
}
|
||||
|
||||
constexpr fix32 operator-(int other) const
|
||||
{
|
||||
return FromRawValue(this->_value - fix32(other)._value);
|
||||
}
|
||||
|
||||
constexpr friend fix32 operator-(int lhs, const fix32& rhs)
|
||||
{
|
||||
return FromRawValue(fix32(lhs)._value - rhs._value);
|
||||
}
|
||||
|
||||
constexpr fix32 operator/(int other) const
|
||||
{
|
||||
return FromRawValue(this->_value / other);
|
||||
}
|
||||
|
||||
constexpr fix32 operator<<(int rhs) const
|
||||
{
|
||||
return FromRawValue(this->_value << rhs);
|
||||
}
|
||||
|
||||
constexpr fix32 operator>>(int rhs) const
|
||||
{
|
||||
return FromRawValue(this->_value >> rhs);
|
||||
}
|
||||
|
||||
constexpr fix32 Abs() const
|
||||
{
|
||||
return FromRawValue(std::abs(this->_value));
|
||||
}
|
||||
|
||||
template <u32 OtherFractionBits>
|
||||
constexpr fix64<FractionBits + OtherFractionBits> LongMul(const fix16<OtherFractionBits>& other) const
|
||||
{
|
||||
return fix64<FractionBits + OtherFractionBits>::FromRawValue((s64)this->_value * other.GetRawValue());
|
||||
}
|
||||
|
||||
template <u32 OtherFractionBits>
|
||||
constexpr fix64<FractionBits + OtherFractionBits> LongMul(const fix32<OtherFractionBits>& other) const
|
||||
{
|
||||
return fix64<FractionBits + OtherFractionBits>::FromRawValue((s64)this->_value * other.GetRawValue());
|
||||
}
|
||||
|
||||
constexpr fix64<FractionBits> LongMul(int other) const
|
||||
{
|
||||
return fix64<FractionBits>::FromRawValue((s64)this->_value * other);
|
||||
}
|
||||
|
||||
template <u32 OtherFractionBits>
|
||||
constexpr fix32 operator*(const fix16<OtherFractionBits>& other) const
|
||||
{
|
||||
return fix32(LongMul(other));
|
||||
}
|
||||
|
||||
template <u32 OtherFractionBits>
|
||||
constexpr fix32 operator*(const fix32<OtherFractionBits>& other) const
|
||||
{
|
||||
return fix32(LongMul(other));
|
||||
}
|
||||
|
||||
constexpr fix32 operator*(int other) const
|
||||
{
|
||||
return FromRawValue(this->_value * other);
|
||||
}
|
||||
|
||||
constexpr friend fix32 operator*(int lhs, const fix32& rhs)
|
||||
{
|
||||
return FromRawValue(lhs * rhs.GetRawValue());
|
||||
}
|
||||
|
||||
template <u32 OtherFractionBits>
|
||||
constexpr fix32 operator/(const fix16<OtherFractionBits>& other) const
|
||||
{
|
||||
s64 lhs = (s64)this->_value << 32;
|
||||
s32 rhs = other.GetRawValue();
|
||||
s64 divResult;
|
||||
if (std::is_constant_evaluated())
|
||||
divResult = lhs / rhs;
|
||||
else
|
||||
divResult = math_div6432(lhs, rhs);
|
||||
return fix32(fix64<FractionBits + 32 - OtherFractionBits>::FromRawValue(divResult));
|
||||
}
|
||||
|
||||
template <u32 OtherFractionBits>
|
||||
constexpr fix32 operator/(const fix32<OtherFractionBits>& other) const
|
||||
{
|
||||
s64 lhs = (s64)this->_value << 32;
|
||||
s32 rhs = other.GetRawValue();
|
||||
s64 divResult;
|
||||
if (std::is_constant_evaluated())
|
||||
divResult = lhs / rhs;
|
||||
else
|
||||
divResult = math_div6432(lhs, rhs);
|
||||
return fix32(fix64<FractionBits + 32 - OtherFractionBits>::FromRawValue(divResult));
|
||||
}
|
||||
|
||||
static constexpr fix32 FromRawValue(int value)
|
||||
{
|
||||
return fix32(value, 0);
|
||||
}
|
||||
};
|
||||
|
||||
// static constexpr fix32<12> operator""fx(long double value) { return fix32<12>(value); }
|
||||
|
||||
template <u32 FractionBits>
|
||||
class fix64 : public fixed<s64, FractionBits>
|
||||
{
|
||||
constexpr fix64(s64 rawValue, int dummy)
|
||||
: fixed<s64, FractionBits>(rawValue, dummy) { }
|
||||
|
||||
public:
|
||||
constexpr fix64() { }
|
||||
|
||||
template <typename T2>
|
||||
constexpr fix64(const fixed<T2, FractionBits>& value)
|
||||
: fixed<s64, FractionBits>(value) { }
|
||||
|
||||
template <typename T2, u32 OtherFractionBits>
|
||||
explicit constexpr fix64(const fixed<T2, OtherFractionBits>& value)
|
||||
: fixed<s64, FractionBits>(value) { }
|
||||
|
||||
constexpr fix64(int value)
|
||||
: fixed<s64, FractionBits>(value) { }
|
||||
|
||||
constexpr fix64(s64 value)
|
||||
: fixed<s64, FractionBits>(value) { }
|
||||
|
||||
constexpr fix64(float value)
|
||||
: fixed<s64, FractionBits>(value) { }
|
||||
|
||||
constexpr fix64(double value)
|
||||
: fixed<s64, FractionBits>(value) { }
|
||||
|
||||
constexpr fix64(long double value)
|
||||
: fixed<s64, FractionBits>(value) { }
|
||||
|
||||
constexpr bool operator<(const fix64& other) const
|
||||
{
|
||||
return this->_value < other._value;
|
||||
}
|
||||
|
||||
constexpr bool operator<=(const fix64& other) const
|
||||
{
|
||||
return this->_value <= other._value;
|
||||
}
|
||||
|
||||
constexpr bool operator>(const fix64& other) const
|
||||
{
|
||||
return this->_value > other._value;
|
||||
}
|
||||
|
||||
constexpr bool operator>=(const fix64& other) const
|
||||
{
|
||||
return this->_value >= other._value;
|
||||
}
|
||||
|
||||
constexpr fix64 operator+(const fix64& other) const
|
||||
{
|
||||
return FromRawValue(this->_value + other._value);
|
||||
}
|
||||
|
||||
constexpr fix64 operator-(const fix64& other) const
|
||||
{
|
||||
return FromRawValue(this->_value - other._value);
|
||||
}
|
||||
|
||||
static constexpr fix64 FromRawValue(s64 value)
|
||||
{
|
||||
return fix64(value, 0);
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user