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; }