diff --git a/.gitignore b/.gitignore
index c0c9bb9..22d5c6b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,4 @@
/build/
/docs/
+/bin/
+/lib/
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c4a7b0d..ea7ac98 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -13,6 +13,14 @@ include_directories(include)
# Metaprogramming is a dependency for generating various type info before compilation of the engine.
add_subdirectory(metaprogramming)
+string(TOLOWER ${CMAKE_BUILD_TYPE} FENNEC_BUILD_NAME)
+
+set(CMAKE_BINARY_DIR ${PROJECT_SOURCE_DIR}/build/${CMAKE_PLATFORM_NO_VERSIONED_SONAME})
+
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib/${FENNEC_BUILD_NAME})
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib/${FENNEC_BUILD_NAME})
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin/${FENNEC_BUILD_NAME})
+
add_library(fennec STATIC
# CORE =================================================================================================================
@@ -24,7 +32,8 @@ add_library(fennec STATIC
include/fennec/containers/dynarray.h
-# LANG =================================================================================================================
+# LANG =================================================================================================================h
+ include/fennec/lang/bits.h
include/fennec/lang/constants.h
include/fennec/lang/conditional_types.h
include/fennec/lang/intrinsics.h
@@ -43,10 +52,10 @@ add_library(fennec STATIC
# MEMORY ===============================================================================================================
- include/fennec/memory/allocator.h
- include/fennec/lang/bits.h
- include/fennec/memory/memory.h
include/fennec/memory/new.h source/memory/new.cpp
+
+ include/fennec/memory/allocator.h
+ include/fennec/memory/memory.h
include/fennec/memory/pointers.h
include/fennec/memory/ptr_traits.h
@@ -78,6 +87,7 @@ add_library(fennec STATIC
include/fennec/math/detail/__types.h
include/fennec/math/detail/__vector_traits.h
include/fennec/lang/lang.h
+ include/fennec/lang/detail/__bits.h
)
# add metaprogramming templates as a dependency and also force documentation to be generated when fennec is compiled
@@ -137,4 +147,4 @@ if(DOXYGEN_FOUND)
VERBATIM)
else()
message("Doxygen not found.")
-endif()
\ No newline at end of file
+endif()
diff --git a/PLANNING.md b/PLANNING.md
index a1258be..01ef1c9 100644
--- a/PLANNING.md
+++ b/PLANNING.md
@@ -4,20 +4,24 @@
## Table of Contents
- 1. [Introduction](#introduction)
- 2. [TODO](#todo)
- 3. [C++ Language](#c-language-library-lang)
- 4. [Math Library](#math-library-math)
- 5. [Memory Library](#memory-library-memory)
- 6. [Containers Library](#containers-containers)
- 7. [Language Processing](#language-processing-proclang)
- 8. [Core](#core-core)
- 1. [Tick](#tick)
- 2. [Frame](#frame)
- 9. [Scene](#scene-scene)
- 10. [3D Graphics](#3d-graphics-gfx3d)
- 11. [3D Physics](#3d-physics-physics3d)
- 12. [Artificial Intelligence](#artificial-intelligence-ai)
+ 1. [Introduction](#introduction)
+ 2. [TODO](#todo)
+ 3. [C++ Language](#c-language-library-lang)
+ 4. [Math Library](#math-library-math)
+ 5. [Memory Library](#memory-library-memory)
+ 6. [Containers Library](#containers-containers)
+ 7. [Format Processing](#format-processing-fproc)
+ 8. [Core](#core-core)
+ 1. [Tick](#tick)
+ 2. [Frame](#frame)
+ 9. [Application Layer](#application-layer-app)
+ 10. [Scene](#scene-scene)
+ 11. [2D Graphics](#2d-graphics-gfx2d)
+ 12. [3D Graphics](#3d-graphics-gfx3d)
+ 1. [Structures](#structures-gfx3d)
+ 2. [Stages](#stages-gfx3d)
+ 13. [3D Physics](#3d-physics-physics3d)
+ 14. [Artificial Intelligence](#artificial-intelligence-ai)
@@ -82,7 +86,7 @@ Implement headers related to memory allocation in C++.
-## Containers (`containers`)
+## Containers Library (`containers`)
All containers of the [C++ Standard Library](https://cppreference.com/w/cpp/container.html) should be implemented.
@@ -96,20 +100,18 @@ Here are essential data-structures not specified in the C++ stdlib:
-## Language Processing (`proclang`)
-
-Pronounced [pɹˈɒkh,læŋ](https://itinerarium.github.io/phoneme-synthesis/?w=pɹˈɒkh,læŋ)
+## Format Processing (`fproc`)
No, this won't include Machine Learning, it will mostly include tools for processing human-readable files.
fennec should be able to use Doxygen and LaTeX externally. Consider including binaries with releases.
- * String Analysis (`proclang/strings`)
+ * String Analysis (`fproc/strings`)
* Search
* Manipulation
* Delimiting
* Regex
- - File Formats (`proclang/formats`)
+ - File Formats (`fproc/formats`)
- Serialization
- JSON
- HTML
@@ -135,7 +137,7 @@ fennec should be able to use Doxygen and LaTeX externally. Consider including bi
- FBX
**MAYBE**
- * Compilation (`proclang/code`)
+ * Compilation (`fproc/code`)
* Lexical Analysis
* Syntax Analysis
* Semantic Analysis
@@ -212,7 +214,29 @@ implementations than I could write.
## 2D Graphics (`gfx2d`)
-
+ - BVH
+ - Quadtree
+ - Leaf Size and Tree Depth should be calculated by the scene, constraints are as follows:
+ - Min Object Size
+ - Max Object Size
+ - Scene Center
+ - Scene Edge
+ - Insertions and Updates are done on the CPU
+ - Nodes
+ - Start Index 32-bits
+ - Object Count 32-bits
+ - Objects
+ - Buffer of Object IDs grouped by Octree Node
+ - Culling
+ - Starting at each Octree Leaf, traverse upwards.
+ - Insert Visible Leaf IDs
+ - Track using atomic buffer
+ - Generate the Command Buffer for Culled Meshes from the Visible Leaf Buffer
+ - Count Materials
+ - Count Meshes per Material
+ - Generate the Culled Object Buffer by copying objects from the Object Buffer
+ - Adjust Buffer Size using the counts
+ - Insert using another atomic buffer
@@ -235,7 +259,10 @@ If you would like to make a fork, have at it, but know that I will hold a deep d
The graphics pipeline will have a buffer with a list of objects and their rendering data.
This will be referred to as the Object Buffer. There will be two, for both the Deferred and Forward Passes.
-The buffers will be optimized by scene prediction. This involves tracking the meshes directly and indirectly used by a scene.
+The buffers will be optimized by scene prediction.
+This involves tracking the meshes and textures directly and indirectly used by a scene.
+A callback function in the graphics system for scene loading can do this.
+
Materials and Lighting models will be run via a shader metaprogram to make the pipeline independent of this aspect.
This allows the GPU to draw every single deferred rendered mesh in a single draw call for each stage of the renderer.
@@ -243,13 +270,62 @@ This allows the GPU to draw every single deferred rendered mesh in a single draw
Specifications for debugging views via early breaks are included in the stages.
+
+### Structures (`gfx3d`)
+
+Object Structure. The mesh is implicit data.
+
+```c++
+struct Object
+{
+ vec3 location, scale; // A matrix would be 64 bytes, this is instead 28 bytes
+ quat rotation;
+ int material;
+}
+```
+
+Textures for 3D rendering are stored in various buffers with sizes of powers of 2.
+Ratios of `1:1` and `2:1` are allowed. The `2:1` ratio is specifically for spherical and cylindrical projection.
+UVs may be transformed to use a `2:1` as if it were `1:2`.
+Cubemaps may only be `1:1`, I would be concerned if you are using any other ratio.
+
+ - 8-Bit R Texture `4096, 2048, 1024, 512` (8)
+ - 8-Bit RG Texture `4096, 2048, 1024, 512` (8)
+ - 8-Bit RGB Texture `4096, 2048, 1024, 512` (8)
+ - 8-Bit RGBA Texture `4096, 2048, 1024, 512` (8)
+ - 8-Bit RGB Cubemap `1024, 512, 256, 128` (4)
+
+ * 16-Bit HDR RGB Texture `4096, 2048, 1024, 512` (8)
+ * 16-Bit HDR RGBA Texture `4096, 2048, 1024, 512` (8)
+ * 16-Bit HDR RGB Cubemap `1024, 512, 256, 128` (4)
+
+ - 16-Bit Shadow Texture `4096, 2048, 1024, 512` (8)
+ - 16-Bit Shadow Cubemap `2048, 1024, 512, 256` (4)
+
+Documentation should provide guidelines on categories of Art Assets and the resolution of textures to use.
+
+Textures are identified by an 8-bit integer and 16-bit integer.
+
+Artists should be informed on the texture structure of the engine and its limitations.
+However, these principles should be followed in other game engines as these are
+guided by what is most efficient for typical GPU hardware.
+
+
+Materials are, for the most part, user-defined. Documentation should make the user aware of this.
+Material buffers will be a sequence of the Material Struct instances.
+They will at the very least contain the id of their shader.
+
+
+
+
+
### Stages (`gfx3d`)
This is the set of stages for the graphics pipeline that runs every frame:
Unless otherwise specified, each stage will be run on the GPU.
- BVH
- - Octree
+ - Octree `(8 Bpn, 64 bpn) [6-Layers ≈ 2.1MB]`
- Leaf Size and Tree Depth should be calculated by the scene, constraints are as follows:
- Min Object Size
- Max Object Size
@@ -257,60 +333,61 @@ Unless otherwise specified, each stage will be run on the GPU.
- Scene Edge
- Insertions and Updates are done on the CPU
- Nodes
- - ID 16-bits
- Start Index 32-bits
- - Object Count 16-bits
+ - Object Count 32-bits
- Objects
- Buffer of Object IDs grouped by Octree Node
- - Culling
+ - Leaf Culling
- Starting at each Octree Leaf, traverse upwards.
- Insert Visible Leaf IDs
- Track using atomic buffer
- - Output: Buffer of Visible Leaves
-
-* LOD Selection
- * Generate the Command Buffer for Culled Mesh LODs from the Visible Leaf Buffer
- * Track counts using atomic buffers
- * To avoid double counting due to the structure of the Octree output, we have some options
- * Ignore Leaf Instances based on occurrences of the mesh in the surrounding 16 Octree Leaves. This would require
- a bias towards a specific corner of the filter.
- * Perform a preprocessing step on the CPU to erase duplicate elements and fix the buffer continuity.
- * Let the duplicates be rendered.
- * Generate the Culled Object Buffer by copying objects from the Object Buffer
- * Adjust Buffer Size using the counts
- * Insert using another atomic buffer
+ - Generate the Command Buffer for Culled Mesh LODs from the Visible Leaf Buffer
+ - Track counts using atomic buffers
+ - To avoid double counting due to the construction of the Octree output, we have some options
+ - Ignore Leaf Instances based on occurrences of the mesh in the surrounding 8 Quadtree Leaves. This would require
+ a bias towards a specific corner of the filter.
+ - Perform a preprocessing step on the CPU to erase duplicate elements and fix the buffer continuity.
+ - Let the duplicates be rendered.
+ - Generate the Culled Object Buffer by copying objects from the Object Buffer
+ - Adjust Buffer Size using the counts
+ - Insert using another atomic buffer
Debug View: Object ID, Mesh ID, LOD
- Visibility
- - Buffer - RGB32I w/ Depth24
- - G = Object ID
- - B = Mesh ID
+ - Buffer `(15 Bpp, 120 bpp) [1920x1080] ≈ 39.4MB`
+ - 24-Bit Depth Buffer
+ - RGB32I Visiblity Info
+ - R = Object ID
+ - G = Mesh ID
+ - B = Material ID
- Regenerate the Command Buffer for Visible Mesh LODs
- Regenerate the Culled Object Buffer
Debug View: Visibility Buffer
-* G-Buffer Pass
- * Depth - Stencil
- * 24-Bit Depth Buffer
- * 8-Bit Stencil Buffer, used to represent the lighting model.
- * Diffuse - RGB8
- * Emission - RGB8
- * Normal - RGB8
- * Specular - RGB8
+* G-Buffer Pass `(17 Bpp, 136 bpp) [1920x1080] ≈ 35.3MB`
+ * Depth - Stencil → D24_S8
+ * S → used to represent the lighting model.
+ * Diffuse → RGBA8
+ * A → Ambient Occlusion
+ * Emission → RGB8
+ * Normal → RGB8
+ * Specular → RGB8
* R → Roughness
- * G → Specularity (sometimes called metallicism)
+ * G → Specularity (sometimes called the Metallicness)
* B → Index of Refraction (IOR)
Debug View: Depth, Stencil, Diffuse, Emission, Normal, Specularity
-- Lighting Pass
+- Deferred Lighting Pass `(10 Bpp, 80 bpp) [1920x1080] ≈ 2 x 16.3MB + 8.3MB ≈ 24.6MB`
+ - Depth Buffer → D24
+ - Lighting Buffer → RGB16 (w/ Mipmapping when Bloom or DoF are enabled)
+ - Stencil Buffer $rarr; S8
- Generate Dynamic Shadows
- Generate Dynamic Reflections (Optional)
- SSAO (Optional)
- Apply Lighting Model
- - Output → RGB16
Debug View: Shadows, Reflections, SSAO, Deferred Lighting
@@ -320,11 +397,13 @@ Debug View: Shadows, Reflections, SSAO, Deferred Lighting
* Translucent Materials
* Dual Depth Peeling
-Debug View: Deferred and Forward Mask
+Debug View: Forward Mask
- Post Processing
- - Depth of Field (Optional) → Poisson Sampling
- - Bloom (Optional) → Mipmap Blurring
+ - Depth of Field (Optional)
+ - When enabled, the Visiblity Buffer, G-Buffer, and Deferred Lighting Pass will be double layered.
+ - At this point the Lighting Buffers will be Flattened
+ - Bloom (Optional) → Mipmap Blurring `(6Bpp, 48bpp) [1920x1080] ≈ 16.3MB`
- Tonemapping (Optional)
- HDR Correction
@@ -355,7 +434,7 @@ Systems
* Cloth → Position-Based Dynamics
* Water
* Oceans → iWave
- * Reasoning: iWave provides interactive lightweight fluid dynamics suitable for flat planes of water. Simulat
+ * Reasoning: iWave provides interactive lightweight fluid dynamics suitable for flat planes of water.
* 3D Fluid Dynamics → Smoothed-Particle Hydrodynamics
diff --git a/include/fennec/lang/bits.h b/include/fennec/lang/bits.h
index e9794b7..0b14b03 100644
--- a/include/fennec/lang/bits.h
+++ b/include/fennec/lang/bits.h
@@ -21,7 +21,7 @@
#define FENNEC_LANG_BITS_H
#include
-#include
+#include
namespace fennec
{
@@ -46,6 +46,20 @@ constexpr ToT bit_cast(const FromT& from)
}
}
+constexpr void* bitmask(void* arr, const void* mask, size_t n)
+{
+ if (arr == mask) return arr;
+ uint8_t* d = static_cast(arr);
+ const uint8_t* s = static_cast(mask);
+
+ while (n >= 8) { detail::__bitmask_64(d, s); d += 8; s += 8; n -= 8; }
+ while (n >= 4) { detail::__bitmask_32(d, s); d += 4; s += 4; n -= 4; }
+ while (n >= 2) { detail::__bitmask_16(d, s); d += 2; s += 2; n -= 2; }
+ while (n >= 1) { *d++ = *s++; --n; }
+
+ return arr;
+}
+
}
#endif // FENNEC_LANG_BITS_H
diff --git a/include/fennec/lang/detail/__bits.h b/include/fennec/lang/detail/__bits.h
new file mode 100644
index 0000000..6e09889
--- /dev/null
+++ b/include/fennec/lang/detail/__bits.h
@@ -0,0 +1,46 @@
+// =====================================================================================================================
+// fennec, a free and open source game engine
+// Copyright © 2025 Medusa Slockbower
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+// =====================================================================================================================
+
+#ifndef FENNEC_LANG_DETAIL_BITS_H
+#define FENNEC_LANG_DETAIL_BITS_H
+
+#include
+
+namespace fennec
+{
+
+namespace detail
+{
+
+// helper for copying 2 bytes at once
+constexpr size_t __bitmask_16(void* dst, const void* src)
+ { *static_cast(dst) = *static_cast(src); return 2; }
+
+// helper for copying 4 bytes at once
+constexpr size_t __bitmask_32(void* dst, const void* src)
+ { *static_cast(dst) = *static_cast(src); return 4; }
+
+// helper for copying 8 bytes at once
+constexpr size_t __bitmask_64(void* dst, const void* src)
+ { *static_cast(dst) = *static_cast(src); return 8; }
+
+}
+
+}
+
+#endif // FENNEC_LANG_DETAIL_BITS_H
diff --git a/include/fennec/lang/float.h b/include/fennec/lang/float.h
index 6cce568..f3d143b 100644
--- a/include/fennec/lang/float.h
+++ b/include/fennec/lang/float.h
@@ -30,7 +30,7 @@
#ifndef FENNEC_LANG_FLOAT_H
#define FENNEC_LANG_FLOAT_H
-#include
+#include
#define FLT_HAS_INFINITY 1
#define FLT_HAS_QUIET_NAN 1
diff --git a/include/fennec/math/common.h b/include/fennec/math/common.h
index 4654b2c..a948384 100644
--- a/include/fennec/math/common.h
+++ b/include/fennec/math/common.h
@@ -276,7 +276,6 @@
#include
#include
-#include <../lang/bits.h>
namespace fennec
{
diff --git a/include/fennec/memory/memory.h b/include/fennec/memory/memory.h
index 44f3f82..19ed615 100644
--- a/include/fennec/memory/memory.h
+++ b/include/fennec/memory/memory.h
@@ -75,6 +75,14 @@ constexpr int memcmp(const void* lhs, const void* rhs, size_t n)
return 0;
}
+///
+/// \brief Safe version of memcmp
+/// \copydoc fennec::memcmp
+/// \param n0 The size, in bytes, of lhs
+/// \param n1 The size, in bytes, of rhs
+constexpr int memcmp_s(const void* lhs, size_t n0, const void* rhs, size_t n1)
+ { return memcmp(lhs, rhs, n0 < n1 ? n0 : n1); }
+
///
/// \brief Copies the first \f$n\f$ bytes of \f$src\f$ to \f$dst\f$.
/// \param dst The destination object, interpreted as an array of bytes
@@ -101,6 +109,14 @@ constexpr void* memcpy(void* dst, const void* src, size_t n)
return dst;
}
+///
+/// \brief Safe version of memcpy
+/// \copydoc fennec::memcpy
+/// \param n0 The size, in bytes, of dst
+/// \param n1 The size, in bytes, of src
+constexpr void* memcpy_s(void* dst, size_t n0, const void* src, size_t n1)
+ { return memcpy(dst, src, n0 < n1 ? n0 : n1); }
+
///
/// \brief Copies the first \f$n\f$ bytes of \f$src\f$ to \f$dst\f$, with overlap correction..
/// \param dst The destination object, interpreted as an array of bytes
@@ -131,6 +147,14 @@ constexpr void* memmove(void* dst, const void* src, size_t n)
return dst;
}
+///
+/// \brief Safe version of memmove
+/// \copydoc fennec::memmove
+/// \param n0 The size, in bytes, of dst
+/// \param n1 The size, in bytes, of src
+constexpr void* memmove_s(void* dst, size_t n0, const void* src, size_t n1)
+ { return memmove(dst, src, n0 < n1 ? n0 : n1); }
+
///
/// \brief Sets all bytes of \f$dst\f$ to \f$ch\f$, interpreted as an \f$uint8_t\f$
/// \param dst The destination object, interpreted as an array of bytes
diff --git a/metaprogramming/CMakeLists.txt b/metaprogramming/CMakeLists.txt
index 64626d2..aef9141 100644
--- a/metaprogramming/CMakeLists.txt
+++ b/metaprogramming/CMakeLists.txt
@@ -3,7 +3,8 @@ project(fennec-metaprogramming)
set(CMAKE_CXX_STANDARD 26)
-add_executable(fennec-metaprogramming main.cpp)
+add_executable(fennec-metaprogramming main.cpp
+ float.h)
add_custom_command(
OUTPUT .metaprogramming
COMMAND fennec-metaprogramming
diff --git a/metaprogramming/float.h b/metaprogramming/float.h
new file mode 100644
index 0000000..61e784d
--- /dev/null
+++ b/metaprogramming/float.h
@@ -0,0 +1,123 @@
+//
+// Created by medusa on 6/14/25.
+//
+
+#ifndef FENNEC_METAPROGRAMMING_FLOAT_H
+#define FENNEC_METAPROGRAMMING_FLOAT_H
+
+#include
+
+inline void float_h()
+{
+ std::ofstream flt("float.h");
+
+ flt << "// =====================================================================================================================" << std::endl;
+ flt << "// fennec, a free and open source game engine" << std::endl;
+ flt << "// Copyright © 2025 Medusa Slockbower" << std::endl;
+ flt << "//" << std::endl;
+ flt << "// This program is free software: you can redistribute it and/or modify" << std::endl;
+ flt << "// it under the terms of the GNU General Public License as published by" << std::endl;
+ flt << "// the Free Software Foundation, either version 3 of the License, or" << std::endl;
+ flt << "// (at your option) any later version." << std::endl;
+ flt << "//" << std::endl;
+ flt << "// This program is distributed in the hope that it will be useful," << std::endl;
+ flt << "// but WITHOUT ANY WARRANTY; without even the implied warranty of" << std::endl;
+ flt << "// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the" << std::endl;
+ flt << "// GNU General Public License for more details." << std::endl;
+ flt << "//" << std::endl;
+ flt << "// You should have received a copy of the GNU General Public License" << std::endl;
+ flt << "// along with this program. If not, see ." << std::endl;
+ flt << "// =====================================================================================================================" << std::endl;
+
+ flt << "" << std::endl;
+
+ flt << "///" << std::endl;
+ flt << "/// \\file float.h" << std::endl;
+ flt << "/// \\brief metaprogramming floating point type info" << std::endl;
+ flt << "///" << std::endl;
+ flt << "///" << std::endl;
+ flt << "/// \\details this file is automatically generated for the current build environment" << std::endl;
+ flt << "///" << std::endl;
+ flt << "/// \\copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))" << std::endl;
+ flt << "///" << std::endl;
+ flt << "///" << std::endl;
+
+ flt << "" << std::endl;
+
+ flt << "#ifndef FENNEC_LANG_FLOAT_H" << std::endl;
+ flt << "#define FENNEC_LANG_FLOAT_H" << std::endl;
+
+ flt << "" << std::endl;
+
+ flt << "#include " << std::endl;
+
+ flt << "" << std::endl;
+
+ // TODO: Fix this to generate info without using the c++stdlib for platforms without this available.
+
+ flt << "#define FLT_HAS_INFINITY " << std::dec << std::numeric_limits::has_infinity << std::endl;
+ flt << "#define FLT_HAS_QUIET_NAN " << std::dec << std::numeric_limits::has_quiet_NaN << std::endl;
+ flt << "#define FLT_HAS_SIGNALING_NAN " << std::dec << std::numeric_limits::has_signaling_NaN << std::endl;
+ flt << "#define FLT_HAS_DENORM " << std::dec << std::numeric_limits::has_denorm << std::endl;
+ flt << "#define FLT_HAS_DENORM_LOSS " << std::dec << std::numeric_limits::has_denorm_loss << std::endl;
+ flt << "#define FLT_ROUNDS " << std::dec << std::numeric_limits::round_style << std::endl;
+ flt << "#define FLT_IS_IEC559 " << std::dec << std::numeric_limits::is_iec559 << std::endl;
+ flt << "#define FLT_MANT_DIG " << std::dec << std::numeric_limits::digits << std::endl;
+ flt << "#define FLT_DIG " << std::dec << std::numeric_limits::digits10 << std::endl;
+ flt << "#define FLT_DECIMAL_DIG " << std::dec << std::numeric_limits::max_digits10 << std::endl;
+ flt << "#define FLT_RADIX " << std::dec << std::numeric_limits::radix << std::endl;
+ flt << "#define FLT_MIN_EXP " << std::dec << std::numeric_limits::min_exponent << std::endl;
+ flt << "#define FLT_MAX_EXP " << std::dec << std::numeric_limits::max_exponent << std::endl;
+ flt << "#define FLT_MIN_10_EXP " << std::dec << std::numeric_limits::min_exponent10 << std::endl;
+ flt << "#define FLT_MAX_10_EXP " << std::dec << std::numeric_limits::max_exponent10 << std::endl;
+ flt << "#define FLT_TRAPS " << std::dec << std::numeric_limits::traps << std::endl;
+ flt << "#define FLT_TINYNESS_BEFORE " << std::dec << std::numeric_limits::tinyness_before << std::endl;
+
+ flt << "#define FLT_MIN " << "fennec::bit_cast(0x" << std::hex << std::bit_cast(std::numeric_limits::min() ) << ")" << std::endl;
+ flt << "#define FLT_MAX " << "fennec::bit_cast(0x" << std::hex << std::bit_cast(std::numeric_limits::max() ) << ")" << std::endl;
+ flt << "#define FLT_EPSILON " << "fennec::bit_cast(0x" << std::hex << std::bit_cast(std::numeric_limits::epsilon() ) << ")" << std::endl;
+ flt << "#define FLT_INF " << "fennec::bit_cast(0x" << std::hex << std::bit_cast(std::numeric_limits::infinity() ) << ")" << std::endl;
+ flt << "#define FLT_QUIET_NAN " << "fennec::bit_cast(0x" << std::hex << std::bit_cast(std::numeric_limits::quiet_NaN() ) << ")" << std::endl;
+ flt << "#define FLT_SIGNALING_NAN " << "fennec::bit_cast(0x" << std::hex << std::bit_cast(std::numeric_limits::signaling_NaN()) << ")" << std::endl;
+ flt << "#define FLT_DENORM_MIN " << "fennec::bit_cast(0x" << std::hex << std::bit_cast(std::numeric_limits::denorm_min() ) << ")" << std::endl;
+ flt << "#define FLT_ROUND_ERR " << "fennec::bit_cast(0x" << std::hex << std::bit_cast(std::numeric_limits::round_error() ) << ")" << std::endl;
+
+ flt << "" << std::endl;
+
+ flt << "#define DBL_HAS_INFINITY " << std::dec << std::numeric_limits::has_infinity << std::endl;
+ flt << "#define DBL_HAS_QUIET_NAN " << std::dec << std::numeric_limits::has_quiet_NaN << std::endl;
+ flt << "#define DBL_HAS_SIGNALING_NAN " << std::dec << std::numeric_limits::has_signaling_NaN << std::endl;
+ flt << "#define DBL_HAS_DENORM " << std::dec << std::numeric_limits::has_denorm << std::endl;
+ flt << "#define DBL_HAS_DENORM_LOSS " << std::dec << std::numeric_limits::has_denorm_loss << std::endl;
+ flt << "#define DBL_ROUNDS " << std::dec << std::numeric_limits::round_style << std::endl;
+ flt << "#define DBL_IS_IEC559 " << std::dec << std::numeric_limits::is_iec559 << std::endl;
+ flt << "#define DBL_MANT_DIG " << std::dec << std::numeric_limits::digits << std::endl;
+ flt << "#define DBL_DIG " << std::dec << std::numeric_limits::digits10 << std::endl;
+ flt << "#define DBL_DECIMAL_DIG " << std::dec << std::numeric_limits::max_digits10 << std::endl;
+ flt << "#define DBL_RADIX " << std::dec << std::numeric_limits::radix << std::endl;
+ flt << "#define DBL_MIN_EXP " << std::dec << std::numeric_limits::min_exponent << std::endl;
+ flt << "#define DBL_MAX_EXP " << std::dec << std::numeric_limits::max_exponent << std::endl;
+ flt << "#define DBL_MIN_10_EXP " << std::dec << std::numeric_limits::min_exponent10 << std::endl;
+ flt << "#define DBL_MAX_10_EXP " << std::dec << std::numeric_limits::max_exponent10 << std::endl;
+ flt << "#define DBL_TRAPS " << std::dec << std::numeric_limits::traps << std::endl;
+ flt << "#define DBL_TINYNESS_BEFORE " << std::dec << std::numeric_limits::tinyness_before << std::endl;
+
+ flt << "#define DBL_MIN " << "fennec::bit_cast(0x" << std::hex << std::bit_cast(std::numeric_limits::min() ) << "l)" << std::endl;
+ flt << "#define DBL_MAX " << "fennec::bit_cast(0x" << std::hex << std::bit_cast(std::numeric_limits::max() ) << "l)" << std::endl;
+ flt << "#define DBL_EPSILON " << "fennec::bit_cast(0x" << std::hex << std::bit_cast(std::numeric_limits::epsilon() ) << "l)" << std::endl;
+ flt << "#define DBL_INF " << "fennec::bit_cast(0x" << std::hex << std::bit_cast(std::numeric_limits::infinity() ) << "l)" << std::endl;
+ flt << "#define DBL_QUIET_NAN " << "fennec::bit_cast(0x" << std::hex << std::bit_cast(std::numeric_limits::quiet_NaN() ) << "l)" << std::endl;
+ flt << "#define DBL_SIGNALING_NAN " << "fennec::bit_cast(0x" << std::hex << std::bit_cast(std::numeric_limits::signaling_NaN()) << "l)" << std::endl;
+ flt << "#define DBL_DENORM_MIN " << "fennec::bit_cast(0x" << std::hex << std::bit_cast(std::numeric_limits::denorm_min() ) << "l)" << std::endl;
+ flt << "#define DBL_ROUND_ERR " << "fennec::bit_cast(0x" << std::hex << std::bit_cast(std::numeric_limits::round_error() ) << "l)" << std::endl;
+
+ flt << "" << std::endl;
+
+ flt << "#endif // FENNEC_LANG_FLOAT_H" << std::endl;
+
+ flt.close();
+
+ return 0;
+}
+
+#endif //FLOAT_H
diff --git a/metaprogramming/main.cpp b/metaprogramming/main.cpp
index 2ef5595..2ed40a3 100644
--- a/metaprogramming/main.cpp
+++ b/metaprogramming/main.cpp
@@ -21,113 +21,4 @@
int main(int, const char**)
{
- std::ofstream flt("float.h");
-
- flt << "// =====================================================================================================================" << std::endl;
- flt << "// fennec, a free and open source game engine" << std::endl;
- flt << "// Copyright © 2025 Medusa Slockbower" << std::endl;
- flt << "//" << std::endl;
- flt << "// This program is free software: you can redistribute it and/or modify" << std::endl;
- flt << "// it under the terms of the GNU General Public License as published by" << std::endl;
- flt << "// the Free Software Foundation, either version 3 of the License, or" << std::endl;
- flt << "// (at your option) any later version." << std::endl;
- flt << "//" << std::endl;
- flt << "// This program is distributed in the hope that it will be useful," << std::endl;
- flt << "// but WITHOUT ANY WARRANTY; without even the implied warranty of" << std::endl;
- flt << "// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the" << std::endl;
- flt << "// GNU General Public License for more details." << std::endl;
- flt << "//" << std::endl;
- flt << "// You should have received a copy of the GNU General Public License" << std::endl;
- flt << "// along with this program. If not, see ." << std::endl;
- flt << "// =====================================================================================================================" << std::endl;
-
- flt << "" << std::endl;
-
- flt << "///" << std::endl;
- flt << "/// \\file float.h" << std::endl;
- flt << "/// \\brief metaprogramming floating point type info" << std::endl;
- flt << "///" << std::endl;
- flt << "///" << std::endl;
- flt << "/// \\details this file is automatically generated for the current build environment" << std::endl;
- flt << "///" << std::endl;
- flt << "/// \\copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))" << std::endl;
- flt << "///" << std::endl;
- flt << "///" << std::endl;
-
- flt << "" << std::endl;
-
- flt << "#ifndef FENNEC_LANG_FLOAT_H" << std::endl;
- flt << "#define FENNEC_LANG_FLOAT_H" << std::endl;
-
- flt << "" << std::endl;
-
- flt << "#include " << std::endl;
-
- flt << "" << std::endl;
-
- // TODO: Fix this to generate info without using the c++stdlib for platforms without this available.
-
- flt << "#define FLT_HAS_INFINITY " << std::dec << std::numeric_limits::has_infinity << std::endl;
- flt << "#define FLT_HAS_QUIET_NAN " << std::dec << std::numeric_limits::has_quiet_NaN << std::endl;
- flt << "#define FLT_HAS_SIGNALING_NAN " << std::dec << std::numeric_limits::has_signaling_NaN << std::endl;
- flt << "#define FLT_HAS_DENORM " << std::dec << std::numeric_limits::has_denorm << std::endl;
- flt << "#define FLT_HAS_DENORM_LOSS " << std::dec << std::numeric_limits::has_denorm_loss << std::endl;
- flt << "#define FLT_ROUNDS " << std::dec << std::numeric_limits::round_style << std::endl;
- flt << "#define FLT_IS_IEC559 " << std::dec << std::numeric_limits::is_iec559 << std::endl;
- flt << "#define FLT_MANT_DIG " << std::dec << std::numeric_limits::digits << std::endl;
- flt << "#define FLT_DIG " << std::dec << std::numeric_limits::digits10 << std::endl;
- flt << "#define FLT_DECIMAL_DIG " << std::dec << std::numeric_limits::max_digits10 << std::endl;
- flt << "#define FLT_RADIX " << std::dec << std::numeric_limits::radix << std::endl;
- flt << "#define FLT_MIN_EXP " << std::dec << std::numeric_limits::min_exponent << std::endl;
- flt << "#define FLT_MAX_EXP " << std::dec << std::numeric_limits::max_exponent << std::endl;
- flt << "#define FLT_MIN_10_EXP " << std::dec << std::numeric_limits::min_exponent10 << std::endl;
- flt << "#define FLT_MAX_10_EXP " << std::dec << std::numeric_limits::max_exponent10 << std::endl;
- flt << "#define FLT_TRAPS " << std::dec << std::numeric_limits::traps << std::endl;
- flt << "#define FLT_TINYNESS_BEFORE " << std::dec << std::numeric_limits::tinyness_before << std::endl;
-
- flt << "#define FLT_MIN " << "fennec::bit_cast(0x" << std::hex << std::bit_cast(std::numeric_limits::min() ) << ")" << std::endl;
- flt << "#define FLT_MAX " << "fennec::bit_cast(0x" << std::hex << std::bit_cast(std::numeric_limits::max() ) << ")" << std::endl;
- flt << "#define FLT_EPSILON " << "fennec::bit_cast(0x" << std::hex << std::bit_cast(std::numeric_limits::epsilon() ) << ")" << std::endl;
- flt << "#define FLT_INF " << "fennec::bit_cast(0x" << std::hex << std::bit_cast(std::numeric_limits::infinity() ) << ")" << std::endl;
- flt << "#define FLT_QUIET_NAN " << "fennec::bit_cast(0x" << std::hex << std::bit_cast(std::numeric_limits::quiet_NaN() ) << ")" << std::endl;
- flt << "#define FLT_SIGNALING_NAN " << "fennec::bit_cast(0x" << std::hex << std::bit_cast(std::numeric_limits::signaling_NaN()) << ")" << std::endl;
- flt << "#define FLT_DENORM_MIN " << "fennec::bit_cast(0x" << std::hex << std::bit_cast(std::numeric_limits::denorm_min() ) << ")" << std::endl;
- flt << "#define FLT_ROUND_ERR " << "fennec::bit_cast(0x" << std::hex << std::bit_cast(std::numeric_limits::round_error() ) << ")" << std::endl;
-
- flt << "" << std::endl;
-
- flt << "#define DBL_HAS_INFINITY " << std::dec << std::numeric_limits::has_infinity << std::endl;
- flt << "#define DBL_HAS_QUIET_NAN " << std::dec << std::numeric_limits::has_quiet_NaN << std::endl;
- flt << "#define DBL_HAS_SIGNALING_NAN " << std::dec << std::numeric_limits::has_signaling_NaN << std::endl;
- flt << "#define DBL_HAS_DENORM " << std::dec << std::numeric_limits::has_denorm << std::endl;
- flt << "#define DBL_HAS_DENORM_LOSS " << std::dec << std::numeric_limits::has_denorm_loss << std::endl;
- flt << "#define DBL_ROUNDS " << std::dec << std::numeric_limits::round_style << std::endl;
- flt << "#define DBL_IS_IEC559 " << std::dec << std::numeric_limits::is_iec559 << std::endl;
- flt << "#define DBL_MANT_DIG " << std::dec << std::numeric_limits::digits << std::endl;
- flt << "#define DBL_DIG " << std::dec << std::numeric_limits::digits10 << std::endl;
- flt << "#define DBL_DECIMAL_DIG " << std::dec << std::numeric_limits::max_digits10 << std::endl;
- flt << "#define DBL_RADIX " << std::dec << std::numeric_limits::radix << std::endl;
- flt << "#define DBL_MIN_EXP " << std::dec << std::numeric_limits::min_exponent << std::endl;
- flt << "#define DBL_MAX_EXP " << std::dec << std::numeric_limits::max_exponent << std::endl;
- flt << "#define DBL_MIN_10_EXP " << std::dec << std::numeric_limits::min_exponent10 << std::endl;
- flt << "#define DBL_MAX_10_EXP " << std::dec << std::numeric_limits::max_exponent10 << std::endl;
- flt << "#define DBL_TRAPS " << std::dec << std::numeric_limits::traps << std::endl;
- flt << "#define DBL_TINYNESS_BEFORE " << std::dec << std::numeric_limits::tinyness_before << std::endl;
-
- flt << "#define DBL_MIN " << "fennec::bit_cast(0x" << std::hex << std::bit_cast(std::numeric_limits::min() ) << "l)" << std::endl;
- flt << "#define DBL_MAX " << "fennec::bit_cast(0x" << std::hex << std::bit_cast(std::numeric_limits::max() ) << "l)" << std::endl;
- flt << "#define DBL_EPSILON " << "fennec::bit_cast(0x" << std::hex << std::bit_cast(std::numeric_limits::epsilon() ) << "l)" << std::endl;
- flt << "#define DBL_INF " << "fennec::bit_cast(0x" << std::hex << std::bit_cast(std::numeric_limits::infinity() ) << "l)" << std::endl;
- flt << "#define DBL_QUIET_NAN " << "fennec::bit_cast(0x" << std::hex << std::bit_cast(std::numeric_limits::quiet_NaN() ) << "l)" << std::endl;
- flt << "#define DBL_SIGNALING_NAN " << "fennec::bit_cast(0x" << std::hex << std::bit_cast(std::numeric_limits::signaling_NaN()) << "l)" << std::endl;
- flt << "#define DBL_DENORM_MIN " << "fennec::bit_cast(0x" << std::hex << std::bit_cast(std::numeric_limits::denorm_min() ) << "l)" << std::endl;
- flt << "#define DBL_ROUND_ERR " << "fennec::bit_cast(0x" << std::hex << std::bit_cast(std::numeric_limits::round_error() ) << "l)" << std::endl;
-
- flt << "" << std::endl;
-
- flt << "#endif // FENNEC_LANG_FLOAT_H" << std::endl;
-
- flt.close();
-
- return 0;
}