mirror of
https://github.com/gbowne1/ClassicOS.git
synced 2024-11-21 22:06:51 -08:00
commit
791af944f7
@ -1,5 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.13.4)
|
||||
project(ClassicOS VERSION 0.0.1 LANGUAGES C ASM_NASM)
|
||||
project(ClassicOS VERSION 0.0.1 LANGUAGES C CXX ASM_NASM)
|
||||
|
||||
set(IS_OS_WINDOWS FALSE)
|
||||
set(IS_OS_LINUX FALSE)
|
||||
@ -7,13 +7,13 @@ set(IS_OS_MAC FALSE)
|
||||
|
||||
if (${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Windows")
|
||||
set(IS_OS_WINDOWS TRUE)
|
||||
message("Building for the Windows operating system.")
|
||||
message("Building on the Windows operating system.")
|
||||
elseif (${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Linux")
|
||||
set(IS_OS_LINUX TRUE)
|
||||
message("Building for the Linux operating system.")
|
||||
message("Building on the Linux operating system.")
|
||||
elseif (${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Darwin")
|
||||
set(IS_OS_MAC TRUE)
|
||||
message("Building for the Mac operating system.")
|
||||
message("Building on the Mac operating system.")
|
||||
endif ()
|
||||
|
||||
# Source files
|
||||
@ -38,7 +38,7 @@ set(DRIVERS_SOURCE_FILES
|
||||
src/drivers/bus/isa.h
|
||||
src/drivers/bus/mca.c
|
||||
src/drivers/bus/mca.h
|
||||
src/drivers/bus/pci.asm
|
||||
#src/drivers/bus/pci.asm
|
||||
src/drivers/bus/pci.c
|
||||
src/drivers/bus/pci.h
|
||||
src/drivers/bus/vesa.c
|
||||
@ -71,10 +71,37 @@ set(KERNEL_SOURCE_FILES
|
||||
src/kernel/print.c
|
||||
)
|
||||
|
||||
set(UTIL_SOURCE_FILES
|
||||
src/EHS.h
|
||||
src/sys/CPU.h src/sys/CPU.cpp src/sys/CPU_GCC_AMD64.asm
|
||||
src/Util.h src/Util.cpp
|
||||
src/Version.h src/Version.cpp
|
||||
src/Serializer.h
|
||||
src/Array.h
|
||||
src/Vector.h
|
||||
src/SArray.h
|
||||
src/Str.h
|
||||
src/PRNG.h
|
||||
src/HRNG.h src/HRNG_GCC.s
|
||||
src/Math.h src/Math.cpp src/Math_GCC_AMD64.s
|
||||
src/Rect.h
|
||||
src/Range.h src/Range.cpp
|
||||
src/Color4.h src/Color4.cpp
|
||||
src/Color3.h src/Color3.cpp
|
||||
src/Quat.h
|
||||
src/Vec4.h
|
||||
src/Vec3.h
|
||||
src/Vec2.h
|
||||
src/Mat4.h
|
||||
src/Mat3.h
|
||||
src/Mat2.h
|
||||
)
|
||||
|
||||
add_executable(ClassicOS
|
||||
${GRUB_SOURCE_FILES}
|
||||
${DRIVERS_SOURCE_FILES}
|
||||
${KERNEL_SOURCE_FILES}
|
||||
${UTIL_SOURCE_FILES}
|
||||
)
|
||||
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
@ -88,6 +115,7 @@ target_link_libraries(ClassicOS PRIVATE)
|
||||
set(CMAKE_SYSTEM_PROCESSOR i386)
|
||||
set(CMAKE_SYSTEM_NAME None)
|
||||
set(CMAKE_C_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_BUILD_TYPE Debug)
|
||||
set(CMAKE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)
|
||||
set(CMAKE_BINARY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/build)
|
||||
|
375
src/Array.h
Normal file
375
src/Array.h
Normal file
@ -0,0 +1,375 @@
|
||||
#pragma once
|
||||
|
||||
#include "EHS.h"
|
||||
|
||||
#include <initializer_list>
|
||||
#include <algorithm>
|
||||
|
||||
/// A helper class for C-style arrays.
|
||||
/// @tparam T Array data type to use.
|
||||
/// @tparam N Number data type to use.
|
||||
template<typename T, typename N = USize>
|
||||
class Array
|
||||
{
|
||||
protected:
|
||||
T* data;
|
||||
N size;
|
||||
|
||||
public:
|
||||
/// Frees any data created on the heap.
|
||||
~Array()
|
||||
{
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
/// Default members initialization.
|
||||
Array()
|
||||
: data(nullptr), size(0)
|
||||
{
|
||||
}
|
||||
|
||||
/// Initializes an empty array with the given size.
|
||||
/// @note Data must be assigned manually using an index.
|
||||
explicit Array(const N size)
|
||||
: data(new T[size]), size(size)
|
||||
{
|
||||
}
|
||||
|
||||
/// Initializes this array with an initializer list object.
|
||||
/// @param [in] list The given initializer list.
|
||||
Array(std::initializer_list<T> list)
|
||||
: data(new T[list.size()]), size(list.size())
|
||||
{
|
||||
N i = 0;
|
||||
for (auto v = list.begin(); v != list.end(); ++v)
|
||||
data[i++] = std::move(*v);
|
||||
}
|
||||
|
||||
/// Initializes members with given C-style array.
|
||||
/// @param [in] data The C-style array.
|
||||
/// @param [in] size The size of the given C-style array.
|
||||
Array(const T* const data, const N size)
|
||||
: data(new T[size]), size(size)
|
||||
{
|
||||
for (N i = 0; i < size; ++i)
|
||||
this->data[i] = data[i];
|
||||
}
|
||||
|
||||
/// Copies all members from the given array object.
|
||||
/// @param [in] array The array object to copy from.
|
||||
Array(const Array& array)
|
||||
: data(new T[array.size]), size(array.size)
|
||||
{
|
||||
for (N i = 0; i < size; ++i)
|
||||
data[i] = array.data[i];
|
||||
}
|
||||
|
||||
Array(Array&& array) noexcept
|
||||
: data(array.data), size(array.size)
|
||||
{
|
||||
array.data = nullptr;
|
||||
array.size = 0;
|
||||
}
|
||||
|
||||
/// Copies all members from the given array object.
|
||||
/// @param [in] array The array object to copy from.
|
||||
/// @returns The array that has been assigned to.
|
||||
Array<T, N>& operator=(const Array& array)
|
||||
{
|
||||
if (this == &array)
|
||||
return *this;
|
||||
|
||||
delete[] data;
|
||||
data = new T[array.size];
|
||||
for (N i = 0; i < array.size; ++i)
|
||||
data[i] = array.data[i];
|
||||
|
||||
size = array.size;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Array<T, N>& operator=(Array&& array) noexcept
|
||||
{
|
||||
if (this == &array)
|
||||
return *this;
|
||||
|
||||
delete[] data;
|
||||
data = array.data;
|
||||
size = array.size;
|
||||
|
||||
array.data = nullptr;
|
||||
array.size = 0;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Copies all members from the given initializer list object.
|
||||
/// @param [in] list The initializer list object to copy from.
|
||||
/// @returns The array that has been assigned to.
|
||||
Array& operator=(std::initializer_list<T> list)
|
||||
{
|
||||
delete[] data;
|
||||
data = new T[list.size];
|
||||
|
||||
N i = 0;
|
||||
for (auto v = list.begin(); v != list.end(); ++v)
|
||||
data[i++] = std::move(*v);
|
||||
|
||||
size = list.size();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Adds a given array object at the end of the array.
|
||||
/// @param [in] value The given array object to push to the end of the array.
|
||||
Array& operator+=(Array value)
|
||||
{
|
||||
T* result = new T[size + value.size];
|
||||
|
||||
for (N i = 0; i < size; ++i)
|
||||
result[i] = std::move(data[i]);
|
||||
|
||||
for (N i = 0; i < value.size; ++i)
|
||||
result[size + i] = std::move(value[i]);
|
||||
|
||||
delete[] data;
|
||||
|
||||
data = result;
|
||||
size += value.size;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const Array<T, N>& array) const
|
||||
{
|
||||
if (size != array.size)
|
||||
return false;
|
||||
|
||||
for (N i = 0; i < size; ++i)
|
||||
if (data[i] != array[i])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator!=(const Array<T, N>& array) const
|
||||
{
|
||||
if (size == array.size)
|
||||
return false;
|
||||
|
||||
for (N i = 0; i < size; ++i)
|
||||
if (data[i] != array[i])
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Adds a given array object at the end of the array.
|
||||
/// @param [in] value The given initializer list to push to the end of the array.
|
||||
Array& operator+=(std::initializer_list<T> value)
|
||||
{
|
||||
T* result = new T[size + value.size()];
|
||||
|
||||
for (N i = 0; i < size; ++i)
|
||||
result[i] = std::move(data[i]);
|
||||
|
||||
N i = 0;
|
||||
for (auto v = value.begin(); v != value.end(); ++v)
|
||||
result[size + i++] = std::move(*v);
|
||||
|
||||
delete[] data;
|
||||
|
||||
data = result;
|
||||
size += value.size();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Adds a given value at the end of the array.
|
||||
/// @param [in] value The given value to push to the end of the array.
|
||||
Array& operator+=(const T value)
|
||||
{
|
||||
T* result = new T[size + 1];
|
||||
|
||||
for (N i = 0; i < size; ++i)
|
||||
result[i] = std::move(data[i]);
|
||||
|
||||
result[size] = std::move(value);
|
||||
|
||||
delete[] data;
|
||||
|
||||
data = result;
|
||||
++size;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Retrieves the raw C-style array from casting an array object.
|
||||
operator T* () const
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
/// Swaps two values in the array.
|
||||
/// @param a The first index to swap with.
|
||||
/// @param b The second index to swap with.
|
||||
void Swap(N a, N b) const
|
||||
{
|
||||
T tmp = std::move(data[a]);
|
||||
|
||||
data[a] = std::move(data[b]);
|
||||
data[b] = std::move(tmp);
|
||||
}
|
||||
|
||||
/// Adds a given C-style array at the end of the array.
|
||||
/// @param [in] value The given C-style array to push to the end of the array.
|
||||
/// @param [in] size The size of the given C-style array.
|
||||
void Push(const T* const value, const N size)
|
||||
{
|
||||
T* result = new T[this->size + size];
|
||||
|
||||
for (N i = 0; i < this->size; ++i)
|
||||
result[i] = std::move(this->data[i]);
|
||||
|
||||
for (N i = 0; i < size; ++i)
|
||||
result[this->size + i] = value[i];
|
||||
|
||||
delete[] data;
|
||||
|
||||
this->data = result;
|
||||
this->size += size;
|
||||
}
|
||||
|
||||
/// Adds a given array object at the end of the array.
|
||||
/// @param [in] value The given array object to push to the end of the array.
|
||||
void Push(Array value)
|
||||
{
|
||||
T* result = new T[size + value.size];
|
||||
|
||||
for (N i = 0; i < size; ++i)
|
||||
result[i] = std::move(data[i]);
|
||||
|
||||
for (N i = 0; i < value.size; ++i)
|
||||
result[size + i] = std::move(value[i]);
|
||||
|
||||
delete[] data;
|
||||
|
||||
data = result;
|
||||
size += value.size;
|
||||
}
|
||||
|
||||
/// Adds a given array object at the end of the array.
|
||||
/// @param [in] value The given initializer list to push to the end of the array.
|
||||
void Push(std::initializer_list<T> value)
|
||||
{
|
||||
T* result = new T[size + value.size()];
|
||||
|
||||
for (N i = 0; i < size; ++i)
|
||||
result[i] = std::move(data[i]);
|
||||
|
||||
N i = 0;
|
||||
for (auto v = value.begin(); v != value.end(); ++v)
|
||||
result[size + i++] = std::move(*v);
|
||||
|
||||
delete[] data;
|
||||
|
||||
data = result;
|
||||
size += value.size();
|
||||
}
|
||||
|
||||
/// Adds a given value at the end of the array.
|
||||
/// @param [in] value The given value to push to the end of the array.
|
||||
void Push(T value)
|
||||
{
|
||||
T* result = new T[size + 1];
|
||||
|
||||
for (N i = 0; i < size; ++i)
|
||||
result[i] = std::move(data[i]);
|
||||
|
||||
result[size] = std::move(value);
|
||||
|
||||
delete[] data;
|
||||
|
||||
data = result;
|
||||
++size;
|
||||
}
|
||||
|
||||
/// Removes a value at the end of the array.
|
||||
/// @returns The value that was popped.
|
||||
T Pop()
|
||||
{
|
||||
T* result = new T[--size];
|
||||
|
||||
T value = std::move(data[size]);
|
||||
|
||||
for (N i = 0; i < size; ++i)
|
||||
result[i] = std::move(data[i]);
|
||||
|
||||
delete[] data;
|
||||
|
||||
data = result;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// Removes a value at a provided index.
|
||||
/// @param [in] index The index of the value to remove.
|
||||
/// @returns The value that was removed.
|
||||
T Remove(const N index)
|
||||
{
|
||||
T* result = new T[--size];
|
||||
|
||||
T value = std::move(data[index]);
|
||||
|
||||
for (N i = 0, c = 0; i < size; ++i)
|
||||
if (i != index)
|
||||
result[c++] = std::move(data[i]);
|
||||
|
||||
delete[] data;
|
||||
|
||||
data = result;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
delete[] data;
|
||||
data = nullptr;
|
||||
size = 0;
|
||||
}
|
||||
|
||||
/// Resizes the array.
|
||||
/// @param [in] newSize The size to change to.
|
||||
void Resize(const N newSize)
|
||||
{
|
||||
if (size == newSize)
|
||||
return;
|
||||
|
||||
T* result = new T[newSize];
|
||||
|
||||
for (N i = 0; i < newSize && i < size; ++i)
|
||||
result[i] = std::move(data[i]);
|
||||
|
||||
delete[] data;
|
||||
|
||||
data = result;
|
||||
size = newSize;
|
||||
}
|
||||
|
||||
/// Retrieves the size of the array.
|
||||
/// @returns The resulting size.
|
||||
N Size() const
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
N End() const
|
||||
{
|
||||
return size - 1;
|
||||
}
|
||||
};
|
89
src/Color3.cpp
Normal file
89
src/Color3.cpp
Normal file
@ -0,0 +1,89 @@
|
||||
#include "Color3.h"
|
||||
|
||||
#include "Math.h"
|
||||
|
||||
Color3::Color3()
|
||||
: r(0.0f), g(0.0f), b(0.0f)
|
||||
{
|
||||
}
|
||||
|
||||
Color3::Color3(const float scalar)
|
||||
: r(Math::Clamp(scalar, 0.0f, 1.0f)), g(Math::Clamp(scalar, 0.0f, 1.0f)), b(Math::Clamp(scalar, 0.0f, 1.0f))
|
||||
{
|
||||
}
|
||||
|
||||
Color3::Color3(const float r, const float g, const float b)
|
||||
: r(Math::Clamp(r, 0.0f, 1.0f)), g(Math::Clamp(g, 0.0f, 1.0f)), b(Math::Clamp(b, 0.0f, 1.0f))
|
||||
{
|
||||
}
|
||||
|
||||
Color3::Color3(const Color3& color)
|
||||
: r(color.r), g(color.g), b(color.b)
|
||||
{
|
||||
}
|
||||
|
||||
Color3& Color3::operator=(const Color3& color)
|
||||
{
|
||||
if (this == &color)
|
||||
return *this;
|
||||
|
||||
r = color.r;
|
||||
g = color.g;
|
||||
b = color.b;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool Color3::operator==(const Color3& color) const
|
||||
{
|
||||
return r == color.r && g == color.g && b == color.b;
|
||||
}
|
||||
|
||||
bool Color3::operator!=(const Color3& color) const
|
||||
{
|
||||
return r != color.r || g != color.g || b != color.b;
|
||||
}
|
||||
|
||||
float Color3::operator[](const UInt_64 i) const
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
return r;
|
||||
case 1:
|
||||
return g;
|
||||
case 2:
|
||||
return b;
|
||||
default:
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
float& Color3::operator[](const UInt_64 i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
return r;
|
||||
case 1:
|
||||
return g;
|
||||
case 2:
|
||||
return b;
|
||||
default:
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
Color3& Color3::operator*=(const Color3& color)
|
||||
{
|
||||
r *= color.r;
|
||||
g *= color.g;
|
||||
b *= color.b;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Color3 Color3::operator*(const Color3& color) const
|
||||
{
|
||||
return {r * color.r, g * color.g, b * color.b};
|
||||
}
|
33
src/Color3.h
Normal file
33
src/Color3.h
Normal file
@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include "EHS.h"
|
||||
|
||||
class Color3
|
||||
{
|
||||
public:
|
||||
float r;
|
||||
float g;
|
||||
float b;
|
||||
|
||||
Color3();
|
||||
|
||||
Color3(const float scalar);
|
||||
|
||||
Color3(const float r, const float g, const float b);
|
||||
|
||||
Color3(const Color3& color);
|
||||
|
||||
Color3& operator=(const Color3& color);
|
||||
|
||||
bool operator==(const Color3& color) const;
|
||||
|
||||
bool operator!=(const Color3& color) const;
|
||||
|
||||
float operator[](const UInt_64 i) const;
|
||||
|
||||
float& operator[](const UInt_64 i);
|
||||
|
||||
Color3& operator*=(const Color3& color);
|
||||
|
||||
Color3 operator*(const Color3& color) const;
|
||||
};
|
94
src/Color4.cpp
Normal file
94
src/Color4.cpp
Normal file
@ -0,0 +1,94 @@
|
||||
#include "Color4.h"
|
||||
|
||||
#include "Math.h"
|
||||
|
||||
Color4::Color4()
|
||||
: r(0.0f), g(0.0f), b(0.0f), a(1.0f)
|
||||
{
|
||||
}
|
||||
|
||||
Color4::Color4(const float scalar, const float a)
|
||||
: r(Math::Clamp(scalar, 0.0f, 1.0f)), g(Math::Clamp(scalar, 0.0f, 1.0f)), b(Math::Clamp(scalar, 0.0f, 1.0f)), a(a)
|
||||
{
|
||||
}
|
||||
|
||||
Color4::Color4(const float r, const float g, const float b, const float a)
|
||||
: r(Math::Clamp(r, 0.0f, 1.0f)), g(Math::Clamp(g, 0.0f, 1.0f)), b(Math::Clamp(b, 0.0f, 1.0f)), a(Math::Clamp(a, 0.0f, 1.0f))
|
||||
{
|
||||
}
|
||||
|
||||
Color4::Color4(const Color4& color)
|
||||
: r(color.r), g(color.g), b(color.b), a(color.a)
|
||||
{
|
||||
}
|
||||
|
||||
Color4& Color4::operator=(const Color4& color)
|
||||
{
|
||||
if (this == &color)
|
||||
return *this;
|
||||
|
||||
r = color.r;
|
||||
g = color.g;
|
||||
b = color.b;
|
||||
a = color.a;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool Color4::operator==(const Color4& color) const
|
||||
{
|
||||
return r == color.r && g == color.g && b == color.b && a == color.a;
|
||||
}
|
||||
|
||||
bool Color4::operator!=(const Color4& color) const
|
||||
{
|
||||
return r != color.r || g != color.g || b != color.b || a != color.a;
|
||||
}
|
||||
|
||||
float Color4::operator[](const UInt_64 i) const
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
return r;
|
||||
case 1:
|
||||
return g;
|
||||
case 2:
|
||||
return b;
|
||||
case 3:
|
||||
return a;
|
||||
default:
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
float& Color4::operator[](const UInt_64 i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
return r;
|
||||
case 1:
|
||||
return g;
|
||||
case 2:
|
||||
return b;
|
||||
case 3:
|
||||
return a;
|
||||
default:
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
Color4& Color4::operator*=(const Color4& color)
|
||||
{
|
||||
r *= color.r;
|
||||
g *= color.g;
|
||||
b *= color.b;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Color4 Color4::operator*(const Color4& color) const
|
||||
{
|
||||
return {r * color.r, g * color.g, b * color.b, a};
|
||||
}
|
34
src/Color4.h
Normal file
34
src/Color4.h
Normal file
@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include "EHS.h"
|
||||
|
||||
class Color4
|
||||
{
|
||||
public:
|
||||
float r;
|
||||
float g;
|
||||
float b;
|
||||
float a;
|
||||
|
||||
Color4();
|
||||
|
||||
Color4(const float scalar, const float a = 1.0f);
|
||||
|
||||
Color4(const float r, const float g, const float b, const float a = 1.0f);
|
||||
|
||||
Color4(const Color4& color);
|
||||
|
||||
Color4& operator=(const Color4& color);
|
||||
|
||||
bool operator==(const Color4& color) const;
|
||||
|
||||
bool operator!=(const Color4& color) const;
|
||||
|
||||
float operator[](const UInt_64 i) const;
|
||||
|
||||
float& operator[](const UInt_64 i);
|
||||
|
||||
Color4& operator*=(const Color4& color);
|
||||
|
||||
Color4 operator*(const Color4& color) const;
|
||||
};
|
72
src/EHS.h
Normal file
72
src/EHS.h
Normal file
@ -0,0 +1,72 @@
|
||||
#if defined(_M_AMD64) || defined(_M_X64) || defined(__x86_64__)
|
||||
#define LITTLE_ENDIAN
|
||||
#define ARCH_X64
|
||||
#elif defined(__i386__)
|
||||
#define LITTLE_ENDIAN
|
||||
#define ARCH_X86
|
||||
#elif defined(_M_ARM64) || defined(__aarch64__)
|
||||
#define LITTLE_ENDIAN
|
||||
#define ARCH_ARM64
|
||||
#else
|
||||
#error Unsupported architecture.
|
||||
#endif
|
||||
|
||||
typedef unsigned char UInt_8;
|
||||
typedef signed char SInt_8;
|
||||
typedef char Int_8;
|
||||
typedef unsigned short UInt_16;
|
||||
typedef signed short SInt_16;
|
||||
typedef short Int_16;
|
||||
typedef unsigned int UInt_32;
|
||||
typedef signed int SInt_32;
|
||||
typedef int Int_32;
|
||||
|
||||
typedef UInt_8 Byte;
|
||||
typedef Int_8 Char_8;
|
||||
typedef Int_16 Char_16;
|
||||
typedef Int_32 Char_32;
|
||||
|
||||
#if defined(__GNUC__)
|
||||
typedef unsigned long long UInt_64;
|
||||
typedef signed long long SInt_64;
|
||||
typedef long long Int_64;
|
||||
#elif defined(_WIN32)
|
||||
typedef unsigned long UInt_64;
|
||||
typedef signed long SInt_64;
|
||||
typedef long Int_64;
|
||||
#endif
|
||||
|
||||
#if defined(ARCH_X64)
|
||||
typedef UInt_64 USize;
|
||||
typedef SInt_64 SSize;
|
||||
typedef Int_64 Size;
|
||||
#elif defined(ARCH_X86)
|
||||
typedef UInt_32 USize;
|
||||
typedef SInt_32 SSize;
|
||||
typedef Int_32 Size;
|
||||
#endif
|
||||
|
||||
#define MAX_PATH 0x104
|
||||
#define UINT_8_MAX 0xFF
|
||||
#define SINT_8_MAX 0x7F
|
||||
#define SINT_8_MIN 0x80
|
||||
#define UINT_16_MAX 0xFFFF
|
||||
#define SINT_16_MAX 0x7FFF
|
||||
#define SINT_16_MIN 0x8000
|
||||
#define UINT_24_MAX 0xFFFFFF
|
||||
#define SINT_24_MAX 0x7FFFFF
|
||||
#define SINT_24_MIN 0x800000
|
||||
#define UINT_32_MAX 0xFFFFFFFF
|
||||
#define SINT_32_MAX 0x7FFFFFFF
|
||||
#define SINT_32_MIN 0x80000000
|
||||
#define UINT_64_MAX 0xFFFFFFFFFFFFFFFF
|
||||
#define SINT_64_MAX 0x7FFFFFFFFFFFFFFF
|
||||
#define SINT_64_MIN 0x8000000000000000
|
||||
#define FLOAT_MAX 3.40282e+038f
|
||||
#define FLOAT_MIN 1.17549e-038f
|
||||
#define DOUBLE_MAX 1.79769e+308
|
||||
#define DOUBLE_MIN 2.22507e-308
|
||||
#define LDOUBLE_MAX 1.79769e+308
|
||||
#define LDOUBLE_MIN 2.22507e-308
|
||||
|
||||
#define INFINITE UINT_32_MAX
|
55
src/HRNG.h
Normal file
55
src/HRNG.h
Normal file
@ -0,0 +1,55 @@
|
||||
#pragma once
|
||||
|
||||
#include "EHS.h"
|
||||
|
||||
class HRNG
|
||||
{
|
||||
public:
|
||||
static UInt_64 GenerateSeed_u64();
|
||||
|
||||
static UInt_64 Generate_u64(const UInt_64 min, const UInt_64 max);
|
||||
|
||||
static UInt_64 Generate_u64();
|
||||
|
||||
static SInt_64 GenerateSeed_s64();
|
||||
|
||||
static SInt_64 Generate_s64(const SInt_64 min, const SInt_64 max);
|
||||
|
||||
static SInt_64 Generate_s64();
|
||||
|
||||
static UInt_32 GenerateSeed_u32();
|
||||
|
||||
static UInt_32 Generate_u32(const UInt_32 min, const UInt_32 max);
|
||||
|
||||
static UInt_32 Generate_u32();
|
||||
|
||||
static SInt_32 GenerateSeed_s32();
|
||||
|
||||
static SInt_32 Generate_s32(const SInt_32 min, const SInt_32 max);
|
||||
|
||||
static SInt_32 Generate_s32();
|
||||
|
||||
static UInt_32 GenerateSeed_u16();
|
||||
|
||||
static UInt_16 Generate_u16(const UInt_16 min, const UInt_16 max);
|
||||
|
||||
static UInt_16 Generate_u16();
|
||||
|
||||
static SInt_16 GenerateSeed_s16();
|
||||
|
||||
static SInt_16 Generate_s16(const SInt_16 min, const SInt_16 max);
|
||||
|
||||
static SInt_16 Generate_s16();
|
||||
|
||||
static UInt_8 GenerateSeed_u8();
|
||||
|
||||
static UInt_8 Generate_u8(const UInt_8 min, const UInt_8 max);
|
||||
|
||||
static UInt_8 Generate_u8();
|
||||
|
||||
static SInt_8 GenerateSeed_s8();
|
||||
|
||||
static SInt_8 Generate_s8(const SInt_8 min, const SInt_8 max);
|
||||
|
||||
static SInt_8 Generate_s8();
|
||||
};
|
161
src/HRNG_GCC.s
Normal file
161
src/HRNG_GCC.s
Normal file
@ -0,0 +1,161 @@
|
||||
global _ZN3lwe4HRNG16GenerateSeed_u64Ev
|
||||
global _ZN3lwe4HRNG12Generate_u64Emm
|
||||
global _ZN3lwe4HRNG12Generate_u64Ev
|
||||
global _ZN3lwe4HRNG16GenerateSeed_s64Ev
|
||||
global _ZN3lwe4HRNG12Generate_s64Ell
|
||||
global _ZN3lwe4HRNG12Generate_s64Ev
|
||||
global _ZN3lwe4HRNG16GenerateSeed_u32Ev
|
||||
global _ZN3lwe4HRNG12Generate_u32Ejj
|
||||
global _ZN3lwe4HRNG12Generate_u32Ev
|
||||
global _ZN3lwe4HRNG16GenerateSeed_s32Ev
|
||||
global _ZN3lwe4HRNG12Generate_s32Eii
|
||||
global _ZN3lwe4HRNG12Generate_s32Ev
|
||||
global _ZN3lwe4HRNG16GenerateSeed_u16Ev
|
||||
global _ZN3lwe4HRNG12Generate_u16Ett
|
||||
global _ZN3lwe4HRNG12Generate_u16Ev
|
||||
global _ZN3lwe4HRNG16GenerateSeed_s16Ev
|
||||
global _ZN3lwe4HRNG12Generate_s16Ess
|
||||
global _ZN3lwe4HRNG12Generate_s16Ev
|
||||
global _ZN3lwe4HRNG15GenerateSeed_u8Ev
|
||||
global _ZN3lwe4HRNG11Generate_u8Ehh
|
||||
global _ZN3lwe4HRNG11Generate_u8Ev
|
||||
global _ZN3lwe4HRNG15GenerateSeed_s8Ev
|
||||
global _ZN3lwe4HRNG11Generate_s8Eaa
|
||||
global _ZN3lwe4HRNG11Generate_s8Ev
|
||||
|
||||
section .text
|
||||
_ZN3lwe4HRNG16GenerateSeed_u64Ev:
|
||||
RDSEED RAX
|
||||
RET
|
||||
|
||||
_ZN3lwe4HRNG12Generate_u64Emm:
|
||||
RDRAND RAX
|
||||
SUB RDI, RCX
|
||||
XOR RDX, RDX
|
||||
DIV RDI
|
||||
MOV RAX, RDX
|
||||
ADD RAX, RCX
|
||||
RET
|
||||
|
||||
_ZN3lwe4HRNG12Generate_u64Ev:
|
||||
RDRAND RAX
|
||||
RET
|
||||
|
||||
_ZN3lwe4HRNG16GenerateSeed_s64Ev:
|
||||
RDSEED RAX
|
||||
RET
|
||||
|
||||
_ZN3lwe4HRNG12Generate_s64Ell:
|
||||
RDRAND RAX
|
||||
SUB RDI, RCX
|
||||
XOR RDX, RDX
|
||||
DIV RDI
|
||||
MOV RAX, RDX
|
||||
ADD RAX, RCX
|
||||
RET
|
||||
|
||||
_ZN3lwe4HRNG12Generate_s64Ev:
|
||||
RDRAND RAX
|
||||
RET
|
||||
|
||||
_ZN3lwe4HRNG16GenerateSeed_u32Ev:
|
||||
RDSEED EAX
|
||||
RET
|
||||
|
||||
_ZN3lwe4HRNG12Generate_u32Ejj:
|
||||
RDRAND EAX
|
||||
SUB EDI, ECX
|
||||
XOR EDX, EDX
|
||||
DIV EDI
|
||||
MOV EAX, EDX
|
||||
ADD EAX, ECX
|
||||
RET
|
||||
|
||||
_ZN3lwe4HRNG12Generate_u32Ev:
|
||||
RDRAND EAX
|
||||
RET
|
||||
|
||||
_ZN3lwe4HRNG16GenerateSeed_s32Ev:
|
||||
RDSEED EAX
|
||||
RET
|
||||
|
||||
_ZN3lwe4HRNG12Generate_s32Eii:
|
||||
RDRAND EAX
|
||||
SUB EDI, ECX
|
||||
XOR EDX, EDX
|
||||
DIV EDI
|
||||
MOV EAX, EDX
|
||||
ADD EAX, ECX
|
||||
RET
|
||||
|
||||
_ZN3lwe4HRNG12Generate_s32Ev:
|
||||
RDRAND EAX
|
||||
RET
|
||||
|
||||
_ZN3lwe4HRNG16GenerateSeed_u16Ev:
|
||||
RDSEED AX
|
||||
RET
|
||||
|
||||
_ZN3lwe4HRNG12Generate_u16Ett:
|
||||
RDRAND AX
|
||||
SUB DI, CX
|
||||
XOR DX, DX
|
||||
DIV DI
|
||||
MOV AX, DX
|
||||
ADD AX, CX
|
||||
RET
|
||||
|
||||
_ZN3lwe4HRNG12Generate_u16Ev:
|
||||
RDRAND AX
|
||||
RET
|
||||
|
||||
_ZN3lwe4HRNG16GenerateSeed_s16Ev:
|
||||
RDSEED AX
|
||||
RET
|
||||
|
||||
_ZN3lwe4HRNG12Generate_s16Ess:
|
||||
RDRAND AX
|
||||
SUB DI, CX
|
||||
XOR DX, DX
|
||||
DIV DI
|
||||
MOV AX, DX
|
||||
ADD AX, CX
|
||||
RET
|
||||
|
||||
_ZN3lwe4HRNG12Generate_s16Ev:
|
||||
RDRAND AX
|
||||
RET
|
||||
|
||||
_ZN3lwe4HRNG15GenerateSeed_u8Ev:
|
||||
RDSEED AX
|
||||
RET
|
||||
|
||||
_ZN3lwe4HRNG11Generate_u8Ehh:
|
||||
RDRAND AX
|
||||
SUB DI, CX
|
||||
XOR DX, DX
|
||||
DIV DI
|
||||
MOV AX, DX
|
||||
ADD AX, CX
|
||||
RET
|
||||
|
||||
_ZN3lwe4HRNG11Generate_u8Ev:
|
||||
RDRAND AX
|
||||
RET
|
||||
|
||||
_ZN3lwe4HRNG15GenerateSeed_s8Ev:
|
||||
RDSEED AX
|
||||
RET
|
||||
|
||||
_ZN3lwe4HRNG11Generate_s8Eaa:
|
||||
RDRAND AX
|
||||
SUB DI, CX
|
||||
XOR DX, DX
|
||||
DIV DI
|
||||
MOV AX, DX
|
||||
ADD AX, CX
|
||||
RET
|
||||
|
||||
_ZN3lwe4HRNG11Generate_s8Ev:
|
||||
RDRAND AX
|
||||
RET
|
169
src/HRNG_MSVC.s
Normal file
169
src/HRNG_MSVC.s
Normal file
@ -0,0 +1,169 @@
|
||||
global ?GenerateSeed_u64@HRNG@lwe@@SA_KXZ
|
||||
global ?Generate_u64@HRNG@lwe@@SA_K_K0@Z
|
||||
global ?Generate_u64@HRNG@lwe@@SA_KXZ
|
||||
global ?GenerateSeed_s64@HRNG@lwe@@SA_JXZ
|
||||
global ?Generate_s64@HRNG@lwe@@SA_J_J0@Z
|
||||
global ?Generate_s64@HRNG@lwe@@SA_JXZ
|
||||
global ?GenerateSeed_u32@HRNG@lwe@@SAIXZ
|
||||
global ?Generate_u32@HRNG@lwe@@SAIII@Z
|
||||
global ?Generate_u32@HRNG@lwe@@SAIXZ
|
||||
global ?GenerateSeed_s32@HRNG@lwe@@SAHXZ
|
||||
global ?Generate_s32@HRNG@lwe@@SAHHH@Z
|
||||
global ?Generate_s32@HRNG@lwe@@SAHXZ
|
||||
global ?GenerateSeed_u16@HRNG@lwe@@SAIXZ
|
||||
global ?Generate_u16@HRNG@lwe@@SAGGG@Z
|
||||
global ?Generate_u16@HRNG@lwe@@SAGXZ
|
||||
global ?GenerateSeed_s16@HRNG@lwe@@SAFXZ
|
||||
global ?Generate_s16@HRNG@lwe@@SAFFF@Z
|
||||
global ?Generate_s16@HRNG@lwe@@SAFXZ
|
||||
global ?GenerateSeed_u8@HRNG@lwe@@SAEXZ
|
||||
global ?Generate_u8@HRNG@lwe@@SAEEE@Z
|
||||
global ?Generate_u8@HRNG@lwe@@SAEXZ
|
||||
global ?GenerateSeed_s8@HRNG@lwe@@SACXZ
|
||||
global ?Generate_s8@HRNG@lwe@@SACCC@Z
|
||||
global ?Generate_s8@HRNG@lwe@@SACXZ
|
||||
|
||||
section .text
|
||||
?GenerateSeed_u64@HRNG@lwe@@SA_KXZ:
|
||||
RDSEED RAX
|
||||
RET
|
||||
|
||||
?Generate_u64@HRNG@lwe@@SA_K_K0@Z:
|
||||
RDRAND RAX
|
||||
MOV R8, RDX
|
||||
SUB R8, RCX
|
||||
XOR RDX, RDX
|
||||
DIV R8
|
||||
MOV RAX, RDX
|
||||
ADD RAX, RCX
|
||||
RET
|
||||
|
||||
?Generate_u64@HRNG@lwe@@SA_KXZ:
|
||||
RDRAND RAX
|
||||
RET
|
||||
|
||||
?GenerateSeed_s64@HRNG@lwe@@SA_JXZ:
|
||||
RDSEED RAX
|
||||
RET
|
||||
|
||||
?Generate_s64@HRNG@lwe@@SA_J_J0@Z:
|
||||
RDRAND RAX
|
||||
MOV R8, RDX
|
||||
SUB R8, RCX
|
||||
XOR RDX, RDX
|
||||
DIV R8
|
||||
MOV RAX, RDX
|
||||
ADD RAX, RCX
|
||||
RET
|
||||
|
||||
?Generate_s64@HRNG@lwe@@SA_JXZ:
|
||||
RDRAND RAX
|
||||
RET
|
||||
|
||||
?GenerateSeed_u32@HRNG@lwe@@SAIXZ:
|
||||
RDSEED EAX
|
||||
RET
|
||||
|
||||
?Generate_u32@HRNG@lwe@@SAIII@Z:
|
||||
RDRAND EAX
|
||||
MOV R8D, EDX
|
||||
SUB R8D, ECX
|
||||
XOR EDX, EDX
|
||||
DIV R8D
|
||||
MOV EAX, EDX
|
||||
ADD EAX, ECX
|
||||
RET
|
||||
|
||||
?Generate_u32@HRNG@lwe@@SAIXZ:
|
||||
RDRAND EAX
|
||||
RET
|
||||
|
||||
?GenerateSeed_s32@HRNG@lwe@@SAHXZ:
|
||||
RDSEED EAX
|
||||
RET
|
||||
|
||||
?Generate_s32@HRNG@lwe@@SAHHH@Z:
|
||||
RDRAND EAX
|
||||
MOV R8D, EDX
|
||||
SUB R8D, ECX
|
||||
XOR EDX, EDX
|
||||
DIV R8D
|
||||
MOV EAX, EDX
|
||||
ADD EAX, ECX
|
||||
RET
|
||||
|
||||
?Generate_s32@HRNG@lwe@@SAHXZ:
|
||||
RDRAND EAX
|
||||
RET
|
||||
|
||||
?GenerateSeed_u16@HRNG@lwe@@SAIXZ:
|
||||
RDSEED AX
|
||||
RET
|
||||
|
||||
?Generate_u16@HRNG@lwe@@SAGGG@Z:
|
||||
RDRAND AX
|
||||
MOV R8W, DX
|
||||
SUB R8W, CX
|
||||
XOR DX, DX
|
||||
DIV R8W
|
||||
MOV AX, DX
|
||||
ADD AX, CX
|
||||
RET
|
||||
|
||||
?Generate_u16@HRNG@lwe@@SAGXZ:
|
||||
RDRAND AX
|
||||
RET
|
||||
|
||||
?GenerateSeed_s16@HRNG@lwe@@SAFXZ:
|
||||
RDSEED AX
|
||||
RET
|
||||
|
||||
?Generate_s16@HRNG@lwe@@SAFFF@Z:
|
||||
RDRAND AX
|
||||
MOV R8W, DX
|
||||
SUB R8W, CX
|
||||
XOR DX, DX
|
||||
DIV R8W
|
||||
MOV AX, DX
|
||||
ADD AX, CX
|
||||
RET
|
||||
|
||||
?Generate_s16@HRNG@lwe@@SAFXZ:
|
||||
RDRAND AX
|
||||
RET
|
||||
|
||||
?GenerateSeed_u8@HRNG@lwe@@SAEXZ:
|
||||
RDSEED AX
|
||||
RET
|
||||
|
||||
?Generate_u8@HRNG@lwe@@SAEEE@Z:
|
||||
RDRAND AX
|
||||
MOV R8W, DX
|
||||
SUB R8W, CX
|
||||
XOR DX, DX
|
||||
DIV R8W
|
||||
MOV AX, DX
|
||||
ADD AX, CX
|
||||
RET
|
||||
|
||||
?Generate_u8@HRNG@lwe@@SAEXZ:
|
||||
RDRAND AX
|
||||
RET
|
||||
|
||||
?GenerateSeed_s8@HRNG@lwe@@SACXZ:
|
||||
RDSEED AX
|
||||
RET
|
||||
|
||||
?Generate_s8@HRNG@lwe@@SACCC@Z:
|
||||
RDRAND AX
|
||||
MOV R8W, DX
|
||||
SUB R8W, CX
|
||||
XOR DX, DX
|
||||
DIV R8W
|
||||
MOV AX, DX
|
||||
ADD AX, CX
|
||||
RET
|
||||
|
||||
?Generate_s8@HRNG@lwe@@SACXZ:
|
||||
RDRAND AX
|
||||
RET
|
66
src/Link.h
Normal file
66
src/Link.h
Normal file
@ -0,0 +1,66 @@
|
||||
#pragma once
|
||||
|
||||
template<typename T>
|
||||
class Link
|
||||
{
|
||||
public:
|
||||
T value;
|
||||
Link<T> *child;
|
||||
|
||||
~Link()
|
||||
{
|
||||
delete child;
|
||||
}
|
||||
|
||||
Link()
|
||||
: value(), child(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
Link(const T value, Link* child)
|
||||
: value(value), child(child)
|
||||
{
|
||||
}
|
||||
|
||||
Link(const T value)
|
||||
: value(value), child(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
Link(const Link& link)
|
||||
: value(link.value), child(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
Link(Link&& link) noexcept
|
||||
: value(link.value), child(link.child)
|
||||
{
|
||||
link.value = 0;
|
||||
link.child = nullptr;
|
||||
}
|
||||
|
||||
Link& operator=(const Link& link)
|
||||
{
|
||||
if (this == &link)
|
||||
return *this;
|
||||
|
||||
value = link.value;
|
||||
child = nullptr;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Link& operator=(Link&& link) noexcept
|
||||
{
|
||||
if (this == &link)
|
||||
return *this;
|
||||
|
||||
value = link.value;
|
||||
child = link.child;
|
||||
|
||||
link.value = 0;
|
||||
link.child = nullptr;
|
||||
|
||||
return *this;
|
||||
}
|
||||
};
|
236
src/LinkedList.h
Normal file
236
src/LinkedList.h
Normal file
@ -0,0 +1,236 @@
|
||||
#pragma once
|
||||
|
||||
#include "EHS.h"
|
||||
#include "Link.h"
|
||||
|
||||
template<typename T, typename N = USize>
|
||||
class LinkedList
|
||||
{
|
||||
private:
|
||||
Link<T>* start;
|
||||
Link<T>* end;
|
||||
N size;
|
||||
|
||||
public:
|
||||
~LinkedList()
|
||||
{
|
||||
delete start;
|
||||
}
|
||||
|
||||
LinkedList()
|
||||
: size(0), start(nullptr), end(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
LinkedList(const LinkedList& list)
|
||||
: start(nullptr), end(nullptr), size(list.size)
|
||||
{
|
||||
const Link<T>* rLast = list.start;
|
||||
Link<T>* last = new Link<T>(rLast->value);
|
||||
start = last;
|
||||
|
||||
while (rLast->child)
|
||||
{
|
||||
last->child = new Link<T>(rLast->child->value);
|
||||
last = last->child;
|
||||
rLast = rLast->child;
|
||||
}
|
||||
|
||||
end = last;
|
||||
}
|
||||
|
||||
LinkedList(LinkedList&& list) noexcept
|
||||
: start(list.start), end(list.end), size(list.size)
|
||||
{
|
||||
list.start = nullptr;
|
||||
list.end = nullptr;
|
||||
list.size = {};
|
||||
}
|
||||
|
||||
LinkedList& operator=(const LinkedList& list)
|
||||
{
|
||||
if (this == &list)
|
||||
return *this;
|
||||
|
||||
const Link<T>* rLast = list.start;
|
||||
Link<T>* last = new Link<T>(rLast->value);
|
||||
start = last;
|
||||
|
||||
while (rLast->child)
|
||||
{
|
||||
last->child = new Link<T>(rLast->child->value);
|
||||
last = last->child;
|
||||
rLast = rLast->child;
|
||||
}
|
||||
|
||||
end = last;
|
||||
size = list.size;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
LinkedList& operator=(LinkedList&& list) noexcept
|
||||
{
|
||||
if (this == &list)
|
||||
return *this;
|
||||
|
||||
start = list.start;
|
||||
end = list.end;
|
||||
size = list.size;
|
||||
|
||||
list.start = nullptr;
|
||||
list.end = nullptr;
|
||||
list.size = {};
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
const Link<T>* operator[](const N index) const
|
||||
{
|
||||
const Link<T>* result = start;
|
||||
|
||||
for (N i = 0; i != index; ++i)
|
||||
result = result->child;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Link<T>* operator[](const N index)
|
||||
{
|
||||
Link<T>* result = start;
|
||||
|
||||
for (N i = 0; i != index; ++i)
|
||||
result = result->child;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
T& Insert(const N index, const T value)
|
||||
{
|
||||
if (index && index == size - 1)
|
||||
{
|
||||
end->child = new Link<T>(value);
|
||||
end = end->child;
|
||||
++size;
|
||||
return end->value;
|
||||
}
|
||||
else if (index)
|
||||
{
|
||||
Link<T>* hierarchy = start;
|
||||
for (N i = 0; i != index - 1; ++i)
|
||||
hierarchy = hierarchy->child;
|
||||
|
||||
hierarchy->child = new Link<T>(value, hierarchy->child);
|
||||
++size;
|
||||
return hierarchy->child->value;
|
||||
}
|
||||
else
|
||||
{
|
||||
start = new Link<T>(value, start);
|
||||
++size;
|
||||
return start->value;
|
||||
}
|
||||
}
|
||||
|
||||
T Remove(const N index)
|
||||
{
|
||||
if (index && index == size - 1)
|
||||
{
|
||||
Link<T>* hierarchy = start;
|
||||
while (hierarchy->child->child)
|
||||
hierarchy = hierarchy->child;
|
||||
|
||||
T result = end->value;
|
||||
delete end;
|
||||
end = hierarchy;
|
||||
--size;
|
||||
return result;
|
||||
}
|
||||
else if (index)
|
||||
{
|
||||
Link<T>* hierarchy = start;
|
||||
for (N i = 0; i != index - 1; ++i)
|
||||
hierarchy = hierarchy->child;
|
||||
|
||||
Link<T>* tmp = hierarchy->child;
|
||||
T result = tmp->value;
|
||||
hierarchy->child = hierarchy->child->child;
|
||||
tmp->child = nullptr;
|
||||
delete tmp;
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
Link<T>* tmp = start;
|
||||
T result = tmp->value;
|
||||
start = start->child;
|
||||
|
||||
if (--size)
|
||||
tmp->child = nullptr;
|
||||
else
|
||||
end = nullptr;
|
||||
|
||||
delete tmp;
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
T& Push(const T value)
|
||||
{
|
||||
if (size)
|
||||
{
|
||||
end->child = new Link<T>(value);
|
||||
end = end->child;
|
||||
++size;
|
||||
return end->value;
|
||||
}
|
||||
else
|
||||
{
|
||||
start = new Link<T>(value);
|
||||
end = start;
|
||||
size = 1;
|
||||
return start->value;
|
||||
}
|
||||
}
|
||||
|
||||
T Pop()
|
||||
{
|
||||
if (size == 1)
|
||||
{
|
||||
T result = start->value;
|
||||
delete start;
|
||||
start = nullptr;
|
||||
end = nullptr;
|
||||
size = 0;
|
||||
return result;
|
||||
}
|
||||
if (size > 1)
|
||||
{
|
||||
Link<T>* hierarchy = start;
|
||||
while (hierarchy->child->child)
|
||||
hierarchy = hierarchy->child;
|
||||
|
||||
T result = hierarchy->child->value;
|
||||
delete hierarchy->child;
|
||||
hierarchy->child = nullptr;
|
||||
end = hierarchy;
|
||||
return result;
|
||||
}
|
||||
else
|
||||
return {};
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
delete start;
|
||||
start = nullptr;
|
||||
end = nullptr;
|
||||
size = 0;
|
||||
}
|
||||
|
||||
N Size() const
|
||||
{
|
||||
return size;
|
||||
}
|
||||
};
|
214
src/Mat2.h
Normal file
214
src/Mat2.h
Normal file
@ -0,0 +1,214 @@
|
||||
#pragma once
|
||||
|
||||
#include "EHS.h"
|
||||
#include "Vec2.h"
|
||||
|
||||
template<typename T = float>
|
||||
class Mat2
|
||||
{
|
||||
private:
|
||||
T data[4];
|
||||
|
||||
public:
|
||||
Mat2()
|
||||
{
|
||||
for (UInt_8 i = 0; i < 4; ++i)
|
||||
data[i] = 0;
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
Mat2(const Mat2<C>& mat)
|
||||
{
|
||||
for (UInt_8 i = 0; i < 4; ++i)
|
||||
data[i] = mat.data[i];
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
Mat2<T>& operator=(const Mat2<C>& mat)
|
||||
{
|
||||
if (this == &mat)
|
||||
return *this;
|
||||
|
||||
for (UInt_8 i = 0; i < 4; ++i)
|
||||
data[i] = mat.data[i];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
operator const T*() const
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
operator T*()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
Vec2<T> operator*(Vec2<T> vec) const
|
||||
{
|
||||
Vec2<T> result;
|
||||
result.x = vec.x * data[0] + vec.y * data[2];
|
||||
result.y = vec.x * data[1] + vec.y * data[3];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Mat2<T>& operator*=(const T scalar)
|
||||
{
|
||||
for (UInt_8 i = 0; i < 4; ++i)
|
||||
data[i] *= scalar;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Mat2<T> operator*(const T scalar) const
|
||||
{
|
||||
Mat2<T> result;
|
||||
for (UInt_8 i = 0; i < 4; ++i)
|
||||
result.data[i] = data[i] * scalar;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Mat2<T>& operator*=(const Mat2<T>& mat)
|
||||
{
|
||||
Mat2<T> old = *this;
|
||||
for (UInt_8 i = 0; i < 4; ++i)
|
||||
{
|
||||
UInt_8 row = i / 2;
|
||||
UInt_8 column = i % 2;
|
||||
data[i] = 0;
|
||||
data[i] += old.data[0 * 2 + column] * mat.data[row * 2 + 0];
|
||||
data[i] += old.data[1 * 2 + column] * mat.data[row * 2 + 1];
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Mat2<T> operator*(const Mat2<T>& mat) const
|
||||
{
|
||||
Mat2<T> result;
|
||||
for (UInt_8 i = 0; i < 4; ++i)
|
||||
{
|
||||
UInt_8 row = i / 2;
|
||||
UInt_8 column = i % 2;
|
||||
result.data[i] += data[0 * 2 + column] * mat.data[row * 2 + 0];
|
||||
result.data[i] += data[1 * 2 + column] * mat.data[row * 2 + 1];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Mat2<T> GetTranspose() const
|
||||
{
|
||||
Mat2<T> result;
|
||||
for (UInt_8 i = 0; i < 4; ++i)
|
||||
result.data[i] = data[2 * (i % 2) + i / 2];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void Transpose()
|
||||
{
|
||||
Mat2<T> old = *this;
|
||||
for (UInt_8 i = 0; i < 4; ++i)
|
||||
data[i] = old.data[2 * (i % 2) + i / 2];
|
||||
}
|
||||
|
||||
Mat2<T> GetMinor() const
|
||||
{
|
||||
Mat2<T> result(0);
|
||||
result.data[0] = data[3];
|
||||
result.data[1] = data[2];
|
||||
result.data[2] = data[1];
|
||||
result.data[3] = data[0];
|
||||
return result;
|
||||
}
|
||||
|
||||
void Minor()
|
||||
{
|
||||
Mat2<T> old = *this;
|
||||
data[0] = old.data[3];
|
||||
data[1] = old.data[2];
|
||||
data[2] = old.data[1];
|
||||
data[3] = old.data[0];
|
||||
}
|
||||
|
||||
T GetDeterminant() const
|
||||
{
|
||||
return data[0] * data[3] - data[1] * data[2];
|
||||
}
|
||||
|
||||
Mat2<T> GetCofactor() const
|
||||
{
|
||||
Mat2<T> minor = GetMinor();
|
||||
Mat2<T> result;
|
||||
|
||||
for (UInt_8 r = 0; r < 2; ++r)
|
||||
{
|
||||
for (UInt_8 c = 0; c < 2; ++c)
|
||||
{
|
||||
UInt_8 i = 2 * c + r;
|
||||
result.data[i] = minor.data[i] * Math::Pow<T>(-1, r + c);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void Cofactor()
|
||||
{
|
||||
Mat2<T> minor = GetMinor();
|
||||
|
||||
for (UInt_8 r = 0; r < 2; ++r)
|
||||
{
|
||||
for (UInt_8 c = 0; c < 2; ++c)
|
||||
{
|
||||
UInt_8 i = 2 * c + r;
|
||||
data[i] = minor.data[i] * Math::Pow<T>(-1, r + c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Mat2<T> GetAdjugate() const
|
||||
{
|
||||
return GetCofactor().GetTranspose();
|
||||
}
|
||||
|
||||
void Adjugate()
|
||||
{
|
||||
Cofactor();
|
||||
Transpose();
|
||||
}
|
||||
|
||||
Mat2<T> GetInverse() const
|
||||
{
|
||||
T det = GetDeterminant();
|
||||
if (Math::ComCmp(det, 0.0f))
|
||||
return {};
|
||||
|
||||
return GetAdjugate() * (1 / det);
|
||||
}
|
||||
|
||||
void Inverse()
|
||||
{
|
||||
T det = GetDeterminant();
|
||||
if (Math::ComCmp(det, 0.0f))
|
||||
return;
|
||||
|
||||
Adjugate();
|
||||
operator*=(1 / det);
|
||||
}
|
||||
|
||||
static Mat2<T> Identity()
|
||||
{
|
||||
Mat2<T> result;
|
||||
result[0] = 1;
|
||||
result[3] = 1;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
typedef Mat2<float> Mat2_f;
|
||||
typedef Mat2<double> Mat2_d;
|
319
src/Mat3.h
Normal file
319
src/Mat3.h
Normal file
@ -0,0 +1,319 @@
|
||||
#pragma once
|
||||
|
||||
#include "EHS.h"
|
||||
#include "Vec3.h"
|
||||
#include "Mat2.h"
|
||||
|
||||
template<typename T = float>
|
||||
class Mat3
|
||||
{
|
||||
private:
|
||||
T data[9];
|
||||
|
||||
public:
|
||||
Mat3()
|
||||
{
|
||||
for (UInt_8 i = 0; i < 9; ++i)
|
||||
data[i] = 0;
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
Mat3(const Mat2<C>& mat)
|
||||
{
|
||||
for (UInt_8 i = 0; i < 4; ++i)
|
||||
data[i / 2 * 4 + i % 2] = mat.data[i];
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
Mat3(const Mat3<C>& mat)
|
||||
{
|
||||
for (UInt_8 i = 0; i < 9; ++i)
|
||||
data[i] = mat.data[i];
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
Mat3<T>& operator=(const Mat3<C>& mat)
|
||||
{
|
||||
if (this == &mat)
|
||||
return *this;
|
||||
|
||||
for (UInt_8 i = 0; i < 9; ++i)
|
||||
data[i] = mat.data[i];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
operator Mat2<T>() const
|
||||
{
|
||||
Mat2<T> result;
|
||||
|
||||
for (UInt_8 i = 0; i < 4; ++i)
|
||||
result.data[i] = data[i / 2 * 4 + i % 2];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
operator const T*() const
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
operator T*()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
Vec3<T> operator*(Vec3<T> vec) const
|
||||
{
|
||||
Vec3<T> result;
|
||||
result.x = vec.x * data[0] + vec.y * data[3] + vec.z * data[6];
|
||||
result.y = vec.x * data[1] + vec.y * data[4] + vec.z * data[7];
|
||||
result.z = vec.x * data[2] + vec.y * data[5] + vec.z * data[8];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Mat3<T>& operator*=(const T scalar)
|
||||
{
|
||||
for (UInt_8 i = 0; i < 9; ++i)
|
||||
data[i] *= scalar;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Mat3<T> operator*(const T scalar) const
|
||||
{
|
||||
Mat3<T> result;
|
||||
for (UInt_8 i = 0; i < 9; ++i)
|
||||
result.data[i] = data[i] * scalar;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Mat3<T>& operator*=(const Mat3<T>& mat)
|
||||
{
|
||||
Mat3<T> old = *this;
|
||||
for (UInt_8 i = 0; i < 9; ++i)
|
||||
{
|
||||
UInt_8 row = i / 3;
|
||||
UInt_8 column = i % 3;
|
||||
data[i] = 0;
|
||||
data[i] += old.data[0 * 3 + column] * mat.data[row * 3 + 0];
|
||||
data[i] += old.data[1 * 3 + column] * mat.data[row * 3 + 1];
|
||||
data[i] += old.data[2 * 3 + column] * mat.data[row * 3 + 2];
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Mat3<T> operator*(const Mat3<T>& mat) const
|
||||
{
|
||||
Mat3<T> result;
|
||||
for (UInt_8 i = 0; i < 9; ++i)
|
||||
{
|
||||
UInt_8 row = i / 3;
|
||||
UInt_8 column = i % 3;
|
||||
result.data[i] += data[0 * 3 + column] * mat.data[row * 3 + 0];
|
||||
result.data[i] += data[1 * 3 + column] * mat.data[row * 3 + 1];
|
||||
result.data[i] += data[2 * 3 + column] * mat.data[row * 3 + 2];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Mat3<T> GetTranspose() const
|
||||
{
|
||||
Mat3<T> result;
|
||||
for (UInt_8 i = 0; i < 9; ++i)
|
||||
result.data[i] = data[3 * (i % 3) + i / 3];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void Transpose()
|
||||
{
|
||||
Mat3<T> old = *this;
|
||||
for (UInt_8 i = 0; i < 9; ++i)
|
||||
data[i] = old.data[3 * (i % 3) + i / 3];
|
||||
}
|
||||
|
||||
Mat3<T> GetMinor() const
|
||||
{
|
||||
Mat3<T> result;
|
||||
|
||||
for (UInt_8 r = 0; r < 3; ++r)
|
||||
for (UInt_8 c = 0; c < 3; ++c)
|
||||
result[3 * r + c] = Cut(r, c).GetDeterminant();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void Minor()
|
||||
{
|
||||
Mat3<T> old = *this;
|
||||
|
||||
for (UInt_8 r = 0; r < 3; ++r)
|
||||
for (UInt_8 c = 0; c < 3; ++c)
|
||||
data[3 * r + c] = old.Cut(r, c).GetDeterminant();
|
||||
}
|
||||
|
||||
Mat2<T> Cut(const UInt_8 row, const UInt_8 column) const
|
||||
{
|
||||
Mat2<T> result;
|
||||
UInt_8 index = 0;
|
||||
|
||||
for (UInt_8 r = 0; r < 3; ++r)
|
||||
{
|
||||
for (UInt_8 c = 0; c < 3; ++c)
|
||||
{
|
||||
if (r == row || c == column)
|
||||
continue;
|
||||
|
||||
result[index++] = data[3 * r + c];
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
T GetDeterminant() const
|
||||
{
|
||||
Mat3<T> cofactor = GetCofactor();
|
||||
T result = 0;
|
||||
|
||||
for (UInt_8 c = 0; c < 3; ++c)
|
||||
result += data[c] * cofactor[c];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Mat3<T> GetCofactor() const
|
||||
{
|
||||
Mat3<T> minor = GetMinor();
|
||||
Mat3<T> result;
|
||||
|
||||
for (UInt_8 r = 0; r < 3; ++r)
|
||||
{
|
||||
for (UInt_8 c = 0; c < 3; ++c)
|
||||
{
|
||||
UInt_8 i = 3 * c + r;
|
||||
result.data[i] = minor.data[i] * Math::Pow<T>(-1, r + c);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void Cofactor()
|
||||
{
|
||||
Mat3<T> minor = GetMinor();
|
||||
|
||||
for (UInt_8 r = 0; r < 3; ++r)
|
||||
{
|
||||
for (UInt_8 c = 0; c < 3; ++c)
|
||||
{
|
||||
UInt_8 i = 3 * c + r;
|
||||
data[i] = minor.data[i] * Math::Pow<T>(-1, r + c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Mat3<T> GetAdjugate() const
|
||||
{
|
||||
return GetCofactor().GetTranspose();
|
||||
}
|
||||
|
||||
void Adjugate()
|
||||
{
|
||||
Cofactor();
|
||||
Transpose();
|
||||
}
|
||||
|
||||
Mat3<T> GetInverse() const
|
||||
{
|
||||
T det = GetDeterminant();
|
||||
if (Math::ComCmp(det, 0.0f))
|
||||
return {};
|
||||
|
||||
return GetAdjugate() * (1 / det);
|
||||
}
|
||||
|
||||
void Inverse()
|
||||
{
|
||||
T det = GetDeterminant();
|
||||
if (Math::ComCmp(det, 0.0f))
|
||||
return;
|
||||
|
||||
Adjugate();
|
||||
operator*=(1 / det);
|
||||
}
|
||||
|
||||
static Mat3<T> Identity()
|
||||
{
|
||||
Mat3<T> result;
|
||||
result.data[0] = 1;
|
||||
result.data[4] = 1;
|
||||
result.data[8] = 1;
|
||||
return result;
|
||||
}
|
||||
|
||||
static Mat3<T> Scale(const Vec3<T>& scale)
|
||||
{
|
||||
Mat3<T> result;
|
||||
result.data[0] = scale.x;
|
||||
result.data[4] = scale.y;
|
||||
result.data[8] = scale.z;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static Mat3<T> PitchRotate(const T angle)
|
||||
{
|
||||
T radians = Math::Rads(angle);
|
||||
|
||||
Mat3<T> result;
|
||||
result.data[0] = 1;
|
||||
result.data[4] = Math::Cos(radians);
|
||||
result.data[5] = Math::Sin(radians);
|
||||
result.data[7] = -Math::Sin(radians);
|
||||
result.data[8] = Math::Cos(radians);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static Mat3<T> YawRotate(const T angle)
|
||||
{
|
||||
T radians = Math::Rads(angle);
|
||||
|
||||
Mat3<T> result;
|
||||
result.data[0] = Math::Cos(radians);
|
||||
result.data[2] = -Math::Sin(radians);
|
||||
result.data[4] = 1;
|
||||
result.data[6] = Math::Sin(radians);
|
||||
result.data[8] = Math::Cos(radians);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static Mat3<T> RollRotate(const T angle)
|
||||
{
|
||||
T radians = Math::Rads(angle);
|
||||
|
||||
Mat3<T> result;
|
||||
result.data[0] = Math::Cos(radians);
|
||||
result.data[1] = Math::Sin(radians);
|
||||
result.data[3] = -Math::Sin(radians);
|
||||
result.data[4] = Math::Cos(radians);
|
||||
result.data[8] = 1;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static Mat3<T> Rotate(const Vec3<T>& vec)
|
||||
{
|
||||
return YawRotate(vec.y) * RollRotate(vec.z) * PitchRotate(vec.x);
|
||||
}
|
||||
};
|
||||
|
||||
typedef Mat3<float> Mat3_f;
|
||||
typedef Mat3<double> Mat3_d;
|
420
src/Mat4.h
Normal file
420
src/Mat4.h
Normal file
@ -0,0 +1,420 @@
|
||||
#pragma once
|
||||
|
||||
#include "EHS.h"
|
||||
#include "Math.h"
|
||||
#include "Mat3.h"
|
||||
#include "Vec4.h"
|
||||
#include "Vec3.h"
|
||||
|
||||
template <typename T = float>
|
||||
class Mat4
|
||||
{
|
||||
private:
|
||||
friend class Uniform;
|
||||
|
||||
T data[16];
|
||||
|
||||
public:
|
||||
Mat4()
|
||||
{
|
||||
for (UInt_8 i = 0; i < 16; ++i)
|
||||
data[i] = 0;
|
||||
}
|
||||
|
||||
explicit Mat4(const T* data)
|
||||
{
|
||||
for (UInt_8 i = 0; i < 16; ++i)
|
||||
this->data[i] = data[i];
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
Mat4(const Mat3<C>& mat)
|
||||
{
|
||||
for (UInt_8 i = 0; i < 9; ++i)
|
||||
{
|
||||
UInt_8 row = i / 3;
|
||||
UInt_8 column = i % 3;
|
||||
UInt_8 dst = row * 4 + column;
|
||||
|
||||
data[dst] = (T)mat[i];
|
||||
}
|
||||
|
||||
data[3] = 0;
|
||||
data[7] = 0;
|
||||
data[11] = 0;
|
||||
data[12] = 0;
|
||||
data[13] = 0;
|
||||
data[14] = 0;
|
||||
data[15] = 1;
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
Mat4(const Mat4<C>& mat)
|
||||
{
|
||||
for (UInt_8 i = 0; i < 16; ++i)
|
||||
data[i] = (T)mat.data[i];
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
Mat4<T>& operator=(const Mat4<C>& mat)
|
||||
{
|
||||
if (this == &mat)
|
||||
return *this;
|
||||
|
||||
for (UInt_8 i = 0; i < 16; ++i)
|
||||
data[i] = (T)mat.data[i];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec4<T> operator*(Vec4<T> vec) const
|
||||
{
|
||||
Vec4<T> result;
|
||||
result.x = vec.x * data[0] + vec.y * data[4] + vec.z * data[8] + vec.w * data[12];
|
||||
result.y = vec.x * data[1] + vec.y * data[5] + vec.z * data[9] + vec.w * data[13];
|
||||
result.z = vec.x * data[2] + vec.y * data[6] + vec.z * data[10] + vec.w * data[14];
|
||||
result.w = vec.x * data[3] + vec.y * data[7] + vec.z * data[11] + vec.w * data[15];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Mat4<T>& operator*=(const T scalar)
|
||||
{
|
||||
for (UInt_8 i = 0; i < 16; ++i)
|
||||
data[i] *= scalar;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Mat4<T> operator*(const T scalar) const
|
||||
{
|
||||
Mat4<T> result;
|
||||
for (UInt_8 i = 0; i < 16; ++i)
|
||||
result.data[i] = data[i] * scalar;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Mat4<T>& operator*=(const Mat4<T>& mat)
|
||||
{
|
||||
Mat4<T> old = *this;
|
||||
for (UInt_8 i = 0; i < 16; ++i)
|
||||
{
|
||||
UInt_8 row = i / 4;
|
||||
UInt_8 column = i % 4;
|
||||
data[i] += old.data[0 * 4 + column] * mat.data[row * 4 + 0];
|
||||
data[i] += old.data[1 * 4 + column] * mat.data[row * 4 + 1];
|
||||
data[i] += old.data[2 * 4 + column] * mat.data[row * 4 + 2];
|
||||
data[i] += old.data[3 * 4 + column] * mat.data[row * 4 + 3];
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Mat4<T> operator*(const Mat4<T>& mat) const
|
||||
{
|
||||
Mat4<T> result;
|
||||
for (UInt_8 i = 0; i < 16; ++i)
|
||||
{
|
||||
UInt_8 row = i / 4;
|
||||
UInt_8 column = i % 4;
|
||||
result.data[i] += data[0 * 4 + column] * mat.data[row * 4 + 0];
|
||||
result.data[i] += data[1 * 4 + column] * mat.data[row * 4 + 1];
|
||||
result.data[i] += data[2 * 4 + column] * mat.data[row * 4 + 2];
|
||||
result.data[i] += data[3 * 4 + column] * mat.data[row * 4 + 3];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
operator const T*() const
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
operator T*()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
Vec3<T> GetRight() const
|
||||
{
|
||||
return Vec3<T>(data[0], data[4], data[8]);
|
||||
}
|
||||
|
||||
Vec3<T> GetUp() const
|
||||
{
|
||||
return Vec3<T>(data[1], data[5], data[9]);
|
||||
}
|
||||
|
||||
Vec3<T> GetForward() const
|
||||
{
|
||||
return Vec3<T>(data[2], data[6], data[10]);
|
||||
}
|
||||
|
||||
Mat4<T> GetTranspose() const
|
||||
{
|
||||
Mat4<T> result;
|
||||
for (UInt_8 i = 0; i < 16; ++i)
|
||||
result.data[i] = data[4 * (i % 4) + i / 4];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void Transpose()
|
||||
{
|
||||
Mat4<T> old = *this;
|
||||
for (UInt_8 i = 0; i < 16; ++i)
|
||||
data[i] = old.data[4 * (i % 4) + i / 4];
|
||||
}
|
||||
|
||||
Mat3<T> Cut(const UInt_8 row, const UInt_8 column) const
|
||||
{
|
||||
Mat3<T> result;
|
||||
UInt_8 index = 0;
|
||||
|
||||
for (UInt_8 r = 0; r < 4; ++r)
|
||||
{
|
||||
for (UInt_8 c = 0; c < 4; ++c)
|
||||
{
|
||||
if (r == row || c == column)
|
||||
continue;
|
||||
|
||||
result[index++] = data[4 * r + c];
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Mat4<T> GetMinor() const
|
||||
{
|
||||
Mat4<T> result;
|
||||
|
||||
for (UInt_8 r = 0; r < 4; ++r)
|
||||
for (UInt_8 c = 0; c < 4; ++c)
|
||||
result.data[4 * r + c] = Cut(r, c).GetDeterminant();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void Minor()
|
||||
{
|
||||
Mat4<T> old = *this;
|
||||
|
||||
for (UInt_8 r = 0; r < 4; ++r)
|
||||
for (UInt_8 c = 0; c < 4; ++c)
|
||||
data[4 * r + c] = old.Cut(r, c).GetDeterminant();
|
||||
}
|
||||
|
||||
Mat4<T> GetCofactor() const
|
||||
{
|
||||
Mat4<T> minor = GetMinor();
|
||||
Mat4<T> result;
|
||||
|
||||
for (UInt_8 r = 0; r < 4; ++r)
|
||||
{
|
||||
for (UInt_8 c = 0; c < 4; ++c)
|
||||
{
|
||||
UInt_8 i = 4 * c + r;
|
||||
result.data[i] = minor.data[i] * Math::Pow<T>(-1, r + c);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void Cofactor()
|
||||
{
|
||||
Mat4<T> minor = GetMinor();
|
||||
|
||||
for (UInt_8 r = 0; r < 4; ++r)
|
||||
{
|
||||
for (UInt_8 c = 0; c < 4; ++c)
|
||||
{
|
||||
UInt_8 i = 4 * c + r;
|
||||
data[i] = minor.data[i] * Math::Pow<T>(-1, r + c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
T GetDeterminant() const
|
||||
{
|
||||
Mat4<T> cofactor = GetCofactor();
|
||||
T result = 0;
|
||||
|
||||
for (UInt_8 c = 0; c < 4; ++c)
|
||||
result += data[c] * cofactor[c];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Mat4<T> GetAdjugate() const
|
||||
{
|
||||
return GetCofactor().GetTranspose();
|
||||
}
|
||||
|
||||
void Adjugate()
|
||||
{
|
||||
Cofactor();
|
||||
Transpose();
|
||||
}
|
||||
|
||||
Mat4<T> GetInverse() const
|
||||
{
|
||||
T det = GetDeterminant();
|
||||
if (Math::ComCmp(det, 0.0f))
|
||||
return {};
|
||||
|
||||
return GetAdjugate() * (1 / det);
|
||||
}
|
||||
|
||||
void Inverse()
|
||||
{
|
||||
T det = GetDeterminant();
|
||||
if (Math::ComCmp(det, 0.0f))
|
||||
return;
|
||||
|
||||
Adjugate();
|
||||
operator*=(1 / det);
|
||||
}
|
||||
|
||||
static Mat4<T> Identity()
|
||||
{
|
||||
Mat4<T> result;
|
||||
result.data[0] = 1;
|
||||
result.data[5] = 1;
|
||||
result.data[10] = 1;
|
||||
result.data[15] = 1;
|
||||
return result;
|
||||
}
|
||||
|
||||
static Mat4<T> Scale(const Vec3<T>& scale)
|
||||
{
|
||||
Mat4<T> result;
|
||||
result.data[0] = scale.x;
|
||||
result.data[5] = scale.y;
|
||||
result.data[10] = scale.z;
|
||||
result.data[15] = 1;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static Mat4<T> Translate(const Vec3<T>& pos)
|
||||
{
|
||||
Mat4<T> result = Identity();
|
||||
result.data[12] = pos.x;
|
||||
result.data[13] = pos.y;
|
||||
result.data[14] = pos.z;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static Mat4<T> PitchRotate(const T angle)
|
||||
{
|
||||
T radians = Math::Rads(angle);
|
||||
|
||||
Mat4<T> result;
|
||||
result.data[0] = 1;
|
||||
result.data[5] = Math::Cos(radians);
|
||||
result.data[6] = Math::Sin(radians);
|
||||
result.data[9] = -Math::Sin(radians);
|
||||
result.data[10] = Math::Cos(radians);
|
||||
result.data[15] = 1;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static Mat4<T> YawRotate(const T angle)
|
||||
{
|
||||
T radians = Math::Rads(angle);
|
||||
|
||||
Mat4<T> result;
|
||||
result.data[0] = Math::Cos(radians);
|
||||
result.data[2] = -Math::Sin(radians);
|
||||
result.data[5] = 1;
|
||||
result.data[8] = Math::Sin(radians);
|
||||
result.data[10] = Math::Cos(radians);
|
||||
result.data[15] = 1;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static Mat4<T> RollRotate(const T angle)
|
||||
{
|
||||
T radians = Math::Rads(angle);
|
||||
|
||||
Mat4<T> result;
|
||||
result.data[0] = Math::Cos(radians);
|
||||
result.data[1] = Math::Sin(radians);
|
||||
result.data[4] = -Math::Sin(radians);
|
||||
result.data[5] = Math::Cos(radians);
|
||||
result.data[10] = 1;
|
||||
result.data[15] = 1;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static Mat4<T> Rotate(const Vec3<T>& vec)
|
||||
{
|
||||
return YawRotate(vec.y) * RollRotate(vec.z) * PitchRotate(vec.x);
|
||||
}
|
||||
|
||||
static Mat4<T> RH_Perspective(const T fov, const T aspect, const T zNear, const T zFar)
|
||||
{
|
||||
const float tanHalfFovy = tan(Math::Rads(fov) / 2.0f);
|
||||
|
||||
Mat4<T> result;
|
||||
result[0] = 1.0f / (aspect * tanHalfFovy);
|
||||
result[5] = -1.0f / tanHalfFovy;
|
||||
result[10] = zFar / (zFar - zNear);
|
||||
result[14] = -(zFar * zNear) / (zFar - zNear);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static Mat4<T> LH_Perspective(const T fov, const T aspect, const T zNear, const T zFar)
|
||||
{
|
||||
const float tanHalfFovy = Math::Tan(Math::Rads(fov) / 2.0f);
|
||||
|
||||
Mat4<T> result;
|
||||
result[0] = 1.0f / (aspect * tanHalfFovy);
|
||||
result[5] = -1.0f / tanHalfFovy;
|
||||
result[10] = zFar / (zFar - zNear);
|
||||
result[11] = 1.0f;
|
||||
result[14] = -(zFar * zNear) / (zFar - zNear);
|
||||
result[15] = 0.0f;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static Mat4<T> LH_Orthographic(const T left, const T right, const T top, const T bottom, const T zNear, const T zFar)
|
||||
{
|
||||
Mat4<T> result;
|
||||
result[0] = 2.0f / (right - left); // 0,0 entry
|
||||
result[5] = 2.0f / (bottom - top); // 1,1 entry
|
||||
result[10] = 1.0f / (zFar - zNear); // 2,2 entry
|
||||
result[12] = -(right + left) / (right - left); // 3,0 entry
|
||||
result[13] = -(bottom + top) / (bottom - top); // 3,1 entry
|
||||
result[14] = -zNear / (zFar - zNear); // 3,2 entry
|
||||
result[15] = 1.0f; // 3,3 entry
|
||||
|
||||
return result;
|
||||
|
||||
/*
|
||||
Mat4<T> result;
|
||||
result.data[0] = 2 / (right - left);
|
||||
result.data[5] = 2 / (top - bottom);
|
||||
result.data[10] = 1 / (zFar - zNear);
|
||||
result.data[12] = (left + right) / (left - right);
|
||||
result.data[13] = (top + bottom) / (bottom - top);
|
||||
result.data[14] = zNear / (zNear - zFar);
|
||||
result.data[15] = 1;
|
||||
|
||||
return result;
|
||||
*/
|
||||
}
|
||||
};
|
||||
|
||||
typedef Mat4<float> Mat4_f;
|
||||
typedef Mat4<double> Mat4_d;
|
87
src/Math.cpp
Normal file
87
src/Math.cpp
Normal file
@ -0,0 +1,87 @@
|
||||
#include "Math.h"
|
||||
|
||||
bool Math::AbsCmp(const float a, const float b)
|
||||
{
|
||||
return Abs(a - b) <= fltEpsilon;
|
||||
}
|
||||
|
||||
bool Math::AbsCmp(const double a, const double b)
|
||||
{
|
||||
return Abs(a - b) <= fltEpsilon;
|
||||
}
|
||||
|
||||
bool Math::RelCmp(const float a, const float b)
|
||||
{
|
||||
return Abs(a - b) <= fltEpsilon * Max(Abs(a), Abs(b));
|
||||
}
|
||||
|
||||
bool Math::RelCmp(const double a, const double b)
|
||||
{
|
||||
return Abs(a - b) <= fltEpsilon * Max(Abs(a), Abs(b));
|
||||
}
|
||||
|
||||
bool Math::ComCmp(const float a, const float b)
|
||||
{
|
||||
return Abs(a - b) <= fltEpsilon * Max(1.0f, Max(Abs(a), Abs(b)));
|
||||
}
|
||||
|
||||
bool Math::ComCmp(const double a, const double b)
|
||||
{
|
||||
return Abs(a - b) <= dblEpsilon * Max(1.0, Max(Abs(a), Abs(b)));
|
||||
}
|
||||
|
||||
double Math::Sqrt(const double from)
|
||||
{
|
||||
#if defined(ARCH_X64)
|
||||
if (CPU::HasAVX())
|
||||
return Sqrt_AVX(from);
|
||||
else if (CPU::HasSSE())
|
||||
return Sqrt_SSE2(from);
|
||||
|
||||
double temp = 0.0;
|
||||
double result = from / 2.0;
|
||||
|
||||
while (result != temp)
|
||||
{
|
||||
temp = result;
|
||||
result = (from / temp + temp) / 2.0;
|
||||
}
|
||||
|
||||
return result;
|
||||
#elif defined(ARCH_ARM64)
|
||||
return Sqrt_VFP4(from);
|
||||
#endif
|
||||
}
|
||||
|
||||
float Math::Sqrt(const float from)
|
||||
{
|
||||
#if defined(ARCH_X64)
|
||||
if (CPU::HasAVX())
|
||||
return Sqrt_AVX(from);
|
||||
else if (CPU::HasSSE())
|
||||
return Sqrt_SSE(from);
|
||||
|
||||
float temp = 0.0f;
|
||||
float result = from / 2.0f;
|
||||
|
||||
while (result != temp)
|
||||
{
|
||||
temp = result;
|
||||
result = (from / temp + temp) / 2.0f;
|
||||
}
|
||||
|
||||
return result;
|
||||
#elif defined(ARCH_ARM64)
|
||||
return Sqrt_VFP4(from);
|
||||
#endif
|
||||
}
|
||||
|
||||
float Math::Mod(const float from, const float divisor)
|
||||
{
|
||||
return from - Trunc(from / divisor) * divisor;
|
||||
}
|
||||
|
||||
double Math::Mod(const double from, const double divisor)
|
||||
{
|
||||
return from - Trunc(from / divisor) * divisor;
|
||||
}
|
313
src/Math.h
Normal file
313
src/Math.h
Normal file
@ -0,0 +1,313 @@
|
||||
#pragma once
|
||||
|
||||
#include "sys/cpu.h"
|
||||
|
||||
#define LOW_WORD(x) *((int*)&x) + 1
|
||||
|
||||
class Math
|
||||
{
|
||||
private:
|
||||
static float Sqrt_AVX(const float from);
|
||||
|
||||
static double Sqrt_AVX(const double from);
|
||||
|
||||
static float Sqrt_SSE(const float from);
|
||||
|
||||
static double Sqrt_SSE2(const double from);
|
||||
|
||||
static float Sqrt_VFP4(const float from);
|
||||
|
||||
static double Sqrt_VFP4(const double from);
|
||||
|
||||
public:
|
||||
constexpr static float fltEpsilon = 1e-7f;
|
||||
constexpr static double dblEpsilon = 1e-16;
|
||||
|
||||
/// Absolute tolerance comparison for single precision floats.
|
||||
static bool AbsCmp(const float a, const float b);
|
||||
|
||||
/// Absolute tolerance comparison for double precision floats.
|
||||
static bool AbsCmp(const double a, const double b);
|
||||
|
||||
/// Relative tolerance comparison for single precision floats.
|
||||
static bool RelCmp(const float a, const float b);
|
||||
|
||||
/// Relative tolerance comparison for double precision floats.
|
||||
static bool RelCmp(const double a, const double b);
|
||||
|
||||
/// Combined absolute and relative tolerance comparison for single precision floats.
|
||||
static bool ComCmp(const float a, const float b);
|
||||
|
||||
/// Combined absolute and relative tolerance comparison for double precision floats.
|
||||
static bool ComCmp(const double a, const double b);
|
||||
|
||||
template<typename T = float>
|
||||
static T Max(const T a, const T b)
|
||||
{
|
||||
return a > b ? a : b;
|
||||
}
|
||||
|
||||
template<typename T = float>
|
||||
static T Min(const T a, const T b)
|
||||
{
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
||||
template<typename T = float>
|
||||
static T Clamp(const T value, const T min, const T max)
|
||||
{
|
||||
if (value < min)
|
||||
return min;
|
||||
else if (value > max)
|
||||
return max;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
template<typename T = float>
|
||||
static T Abs(const T from)
|
||||
{
|
||||
return from < 0 ? -from : from;
|
||||
}
|
||||
|
||||
/// Retrieves a very accurate version of Pi as a long double and converts it.
|
||||
/// @tparam T The data type to return Pi as.
|
||||
/// @returns The result.
|
||||
template<typename T = float>
|
||||
static constexpr T Pi()
|
||||
{
|
||||
return (T)3.141592653589793238462643383279502884L;
|
||||
}
|
||||
|
||||
/// Converts degrees into radians.
|
||||
/// @tparam T The data type to return;
|
||||
/// @param [in] from The value to convert to radians.
|
||||
/// @returns The value in radians.
|
||||
template<typename T = float>
|
||||
static T Rads(const T from)
|
||||
{
|
||||
return from * 0.01745329251994329576923690768489;
|
||||
}
|
||||
|
||||
/// Converts radians into degrees.
|
||||
/// @tparam T The data type to return;
|
||||
/// @param [in] from The value to convert to degrees.
|
||||
/// @returns The value in degrees.
|
||||
template<typename T = float>
|
||||
static T Degr(const T from)
|
||||
{
|
||||
return from * 57.295779513082320876798154814105;
|
||||
}
|
||||
|
||||
/// A method for use of exponents.
|
||||
/// @tparam T The data type to return;
|
||||
/// @tparam I The data type to use as the exponent.
|
||||
/// @param [in] from The value to use the exponent on.
|
||||
/// @param [in] of The exponent.
|
||||
/// @returns The result.
|
||||
template<typename T = float, typename I = UInt_64>
|
||||
static T Pow(const T from, const I of)
|
||||
{
|
||||
if (of < 0)
|
||||
{
|
||||
if (from == 0)
|
||||
return -0;
|
||||
|
||||
return 1 / (from * Pow<T>(from, (-of) - 1));
|
||||
}
|
||||
|
||||
if (of == 0)
|
||||
return 1;
|
||||
else if (of == 1)
|
||||
return from;
|
||||
|
||||
return from * Pow<T>(from, of - 1);
|
||||
}
|
||||
|
||||
static float Near(const float from);
|
||||
|
||||
static double Near(const double from);
|
||||
|
||||
static float Floor(const float from);
|
||||
|
||||
static double Floor(const double from);
|
||||
|
||||
static float Ceil(const float from);
|
||||
|
||||
static double Ceil(const double from);
|
||||
|
||||
static float Trunc(const float from);
|
||||
|
||||
static double Trunc(const double from);
|
||||
|
||||
static float Mod(const float from, const float divisor);
|
||||
|
||||
static double Mod(const double from, const double divisor);
|
||||
|
||||
/// A method for retrieving the square root of a value.
|
||||
/// @tparam T The data type to use.
|
||||
/// @param [in] from The value to retrieve to square root of.
|
||||
/// @returns The result.
|
||||
template<typename T = float>
|
||||
static T Sqrt(const T from)
|
||||
{
|
||||
T temp = 0;
|
||||
T result = from / 2;
|
||||
|
||||
while (result != temp)
|
||||
{
|
||||
temp = result;
|
||||
result = (from / temp + temp) / 2;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static double Sqrt(const double from);
|
||||
|
||||
static float Sqrt(const float from);
|
||||
|
||||
template<typename R = float>
|
||||
static R Sin(const R angle, const R precision = 0.001)
|
||||
{
|
||||
R sum = angle;
|
||||
R term = angle;
|
||||
|
||||
for (UInt_64 i = 1; Abs<R>(term) >= precision; ++i)
|
||||
{
|
||||
term *= -angle * angle / (R)((2 * i + 1) * (2 * i));
|
||||
sum += term;
|
||||
}
|
||||
|
||||
return sum;
|
||||
|
||||
/*
|
||||
R sum = 0;
|
||||
|
||||
for (USize n = 0; n < precision; ++n)
|
||||
sum += Pow<R>(-1, n) / (R)Fact<T>(2 * n + 1) * Pow<R>(angle, 2 * n + 1);
|
||||
|
||||
return sum;
|
||||
*/
|
||||
}
|
||||
|
||||
template<typename R = float, typename T = UInt_64>
|
||||
static R ASin(const R yPos, const T precision = 10)
|
||||
{
|
||||
R sum = 0;
|
||||
|
||||
for (T n = 0; n < precision; ++n)
|
||||
sum += (R)Fact<T>(2 * n) / (Pow<R>(4, n) * Pow<R>((R)Fact<T>(n), 2) * (2 * n + 1)) * Pow<R>(yPos, 2 * n + 1);
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
/// A trigonometry Cosine function for finding the X-Axis position from the Z-Axis angle.
|
||||
/// @tparam R Input and result data type.
|
||||
/// @tparam T Precision data type.
|
||||
/// @param[in] angle The angle in radians from the Z-Axis.
|
||||
/// @param [in] precision Sigma max.
|
||||
/// @returns The X-Axis position.
|
||||
template<typename R = float>
|
||||
static R Cos(const R angle, const R precision = 0.001)
|
||||
{
|
||||
R sum = 1.0;
|
||||
R term = 1.0;
|
||||
|
||||
for (UInt_64 i = 2; Abs<R>(term) >= precision; i += 2)
|
||||
{
|
||||
term *= -angle * angle / (R)(i * (i - 1));
|
||||
sum += term;
|
||||
}
|
||||
|
||||
return sum;
|
||||
|
||||
/*
|
||||
R sum = 0;
|
||||
|
||||
for (T n = 0; n < precision; ++n)
|
||||
sum += Pow<R>(-1, n) / (R)Fact<T>(2 * n) * Pow<R>(angle, 2 * n);
|
||||
|
||||
return sum;
|
||||
*/
|
||||
}
|
||||
|
||||
/// A trigonometry Arc Cosine function for finding the Z-Axis angle form the X-Axis position.
|
||||
/// @tparam R Input and result data type.
|
||||
/// @tparam T Precision data type.
|
||||
/// @param [in] xPos The position from the X-Axis.
|
||||
/// @param [in] precision Sigma max.
|
||||
/// @returns The Z-Axis angle.
|
||||
template<typename R = float, typename T = UInt_64>
|
||||
static R ACos(const R xPos, const T precision = 10)
|
||||
{
|
||||
return Pi<R>() / 2 - ASin<R, T>(xPos, precision);
|
||||
}
|
||||
|
||||
template<typename R = float>
|
||||
static R Tan(const R angle, const R precision = 0.001)
|
||||
{
|
||||
/*
|
||||
R sum = 0;
|
||||
|
||||
for (T n = 1; n < precision + 1; ++n)
|
||||
sum += B<R>(2 * n) * Pow<R>(-4, n) * (1 - Pow<R>(4, n)) / (R)Fact<T>(2 * n) * Pow<R>(angle, 2 * n - 1);
|
||||
|
||||
return sum;
|
||||
*/
|
||||
return Sin<R>(angle) / Cos<R>(angle);
|
||||
}
|
||||
|
||||
template<typename R = float, typename T = UInt_64>
|
||||
static R ATan(const R x, const T precision = 1)
|
||||
{
|
||||
R sum = 0;
|
||||
|
||||
for (T n = 0; n < precision; ++n)
|
||||
sum += Pow<R>(-1, n) / (2 * n + 1) * Pow<R>(x, 2 * n + 1);
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
template<typename R = float>
|
||||
static R Cot(const R x, const R precision = 0.001)
|
||||
{
|
||||
return 1 / Tan<R>(x, precision);
|
||||
}
|
||||
|
||||
template<typename T = UInt_64>
|
||||
static T Fact(const T n)
|
||||
{
|
||||
if (n <= 1)
|
||||
return 1;
|
||||
|
||||
return n * Fact<T>(n - 1);
|
||||
}
|
||||
|
||||
template<typename R = float, typename T = UInt_64>
|
||||
static R Combination(const T n, const T k)
|
||||
{
|
||||
if (k <= n)
|
||||
return (R)Fact<T>(n) / (R)(Fact<T>(n - k) * Fact<T>(k));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename R = float, typename T = UInt_64>
|
||||
static R B(const T n)
|
||||
{
|
||||
R innerSum = 0;
|
||||
R outerSum = 0;
|
||||
|
||||
for (T k = 0; k <= n; ++k)
|
||||
{
|
||||
for (T r = 0; r <= k; ++r)
|
||||
innerSum += Pow<R, T>(-1, r) * Combination<R, T>(k, r) * Pow<R, T>(r, n);
|
||||
|
||||
outerSum += 1 / ((R)k + 1) * innerSum;
|
||||
innerSum = 0;
|
||||
}
|
||||
|
||||
return outerSum;
|
||||
}
|
||||
};
|
61
src/Math_GCC_AMD64.s
Normal file
61
src/Math_GCC_AMD64.s
Normal file
@ -0,0 +1,61 @@
|
||||
global _ZN3lwe4Math8Sqrt_AVXEf
|
||||
global _ZN3lwe4Math8Sqrt_AVXEd
|
||||
global _ZN3lwe4Math8Sqrt_SSEEf
|
||||
global _ZN3lwe4Math9Sqrt_SSE2Ed
|
||||
global _ZN3lwe4Math4NearEf
|
||||
global _ZN3lwe4Math4NearEd
|
||||
global _ZN3lwe4Math5FloorEf
|
||||
global _ZN3lwe4Math5FloorEd
|
||||
global _ZN3lwe4Math4CeilEf
|
||||
global _ZN3lwe4Math4CeilEd
|
||||
global _ZN3lwe4Math5TruncEf
|
||||
global _ZN3lwe4Math5TruncEd
|
||||
|
||||
section .text
|
||||
_ZN3lwe4Math8Sqrt_AVXEf:
|
||||
VSQRTPS XMM0, XMM0
|
||||
RET
|
||||
|
||||
_ZN3lwe4Math8Sqrt_AVXEd:
|
||||
VSQRTPD XMM0, XMM0
|
||||
RET
|
||||
|
||||
_ZN3lwe4Math8Sqrt_SSEEf:
|
||||
SQRTPS XMM0, XMM0
|
||||
RET
|
||||
|
||||
_ZN3lwe4Math9Sqrt_SSE2Ed:
|
||||
SQRTPD XMM0, XMM0
|
||||
RET
|
||||
|
||||
_ZN3lwe4Math4NearEf:
|
||||
ROUNDPS XMM0, XMM0, 0
|
||||
RET
|
||||
|
||||
_ZN3lwe4Math4NearEd:
|
||||
ROUNDPD XMM0, XMM0, 0
|
||||
RET
|
||||
|
||||
_ZN3lwe4Math5FloorEf:
|
||||
ROUNDPS XMM0, XMM0, 1
|
||||
RET
|
||||
|
||||
_ZN3lwe4Math5FloorEd:
|
||||
ROUNDPD XMM0, XMM0, 1
|
||||
RET
|
||||
|
||||
_ZN3lwe4Math4CeilEf:
|
||||
ROUNDPS XMM0, XMM0, 2
|
||||
RET
|
||||
|
||||
_ZN3lwe4Math4CeilEd:
|
||||
ROUNDPD XMM0, XMM0, 2
|
||||
RET
|
||||
|
||||
_ZN3lwe4Math5TruncEf:
|
||||
ROUNDPS XMM0, XMM0, 3
|
||||
RET
|
||||
|
||||
_ZN3lwe4Math5TruncEd:
|
||||
ROUNDPD XMM0, XMM0, 3
|
||||
RET
|
61
src/Math_MSVC_AMD64.s
Normal file
61
src/Math_MSVC_AMD64.s
Normal file
@ -0,0 +1,61 @@
|
||||
global ?Sqrt_AVX@Math@lwe@@CAMM@Z
|
||||
global ?Sqrt_AVX@Math@lwe@@CANN@Z
|
||||
global ?Sqrt_SSE@Math@lwe@@CAMM@Z
|
||||
global ?Sqrt_SSE2@Math@lwe@@CANN@Z
|
||||
global ?Near@Math@lwe@@SAMM@Z
|
||||
global ?Near@Math@lwe@@SANN@Z
|
||||
global ?Floor@Math@lwe@@SAMM@Z
|
||||
global ?Floor@Math@lwe@@SANN@Z
|
||||
global ?Ceil@Math@lwe@@SAMM@Z
|
||||
global ?Ceil@Math@lwe@@SANN@Z
|
||||
global ?Trunc@Math@lwe@@SAMM@Z
|
||||
global ?Trunc@Math@lwe@@SANN@Z
|
||||
|
||||
section .text
|
||||
?Sqrt_AVX@Math@lwe@@CAMM@Z:
|
||||
VSQRTPS XMM0, XMM0
|
||||
RET
|
||||
|
||||
?Sqrt_AVX@Math@lwe@@CANN@Z:
|
||||
VSQRTPD XMM0, XMM0
|
||||
RET
|
||||
|
||||
?Sqrt_SSE@Math@lwe@@CAMM@Z:
|
||||
SQRTPS XMM0, XMM0
|
||||
RET
|
||||
|
||||
?Sqrt_SSE2@Math@lwe@@CANN@Z:
|
||||
SQRTPD XMM0, XMM0
|
||||
RET
|
||||
|
||||
?Near@Math@lwe@@SAMM@Z:
|
||||
ROUNDPS XMM0, XMM0, 0
|
||||
RET
|
||||
|
||||
?Near@Math@lwe@@SANN@Z:
|
||||
ROUNDPD XMM0, XMM0, 0
|
||||
RET
|
||||
|
||||
?Floor@Math@lwe@@SAMM@Z:
|
||||
ROUNDPS XMM0, XMM0, 1
|
||||
RET
|
||||
|
||||
?Floor@Math@lwe@@SANN@Z:
|
||||
ROUNDPD XMM0, XMM0, 1
|
||||
RET
|
||||
|
||||
?Ceil@Math@lwe@@SAMM@Z:
|
||||
ROUNDPS XMM0, XMM0, 2
|
||||
RET
|
||||
|
||||
?Ceil@Math@lwe@@SANN@Z:
|
||||
ROUNDPD XMM0, XMM0, 2
|
||||
RET
|
||||
|
||||
?Trunc@Math@lwe@@SAMM@Z:
|
||||
ROUNDPS XMM0, XMM0, 3
|
||||
RET
|
||||
|
||||
?Trunc@Math@lwe@@SANN@Z:
|
||||
ROUNDPD XMM0, XMM0, 3
|
||||
RET
|
55
src/PRNG.h
Normal file
55
src/PRNG.h
Normal file
@ -0,0 +1,55 @@
|
||||
#pragma once
|
||||
|
||||
#include "EHS.h"
|
||||
|
||||
template<typename T>
|
||||
class PRNG
|
||||
{
|
||||
private:
|
||||
T seed;
|
||||
T last;
|
||||
|
||||
public:
|
||||
PRNG()
|
||||
: seed(0), last(0)
|
||||
{
|
||||
}
|
||||
|
||||
PRNG(const T seed)
|
||||
: seed(seed), last(seed)
|
||||
{
|
||||
}
|
||||
|
||||
PRNG(const PRNG& prng)
|
||||
: seed(prng.seed), last(prng.last)
|
||||
{
|
||||
}
|
||||
|
||||
PRNG& operator=(const PRNG& prng)
|
||||
{
|
||||
if (this == &prng)
|
||||
return *this;
|
||||
|
||||
seed = prng.seec;
|
||||
last = prng.last;
|
||||
}
|
||||
|
||||
T Generate(const T min, const T max)
|
||||
{
|
||||
return Generate() % (max - min) + min;
|
||||
}
|
||||
|
||||
T Generate()
|
||||
{
|
||||
return ((last = last * 214013 + 2531011) >> 16) & 0x7fff;
|
||||
}
|
||||
};
|
||||
|
||||
typedef PRNG<SInt_64> PRNG_s64;
|
||||
typedef PRNG<UInt_64> PRNG_u64;
|
||||
typedef PRNG<SInt_32> PRNG_s32;
|
||||
typedef PRNG<UInt_32> PRNG_u32;
|
||||
typedef PRNG<SInt_16> PRNG_s16;
|
||||
typedef PRNG<UInt_16> PRNG_u16;
|
||||
typedef PRNG<SInt_8> PRNG_s8;
|
||||
typedef PRNG<UInt_8> PRNG_u8;
|
393
src/Quat.h
Normal file
393
src/Quat.h
Normal file
@ -0,0 +1,393 @@
|
||||
#pragma once
|
||||
|
||||
#include "EHS.h"
|
||||
#include "Math.h"
|
||||
#include "Mat4.h"
|
||||
#include "Vec3.h"
|
||||
|
||||
template<typename T>
|
||||
class Quat
|
||||
{
|
||||
public:
|
||||
T w;
|
||||
T x;
|
||||
T y;
|
||||
T z;
|
||||
|
||||
Quat()
|
||||
: w(0), x(0), y(0), z(0)
|
||||
{
|
||||
}
|
||||
|
||||
Quat(const T w, const T x, const T y, const T z)
|
||||
: w(w), x(x), y(y), z(z)
|
||||
{
|
||||
}
|
||||
|
||||
Quat(const T yaw, const T pitch, const T roll)
|
||||
: w(0), x(0), y(0), z(0)
|
||||
{
|
||||
T c1 = cos(yaw / 2);
|
||||
T c2 = cos(pitch / 2);
|
||||
T c3 = cos(roll / 2);
|
||||
T s1 = sin(yaw / 2);
|
||||
T s2 = sin(pitch / 2);
|
||||
T s3 = sin(roll / 2);
|
||||
|
||||
w = c1 * c2 * c3 - s1 * s2 * s3;
|
||||
x = s1 * s2 * c3 + c1 * c2 * s3;
|
||||
y = s1 * c2 * c3 + c1 * s2 * s3;
|
||||
z = c1 * s2 * c3 - s1 * c2 * s3;
|
||||
}
|
||||
|
||||
explicit Quat(const Vec3<T>& euler)
|
||||
: w(0), x(0), y(0), z(0)
|
||||
{
|
||||
T c1 = cos(euler.x / 2);
|
||||
T c2 = cos(euler.y / 2);
|
||||
T c3 = cos(euler.z / 2);
|
||||
T s1 = sin(euler.x / 2);
|
||||
T s2 = sin(euler.y / 2);
|
||||
T s3 = sin(euler.z / 2);
|
||||
|
||||
w = c1 * c2 * c3 - s1 * s2 * s3;
|
||||
x = s1 * s2 * c3 + c1 * c2 * s3;
|
||||
y = s1 * c2 * c3 + c1 * s2 * s3;
|
||||
z = c1 * s2 * c3 - s1 * c2 * s3;
|
||||
}
|
||||
|
||||
Quat(const Vec3<T>& n, const T a)
|
||||
: w(cosf(a / 2)), x(n.x * sinf(a / 2)), y(n.y * sinf(a / 2)), z(n.z * sinf(a / 2))
|
||||
{
|
||||
}
|
||||
|
||||
explicit Quat(const Mat4<T>& rotMatrix)
|
||||
: w(0), x(0), y(0), z(0)
|
||||
{
|
||||
ToQuaternion(rotMatrix);
|
||||
}
|
||||
|
||||
Quat(const Quat& quat)
|
||||
: w(quat.w), x(quat.x), y(quat.y), z(quat.z)
|
||||
{
|
||||
}
|
||||
|
||||
explicit Quat(const T scalar)
|
||||
: w(scalar), x(scalar), y(scalar), z(scalar)
|
||||
{
|
||||
}
|
||||
|
||||
Quat& operator=(const Quat& quat)
|
||||
{
|
||||
if (this == &quat)
|
||||
return *this;
|
||||
|
||||
w = quat.w;
|
||||
x = quat.x;
|
||||
y = quat.y;
|
||||
z = quat.z;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Quat& operator=(const Mat4<T>& rotMatrix)
|
||||
{
|
||||
ToQuaternion(rotMatrix);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Quat operator+(const Quat& other) const
|
||||
{
|
||||
return {w + other.w, x + other.x, y + other.y, z + other.z};
|
||||
}
|
||||
|
||||
Quat operator-() const
|
||||
{
|
||||
return {-w, -x, -y, -z};
|
||||
}
|
||||
|
||||
Quat operator-(const Quat& other) const
|
||||
{
|
||||
return {w - other.w, x - other.x, y - other.y, z - other.z};
|
||||
}
|
||||
|
||||
Quat operator*(const T scalar)
|
||||
{
|
||||
return {w * scalar, x * scalar, x * scalar, x * scalar};
|
||||
}
|
||||
|
||||
Quat operator*(const Quat& other)
|
||||
{
|
||||
return Quat
|
||||
(
|
||||
w * other.w - x * other.x - y * other.y - z * other.z,
|
||||
w * other.x + x * other.w + y * other.z - z * other.y,
|
||||
w * other.y - x * other.z + y * other.w + z * other.x,
|
||||
w * other.z + x * other.y - y * other.x + z * other.w
|
||||
);
|
||||
}
|
||||
|
||||
Vec3<T> operator*(const Vec3<T>& vect)
|
||||
{
|
||||
Quat tmp(0, vect[0], vect[1], vect[2]);
|
||||
Vec3<T> tmpVect(x, y, z);
|
||||
|
||||
Vec3<T> vcV = tmpVect.CrossProduct(vect);
|
||||
return vect + vcV * (2 * w) + tmpVect.CrossProduct(vcV) * 2;
|
||||
}
|
||||
|
||||
Quat operator^(const T t)
|
||||
{
|
||||
Vec3<T> n;
|
||||
T a;
|
||||
|
||||
ToAxisAngle(&n, &a);
|
||||
|
||||
float at = a * t;
|
||||
|
||||
return Quat<T>(n, at);
|
||||
}
|
||||
|
||||
bool operator==(const Quat& quat) const
|
||||
{
|
||||
return w == quat.w && x == quat.x && y == quat.y && z == quat.z;
|
||||
}
|
||||
|
||||
bool operator!=(const Quat& quat) const
|
||||
{
|
||||
return w != quat.w || x != quat.x || y != quat.y || z == quat.z;
|
||||
}
|
||||
|
||||
T operator[](const UInt_64 index) const
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
return w;
|
||||
case 1:
|
||||
return x;
|
||||
case 2:
|
||||
return y;
|
||||
case 3:
|
||||
return z;
|
||||
default:
|
||||
return w;
|
||||
}
|
||||
}
|
||||
|
||||
T& operator[](const UInt_64 index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
return w;
|
||||
case 1:
|
||||
return x;
|
||||
case 2:
|
||||
return y;
|
||||
case 3:
|
||||
return z;
|
||||
default:
|
||||
return w;
|
||||
}
|
||||
}
|
||||
|
||||
void ToAxisAngle(Vec3<T>* vectAxis, T* flAngle)
|
||||
{
|
||||
Vec3<T> tmp(x, y, z);
|
||||
|
||||
if (tmp.GetDis2() < 0.0001f)
|
||||
*vectAxis = Vec3<T>(1, 0, 0);
|
||||
else
|
||||
*vectAxis = tmp.GetNorm();
|
||||
|
||||
*flAngle = acosf(w) * 2;
|
||||
*flAngle = Math::Degr<T>(*flAngle);
|
||||
}
|
||||
|
||||
void ToQuaternion(const Mat4<T>& rotMatrix)
|
||||
{
|
||||
T trace = rotMatrix[0][0] + rotMatrix[1][1] + rotMatrix[2][2];
|
||||
|
||||
if (trace > 0)
|
||||
{
|
||||
T s = 0.5f / Math::Sqrt<T>(trace + 1.0f);
|
||||
w = 0.25f / s;
|
||||
|
||||
x = (rotMatrix[2][1] - rotMatrix[1][2]) * s;
|
||||
y = (rotMatrix[0][2] - rotMatrix[2][0]) * s;
|
||||
z = (rotMatrix[1][0] - rotMatrix[0][1]) * s;
|
||||
} else
|
||||
{
|
||||
if ((rotMatrix[0][0] > rotMatrix[1][1]) && (rotMatrix[0][0] > rotMatrix[2][2]))
|
||||
{
|
||||
T s = 2.0f * Math::Sqrt(1.0f + rotMatrix[0][0] - rotMatrix[1][1] - rotMatrix[2][2]);
|
||||
w = (rotMatrix[2][1] - rotMatrix[1][2]) / s;
|
||||
x = 0.25f * s;
|
||||
y = (rotMatrix[0][1] + rotMatrix[1][0]) / s;
|
||||
z = (rotMatrix[0][2] + rotMatrix[2][0]) / s;
|
||||
} else if (rotMatrix[1][1] > rotMatrix[2][2])
|
||||
{
|
||||
T s = 2.0f * sqrtf(1.0f + rotMatrix[1][1] - rotMatrix[0][0] - rotMatrix[2][2]);
|
||||
w = (rotMatrix[0][2] - rotMatrix[2][0]) / s;
|
||||
x = (rotMatrix[0][1] + rotMatrix[1][0]) / s;
|
||||
y = 0.25f * s;
|
||||
z = (rotMatrix[1][2] + rotMatrix[2][1]) / s;
|
||||
} else
|
||||
{
|
||||
T s = 2.0f * sqrtf(1.0f + rotMatrix[2][2] - rotMatrix[0][0] - rotMatrix[1][1]);
|
||||
w = (rotMatrix[1][0] - rotMatrix[0][1]) / s;
|
||||
x = (rotMatrix[0][2] + rotMatrix[2][0]) / s;
|
||||
y = (rotMatrix[1][2] + rotMatrix[2][1]) / s;
|
||||
z = 0.25f * s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Vec3<T> ToEulerAngle() const
|
||||
{
|
||||
Vec3<T> euler;
|
||||
|
||||
float ysqr = y * y;
|
||||
|
||||
float t0 = 2 * (w * x + y * z);
|
||||
float t1 = 1 - 2 * (x * x + ysqr);
|
||||
euler.z = std::atan2(t0, t1);
|
||||
|
||||
float t2 = 2 * (w * y - z * x);
|
||||
t2 = t2 > 1 ? 1 : t2;
|
||||
t2 = t2 < -1 ? -1 : t2;
|
||||
euler.y = std::asin(t2);
|
||||
|
||||
float t3 = 2 * (w * z + x * y);
|
||||
float t4 = 1 - 2 * (ysqr + z * z);
|
||||
euler.x = std::atan2(t3, t4);
|
||||
|
||||
return euler;
|
||||
}
|
||||
*/
|
||||
|
||||
Mat4<T> ToMatrix() const
|
||||
{
|
||||
Mat4<T> result;
|
||||
|
||||
T x2 = x + x;
|
||||
T y2 = y + y;
|
||||
T z2 = z + z;
|
||||
T x2w = x2 * w;
|
||||
T y2w = y2 * w;
|
||||
T z2w = z2 * w;
|
||||
T x2x = x2 * x;
|
||||
T y2x = y2 * x;
|
||||
T z2x = z2 * x;
|
||||
T y2y = y2 * y;
|
||||
T z2y = z2 * y;
|
||||
T z2z = z2 * y;
|
||||
|
||||
result[0] = T(1) - (y2y + z2z);
|
||||
result[1] = y2x - z2w;
|
||||
result[2] = z2x + y2w;
|
||||
result[3] = T(0);
|
||||
|
||||
result[4] = y2x + z2w;
|
||||
result[5] = T(1) - (x2x + z2z);
|
||||
result[6] = z2y - x2w;
|
||||
result[7] = T(0);
|
||||
|
||||
result[8] = z2x - y2w;
|
||||
result[9] = z2y + x2w;
|
||||
result[10] = T(1) - (x2x + y2y);
|
||||
result[11] = T(0);
|
||||
|
||||
result[12] = T(0);
|
||||
result[13] = T(0);
|
||||
result[14] = T(0);
|
||||
result[15] = T(1);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
float GetMagnitude()
|
||||
{
|
||||
return Math::Sqrt<T>(Math::Pow<T>(w, 2) + Math::Pow<T>(x, 2) + Math::Pow<T>(y, 2) + Math::Pow<T>(z, 2));
|
||||
}
|
||||
|
||||
Quat<T> GetNormalized()
|
||||
{
|
||||
T mag = GetMagnitude();
|
||||
|
||||
return Quat<T>(w / mag, x / mag, y / mag, z / mag);
|
||||
}
|
||||
|
||||
void Normalize()
|
||||
{
|
||||
T mag = GetMagnitude();
|
||||
|
||||
w = w / mag;
|
||||
x = x / mag;
|
||||
y = y / mag;
|
||||
z = z / mag;
|
||||
}
|
||||
|
||||
T Dot(const Quat& other) const
|
||||
{
|
||||
return w * other.w + x * other.x + y * other.y + z * other.z;
|
||||
}
|
||||
|
||||
Quat<T> GetConjugate()
|
||||
{
|
||||
return Quat<T>(w, -x, -y, -z);
|
||||
}
|
||||
|
||||
void Conjugate()
|
||||
{
|
||||
x = -x;
|
||||
y = -y;
|
||||
z = -z;
|
||||
}
|
||||
|
||||
Quat<T> GetInverse()
|
||||
{
|
||||
return Quat<T>(w, -x, -y, -z);
|
||||
}
|
||||
|
||||
void Inverse()
|
||||
{
|
||||
x = -x;
|
||||
y = -y;
|
||||
z = -z;
|
||||
}
|
||||
|
||||
static Quat<T> Slerp(Quat<T> start, Quat<T> finish, const T t)
|
||||
{
|
||||
T cosHalfTheta = start.Dot(finish);
|
||||
if (Math::Abs(cosHalfTheta) >= 1.0f)
|
||||
return start;
|
||||
|
||||
float halfTheta = Math::ACos(cosHalfTheta);
|
||||
float sinHalfTheta = Math::Sqrt(1.0f - cosHalfTheta * cosHalfTheta);
|
||||
if (Math::Abs(sinHalfTheta) < 0.001f)
|
||||
{
|
||||
return {
|
||||
start.w * 0.5f + finish.w * 0.5f,
|
||||
start.x * 0.5f + finish.x * 0.5f,
|
||||
start.y * 0.5f + finish.y * 0.5f,
|
||||
start.z * 0.5f + finish.z * 0.5f
|
||||
};
|
||||
}
|
||||
|
||||
float ratioA = Math::Sin((1 - t) * halfTheta) / sinHalfTheta;
|
||||
float ratioB = Math::Sin(t * halfTheta) / sinHalfTheta;
|
||||
|
||||
return {
|
||||
start.w * ratioA + finish.w * ratioB,
|
||||
start.x * ratioA + finish.x * ratioB,
|
||||
start.y * ratioA + finish.y * ratioB,
|
||||
start.z * ratioA + finish.z * ratioB
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
typedef Quat<float> Quat_f;
|
5
src/Range.cpp
Normal file
5
src/Range.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
//
|
||||
// Created by Nelso on 3/29/2022.
|
||||
//
|
||||
|
||||
#include "Range.h"
|
25
src/Range.h
Normal file
25
src/Range.h
Normal file
@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
template<typename N>
|
||||
class Range
|
||||
{
|
||||
public:
|
||||
N min;
|
||||
N max;
|
||||
|
||||
Range()
|
||||
: min(0), max(0)
|
||||
{
|
||||
}
|
||||
|
||||
Range(const N min, const N max)
|
||||
: min(min), max(max)
|
||||
{
|
||||
}
|
||||
|
||||
Range(const Range& range)
|
||||
: min(range.min), max(range.max)
|
||||
{
|
||||
}
|
||||
};
|
181
src/Rect.h
Normal file
181
src/Rect.h
Normal file
@ -0,0 +1,181 @@
|
||||
#pragma once
|
||||
|
||||
#include "EHS.h"
|
||||
#include "Vec2.h"
|
||||
#include "Vec3.h"
|
||||
#include "Vec4.h"
|
||||
|
||||
template<typename T>
|
||||
class Rect
|
||||
{
|
||||
public:
|
||||
T x;
|
||||
T y;
|
||||
T w;
|
||||
T h;
|
||||
|
||||
Rect(const T scalar = 0)
|
||||
: x(scalar), y(scalar), w(scalar), h(scalar)
|
||||
{
|
||||
}
|
||||
|
||||
Rect(const T x, const T y, const T w, const T h)
|
||||
: x(x), y(y), w(w), h(h)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
Rect(const Vec2<C>& vec, const T w = 0, const T h = 0)
|
||||
: x((T)vec.x), y((T)vec.y), w(w), h(h)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
Rect(const Vec3<C>& vec, const T h = 0)
|
||||
: x((T)vec.x), y((T)vec.y), w((T)vec.z), h(h)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
Rect(const Vec4<C>& vec)
|
||||
: x((T)vec.x), y((T)vec.y), w((T)vec.z), h((T)vec.w)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
Rect(const Rect<C>& rect)
|
||||
: x((T)rect.x), y((T)rect.y), w((T)rect.w), h((T)rect.h)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
Rect<T>& operator=(const Vec2<C>& vec)
|
||||
{
|
||||
x = (T)vec.x;
|
||||
y = (T)vec.y;
|
||||
w = 0;
|
||||
h = 0;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
Rect<T>& operator=(const Vec3<C>& vec)
|
||||
{
|
||||
x = (T)vec.x;
|
||||
y = (T)vec.y;
|
||||
w = (T)vec.z;
|
||||
h = 0;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
Rect<T>& operator=(const Vec4<C>& vec)
|
||||
{
|
||||
x = (T)vec.x;
|
||||
y = (T)vec.y;
|
||||
w = (T)vec.z;
|
||||
h = (T)vec.w;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
Rect<T>& operator=(const Rect<C>& rect)
|
||||
{
|
||||
if (this == &rect)
|
||||
return *this;
|
||||
|
||||
x = (T)rect.x;
|
||||
y = (T)rect.y;
|
||||
w = (T)rect.w;
|
||||
h = (T)rect.h;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const Vec4<T>& vec)
|
||||
{
|
||||
return x == vec.x && y == vec.y && w == vec.z && h == vec.w;
|
||||
}
|
||||
|
||||
bool operator!=(const Vec4<T>& vec)
|
||||
{
|
||||
return x != vec.x || y != vec.y || w != vec.z || h != vec.w;
|
||||
}
|
||||
|
||||
bool operator==(const Rect<T>& rect)
|
||||
{
|
||||
return x == rect.x && y == rect.y && w == rect.w && h == rect.h;
|
||||
}
|
||||
|
||||
bool operator!=(const Rect<T>& rect)
|
||||
{
|
||||
return x != rect.x || y != rect.y || w != rect.w || h != rect.h;
|
||||
}
|
||||
|
||||
T operator[](const UInt_64 index) const
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
return x;
|
||||
case 1:
|
||||
return y;
|
||||
case 2:
|
||||
return w;
|
||||
case 3:
|
||||
return h;
|
||||
default:
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
T& operator[](const UInt_64 index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
return x;
|
||||
case 1:
|
||||
return y;
|
||||
case 2:
|
||||
return w;
|
||||
case 3:
|
||||
return h;
|
||||
default:
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
operator Vec4<T>()
|
||||
{
|
||||
return Vec4<T>(x, y, w, h);
|
||||
}
|
||||
|
||||
Vec2<T> GetPos() const
|
||||
{
|
||||
return {x, y};
|
||||
}
|
||||
|
||||
Vec2<T> GetScale() const
|
||||
{
|
||||
return {w, h};
|
||||
}
|
||||
};
|
||||
|
||||
typedef Rect<UInt_64> Rect_u64;
|
||||
typedef Rect<SInt_64> Rect_s64;
|
||||
typedef Rect<Int_64> Rect_64;
|
||||
typedef Rect<UInt_32> Rect_u32;
|
||||
typedef Rect<SInt_32> Rect_s32;
|
||||
typedef Rect<Int_32> Rect_32;
|
||||
typedef Rect<UInt_16> Rect_u16;
|
||||
typedef Rect<SInt_16> Rect_s16;
|
||||
typedef Rect<Int_16> Rect_16;
|
||||
typedef Rect<UInt_8> Rect_u8;
|
||||
typedef Rect<SInt_8> Rect_s8;
|
||||
typedef Rect<Int_8> Rect_8;
|
||||
typedef Rect<float> Rect_f;
|
||||
typedef Rect<double> Rect_d;
|
105
src/SArray.h
Normal file
105
src/SArray.h
Normal file
@ -0,0 +1,105 @@
|
||||
#pragma once
|
||||
|
||||
#include "EHS.h"
|
||||
|
||||
/// This container is useful for sorting arrays efficiently.
|
||||
template<typename T, typename N = UInt_64>
|
||||
class SArray
|
||||
{
|
||||
private:
|
||||
T* data;
|
||||
N size;
|
||||
|
||||
public:
|
||||
~SArray()
|
||||
{
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
SArray()
|
||||
: data(nullptr), size(0)
|
||||
{
|
||||
}
|
||||
|
||||
SArray(const N size)
|
||||
: data(new T[size]), size(size)
|
||||
{
|
||||
}
|
||||
|
||||
SArray(const SArray& sArray)
|
||||
: data(new T[sArray.size]), size(sArray.size)
|
||||
{
|
||||
for (N i = 0; i < size; ++i)
|
||||
data[i] = sArray.data[i];
|
||||
}
|
||||
|
||||
SArray(SArray&& sArray) noexcept
|
||||
: data(sArray.data), size(sArray.size)
|
||||
{
|
||||
sArray.data = nullptr;
|
||||
sArray.size = 0;
|
||||
}
|
||||
|
||||
SArray& operator=(const SArray& pArray)
|
||||
{
|
||||
if (this == &pArray)
|
||||
return *this;
|
||||
|
||||
delete[] data;
|
||||
data = new T[pArray.size];
|
||||
for (N i = 0; i < pArray.size; ++i)
|
||||
data[i] = pArray.data[i];
|
||||
|
||||
size = pArray.size;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
SArray& operator=(SArray&& pArray) noexcept
|
||||
{
|
||||
if (this == &pArray)
|
||||
return *this;
|
||||
|
||||
delete[] data;
|
||||
data = pArray.data;
|
||||
size = pArray.size;
|
||||
|
||||
pArray.data = nullptr;
|
||||
pArray.size = 0;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
operator const T* () const
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
operator T* ()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
void Insert(const N index, T value)
|
||||
{
|
||||
if (index >= size)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (N i = size; i > index + 1; --i)
|
||||
data[i - 1] = std::move(data[i - 2]);
|
||||
|
||||
data[index] = std::move(value);
|
||||
}
|
||||
|
||||
void SetSize(const N newSize)
|
||||
{
|
||||
size = newSize;
|
||||
}
|
||||
|
||||
N Size() const
|
||||
{
|
||||
return size;
|
||||
}
|
||||
};
|
1122
src/Serializer.h
Normal file
1122
src/Serializer.h
Normal file
File diff suppressed because it is too large
Load Diff
109
src/Util.cpp
Normal file
109
src/Util.cpp
Normal file
@ -0,0 +1,109 @@
|
||||
#include "Util.h"
|
||||
|
||||
bool Util::IsEqual(const void* const a, const void* const b, const UInt_64 size)
|
||||
{
|
||||
Byte* aBytes = (Byte*)a;
|
||||
Byte* bBytes = (Byte*)b;
|
||||
UInt_64 remainder = size;
|
||||
UInt_64 i = 0;
|
||||
|
||||
while (i < size)
|
||||
{
|
||||
if (remainder >= sizeof(UInt_64))
|
||||
{
|
||||
if (*(UInt_64*)&aBytes[i] != *(UInt_64*)&bBytes[i])
|
||||
return false;
|
||||
|
||||
i += sizeof(UInt_64);
|
||||
}
|
||||
else if (remainder >= sizeof(UInt_32))
|
||||
{
|
||||
if (*(UInt_32*)&aBytes[i] != *(UInt_32*)&bBytes[i])
|
||||
return false;
|
||||
|
||||
i += sizeof(UInt_32);
|
||||
}
|
||||
else if (remainder >= sizeof(UInt_16))
|
||||
{
|
||||
if (*(UInt_16*)&aBytes[i] != *(UInt_16*)&bBytes[i])
|
||||
return false;
|
||||
|
||||
i += sizeof(UInt_16);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (aBytes[i] != bBytes[i])
|
||||
return false;
|
||||
|
||||
i += sizeof(Byte);
|
||||
}
|
||||
|
||||
remainder = size - i;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Util::Copy(void* const out, const void* const in, const UInt_64 size)
|
||||
{
|
||||
Byte* outB = (Byte*)out;
|
||||
Byte* inB = (Byte*)in;
|
||||
UInt_64 remainder = size;
|
||||
|
||||
UInt_64 i = 0;
|
||||
while (i < size)
|
||||
{
|
||||
if (remainder >= sizeof(UInt_64))
|
||||
{
|
||||
*(UInt_64*)&outB[i] = *(UInt_64*)&inB[i];
|
||||
i += sizeof(UInt_64);
|
||||
}
|
||||
else if (remainder >= sizeof(UInt_32))
|
||||
{
|
||||
*(UInt_32*)&outB[i] = *(UInt_32*)&inB[i];
|
||||
i += sizeof(UInt_32);
|
||||
}
|
||||
else if (remainder >= sizeof(UInt_16))
|
||||
{
|
||||
*(UInt_16*)&outB[i] = *(UInt_16*)&inB[i];
|
||||
i += sizeof(UInt_16);
|
||||
}
|
||||
else
|
||||
{
|
||||
outB[i++] = inB[i];
|
||||
}
|
||||
|
||||
remainder = size - i;
|
||||
}
|
||||
}
|
||||
|
||||
void Util::Zero(void* const in, const UInt_64 size)
|
||||
{
|
||||
Byte* inB = (Byte*)in;
|
||||
UInt_64 remainder = size;
|
||||
UInt_64 i = 0;
|
||||
while (i < size)
|
||||
{
|
||||
if (remainder >= sizeof(UInt_64))
|
||||
{
|
||||
*(UInt_64*)&inB[i] = 0;
|
||||
i += sizeof(UInt_64);
|
||||
}
|
||||
else if (remainder >= sizeof(UInt_32))
|
||||
{
|
||||
*(UInt_32*)&inB[i] = 0;
|
||||
i += sizeof(UInt_32);
|
||||
}
|
||||
else if (remainder >= sizeof(UInt_16))
|
||||
{
|
||||
*(UInt_16*)&inB[i] = 0;
|
||||
i += sizeof(UInt_16);
|
||||
}
|
||||
else
|
||||
{
|
||||
inB[i++] = 0;
|
||||
}
|
||||
|
||||
remainder = size - i;
|
||||
}
|
||||
}
|
13
src/Util.h
Normal file
13
src/Util.h
Normal file
@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "EHS.h"
|
||||
|
||||
class Util
|
||||
{
|
||||
public:
|
||||
static bool IsEqual(const void* const a, const void* const b, const UInt_64 size);
|
||||
|
||||
static void Copy(void* const out, const void* const in, const UInt_64 size);
|
||||
|
||||
static void Zero(void* const in, const UInt_64 size);
|
||||
};
|
375
src/Vec2.h
Normal file
375
src/Vec2.h
Normal file
@ -0,0 +1,375 @@
|
||||
#pragma once
|
||||
|
||||
#include "EHS.h"
|
||||
#include "UTF.h"
|
||||
#include "Str.h"
|
||||
#include "Math.h"
|
||||
|
||||
template<typename T = float>
|
||||
class Vec2
|
||||
{
|
||||
public:
|
||||
T x;
|
||||
T y;
|
||||
|
||||
Vec2(const T x, const T y)
|
||||
: x(x), y(y)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
Vec2(const Vec2<C>& vec)
|
||||
: x((T)vec.x), y((T)vec.y)
|
||||
{
|
||||
}
|
||||
|
||||
Vec2(const T scalar = 0)
|
||||
: x(scalar), y(scalar)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
Vec2<T>& operator=(const Vec2<C>& vec)
|
||||
{
|
||||
x = (T)vec.x;
|
||||
y = (T)vec.y;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const Vec2<T>& vec) const
|
||||
{
|
||||
return Math::ComCmp(x, vec.x) && Math::ComCmp(x, vec.y);
|
||||
}
|
||||
|
||||
bool operator!=(const Vec2<T>& vec) const
|
||||
{
|
||||
return !Math::ComCmp(x, vec.x) || !Math::ComCmp(x, vec.y);
|
||||
}
|
||||
|
||||
Vec2<T>& operator+=(const Vec2<T>& vec)
|
||||
{
|
||||
x += vec.x;
|
||||
y += vec.y;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec2<T> operator+(const Vec2<T>& vec) const
|
||||
{
|
||||
Vec2<T> tmp;
|
||||
|
||||
tmp.x = x + vec.x;
|
||||
tmp.y = y + vec.y;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
Vec2<T>& operator+=(const T scalar)
|
||||
{
|
||||
x += scalar;
|
||||
y += scalar;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec2<T> operator+(const T scalar) const
|
||||
{
|
||||
Vec2<T> tmp;
|
||||
|
||||
tmp.x = x + scalar;
|
||||
tmp.y = y + scalar;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
Vec2<T>& operator-=(const Vec2<T>& vec)
|
||||
{
|
||||
x -= vec.x;
|
||||
y -= vec.y;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec2<T> operator-(const Vec2<T>& vec) const
|
||||
{
|
||||
Vec2<T> tmp;
|
||||
|
||||
tmp.x = x - vec.x;
|
||||
tmp.y = y - vec.y;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
Vec2<T>& operator-=(const T scalar)
|
||||
{
|
||||
x -= scalar;
|
||||
y -= scalar;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec2<T> operator-(const T scalar) const
|
||||
{
|
||||
Vec2<T> tmp;
|
||||
|
||||
tmp.x = x - scalar;
|
||||
tmp.y = y - scalar;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
Vec2<T>& operator/=(const Vec2<T>& vec)
|
||||
{
|
||||
x /= vec.x;
|
||||
y /= vec.y;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec2<T> operator/(const Vec2<T>& vec) const
|
||||
{
|
||||
Vec2<T> tmp;
|
||||
|
||||
tmp.x = x / vec.x;
|
||||
tmp.y = y / vec.y;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
Vec2<T>& operator/=(const T scalar)
|
||||
{
|
||||
x /= scalar;
|
||||
y /= scalar;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec2<T> operator/(const T scalar) const
|
||||
{
|
||||
|
||||
Vec2<T> tmp;
|
||||
|
||||
tmp.x = x / scalar;
|
||||
tmp.y = y / scalar;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
Vec2<T>& operator*=(const Vec2<T>& vec)
|
||||
{
|
||||
x *= vec.x;
|
||||
y *= vec.y;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec2<T> operator*(const Vec2<T>& vec) const
|
||||
{
|
||||
Vec2<T> tmp;
|
||||
|
||||
tmp.x = x * vec.x;
|
||||
tmp.y = y * vec.y;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
Vec2<T>& operator*=(const T scalar)
|
||||
{
|
||||
x *= scalar;
|
||||
y *= scalar;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec2<T> operator*(const T scalar) const
|
||||
{
|
||||
Vec2<T> tmp;
|
||||
|
||||
tmp.x = x * scalar;
|
||||
tmp.y = y * scalar;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
bool operator<=(const Vec2<T>& other) const
|
||||
{
|
||||
return x <= other.x && y <= other.y;
|
||||
}
|
||||
|
||||
bool operator<(const Vec2<T>& other) const
|
||||
{
|
||||
return x < other.x && y < other.y;
|
||||
}
|
||||
|
||||
bool operator>=(const Vec2<T>& other) const
|
||||
{
|
||||
return x >= other.x && y >= other.y;
|
||||
}
|
||||
|
||||
bool operator>(const Vec2<T>& other) const
|
||||
{
|
||||
return x > other.x && y > other.y;
|
||||
}
|
||||
|
||||
T operator[](const UInt_64 index) const
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
return x;
|
||||
case 1:
|
||||
return y;
|
||||
default:
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
T& operator[](const UInt_64 index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
return x;
|
||||
case 1:
|
||||
return y;
|
||||
default:
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
Vec2<T> GetAbs() const
|
||||
{
|
||||
Vec2<T> tmp;
|
||||
|
||||
tmp.x = Math::Abs(x);
|
||||
tmp.y = Math::Abs(y);
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void Abs()
|
||||
{
|
||||
x = Math::Abs(x);
|
||||
y = Math::Abs(y);
|
||||
}
|
||||
|
||||
/// If positive, the vectors are pointing in the same direction. If negative, the vectors are pointing in opposing directions.
|
||||
/// If zero, the vectors are perpendicular.
|
||||
T GetDot(const Vec2<T>& vec) const
|
||||
{
|
||||
return x * vec.x + y * vec.y;
|
||||
}
|
||||
|
||||
T GetAngle(const Vec2<T>& vec) const
|
||||
{
|
||||
return Math::ACos(GetDot(vec) / Math::Sqrt(GetMagnitude2() * vec.GetMagnitude2()));
|
||||
}
|
||||
|
||||
Vec2<T> GetProjection(const Vec2<T>& length) const
|
||||
{
|
||||
return operator*(length.GetDot(*this) / GetMagnitude2());
|
||||
}
|
||||
|
||||
Vec2<T> GetPerpendicular(const Vec2<T>& length) const
|
||||
{
|
||||
return length - GetProjection(length);
|
||||
}
|
||||
|
||||
Vec2<T> GetReflection(const Vec2<T>& normal) const
|
||||
{
|
||||
return operator-(normal * (GetDot(normal) * 2));
|
||||
}
|
||||
|
||||
T GetMagnitude() const
|
||||
{
|
||||
return Math::Sqrt(x * x + y * y);
|
||||
}
|
||||
|
||||
T GetMagnitude2() const
|
||||
{
|
||||
return x * x + y * y;
|
||||
}
|
||||
|
||||
T GetDistance(const Vec2<T>& vec) const
|
||||
{
|
||||
return Math::Sqrt(Math::Pow(vec.x - x, 2) + Math::Pow(vec.y - y, 2));
|
||||
}
|
||||
|
||||
T GetDistance2(const Vec2<T>& vec) const
|
||||
{
|
||||
return Math::Pow(vec.x - x, 2) + Math::Pow(vec.y - y, 2);
|
||||
}
|
||||
|
||||
Vec2<T> GetNorm() const
|
||||
{
|
||||
Vec2<T> norm;
|
||||
|
||||
T dis = GetMagnitude();
|
||||
|
||||
norm.x = x / dis;
|
||||
norm.y = y / dis;
|
||||
|
||||
return norm;
|
||||
}
|
||||
|
||||
void Norm()
|
||||
{
|
||||
T dis = GetMagnitude();
|
||||
|
||||
x /= dis;
|
||||
y /= dis;
|
||||
}
|
||||
|
||||
Vec2<T> GetRads() const
|
||||
{
|
||||
Vec2<T> tmp;
|
||||
|
||||
tmp.x = Math::Rads(x);
|
||||
tmp.y = Math::Rads(y);
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void ToRads()
|
||||
{
|
||||
x = Math::Rads(x);
|
||||
y = Math::Rads(y);
|
||||
}
|
||||
|
||||
Vec2<T> GetDegr() const
|
||||
{
|
||||
Vec2<T> tmp;
|
||||
|
||||
tmp.x = Math::Degr(x);
|
||||
tmp.y = Math::Degr(y);
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void ToDegr()
|
||||
{
|
||||
x = Math::Degr(x);
|
||||
y = Math::Degr(y);
|
||||
}
|
||||
|
||||
static Vec2 Lerp(const Vec2& start, const Vec2& finish, const T t)
|
||||
{
|
||||
return start + (finish - start) * t;
|
||||
}
|
||||
};
|
||||
|
||||
typedef Vec2<UInt_64> Vec2_u64;
|
||||
typedef Vec2<SInt_64> Vec2_s64;
|
||||
typedef Vec2<Int_64> Vec2_64;
|
||||
typedef Vec2<UInt_32> Vec2_u32;
|
||||
typedef Vec2<SInt_32> Vec2_s32;
|
||||
typedef Vec2<Int_32> Vec2_32;
|
||||
typedef Vec2<UInt_16> Vec2_u16;
|
||||
typedef Vec2<SInt_16> Vec2_s16;
|
||||
typedef Vec2<Int_16> Vec2_16;
|
||||
typedef Vec2<UInt_8> Vec2_u8;
|
||||
typedef Vec2<SInt_8> Vec2_s8;
|
||||
typedef Vec2<Int_8> Vec2_8;
|
||||
typedef Vec2<float> Vec2_f;
|
||||
typedef Vec2<double> Vec2_d;
|
434
src/Vec3.h
Normal file
434
src/Vec3.h
Normal file
@ -0,0 +1,434 @@
|
||||
#pragma once
|
||||
|
||||
#include "EHS.h"
|
||||
#include "UTF.h"
|
||||
#include "Str.h"
|
||||
#include "Math.h"
|
||||
#include "Vec2.h"
|
||||
|
||||
template<typename T>
|
||||
class Vec3
|
||||
{
|
||||
public:
|
||||
T x;
|
||||
T y;
|
||||
T z;
|
||||
|
||||
Vec3(const T scalar = 0)
|
||||
: x(scalar), y(scalar), z(scalar)
|
||||
{
|
||||
}
|
||||
|
||||
Vec3(const T x, const T y, const T z)
|
||||
: x(x), y(y), z(z)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
Vec3(const Vec2<C>& vec, const T z = 0)
|
||||
: x((T)vec.x), y((T)vec.y), z(z)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
Vec3(const Vec3<C>& vec)
|
||||
: x((T)vec.x), y((T)vec.y), z((T)vec.z)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
Vec3<T>& operator=(const Vec2<C>& vec)
|
||||
{
|
||||
x = (T)vec.x;
|
||||
y = (T)vec.y;
|
||||
z = 0;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
Vec3<T>& operator=(const Vec3<C>& vec)
|
||||
{
|
||||
x = (T)vec.x;
|
||||
y = (T)vec.y;
|
||||
z = (T)vec.z;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const Vec3<T>& vec) const
|
||||
{
|
||||
return Math::ComCmp(x, vec.x) && Math::ComCmp(y, vec.y) && Math::ComCmp(z, vec.z);
|
||||
}
|
||||
|
||||
|
||||
bool operator!=(const Vec3<T>& vec) const
|
||||
{
|
||||
return !Math::ComCmp(z, vec.z) || !Math::ComCmp(y, vec.y) || !Math::ComCmp(z, vec.z);
|
||||
}
|
||||
|
||||
Vec3<T> operator+(const Vec3<T>& vec) const
|
||||
{
|
||||
Vec3<T> tmp;
|
||||
|
||||
tmp.x = x + vec.x;
|
||||
tmp.y = y + vec.y;
|
||||
tmp.z = z + vec.z;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
Vec3<T>& operator+=(const Vec3<T>& vec)
|
||||
{
|
||||
x += vec.x;
|
||||
y += vec.y;
|
||||
z += vec.z;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec3<T> operator+(const T scalar) const
|
||||
{
|
||||
Vec3<T> tmp;
|
||||
|
||||
tmp.x = x + scalar;
|
||||
tmp.y = y + scalar;
|
||||
tmp.z = z + scalar;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
Vec3<T>& operator+=(const T scalar)
|
||||
{
|
||||
x += scalar;
|
||||
y += scalar;
|
||||
z += scalar;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec3<T> operator-(const Vec3<T>& vec) const
|
||||
{
|
||||
Vec3<T> tmp;
|
||||
|
||||
tmp.x = x - vec.x;
|
||||
tmp.y = y - vec.y;
|
||||
tmp.z = z - vec.z;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
Vec3<T>& operator-=(const Vec3<T>& vec)
|
||||
{
|
||||
x -= vec.x;
|
||||
y -= vec.y;
|
||||
z -= vec.z;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec3<T> operator-(const T scalar) const
|
||||
{
|
||||
Vec3<T> tmp;
|
||||
|
||||
tmp.x = x - scalar;
|
||||
tmp.y = y - scalar;
|
||||
tmp.z = z - scalar;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
Vec3<T>& operator-=(const T scalar)
|
||||
{
|
||||
x -= scalar;
|
||||
y -= scalar;
|
||||
z -= scalar;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec3<T> operator*(const Vec3<T>& vec) const
|
||||
{
|
||||
Vec3<T> tmp;
|
||||
|
||||
tmp.x = x * vec.x;
|
||||
tmp.y = y * vec.y;
|
||||
tmp.z = z * vec.z;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
Vec3<T>& operator*=(const Vec3<T>& vec)
|
||||
{
|
||||
x *= vec.x;
|
||||
y *= vec.y;
|
||||
z *= vec.z;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec3<T> operator*(const T scalar) const
|
||||
{
|
||||
Vec3<T> tmp;
|
||||
|
||||
tmp.x = x * scalar;
|
||||
tmp.y = y * scalar;
|
||||
tmp.z = z * scalar;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
Vec3<T>& operator*=(const T scalar)
|
||||
{
|
||||
x *= scalar;
|
||||
y *= scalar;
|
||||
z *= scalar;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec3<T> operator/(const Vec3<T>& vec) const
|
||||
{
|
||||
Vec3<T> tmp;
|
||||
|
||||
tmp.x = x / vec.x;
|
||||
tmp.y = y / vec.y;
|
||||
tmp.z = z / vec.z;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
Vec3<T>& operator/=(const Vec3<T>& vec)
|
||||
{
|
||||
x /= vec.x;
|
||||
y /= vec.y;
|
||||
z /= vec.z;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec3<T> operator/(const T scalar) const
|
||||
{
|
||||
Vec3<T> tmp;
|
||||
|
||||
tmp.x = x / scalar;
|
||||
tmp.y = y / scalar;
|
||||
tmp.z = z / scalar;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
Vec3<T>& operator/=(const T scalar)
|
||||
{
|
||||
x /= scalar;
|
||||
y /= scalar;
|
||||
z /= scalar;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator<=(const Vec3<T>& other) const
|
||||
{
|
||||
return x <= other.x && y <= other.y && z <= other.z;
|
||||
}
|
||||
|
||||
bool operator<(const Vec3<T>& other) const
|
||||
{
|
||||
return x < other.x && y < other.y && z < other.z;
|
||||
}
|
||||
|
||||
bool operator>=(const Vec3<T>& other) const
|
||||
{
|
||||
return x >= other.x && y >= other.y && z >= other.z;
|
||||
}
|
||||
|
||||
bool operator>(const Vec3<T>& other) const
|
||||
{
|
||||
return x > other.x && y > other.y && z > other.z;
|
||||
}
|
||||
|
||||
T operator[](const UInt_64 index) const
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
return x;
|
||||
case 1:
|
||||
return y;
|
||||
case 2:
|
||||
return z;
|
||||
default:
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
T& operator[](const UInt_64 index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
return x;
|
||||
case 1:
|
||||
return y;
|
||||
case 2:
|
||||
return z;
|
||||
default:
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
operator Vec2<T>()
|
||||
{
|
||||
return Vec2<T>(x, y);
|
||||
}
|
||||
|
||||
Vec3<T> GetAbs() const
|
||||
{
|
||||
Vec3<T> absolute;
|
||||
|
||||
absolute.x = Math::Abs(x);
|
||||
absolute.y = Math::Abs(y);
|
||||
absolute.z = Math::Abs(z);
|
||||
|
||||
return absolute;
|
||||
}
|
||||
|
||||
void Abs()
|
||||
{
|
||||
x = Math::Abs(x);
|
||||
y = Math::Abs(y);
|
||||
z = Math::Abs(z);
|
||||
}
|
||||
|
||||
Vec3<T> GetNorm() const
|
||||
{
|
||||
Vec3<T> norm;
|
||||
|
||||
T dis = GetMagnitude();
|
||||
|
||||
norm.x = x / dis;
|
||||
norm.y = y / dis;
|
||||
norm.z = z / dis;
|
||||
|
||||
return norm;
|
||||
}
|
||||
|
||||
void Norm()
|
||||
{
|
||||
T dis = GetMagnitude();
|
||||
|
||||
x /= dis;
|
||||
y /= dis;
|
||||
z /= dis;
|
||||
}
|
||||
|
||||
Vec3<T> GetCross(const Vec3<T>& vec) const
|
||||
{
|
||||
return Vec3<T>(
|
||||
y * vec.z - z * vec.y,
|
||||
z * vec.x - x * vec.z,
|
||||
x * vec.y - y * vec.x
|
||||
);
|
||||
}
|
||||
|
||||
T GetDot(const Vec3<T>& vec) const
|
||||
{
|
||||
return x * vec.x + y * vec.y + z * vec.z;
|
||||
}
|
||||
|
||||
T GetAngle(const Vec2<T>& vec) const
|
||||
{
|
||||
return Math::ACos(GetDot(vec) / Math::Sqrt(GetMagnitude2() * vec.GetMagnitude2()));
|
||||
}
|
||||
|
||||
Vec2<T> GetProjection(const Vec2<T>& length) const
|
||||
{
|
||||
return operator*(length.GetDot(*this) / GetMagnitude2());
|
||||
}
|
||||
|
||||
Vec2<T> GetPerpendicular(const Vec2<T>& length) const
|
||||
{
|
||||
return length - GetProjection(length);
|
||||
}
|
||||
|
||||
Vec2<T> GetReflection(const Vec2<T>& normal) const
|
||||
{
|
||||
return operator-(normal * (GetDot(normal) * 2));
|
||||
}
|
||||
|
||||
T GetMagnitude() const
|
||||
{
|
||||
return Math::Sqrt(x * x + y * y + z * z);
|
||||
}
|
||||
|
||||
T GetMagnitude2() const
|
||||
{
|
||||
return x * x + y * y + z * z;
|
||||
}
|
||||
|
||||
T GetDistance(const Vec3<T>& vec) const
|
||||
{
|
||||
return (T)Math::Sqrt(Math::Pow<T>(vec.x - x, 2) + Math::Pow<T>(vec.y - y, 2) + Math::Pow<T>(vec.z - z, 2));
|
||||
}
|
||||
|
||||
T GetDistance2(const Vec3<T>& vec) const
|
||||
{
|
||||
return static_cast<T>(Math::Pow<T>(vec.x - x, 2) + Math::Pow<T>(vec.y - y, 2) + Math::Pow<T>(vec.z - z, 2));
|
||||
}
|
||||
|
||||
Vec3<T> GetRads() const
|
||||
{
|
||||
Vec3<T> tmp;
|
||||
|
||||
tmp.x = Math::Rads(x);
|
||||
tmp.y = Math::Rads(y);
|
||||
tmp.z = Math::Rads(z);
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void ToRads()
|
||||
{
|
||||
x = Math::Rads(x);
|
||||
y = Math::Rads(y);
|
||||
z = Math::Rads(z);
|
||||
}
|
||||
|
||||
Vec3<T> GetDegr() const
|
||||
{
|
||||
Vec3<T> tmp;
|
||||
|
||||
tmp.x = Math::Degr(x);
|
||||
tmp.y = Math::Degr(y);
|
||||
tmp.z = Math::Degr(z);
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void ToDegr()
|
||||
{
|
||||
x = Math::Degr(x);
|
||||
y = Math::Degr(y);
|
||||
z = Math::Degr(z);
|
||||
}
|
||||
|
||||
static Vec3 Lerp(const Vec3& start, const Vec3& finish, const T t)
|
||||
{
|
||||
return start + (finish - start) * t;
|
||||
}
|
||||
};
|
||||
|
||||
typedef Vec3<UInt_64> Vec3_u64;
|
||||
typedef Vec3<SInt_64> Vec3_s64;
|
||||
typedef Vec3<Int_64> Vec3_64;
|
||||
typedef Vec3<UInt_32> Vec3_u32;
|
||||
typedef Vec3<SInt_32> Vec3_s32;
|
||||
typedef Vec3<Int_32> Vec3_32;
|
||||
typedef Vec3<UInt_16> Vec3_u16;
|
||||
typedef Vec3<SInt_16> Vec3_s16;
|
||||
typedef Vec3<Int_16> Vec3_16;
|
||||
typedef Vec3<UInt_8> Vec3_u8;
|
||||
typedef Vec3<SInt_8> Vec3_s8;
|
||||
typedef Vec3<Int_8> Vec3_8;
|
||||
typedef Vec3<float> Vec3_f;
|
||||
typedef Vec3<double> Vec3_d;
|
339
src/Vec4.h
Normal file
339
src/Vec4.h
Normal file
@ -0,0 +1,339 @@
|
||||
#pragma once
|
||||
|
||||
#include "EHS.h"
|
||||
#include "UTF.h"
|
||||
#include "Str.h"
|
||||
#include "Math.h"
|
||||
#include "Vec2.h"
|
||||
#include "Vec3.h"
|
||||
|
||||
template<typename T>
|
||||
class Vec4
|
||||
{
|
||||
public:
|
||||
T x;
|
||||
T y;
|
||||
T z;
|
||||
T w;
|
||||
|
||||
Vec4(const T scalar = 0)
|
||||
: x(scalar), y(scalar), z(scalar), w(scalar)
|
||||
{
|
||||
}
|
||||
|
||||
Vec4(const T x, const T y, const T z, const T w)
|
||||
: x(x), y(y), z(z), w(w)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
Vec4(const Vec2<C>& vec, const T z = 0, const T w = 0)
|
||||
: x((T)vec.x), y((T)vec.y), z(z), w(w)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
Vec4(const Vec3<C>& vec, const T w = 1)
|
||||
: x((T)vec.x), y((T)vec.y), z((T)vec.z), w(w)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
Vec4(const Vec4<C>& vec)
|
||||
: x((T)vec.x), y((T)vec.y), z((T)vec.z), w((T)vec.w)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
Vec4<T>& operator=(const Vec2<C>& vec)
|
||||
{
|
||||
x = (T)vec.x;
|
||||
y = (T)vec.y;
|
||||
z = (T)0;
|
||||
w = (T)0;
|
||||
|
||||
return*this;
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
Vec4<T>& operator=(const Vec3<C>& vec)
|
||||
{
|
||||
x = (T)vec.x;
|
||||
y = (T)vec.y;
|
||||
z = (T)vec.z;
|
||||
w = (T)0;
|
||||
|
||||
return*this;
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
Vec4<T>& operator=(const Vec4<C>& vec)
|
||||
{
|
||||
x = (T)vec.x;
|
||||
y = (T)vec.y;
|
||||
z = (T)vec.z;
|
||||
w = (T)vec.w;
|
||||
|
||||
return*this;
|
||||
}
|
||||
|
||||
bool operator==(const Vec4<T>& vec)
|
||||
{
|
||||
return Math::ComCmp(x, vec.x) && Math::ComCmp(y, vec.y) && Math::ComCmp(z, vec.z) && Math::ComCmp(w, vec.w);
|
||||
}
|
||||
|
||||
bool operator!=(const Vec4<T>& vec)
|
||||
{
|
||||
return !Math::ComCmp(z, vec.z) || !Math::ComCmp(y, vec.y) || !Math::ComCmp(z, vec.z) || !Math::ComCmp(w, vec.w);
|
||||
}
|
||||
|
||||
Vec4<T>& operator+=(const Vec4<T>& vec)
|
||||
{
|
||||
x += vec.x;
|
||||
y += vec.y;
|
||||
z += vec.z;
|
||||
w += vec.w;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec4<T> operator+(const Vec4<T>& vec)
|
||||
{
|
||||
Vec4<T> tmp;
|
||||
|
||||
tmp.x = x + vec.x;
|
||||
tmp.y = y + vec.y;
|
||||
tmp.z = z + vec.z;
|
||||
tmp.w = w + vec.w;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
Vec4<T>& operator+=(const T scalar)
|
||||
{
|
||||
x += scalar;
|
||||
y += scalar;
|
||||
z += scalar;
|
||||
w += scalar;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec4<T> operator+(const T scalar)
|
||||
{
|
||||
Vec4<T> tmp;
|
||||
|
||||
tmp.x = x + scalar;
|
||||
tmp.y = y + scalar;
|
||||
tmp.z = z + scalar;
|
||||
tmp.w = w + scalar;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
Vec4<T>& operator-=(const Vec4<T>& vec)
|
||||
{
|
||||
x -= vec.x;
|
||||
y -= vec.y;
|
||||
z -= vec.z;
|
||||
w -= vec.w;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec4<T> operator-(const Vec4<T>& vec)
|
||||
{
|
||||
Vec4<T> tmp;
|
||||
|
||||
tmp.x = x - vec.x;
|
||||
tmp.y = y - vec.y;
|
||||
tmp.z = z - vec.z;
|
||||
tmp.w = w - vec.w;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
Vec4<T>& operator-=(const T scalar)
|
||||
{
|
||||
x -= scalar;
|
||||
y -= scalar;
|
||||
z -= scalar;
|
||||
w -= scalar;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec4<T> operator-(const T scalar)
|
||||
{
|
||||
Vec4<T> tmp;
|
||||
|
||||
tmp.x = x - scalar;
|
||||
tmp.y = y - scalar;
|
||||
tmp.z = z - scalar;
|
||||
tmp.w = w - scalar;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
Vec4<T>& operator*=(const Vec4<T>& vec)
|
||||
{
|
||||
x *= vec.x;
|
||||
y *= vec.y;
|
||||
z *= vec.z;
|
||||
w *= vec.w;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec4<T> operator*(const Vec4<T>& vec)
|
||||
{
|
||||
Vec4<T> tmp;
|
||||
|
||||
tmp.x = x * vec.x;
|
||||
tmp.y = y * vec.y;
|
||||
tmp.z = z * vec.z;
|
||||
tmp.w = w * vec.w;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
Vec4<T>& operator*=(const T scalar)
|
||||
{
|
||||
x *= scalar;
|
||||
y *= scalar;
|
||||
z *= scalar;
|
||||
w *= scalar;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec4<T> operator*(const T scalar)
|
||||
{
|
||||
Vec4<T> tmp;
|
||||
|
||||
tmp.x = x * scalar;
|
||||
tmp.y = y * scalar;
|
||||
tmp.z = z * scalar;
|
||||
tmp.w = w * scalar;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
Vec4<T>& operator/=(const Vec4<T>& vec)
|
||||
{
|
||||
x /= vec.x;
|
||||
y /= vec.y;
|
||||
z /= vec.z;
|
||||
w /= vec.w;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec4<T> operator/(const Vec4<T>& vec)
|
||||
{
|
||||
Vec4<T> tmp;
|
||||
|
||||
tmp.x = x / vec.x;
|
||||
tmp.y = y / vec.y;
|
||||
tmp.z = z / vec.z;
|
||||
tmp.w = w / vec.w;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
Vec4<T>& operator/=(const T scalar)
|
||||
{
|
||||
x /= scalar;
|
||||
y /= scalar;
|
||||
z /= scalar;
|
||||
w /= scalar;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec4<T> operator/(const T scalar)
|
||||
{
|
||||
Vec4<T> tmp;
|
||||
|
||||
tmp.x = x / scalar;
|
||||
tmp.y = y / scalar;
|
||||
tmp.z = z / scalar;
|
||||
tmp.w = w / scalar;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
T operator[](const UInt_64 index) const
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
return x;
|
||||
case 1:
|
||||
return y;
|
||||
case 2:
|
||||
return z;
|
||||
case 3:
|
||||
return w;
|
||||
default:
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
T& operator[](const UInt_64 index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
return x;
|
||||
case 1:
|
||||
return y;
|
||||
case 2:
|
||||
return z;
|
||||
case 3:
|
||||
return w;
|
||||
default:
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
operator Vec3<T>()
|
||||
{
|
||||
return Vec3<T>(x, y, z);
|
||||
}
|
||||
|
||||
operator Vec2<T>()
|
||||
{
|
||||
return Vec2<T>(x, y);
|
||||
}
|
||||
|
||||
T GetDotProduct(const Vec4<T>& vec) const
|
||||
{
|
||||
return x * vec.x + y * vec.y + z * vec.z + w * vec.w;
|
||||
}
|
||||
|
||||
T GetMagnitude() const
|
||||
{
|
||||
return Math::Sqrt(x * x + y * y + z * z + w * w);
|
||||
}
|
||||
|
||||
T GetMagnitude2() const
|
||||
{
|
||||
return x * x + y * y + z * z + w * w;
|
||||
}
|
||||
};
|
||||
|
||||
typedef Vec4<UInt_64> Vec4_u64;
|
||||
typedef Vec4<SInt_64> Vec4_s64;
|
||||
typedef Vec4<Int_64> Vec4_64;
|
||||
typedef Vec4<UInt_32> Vec4_u32;
|
||||
typedef Vec4<SInt_32> Vec4_s32;
|
||||
typedef Vec4<Int_32> Vec4_32;
|
||||
typedef Vec4<UInt_16> Vec4_u16;
|
||||
typedef Vec4<SInt_16> Vec4_s16;
|
||||
typedef Vec4<Int_16> Vec4_16;
|
||||
typedef Vec4<UInt_8> Vec4_u8;
|
||||
typedef Vec4<SInt_8> Vec4_s8;
|
||||
typedef Vec4<Int_8> Vec4_8;
|
||||
typedef Vec4<float> Vec4_f;
|
||||
typedef Vec4<double> Vec4_d;
|
587
src/Vector.h
Normal file
587
src/Vector.h
Normal file
@ -0,0 +1,587 @@
|
||||
#pragma once
|
||||
|
||||
#include "EHS.h"
|
||||
|
||||
#include <initializer_list>
|
||||
#include <utility>
|
||||
|
||||
/// An array with extra memory pre-allocated for fast pushes.
|
||||
/// @tparam T Array data type to use.
|
||||
/// @tparam N Number data type to use.
|
||||
/// @note If extra memory is set to five then each time that memory is filled it will add five extra.
|
||||
template<typename T, typename N = UInt_64>
|
||||
class Vector
|
||||
{
|
||||
protected:
|
||||
N rawSize;
|
||||
N size;
|
||||
N stride;
|
||||
T* data;
|
||||
|
||||
public:
|
||||
/// Frees any data created on the heap.
|
||||
~Vector()
|
||||
{
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
/// Default members initialization.
|
||||
Vector()
|
||||
: rawSize(0), size(0), stride(5), data(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
/// Initializes members for pre-allocated memory to write to later.
|
||||
/// @param [in] size The size of memory to pre-allocate.
|
||||
/// @param [in] stride The stride size of memory to pre-allocate.
|
||||
Vector(const N size, const N stride)
|
||||
: rawSize(size + stride), size(size), stride(stride), data(new T[rawSize])
|
||||
{
|
||||
}
|
||||
|
||||
/// Initializes this vector with an initializer list object.
|
||||
/// @param [in] list The given initializer list.
|
||||
/// @param [in] stride The extra amount of memory to allocate.
|
||||
Vector(std::initializer_list<T> list, const N stride = 5)
|
||||
: rawSize(0), size(list.size()), stride(stride), data(nullptr)
|
||||
{
|
||||
if (stride)
|
||||
{
|
||||
rawSize = list.size() / stride * stride;
|
||||
if (list.size() % stride)
|
||||
rawSize += stride;
|
||||
}
|
||||
else
|
||||
{
|
||||
rawSize = list.size();
|
||||
}
|
||||
|
||||
data = new T[rawSize];
|
||||
|
||||
N i = 0;
|
||||
for (auto v = list.begin(); v != list.end(); ++v)
|
||||
data[i++] = std::move(*v);
|
||||
}
|
||||
|
||||
/// Initializes members with given C-style array.
|
||||
/// @param [in] data The C-style array.
|
||||
/// @param [in] size The size of the given C-style array.
|
||||
/// @param [in] stride The size of the extra memory allocated.
|
||||
Vector(const T* data, const N size, const N stride)
|
||||
: rawSize(0), size(size), stride(stride), data(nullptr)
|
||||
{
|
||||
if (stride)
|
||||
{
|
||||
rawSize = size / stride * stride;
|
||||
if (size % stride)
|
||||
rawSize += stride;
|
||||
}
|
||||
else
|
||||
{
|
||||
rawSize = size;
|
||||
}
|
||||
|
||||
data = new T[rawSize];
|
||||
|
||||
for (N i = 0; i < size; ++i)
|
||||
this->data[i] = data[i];
|
||||
}
|
||||
|
||||
/// Copies all members from the given vector object.
|
||||
/// @param [in] vec The vector object to copy from.
|
||||
Vector(const Vector& vec)
|
||||
: rawSize(vec.rawSize), size(vec.size), stride(vec.stride), data(new T[rawSize])
|
||||
{
|
||||
for (N i = 0; i < size; ++i)
|
||||
data[i] = vec.data[i];
|
||||
}
|
||||
|
||||
Vector(Vector&& vec) noexcept
|
||||
: rawSize(vec.rawSize), size(vec.size), stride(vec.stride), data(vec.data)
|
||||
{
|
||||
vec.rawSize = 0;
|
||||
vec.size = 0;
|
||||
vec.stride = 0;
|
||||
vec.data = nullptr;
|
||||
}
|
||||
|
||||
/// Copies all members from the given vector object.
|
||||
/// @param [in] vec The vector object to copy from.
|
||||
/// @returns The vector that has been assigned to.
|
||||
Vector& operator=(const Vector& vec)
|
||||
{
|
||||
if (this == &vec)
|
||||
return *this;
|
||||
|
||||
rawSize = vec.rawSize;
|
||||
size = vec.size;
|
||||
stride = vec.stride;
|
||||
|
||||
delete[] data;
|
||||
data = new T[rawSize];
|
||||
|
||||
for (N i = 0; i < size; ++i)
|
||||
data[i] = vec.data[i];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vector& operator=(Vector&& vec) noexcept
|
||||
{
|
||||
if (this == &vec)
|
||||
return *this;
|
||||
|
||||
rawSize = vec.rawSize;
|
||||
size = vec.size;
|
||||
stride = vec.stride;
|
||||
delete[] data;
|
||||
data = vec.data;
|
||||
|
||||
vec.rawSize = 0;
|
||||
vec.size = 0;
|
||||
vec.stride = 0;
|
||||
vec.data = nullptr;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Adds a given initializer list at the end of the vector.
|
||||
/// @param [in] value The given initializer list to push to the end of the vector.
|
||||
Vector& operator+=(std::initializer_list<T> value)
|
||||
{
|
||||
if (size + value.size() >= rawSize)
|
||||
{
|
||||
if (stride)
|
||||
{
|
||||
rawSize = (size + value.size()) / stride * stride;
|
||||
if ((size + value.size()) % stride)
|
||||
rawSize += stride;
|
||||
}
|
||||
else
|
||||
{
|
||||
rawSize = size + value.size();
|
||||
}
|
||||
|
||||
T* result = new T[rawSize];
|
||||
|
||||
for (N i = 0; i < size; ++i)
|
||||
result[i] = std::move(std::move(data[i]));
|
||||
|
||||
delete[] data;
|
||||
data = result;
|
||||
}
|
||||
|
||||
for (auto v = value.begin(); v != value.end(); ++v)
|
||||
data[size++] = std::move(*v);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Adds a given value at the end of the vector.
|
||||
/// @param [in] value The given value to push to the end of the vector.
|
||||
Vector& operator+=(const T value)
|
||||
{
|
||||
if (size + 1 >= rawSize)
|
||||
{
|
||||
if (stride)
|
||||
rawSize = size + stride;
|
||||
else
|
||||
rawSize = size + 1;
|
||||
|
||||
T* result = new T[rawSize];
|
||||
|
||||
for (N i = 0; i < size; ++i)
|
||||
result[i] = std::move(data[i]);
|
||||
|
||||
delete[] data;
|
||||
data = result;
|
||||
}
|
||||
|
||||
data[size++] = std::move(value);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Retrieves the raw C-style array from casting an array object.
|
||||
operator T* () const
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
/// Retrieves the size of the vector object including the extra memory allocated.
|
||||
/// @returns The raw size.
|
||||
N RawSize() const
|
||||
{
|
||||
return rawSize;
|
||||
}
|
||||
|
||||
/// Retrieves the size of the array not including the extra memory allocated.
|
||||
/// @returns The size.
|
||||
N Size() const
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
/// Retrieves the size of the extra memory allocated.
|
||||
/// @returns The extra size.
|
||||
N Stride() const
|
||||
{
|
||||
return stride;
|
||||
}
|
||||
|
||||
N End() const
|
||||
{
|
||||
return size ? size - 1 : size;
|
||||
}
|
||||
|
||||
/// Copies a vector object with offsets.
|
||||
/// @param [in] dstOffset The offset index to copy the given vector object to.
|
||||
/// @param [in] src The given vector object.
|
||||
/// @param [in] srcOffset The offset index from the given vector object to copy from.
|
||||
void Copy(const N dstOffset, Vector<T, N> src, const N srcOffset = 0)
|
||||
{
|
||||
for (N i = 0; i < src.Size() - srcOffset; ++i)
|
||||
data[i + dstOffset] = std::move(src[i + srcOffset]);
|
||||
}
|
||||
|
||||
/// Copies a C-style array with offsets.
|
||||
/// @param [in] dstOffset The offset index to copy the given C-style array to.
|
||||
/// @param [in] src The given C-style array.
|
||||
/// @param [in] size The size from the given C-style array to copy.
|
||||
void Copy(const N dstOffset, const T* src, const N size)
|
||||
{
|
||||
for (N i = 0; i < size; ++i)
|
||||
data[i + dstOffset] = src[i];
|
||||
}
|
||||
|
||||
/// Swaps two values in the vector.
|
||||
/// @param [in] a The first index to swap with.
|
||||
/// @param [in] b The second index to swap with.
|
||||
void Swap(N a, N b)
|
||||
{
|
||||
T tmp = std::move(data[a]);
|
||||
|
||||
data[a] = std::move(data[b]);
|
||||
data[b] = std::move(tmp);
|
||||
}
|
||||
|
||||
/// Inserts a value at a specified index that is available.
|
||||
/// @param [in] index The index to insert the value at.
|
||||
/// @param [in] value The given value to insert.
|
||||
void Insert(const N index, const T value)
|
||||
{
|
||||
N newSize = 0;
|
||||
if (index > size - 1)
|
||||
newSize = size + ((index + 1) - size);
|
||||
else
|
||||
newSize = size + 1;
|
||||
|
||||
if (newSize >= rawSize)
|
||||
{
|
||||
if (stride)
|
||||
rawSize += newSize + stride;
|
||||
else
|
||||
rawSize = newSize;
|
||||
|
||||
T* result = new T[rawSize];
|
||||
|
||||
for (N i = 0; i < index; ++i)
|
||||
result[i] = std::move(data[i]);
|
||||
|
||||
result[index] = std::move(value);
|
||||
|
||||
for (N i = index; i < size; ++i)
|
||||
result[i + 1] = std::move(data[i]);
|
||||
|
||||
delete[] data;
|
||||
data = result;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (N i = index; i < size; ++i)
|
||||
data[i + 1] = std::move(data[i]);
|
||||
|
||||
data[index] = std::move(value);
|
||||
}
|
||||
|
||||
size += newSize;
|
||||
}
|
||||
|
||||
/// Removes a value at a specified index.
|
||||
/// @param [in] index The index to remove the value at.
|
||||
/// @returns The removed data.
|
||||
T Remove(const N index)
|
||||
{
|
||||
T popped = {};
|
||||
|
||||
if (!size || index >= size)
|
||||
return popped;
|
||||
|
||||
popped = std::move(data[index]);
|
||||
|
||||
if (!stride)
|
||||
{
|
||||
rawSize = size - 1;
|
||||
T* result = new T[rawSize];
|
||||
|
||||
for (N i = 0; i < index; ++i)
|
||||
result[i] = std::move(data[i]);
|
||||
|
||||
for (N i = index + 1; i < size; ++i)
|
||||
result[i - 1] = std::move(data[i]);
|
||||
|
||||
delete[] data;
|
||||
data = result;
|
||||
}
|
||||
else if (rawSize - stride && size - 1 <= rawSize - stride)
|
||||
{
|
||||
rawSize -= stride;
|
||||
T* result = new T[rawSize];
|
||||
|
||||
for (N i = 0; i < index; ++i)
|
||||
result[i] = std::move(data[i]);
|
||||
|
||||
for (N i = index + 1; i < size; ++i)
|
||||
result[i - 1] = std::move(data[i]);
|
||||
|
||||
delete[] data;
|
||||
data = result;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (N i = index + 1; i < size; ++i)
|
||||
data[i - 1] = std::move(data[i]);
|
||||
}
|
||||
|
||||
--size;
|
||||
|
||||
return popped;
|
||||
}
|
||||
|
||||
/// Adds a given C-style array at the end of the vector.
|
||||
/// @param [in] value The given C-style array to push to the end of the vector.
|
||||
/// @param [in] size The size of the given C-style array.
|
||||
void Push(const T* const value, const N size)
|
||||
{
|
||||
if (this->size + size >= rawSize)
|
||||
{
|
||||
if (stride)
|
||||
{
|
||||
rawSize = (this->size + size()) / stride * stride;
|
||||
if ((this->size + size) % stride)
|
||||
rawSize += stride;
|
||||
}
|
||||
else
|
||||
{
|
||||
rawSize = this->size + size;
|
||||
}
|
||||
|
||||
T* result = new T[rawSize];
|
||||
|
||||
for (N i = 0; i < size; ++i)
|
||||
result[i] = std::move(data[i]);
|
||||
|
||||
delete[] data;
|
||||
data = result;
|
||||
}
|
||||
|
||||
for (N i = 0; i < size; ++i)
|
||||
data[this->size + i] = value[i];
|
||||
|
||||
this->size += size;
|
||||
}
|
||||
|
||||
/// Adds a given vector object at the end of the vector.
|
||||
/// @param [in] value The given vector object to push to the end of the vector.
|
||||
void Push(Vector<T> value)
|
||||
{
|
||||
if (size + value.size >= rawSize)
|
||||
{
|
||||
if (stride)
|
||||
{
|
||||
rawSize = (size + value.size) / stride * stride;
|
||||
if ((size + value.size) % stride)
|
||||
rawSize += stride;
|
||||
}
|
||||
else
|
||||
{
|
||||
rawSize = size + value.size;
|
||||
}
|
||||
|
||||
T* result = new T[rawSize];
|
||||
|
||||
for (N i = 0; i < size; ++i)
|
||||
result[i] = std::move(data[i]);
|
||||
|
||||
delete[] data;
|
||||
data = result;
|
||||
}
|
||||
|
||||
for (N i = 0; i < value.size; ++i)
|
||||
data[size + i] = std::move(value.data[i]);
|
||||
|
||||
size += value.size;
|
||||
}
|
||||
|
||||
/// Adds a given initializer at the end of the vector.
|
||||
/// @param [in] value The given initializer list to push to the end of the vector.
|
||||
void Push(std::initializer_list<T> value)
|
||||
{
|
||||
if (size + value.size() >= rawSize)
|
||||
{
|
||||
if (stride)
|
||||
{
|
||||
rawSize = (size + value.size()) / stride * stride;
|
||||
if ((size + value.size()) % stride)
|
||||
rawSize += stride;
|
||||
}
|
||||
else
|
||||
{
|
||||
rawSize = size + value.size();
|
||||
}
|
||||
|
||||
T* result = new T[rawSize];
|
||||
|
||||
for (N i = 0; i < size; ++i)
|
||||
result[i] = std::move(data[i]);
|
||||
|
||||
delete[] data;
|
||||
data = result;
|
||||
}
|
||||
|
||||
for (auto v = value.begin(); v != value.end(); ++v)
|
||||
data[size++] = std::move(*v);
|
||||
}
|
||||
|
||||
/// Adds a given value at the end of the vector.
|
||||
/// @param [in] value The given value to push to the end of the vector.
|
||||
void Push(T value)
|
||||
{
|
||||
if (size + 1 >= rawSize)
|
||||
{
|
||||
if (stride)
|
||||
rawSize += stride;
|
||||
else
|
||||
rawSize = size + 1;
|
||||
|
||||
T* result = new T[rawSize];
|
||||
|
||||
for (N i = 0; i < size; ++i)
|
||||
result[i] = std::move(data[i]);
|
||||
|
||||
delete[] data;
|
||||
data = result;
|
||||
}
|
||||
|
||||
data[size++] = std::move(value);
|
||||
}
|
||||
|
||||
/// Much like the stack it pops a value at the end of the vector.
|
||||
/// @returns The removed data.
|
||||
T Pop()
|
||||
{
|
||||
T popped = {};
|
||||
|
||||
if (!size)
|
||||
return popped;
|
||||
|
||||
popped = std::move(data[--size]);
|
||||
|
||||
if (!stride)
|
||||
{
|
||||
rawSize = size;
|
||||
T* result = new T[rawSize];
|
||||
|
||||
for (N i = 0; i < size; ++i)
|
||||
result[i] = std::move(data[i]);
|
||||
|
||||
delete[] data;
|
||||
data = result;
|
||||
}
|
||||
else if (rawSize - stride && size < rawSize - stride)
|
||||
{
|
||||
rawSize -= stride;
|
||||
T* result = new T[rawSize];
|
||||
|
||||
for (N i = 0; i < size; ++i)
|
||||
result[i] = std::move(data[i]);
|
||||
|
||||
delete[] data;
|
||||
data = result;
|
||||
}
|
||||
|
||||
return popped;
|
||||
}
|
||||
|
||||
/// Resizes the vector while keeping its alignment.
|
||||
/// @param [in] newSize The size to change to.
|
||||
void Resize(const N newSize)
|
||||
{
|
||||
if (newSize == size)
|
||||
return;
|
||||
|
||||
if (stride)
|
||||
{
|
||||
rawSize = newSize / stride * stride;
|
||||
if (newSize % stride)
|
||||
rawSize += stride;
|
||||
}
|
||||
else
|
||||
{
|
||||
rawSize = newSize;
|
||||
}
|
||||
|
||||
T* result = new T[rawSize];
|
||||
|
||||
for (N i = 0; i < size && i < newSize; ++i)
|
||||
result[i] = std::move(data[i]);
|
||||
|
||||
delete[] data;
|
||||
data = result;
|
||||
size = newSize;
|
||||
}
|
||||
|
||||
/// Removes any extra allocated memory.
|
||||
void ExactSize()
|
||||
{
|
||||
if (!stride)
|
||||
return;
|
||||
|
||||
stride = 0;
|
||||
|
||||
if (size)
|
||||
{
|
||||
rawSize = size;
|
||||
T* result = new T[rawSize];
|
||||
|
||||
for (N i = 0; i < size; ++i)
|
||||
result[i] = std::move(data[i]);
|
||||
|
||||
delete[] data;
|
||||
data = result;
|
||||
}
|
||||
else
|
||||
{
|
||||
rawSize = 0;
|
||||
delete[] data;
|
||||
data = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/// Clears all values in the vector object.
|
||||
void Clear()
|
||||
{
|
||||
if (!size)
|
||||
return;
|
||||
|
||||
rawSize = stride;
|
||||
size = 0;
|
||||
|
||||
delete[] data;
|
||||
|
||||
if (rawSize)
|
||||
data = new T[rawSize];
|
||||
else
|
||||
data = nullptr;
|
||||
}
|
||||
};
|
68
src/Version.cpp
Normal file
68
src/Version.cpp
Normal file
@ -0,0 +1,68 @@
|
||||
#include "Version.h"
|
||||
|
||||
Version::Version()
|
||||
: major(0), minor(0), patch(0)
|
||||
{
|
||||
}
|
||||
|
||||
Version::Version(const unsigned int major, const unsigned int minor, const unsigned int patch)
|
||||
: major(major), minor(minor), patch(patch)
|
||||
{
|
||||
}
|
||||
|
||||
Version::Version(const Version& version)
|
||||
: major(version.major), minor(version.minor), patch(version.patch)
|
||||
{
|
||||
}
|
||||
|
||||
Version& Version::operator=(const Version& version)
|
||||
{
|
||||
if (this == &version)
|
||||
return *this;
|
||||
|
||||
major = version.major;
|
||||
minor = version.minor;
|
||||
patch = version.patch;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool Version::operator==(const Version& version) const
|
||||
{
|
||||
return major == version.major && minor == version.minor && patch == version.patch;
|
||||
}
|
||||
|
||||
bool Version::operator!=(const Version& version) const
|
||||
{
|
||||
return major != version.major || minor != version.minor || patch != version.patch;
|
||||
}
|
||||
|
||||
unsigned int Version::operator[](const unsigned int i) const
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
return major;
|
||||
case 1:
|
||||
return minor;
|
||||
case 2:
|
||||
return patch;
|
||||
default:
|
||||
return major;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int& Version::operator[](const unsigned int i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
return major;
|
||||
case 1:
|
||||
return minor;
|
||||
case 2:
|
||||
return patch;
|
||||
default:
|
||||
return major;
|
||||
}
|
||||
}
|
36
src/Version.h
Normal file
36
src/Version.h
Normal file
@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
/// A helper class for storing version major, minor and patch.
|
||||
class Version
|
||||
{
|
||||
public:
|
||||
unsigned int major;
|
||||
unsigned int minor;
|
||||
unsigned int patch;
|
||||
|
||||
/// Default members initialization.
|
||||
Version();
|
||||
|
||||
/// Initializes members with given major, minor and patch.
|
||||
/// @param [in] major The major version.
|
||||
/// @param [in] minor The minor version.
|
||||
/// @param [in] patch The patch version.
|
||||
Version(const unsigned int major, const unsigned int minor, const unsigned int patch);
|
||||
|
||||
/// Copies all members from the given version object.
|
||||
/// @param [in] version The version object to copy from.
|
||||
Version(const Version& version);
|
||||
|
||||
/// Copies all members from the given version object.
|
||||
/// @param [in] version The version object to copy from.
|
||||
/// @returns The version object that has been assigned to.
|
||||
Version& operator=(const Version& version);
|
||||
|
||||
bool operator==(const Version& version) const;
|
||||
|
||||
bool operator!=(const Version& version) const;
|
||||
|
||||
unsigned int operator[](const unsigned int i) const;
|
||||
|
||||
unsigned int& operator[](const unsigned int i);
|
||||
};
|
432
src/sys/CPU.cpp
Normal file
432
src/sys/CPU.cpp
Normal file
@ -0,0 +1,432 @@
|
||||
#include "CPU.h"
|
||||
|
||||
Architecture CPU::GetArchitecture()
|
||||
{
|
||||
#if defined(ARCH_X64)
|
||||
return Architecture::X64;
|
||||
#elif defined(ARCH_ARM64)
|
||||
return Architecture::ARM64;
|
||||
#else
|
||||
return Architecture::UNKNOWN;
|
||||
#endif
|
||||
}
|
||||
|
||||
UInt_8 CPU::PointerSize()
|
||||
{
|
||||
return sizeof(void*);
|
||||
}
|
||||
|
||||
Endianness CPU::GetEndianness()
|
||||
{
|
||||
#if defined(LITTLE_ENDIAN)
|
||||
return Endianness::LE;
|
||||
#elif defined(BIG_ENDIAN)
|
||||
return Endianness::BE;
|
||||
#else
|
||||
UInt_16 tmp = 1;
|
||||
if (((Byte*)&tmp)[0] == 1)
|
||||
return Endianness::LE;
|
||||
|
||||
return Endianness::BE;
|
||||
#endif
|
||||
}
|
||||
|
||||
UInt_64 CPU::GetTSC()
|
||||
{
|
||||
TSC tsc;
|
||||
RDTSCP(&tsc);
|
||||
|
||||
#if defined(ARCH_X64)
|
||||
UInt_64 result = 0;
|
||||
|
||||
#if defined(LITTLE_ENDIAN)
|
||||
((UInt_32*)&result)[0] = tsc.lowCount;
|
||||
((UInt_32*)&result)[1] = tsc.highCount;
|
||||
#elif defined(BIG_ENDIAN)
|
||||
((UInt_32*)&result)[0] = tsc.highCount;
|
||||
((UInt_32*)&result)[1] = tsc.lowCount;
|
||||
#endif
|
||||
|
||||
return result;
|
||||
#elif defined(ARCH_X86)
|
||||
return tsc.lowPart;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
UInt_8 CPU::GetSteppingId()
|
||||
{
|
||||
return (UInt_8)GetInfoBits() & 0x00001111;
|
||||
}
|
||||
|
||||
UInt_8 CPU::GetModelId()
|
||||
{
|
||||
return (UInt_8)GetInfoBits() & 0x11110000;
|
||||
}
|
||||
|
||||
UInt_8 CPU::GetFamilyId()
|
||||
{
|
||||
return (UInt_8)(GetInfoBits() >> 8) & 0x00001111;
|
||||
}
|
||||
|
||||
UInt_8 CPU::GetProcessorTypeId()
|
||||
{
|
||||
return (UInt_8)(GetInfoBits() >> 12) & 0x00000011;
|
||||
}
|
||||
|
||||
UInt_8 CPU::GetExtModelId()
|
||||
{
|
||||
return (UInt_8)(GetInfoBits() >> 16) & 0x00001111;
|
||||
}
|
||||
|
||||
UInt_8 CPU::GetExtFamilyId()
|
||||
{
|
||||
return (UInt_8)(GetInfoBits() >> 20);
|
||||
}
|
||||
|
||||
bool CPU::HasFPU()
|
||||
{
|
||||
return GetFeatureBits_1() & 0b00000000000000000000000000000001;
|
||||
}
|
||||
|
||||
bool CPU::HasVME()
|
||||
{
|
||||
return GetFeatureBits_1() & 0b00000000000000000000000000000010;
|
||||
}
|
||||
|
||||
bool CPU::HasDE()
|
||||
{
|
||||
return GetFeatureBits_1() & 0b00000000000000000000000000000100;
|
||||
}
|
||||
|
||||
bool CPU::HasPSE()
|
||||
{
|
||||
return GetFeatureBits_1() & 0b00000000000000000000000000001000;
|
||||
}
|
||||
|
||||
bool CPU::HasTSC()
|
||||
{
|
||||
return GetFeatureBits_1() & 0b00000000000000000000000000010000;
|
||||
}
|
||||
|
||||
bool CPU::HasMSR()
|
||||
{
|
||||
return GetFeatureBits_1() & 0b00000000000000000000000000100000;
|
||||
}
|
||||
|
||||
bool CPU::HasPAE()
|
||||
{
|
||||
return GetFeatureBits_1() & 0b00000000000000000000000001000000;
|
||||
}
|
||||
|
||||
bool CPU::HasMCE()
|
||||
{
|
||||
return GetFeatureBits_1() & 0b00000000000000000000000010000000;
|
||||
}
|
||||
|
||||
bool CPU::HasCX8()
|
||||
{
|
||||
return GetFeatureBits_1() & 0b00000000000000000000000100000000;
|
||||
}
|
||||
|
||||
bool CPU::HasAPIC()
|
||||
{
|
||||
return GetFeatureBits_1() & 0b00000000000000000000001000000000;
|
||||
}
|
||||
|
||||
bool CPU::HasSEP()
|
||||
{
|
||||
return GetFeatureBits_1() & 0b00000000000000000000100000000000;
|
||||
}
|
||||
|
||||
bool CPU::HasMTRR()
|
||||
{
|
||||
return GetFeatureBits_1() & 0b00000000000000000001000000000000;
|
||||
}
|
||||
|
||||
bool CPU::HasPGE()
|
||||
{
|
||||
return GetFeatureBits_1() & 0b00000000000000000010000000000000;
|
||||
}
|
||||
|
||||
bool CPU::HasMCA()
|
||||
{
|
||||
return GetFeatureBits_1() & 0b00000000000000000100000000000000;
|
||||
}
|
||||
|
||||
bool CPU::HasCMOV()
|
||||
{
|
||||
return GetFeatureBits_1() & 0b00000000000000001000000000000000;
|
||||
}
|
||||
|
||||
bool CPU::HasPAT()
|
||||
{
|
||||
return GetFeatureBits_1() & 0b00000000000000010000000000000000;
|
||||
}
|
||||
|
||||
bool CPU::HasPSE_36()
|
||||
{
|
||||
return GetFeatureBits_1() & 0b00000000000000100000000000000000;
|
||||
}
|
||||
|
||||
bool CPU::HasPSN()
|
||||
{
|
||||
return GetFeatureBits_1() & 0b00000000000001000000000000000000;
|
||||
}
|
||||
|
||||
bool CPU::HasCLFSH()
|
||||
{
|
||||
return GetFeatureBits_1() & 0b00000000000010000000000000000000;
|
||||
}
|
||||
|
||||
bool CPU::HasDS()
|
||||
{
|
||||
return GetFeatureBits_1() & 0b00000000001000000000000000000000;
|
||||
}
|
||||
|
||||
bool CPU::HasACPI()
|
||||
{
|
||||
return GetFeatureBits_1() & 0b00000000010000000000000000000000;
|
||||
}
|
||||
|
||||
bool CPU::HasMMX()
|
||||
{
|
||||
return GetFeatureBits_1() & 0b00000000100000000000000000000000;
|
||||
}
|
||||
|
||||
bool CPU::HasFXSR()
|
||||
{
|
||||
return GetFeatureBits_1() & 0b00000001000000000000000000000000;
|
||||
}
|
||||
|
||||
bool CPU::HasSSE()
|
||||
{
|
||||
return GetFeatureBits_1() & 0b00000010000000000000000000000000;
|
||||
}
|
||||
|
||||
bool CPU::HasSSE2()
|
||||
{
|
||||
return GetFeatureBits_1() & 0b00000100000000000000000000000000;
|
||||
}
|
||||
|
||||
bool CPU::HasSS()
|
||||
{
|
||||
return GetFeatureBits_1() & 0b00001000000000000000000000000000;
|
||||
}
|
||||
|
||||
bool CPU::HasHTT()
|
||||
{
|
||||
return GetFeatureBits_1() & 0b00010000000000000000000000000000;
|
||||
}
|
||||
|
||||
bool CPU::HasTM()
|
||||
{
|
||||
return GetFeatureBits_1() & 0b00100000000000000000000000000000;
|
||||
}
|
||||
|
||||
bool CPU::HasIA64()
|
||||
{
|
||||
return GetFeatureBits_1() & 0b01000000000000000000000000000000;
|
||||
}
|
||||
|
||||
bool CPU::HasPBE()
|
||||
{
|
||||
return GetFeatureBits_1() & 0b10000000000000000000000000000000;
|
||||
}
|
||||
|
||||
bool CPU::HasSSE3()
|
||||
{
|
||||
return GetFeatureBits_2() & 0b00000000000000000000000000000001;
|
||||
}
|
||||
|
||||
bool CPU::HasPCLMULQDQ()
|
||||
{
|
||||
return GetFeatureBits_2() & 0b00000000000000000000000000000010;
|
||||
}
|
||||
|
||||
bool CPU::HasDTES64()
|
||||
{
|
||||
return GetFeatureBits_2() & 0b00000000000000000000000000000100;
|
||||
}
|
||||
|
||||
bool CPU::HasMONITOR()
|
||||
{
|
||||
return GetFeatureBits_2() & 0b00000000000000000000000000001000;
|
||||
}
|
||||
|
||||
bool CPU::HasDS_CPL()
|
||||
{
|
||||
return GetFeatureBits_2() & 0b00000000000000000000000000010000;
|
||||
}
|
||||
|
||||
bool CPU::HasVMX()
|
||||
{
|
||||
return GetFeatureBits_2() & 0b00000000000000000000000000100000;
|
||||
}
|
||||
|
||||
bool CPU::HasSMX()
|
||||
{
|
||||
return GetFeatureBits_2() & 0b00000000000000000000000001000000;
|
||||
}
|
||||
|
||||
bool CPU::HasEST()
|
||||
{
|
||||
return GetFeatureBits_2() & 0b00000000000000000000000010000000;
|
||||
}
|
||||
|
||||
bool CPU::HasTM2()
|
||||
{
|
||||
return GetFeatureBits_2() & 0b00000000000000000000000100000000;
|
||||
}
|
||||
|
||||
bool CPU::HasSSSE3()
|
||||
{
|
||||
return GetFeatureBits_2() & 0b00000000000000000000001000000000;
|
||||
}
|
||||
|
||||
bool CPU::HasCNXT_ID()
|
||||
{
|
||||
return GetFeatureBits_2() & 0b00000000000000000000010000000000;
|
||||
}
|
||||
|
||||
bool CPU::HasSDBG()
|
||||
{
|
||||
return GetFeatureBits_2() & 0b00000000000000000000100000000000;
|
||||
}
|
||||
|
||||
bool CPU::HasFMA()
|
||||
{
|
||||
return GetFeatureBits_2() & 0b00000000000000000001000000000000;
|
||||
}
|
||||
|
||||
bool CPU::HasCX16()
|
||||
{
|
||||
return GetFeatureBits_2() & 0b00000000000000000010000000000000;
|
||||
}
|
||||
|
||||
bool CPU::HasXTPR()
|
||||
{
|
||||
return GetFeatureBits_2() & 0b00000000000000000100000000000000;
|
||||
}
|
||||
|
||||
bool CPU::HasPDCM()
|
||||
{
|
||||
return GetFeatureBits_2() & 0b00000000000000001000000000000000;
|
||||
}
|
||||
|
||||
bool CPU::HasPCID()
|
||||
{
|
||||
return GetFeatureBits_2() & 0b00000000000000100000000000000000;
|
||||
}
|
||||
|
||||
bool CPU::HasDCA()
|
||||
{
|
||||
return GetFeatureBits_2() & 0b00000000000001000000000000000000;
|
||||
}
|
||||
|
||||
bool CPU::HasSSE4_1()
|
||||
{
|
||||
return GetFeatureBits_2() & 0b00000000000010000000000000000000;
|
||||
}
|
||||
|
||||
bool CPU::HasSSE4_2()
|
||||
{
|
||||
return GetFeatureBits_2() & 0b00000000000100000000000000000000;
|
||||
}
|
||||
|
||||
bool CPU::HasX2APIC()
|
||||
{
|
||||
return GetFeatureBits_2() & 0b00000000001000000000000000000000;
|
||||
}
|
||||
|
||||
bool CPU::HasMOVBE()
|
||||
{
|
||||
return GetFeatureBits_2() & 0b00000000010000000000000000000000;
|
||||
}
|
||||
|
||||
bool CPU::HasPOPCNT()
|
||||
{
|
||||
return GetFeatureBits_2() & 0b00000000100000000000000000000000;
|
||||
}
|
||||
|
||||
bool CPU::HasTSC_DEADLINE()
|
||||
{
|
||||
return GetFeatureBits_2() & 0b00000001000000000000000000000000;
|
||||
}
|
||||
|
||||
bool CPU::HasAES()
|
||||
{
|
||||
return GetFeatureBits_2() & 0b00000010000000000000000000000000;
|
||||
}
|
||||
|
||||
bool CPU::HasXSAVE()
|
||||
{
|
||||
return GetFeatureBits_2() & 0b00000100000000000000000000000000;
|
||||
}
|
||||
|
||||
bool CPU::HasOSXSAVE()
|
||||
{
|
||||
return GetFeatureBits_2() & 0b00001000000000000000000000000000;
|
||||
}
|
||||
|
||||
bool CPU::HasAVX()
|
||||
{
|
||||
return GetFeatureBits_2() & 0b00010000000000000000000000000000;
|
||||
}
|
||||
|
||||
bool CPU::HasF16C()
|
||||
{
|
||||
return GetFeatureBits_2() & 0b00100000000000000000000000000000;
|
||||
}
|
||||
|
||||
bool CPU::HasRDRND()
|
||||
{
|
||||
return GetFeatureBits_2() & 0b01000000000000000000000000000000;
|
||||
}
|
||||
|
||||
bool CPU::HasHYPERVISOR()
|
||||
{
|
||||
return GetFeatureBits_2() & 0b10000000000000000000000000000000;
|
||||
}
|
||||
|
||||
bool CPU::HasAVX2()
|
||||
{
|
||||
return GetExtFeatureBits_1() & 0b00000000000000000000000000100000;
|
||||
}
|
||||
|
||||
bool CPU::HasRDSEED()
|
||||
{
|
||||
return GetExtFeatureBits_1() & 0b00000000000001000000000000000000;
|
||||
}
|
||||
|
||||
bool CPU::HasADX()
|
||||
{
|
||||
return GetExtFeatureBits_1() & 0b00000000000010000000000000000000;
|
||||
}
|
||||
|
||||
/*
|
||||
Str_8 CPU::ToStr()
|
||||
{
|
||||
return "Manufacturer: " + GetManufacturer() + "\r\n" +
|
||||
"Brand: " + GetBrand() + "\r\n" +
|
||||
"Stepping Id: " + Str_8::FromNum(GetSteppingId()) + "\r\n" +
|
||||
"GpuModel Id: " + Str_8::FromNum(GetModelId()) + "\r\n" +
|
||||
"Family Id: " + Str_8::FromNum(GetFamilyId()) + "\r\n" +
|
||||
"Processor Type Id: " + Str_8::FromNum(GetProcessorTypeId()) + "\r\n" +
|
||||
"Extended GpuModel Id: " + Str_8::FromNum(GetExtModelId()) + "\r\n" +
|
||||
"Extended Family Id: " + Str_8::FromNum(GetExtFamilyId()) + "\r\n" +
|
||||
"Has FPU: " + Str_8::FromNum((UInt_8)HasFPU()) + "\r\n" +
|
||||
"Has SSE: " + Str_8::FromNum((UInt_8)HasSSE()) + "\r\n" +
|
||||
"Has SSE 2: " + Str_8::FromNum((UInt_8)HasSSE2()) + "\r\n" +
|
||||
"Has SSE 3: " + Str_8::FromNum((UInt_8)HasSSE3()) + "\r\n" +
|
||||
"Has SSSE 3: " + Str_8::FromNum((UInt_8)HasSSSE3()) + "\r\n" +
|
||||
"Has SSE 4.1: " + Str_8::FromNum((UInt_8)HasSSE4_1()) + "\r\n" +
|
||||
"Has SSE 4.2: " + Str_8::FromNum((UInt_8)HasSSE4_2()) + "\r\n" +
|
||||
"Has AVX: " + Str_8::FromNum((UInt_8)HasAVX()) + "\r\n" +
|
||||
"Has RDRND: " + Str_8::FromNum((UInt_8)HasRDRND()) + "\r\n" +
|
||||
"Has AVX 2: " + Str_8::FromNum((UInt_8)HasAVX2()) + "\r\n" +
|
||||
"Has ADX: " + Str_8::FromNum((UInt_8)HasADX()) + "\r\n" +
|
||||
"Has RDSEED: " + Str_8::FromNum((UInt_8)HasRDSEED());
|
||||
}
|
||||
*/
|
203
src/sys/CPU.h
Normal file
203
src/sys/CPU.h
Normal file
@ -0,0 +1,203 @@
|
||||
#pragma once
|
||||
|
||||
#include "../EHS.h"
|
||||
#include "../Str.h"
|
||||
#include "../Array.h"
|
||||
|
||||
enum class Architecture : UInt_8
|
||||
{
|
||||
X64,
|
||||
X86,
|
||||
ARM64,
|
||||
ARM,
|
||||
UNKNOWN
|
||||
};
|
||||
|
||||
enum class Endianness : UInt_8
|
||||
{
|
||||
LE,
|
||||
BE
|
||||
};
|
||||
|
||||
struct TSC
|
||||
{
|
||||
UInt_32 coreId = 0;
|
||||
UInt_32 highCount = 0;
|
||||
UInt_32 lowCount = 0;
|
||||
};
|
||||
|
||||
class CPU
|
||||
{
|
||||
public:
|
||||
static Architecture GetArchitecture();
|
||||
|
||||
static UInt_8 PointerSize();
|
||||
|
||||
static Endianness GetEndianness();
|
||||
|
||||
static void RDTSCP(TSC* tsc);
|
||||
|
||||
static UInt_64 GetTSC();
|
||||
|
||||
/// Retrieves the CPU manufacturer id as a null-terminated ASCII string.
|
||||
/// @param[out] input A twelve byte character array representing the manufacturer id.
|
||||
static void GetManufacturer(Char_8* input);
|
||||
|
||||
static UInt_32 GetInfoBits();
|
||||
|
||||
static UInt_8 GetSteppingId();
|
||||
|
||||
static UInt_8 GetModelId();
|
||||
|
||||
static UInt_8 GetFamilyId();
|
||||
|
||||
static UInt_8 GetProcessorTypeId();
|
||||
|
||||
static UInt_8 GetExtModelId();
|
||||
|
||||
static UInt_8 GetExtFamilyId();
|
||||
|
||||
static UInt_32 GetFeatureBits_1();
|
||||
|
||||
static bool HasFPU();
|
||||
|
||||
static bool HasVME();
|
||||
|
||||
static bool HasDE();
|
||||
|
||||
static bool HasPSE();
|
||||
|
||||
static bool HasTSC();
|
||||
|
||||
static bool HasMSR();
|
||||
|
||||
static bool HasPAE();
|
||||
|
||||
static bool HasMCE();
|
||||
|
||||
static bool HasCX8();
|
||||
|
||||
static bool HasAPIC();
|
||||
|
||||
static bool HasSEP();
|
||||
|
||||
static bool HasMTRR();
|
||||
|
||||
static bool HasPGE();
|
||||
|
||||
static bool HasMCA();
|
||||
|
||||
static bool HasCMOV();
|
||||
|
||||
static bool HasPAT();
|
||||
|
||||
static bool HasPSE_36();
|
||||
|
||||
static bool HasPSN();
|
||||
|
||||
static bool HasCLFSH();
|
||||
|
||||
static bool HasDS();
|
||||
|
||||
static bool HasACPI();
|
||||
|
||||
static bool HasMMX();
|
||||
|
||||
static bool HasFXSR();
|
||||
|
||||
static bool HasSSE();
|
||||
|
||||
static bool HasSSE2();
|
||||
|
||||
static bool HasSS();
|
||||
|
||||
static bool HasHTT();
|
||||
|
||||
static bool HasTM();
|
||||
|
||||
static bool HasIA64();
|
||||
|
||||
static bool HasPBE();
|
||||
|
||||
static UInt_32 GetFeatureBits_2();
|
||||
|
||||
static bool HasSSE3();
|
||||
|
||||
static bool HasPCLMULQDQ();
|
||||
|
||||
static bool HasDTES64();
|
||||
|
||||
static bool HasMONITOR();
|
||||
|
||||
static bool HasDS_CPL();
|
||||
|
||||
static bool HasVMX();
|
||||
|
||||
static bool HasSMX();
|
||||
|
||||
static bool HasEST();
|
||||
|
||||
static bool HasTM2();
|
||||
|
||||
static bool HasSSSE3();
|
||||
|
||||
static bool HasCNXT_ID();
|
||||
|
||||
static bool HasSDBG();
|
||||
|
||||
static bool HasFMA();
|
||||
|
||||
static bool HasCX16();
|
||||
|
||||
static bool HasXTPR();
|
||||
|
||||
static bool HasPDCM();
|
||||
|
||||
static bool HasPCID();
|
||||
|
||||
static bool HasDCA();
|
||||
|
||||
static bool HasSSE4_1();
|
||||
|
||||
static bool HasSSE4_2();
|
||||
|
||||
static bool HasX2APIC();
|
||||
|
||||
static bool HasMOVBE();
|
||||
|
||||
static bool HasPOPCNT();
|
||||
|
||||
static bool HasTSC_DEADLINE();
|
||||
|
||||
static bool HasAES();
|
||||
|
||||
static bool HasXSAVE();
|
||||
|
||||
static bool HasOSXSAVE();
|
||||
|
||||
static bool HasAVX();
|
||||
|
||||
static bool HasF16C();
|
||||
|
||||
static bool HasRDRND();
|
||||
|
||||
static bool HasHYPERVISOR();
|
||||
|
||||
static UInt_32 GetExtFeatureBits_1();
|
||||
|
||||
static bool HasAVX2();
|
||||
|
||||
static bool HasRDSEED();
|
||||
|
||||
static bool HasADX();
|
||||
|
||||
static UInt_32 GetExtFeatureBits_2();
|
||||
|
||||
static UInt_32 GetExtFeatureBits_3();
|
||||
|
||||
/// Retrieves the CPU brand as a null-terminated ASCII string.
|
||||
/// @param[out] input A 48 byte character array representing the brand.
|
||||
static void GetBrand(Char_8* input);
|
||||
|
||||
//static Str_8 ToStr();
|
||||
};
|
132
src/sys/CPU_GCC_AMD64.asm
Normal file
132
src/sys/CPU_GCC_AMD64.asm
Normal file
@ -0,0 +1,132 @@
|
||||
global _ZN3lwe3CPU6RDTSCPEPNS_3TSCE
|
||||
global _ZN3lwe3CPU15GetManufacturerEPc
|
||||
global _ZN3lwe3CPU11GetInfoBitsEv
|
||||
global _ZN3lwe3CPU16GetFeatureBits_1Ev
|
||||
global _ZN3lwe3CPU16GetFeatureBits_2Ev
|
||||
global _ZN3lwe3CPU19GetExtFeatureBits_1Ev
|
||||
global _ZN3lwe3CPU19GetExtFeatureBits_2Ev
|
||||
global _ZN3lwe3CPU19GetExtFeatureBits_3Ev
|
||||
global _ZN3lwe3CPU8GetBrandEPc
|
||||
|
||||
section .text
|
||||
_ZN3lwe3CPU6RDTSCPEPNS_3TSCE:
|
||||
RDTSCP
|
||||
MOV DWORD [RDI], ECX
|
||||
MOV DWORD [RDI + 4], EDX
|
||||
MOV DWORD [RDI + 8], EAX
|
||||
RET
|
||||
|
||||
_ZN3lwe3CPU15GetManufacturerEPc:
|
||||
PUSH RBX
|
||||
|
||||
XOR EAX, EAX
|
||||
CPUID
|
||||
|
||||
MOV DWORD [RDI], EBX
|
||||
MOV DWORD [RDI + 4], EDX
|
||||
MOV DWORD [RDI + 8], ECX
|
||||
|
||||
POP RBX
|
||||
|
||||
RET
|
||||
|
||||
_ZN3lwe3CPU11GetInfoBitsEv:
|
||||
PUSH RBX
|
||||
|
||||
MOV EAX, 1
|
||||
CPUID
|
||||
|
||||
POP RBX
|
||||
|
||||
RET
|
||||
|
||||
_ZN3lwe3CPU16GetFeatureBits_1Ev:
|
||||
PUSH RBX
|
||||
|
||||
MOV EAX, 1
|
||||
CPUID
|
||||
|
||||
MOV EAX, EDX
|
||||
|
||||
POP RBX
|
||||
|
||||
RET
|
||||
|
||||
_ZN3lwe3CPU16GetFeatureBits_2Ev:
|
||||
PUSH RBX
|
||||
|
||||
MOV EAX, 1
|
||||
CPUID
|
||||
|
||||
MOV EAX, ECX
|
||||
|
||||
POP RBX
|
||||
|
||||
RET
|
||||
|
||||
_ZN3lwe3CPU19GetExtFeatureBits_1Ev:
|
||||
PUSH RBX
|
||||
|
||||
MOV EAX, 7
|
||||
XOR ECX, ECX
|
||||
CPUID
|
||||
|
||||
MOV EAX, EBX
|
||||
|
||||
POP RBX
|
||||
|
||||
RET
|
||||
|
||||
_ZN3lwe3CPU19GetExtFeatureBits_2Ev:
|
||||
PUSH RBX
|
||||
|
||||
MOV EAX, 7
|
||||
XOR ECX, ECX
|
||||
CPUID
|
||||
|
||||
MOV EAX, ECX
|
||||
|
||||
POP RBX
|
||||
|
||||
RET
|
||||
|
||||
_ZN3lwe3CPU19GetExtFeatureBits_3Ev:
|
||||
PUSH RBX
|
||||
|
||||
MOV EAX, 7
|
||||
XOR ECX, ECX
|
||||
CPUID
|
||||
|
||||
MOV EAX, EDX
|
||||
|
||||
POP RBX
|
||||
|
||||
RET
|
||||
|
||||
_ZN3lwe3CPU8GetBrandEPc:
|
||||
PUSH RBX
|
||||
|
||||
MOV EAX, 80000002h
|
||||
CPUID
|
||||
MOV DWORD [RDI], EAX
|
||||
MOV DWORD [RDI + 4], EBX
|
||||
MOV DWORD [RDI + 8], ECX
|
||||
MOV DWORD [RDI + 12], EDX
|
||||
|
||||
MOV EAX, 80000003h
|
||||
CPUID
|
||||
MOV DWORD [RDI + 16], EAX
|
||||
MOV DWORD [RDI + 20], EBX
|
||||
MOV DWORD [RDI + 24], ECX
|
||||
MOV DWORD [RDI + 28], EDX
|
||||
|
||||
MOV EAX, 80000004h
|
||||
CPUID
|
||||
MOV DWORD [RDI + 32], EAX
|
||||
MOV DWORD [RDI + 36], EBX
|
||||
MOV DWORD [RDI + 40], ECX
|
||||
MOV DWORD [RDI + 44], EDX
|
||||
|
||||
POP RBX
|
||||
|
||||
RET
|
127
src/sys/CPU_MSVC_AMD64.asm
Normal file
127
src/sys/CPU_MSVC_AMD64.asm
Normal file
@ -0,0 +1,127 @@
|
||||
global ?GetManufacturer@CPU@lwe@@SAXPEAD@Z
|
||||
global ?GetInfoBits@CPU@lwe@@SAIXZ
|
||||
global ?GetFeatureBits_1@CPU@lwe@@SAIXZ
|
||||
global ?GetFeatureBits_2@CPU@lwe@@SAIXZ
|
||||
global ?GetExtFeatureBits_1@CPU@lwe@@SAIXZ
|
||||
global ?GetExtFeatureBits_2@CPU@lwe@@SAKXZ
|
||||
global ?GetExtFeatureBits_3@CPU@lwe@@SAKXZ
|
||||
global ?GetBrand@CPU@lwe@@SAXPEAD@Z
|
||||
|
||||
section .text
|
||||
?GetManufacturer@CPU@lwe@@SAXPEAD@Z:
|
||||
PUSH RBX
|
||||
|
||||
XOR EAX, EAX
|
||||
MOV R8, RCX
|
||||
CPUID
|
||||
|
||||
MOV DWORD [R8], EBX
|
||||
MOV DWORD [R8 + 4], EDX
|
||||
MOV DWORD [R8 + 8], ECX
|
||||
|
||||
POP RBX
|
||||
|
||||
RET
|
||||
|
||||
?GetInfoBits@CPU@lwe@@SAIXZ:
|
||||
PUSH RBX
|
||||
|
||||
MOV EAX, 1
|
||||
CPUID
|
||||
|
||||
POP RBX
|
||||
|
||||
RET
|
||||
|
||||
?GetFeatureBits_1@CPU@lwe@@SAIXZ:
|
||||
PUSH RBX
|
||||
|
||||
MOV EAX, 1
|
||||
CPUID
|
||||
|
||||
MOV EAX, EDX
|
||||
|
||||
POP RBX
|
||||
|
||||
RET
|
||||
|
||||
?GetFeatureBits_2@CPU@lwe@@SAIXZ:
|
||||
PUSH RBX
|
||||
|
||||
MOV EAX, 1
|
||||
CPUID
|
||||
|
||||
MOV EAX, ECX
|
||||
|
||||
POP RBX
|
||||
|
||||
RET
|
||||
|
||||
?GetExtFeatureBits_1@CPU@lwe@@SAIXZ:
|
||||
PUSH RBX
|
||||
|
||||
MOV EAX, 7
|
||||
XOR ECX, ECX
|
||||
CPUID
|
||||
|
||||
MOV EAX, EBX
|
||||
|
||||
POP RBX
|
||||
|
||||
RET
|
||||
|
||||
?GetExtFeatureBits_2@CPU@lwe@@SAKXZ:
|
||||
PUSH RBX
|
||||
|
||||
MOV EAX, 7
|
||||
XOR ECX, ECX
|
||||
CPUID
|
||||
|
||||
MOV EAX, ECX
|
||||
|
||||
POP RBX
|
||||
|
||||
RET
|
||||
|
||||
?GetExtFeatureBits_3@CPU@lwe@@SAKXZ:
|
||||
PUSH RBX
|
||||
|
||||
MOV EAX, 7
|
||||
XOR ECX, ECX
|
||||
CPUID
|
||||
|
||||
MOV EAX, EDX
|
||||
|
||||
POP RBX
|
||||
|
||||
RET
|
||||
|
||||
?GetBrand@CPU@lwe@@SAXPEAD@Z:
|
||||
PUSH RBX
|
||||
|
||||
MOV R8, RCX
|
||||
|
||||
MOV EAX, 80000002h
|
||||
CPUID
|
||||
MOV DWORD [R8], EAX
|
||||
MOV DWORD [R8 + 4], EBX
|
||||
MOV DWORD [R8 + 8], ECX
|
||||
MOV DWORD [R8 + 12], EDX
|
||||
|
||||
MOV EAX, 80000003h
|
||||
CPUID
|
||||
MOV DWORD [R8 + 16], EAX
|
||||
MOV DWORD [R8 + 20], EBX
|
||||
MOV DWORD [R8 + 24], ECX
|
||||
MOV DWORD [R8 + 28], EDX
|
||||
|
||||
MOV EAX, 80000004h
|
||||
CPUID
|
||||
MOV DWORD [R8 + 32], EAX
|
||||
MOV DWORD [R8 + 36], EBX
|
||||
MOV DWORD [R8 + 40], ECX
|
||||
MOV DWORD [R8 + 44], EDX
|
||||
|
||||
POP RBX
|
||||
|
||||
RET
|
Loading…
Reference in New Issue
Block a user