diff --git a/CMakeLists.txt b/CMakeLists.txt index 7110dab..230c653 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,6 @@ project(fennec) # External dependencies should be loaded here # SDL is a dependency of the project, added as a git submodule -set(SDL_STATIC 1) add_subdirectory(external/sdl) # CppTrace is a dependency of the project, added as a git submodule @@ -134,9 +133,9 @@ add_library(fennec STATIC # add metaprogramming templates as a dependency and also force documentation to be generated when fennec is compiled if(DOXYGEN_FOUND) - add_dependencies(fennec fennecdocs metaprogramming SDL3-static cpptrace::cpptrace) + add_dependencies(fennec fennecdocs metaprogramming SDL3-shared cpptrace::cpptrace) else() - add_dependencies(fennec metaprogramming SDL3-static cpptrace::cpptrace) + add_dependencies(fennec metaprogramming SDL3-shared cpptrace::cpptrace) endif() # Compiler Warning Flags @@ -148,11 +147,11 @@ endif() target_compile_options(fennec PUBLIC "-mavx" "-mavx2" "-mavx512f") # SIMD Instructions, automatic vectorization will occur -target_link_options(fennec PRIVATE "-nostdlib -nodefaultlibs -fno-exceptions -fdiagnostics-all-candidates") # Do not compile base fennec library with c++ stdlib +target_link_options(fennec PRIVATE "-nostdlib" "-fno-exceptions" "-fno-rtti" "-fdiagnostics-all-candidates") # Do not compile base fennec library with c++ stdlib # fennec does not use the C++ stdlib because it is bloated, difficult to read, and implementation defined. # This implementation is designed to be as readable as possible, and expose information that would otherwise be obfuscated -target_link_libraries(fennec PRIVATE SDL3-static cpptrace::cpptrace) +target_link_libraries(fennec PRIVATE SDL3-shared cpptrace::cpptrace) # add the test suite as a sub-project diff --git a/README.md b/README.md index 2f0797d..c4e5752 100644 --- a/README.md +++ b/README.md @@ -202,7 +202,7 @@ information displayed is correct. ### Licensing -The following statement is not legal advice, nor is it legally binding, and nor does it change the terms of the license. +The following content of this section is not legal advice, nor is it legally binding, and nor does it change the terms of the license. fennec is licensed under GPLv3. The primary reason for the choice of license is to dissuade corporations from modifying fennec and using it in a commercial manner. This of course does not bar them from using fennec commercially, however @@ -210,10 +210,42 @@ it will prevent them from being able to make the derivative work proprietary. Yo fennec however you wish according to the terms of the license, which does not bar you from commercializing software based on fennec. +If you wish to protect your game files, assets and generated content do not constitute a covered work and may be +copyrighted under a non-compliant license. Think of it in terms of using Blender to create a mesh for a game, then +licensing that mesh under another license. + +Any code that is linked against fennec or uses any part is by definition a covered work must be licensed under GPLv3. + +As long as you use the official editor, it will properly include licenses in project content when provided a license +and the name of the license holder. Archive packs will include the license holders non-GPLv3 license in them and any +linked code will be covered by GPLv3 under the name of the license holder. Be aware that the parts of your project +licensed under GPLv3 must be available upon request. + +A release project will consist of an executable, a shared library for your code, an archive pak, and streamable assets. +The executable and shared library are protected under the GPLv3 license, while the archive pak and streamable assets are +protected under your license. + +I will at no point provide official cross-compilation toolchains for fennec, if you wish to compile your project for +both Windows and Linux, working on Windows with WSL is likely your best option besides dual-booting. For Android and +iOS, using the GCC and Clang cross-compilation toolchains, respectively, will suffice. + +It is to my discretion whether I enforce the terms of the license on a party. + +The following practices are more likely to get my attention and enforcement: + - Redistributing a modified version of fennec that is not licensed under GPLv3 + - Distributing an engine that is, by definition, a derivative work of fennec that is not licensed under GPLv3 + - Distributing an editor that runs on fennec or its derivatives that is not licensed under GPLv3 + - Using fennec to train a Machine Learning or Artificial Intelligence algorithm that is not licensed under GPLv3 + - Non-compliance of GPLv3 in games with the following mechanics: + - Gacha Mechanics + - Gambling with real currency + - Subscription-Based Sales Model + - NFTs or Nonfungible Tokens + I encourage those who wish to commercialize derivative works crowdfund rather than use a sales model. I also ask that you kindly support me as a developer, I will set up a Buy Me a Coffee link at some point. -GPLv3 is bound by fair use; here is the clause, 17 U.S. Code § 107: +GPLv3 is bound by fair use; here is the clause, 17 U.S. Code § 107: ``` 107. Limitations on exclusive rights: Fair use @@ -237,6 +269,22 @@ consideration of all the above factors. If you have any questions or concerns, please seek legal council. If you believe someone else has violated the terms of this license, please contact me at [mslockbo@gmail.com](mailto:mslockbo@gmail.com). +I am aware of Universities with Game Development programs such as DigiPen Institute of Technology and Full-Sail +University which license student work to protect them and the faculty. + +Champlain College does not license student projects and constitutes fair use. + +I have not worked with Full-Sail University before, so I am not familiar with any of their staff members, and I will +require legal council to consult with them which may dissuade permission to use my engine. + +I hold a Bachelor's Degree in Computer Science and Real-Time Interactive Simulation from DigiPen Institute of Technology, +so I am familiar with their copyright policy. Ask your professor about usage of my engine, and they or someone with +appropriate standing will reach out to me. Eventually I may reach out on my own terms to negotiate usage of fennec for +educative purposes at DigiPen while retaining their license on student work. + +If your University is not listed here, reach out to your professor for permission. Ask them to reach out to me, I am +willing to work with educational institutes to protect both fennec and student work in accordance to university policy. +

diff --git a/include/fennec/fproc/io/common.h b/include/fennec/fproc/io/common.h index fe7917f..2c1a513 100644 --- a/include/fennec/fproc/io/common.h +++ b/include/fennec/fproc/io/common.h @@ -21,11 +21,40 @@ #include + +#ifdef _WIN32 + namespace fennec { -string getcwd(); +inline string getcwd() { + char cstr[MAX_PATH]; + if (GetCurrentDirectory(sizeof(str), str) == 0) { + return string(""); + } + return string(cstr); +} } +#else + +#include +#include + +namespace fennec +{ + +inline string getcwd() { + char cstr[PATH_MAX]; + if (::getcwd(cstr, sizeof(cstr)) == NULL) { + return string(""); + } + return string(cstr); +} + +} + +#endif + #endif // FENNEC_FPROC_IO_COMMON_H diff --git a/include/fennec/fproc/strings/string.h b/include/fennec/fproc/strings/string.h index 6470080..69fa240 100644 --- a/include/fennec/fproc/strings/string.h +++ b/include/fennec/fproc/strings/string.h @@ -136,13 +136,13 @@ public: /// \brief Dereference Operator /// \returns A const qualified pointer to the underlying allocation constexpr const char* operator*() const { - return _str; + return _str.data(); } /// /// \brief Implicit Dereference Cast constexpr operator const char*() const { - return _str; + return _str.data(); } @@ -163,9 +163,27 @@ public: if (i >= size()) { // bounds check return -1; } - n = min(n, max(_str, str.size()) + 1); + n = fennec::min(n, fennec::max(_str, str.size()) + 1); - return ::strncmp(_str + i, str, n); + return ::strncmp(_str.data() + i, str, n); + } + + /// + /// \brief String Comparison + /// \param ostr the string to compare against + /// \returns Zero if both strings are equal, otherwise a negative value if lhs appears before rhs according to the + /// current locale, otherwise a positive value. + constexpr int compare(const string& str, size_t i = 0, size_t n = npos) const { + if (i >= size()) { // bounds check + return -1; + } + n = min(n, max(size(), str.size()) + 1); + + return ::strncmp(_str.data() + i, str, n); + } + + constexpr bool operator==(const _string& str) const { + return compare(str) == 0; } /// diff --git a/include/fennec/memory/allocator.h b/include/fennec/memory/allocator.h index 451a240..cac1831 100644 --- a/include/fennec/memory/allocator.h +++ b/include/fennec/memory/allocator.h @@ -548,6 +548,13 @@ public: return _data; } + /// + /// \brief Getter for the real pointer to the allocated block of memory + /// \returns Pointer to the allocated memory. + constexpr const value_t* data() const { + return _data; + } + private: alloc_t _alloc; // Allocator object value_t* _data; // Handle for the memory block diff --git a/include/fennec/memory/new.h b/include/fennec/memory/new.h index 8b67bd9..88d831f 100644 --- a/include/fennec/memory/new.h +++ b/include/fennec/memory/new.h @@ -102,4 +102,37 @@ void operator delete (void* ptr, fennec::align_t, const fennec::nothrow_t&) noe void operator delete[](void* ptr, fennec::align_t, const fennec::nothrow_t&) noexcept; +// Platform specific code +#ifdef _WIN32 + +#define WIN32_LEAN_AND_MEAN +#include + +namespace fennec +{ + +inline size_T pagesize() { + SYSTEM_INFO sysInfo; + GetSystemInfo(&sysInfo); + return sysInfo.dwPageSize; +} + +} + +#else + +#include + +namespace fennec +{ + +inline size_t pagesize() { + return sysconf(_SC_PAGESIZE); +} + +} + +#endif + + #endif // FENNEC_MEMORY_NEW_H diff --git a/metaprogramming/CMakeLists.txt b/metaprogramming/CMakeLists.txt index 1722344..d1ff56b 100644 --- a/metaprogramming/CMakeLists.txt +++ b/metaprogramming/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.30) project(fennec-metaprogramming) -set(CMAKE_CXX_STANDARD 26) +set(CMAKE_CXX_STANDARD 23) add_executable(fennec-metaprogramming main.cpp float.h @@ -14,8 +14,6 @@ add_custom_command( VERBATIM ) -target_link_libraries(fennec-metaprogramming PRIVATE) - add_custom_target( metaprogramming DEPENDS .metaprogramming diff --git a/source/fproc/io/common.cpp b/source/fproc/io/common.cpp index 6efa02f..7a5b71f 100644 --- a/source/fproc/io/common.cpp +++ b/source/fproc/io/common.cpp @@ -18,39 +18,3 @@ #include -#ifdef _WIN32 - -namespace fennec -{ - -string getcwd() { - char cstr[MAX_PATH]; - if (GetCurrentDirectory(sizeof(str), str) == 0) { - return string(""); - } - string result(cstr); - return result; -} - -} - -#else - -#include -#include - -namespace fennec -{ - -string getcwd() { - char cstr[PATH_MAX]; - if (::getcwd(cstr, sizeof(cstr)) == NULL) { - return string(""); - } - string result(cstr); - return result; -} - -#endif - -} diff --git a/source/memory/new.cpp b/source/memory/new.cpp index 5919201..3e9b936 100644 --- a/source/memory/new.cpp +++ b/source/memory/new.cpp @@ -30,83 +30,50 @@ // Windows does not define ISO C aligned allocation functions #ifdef _WIN32 -inline void operator delete (void* ptr) noexcept { _aligned_free(ptr); } -inline void operator delete[](void* ptr) noexcept { _aligned_free(ptr); } -inline void operator delete (void* ptr, fennec::align_t) noexcept { ::_aligned_free(ptr); } -inline void operator delete[](void* ptr, fennec::align_t) noexcept { ::_aligned_free(ptr); } -inline void operator delete (void* ptr, fennec::size_t, fennec::align_t) noexcept { ::_aligned_free(ptr); } -inline void operator delete[](void* ptr, fennec::size_t, fennec::align_t) noexcept { ::_aligned_free(ptr); } -inline void operator delete (void* ptr, fennec::align_t, const fennec::nothrow_t&) noexcept { _aligned_free(ptr); } -inline void operator delete[](void* ptr, fennec::align_t, const fennec::nothrow_t&) noexcept { _aligned_free(ptr); } +void operator delete (void* ptr) noexcept { _aligned_free(ptr); } +void operator delete[](void* ptr) noexcept { _aligned_free(ptr); } +void operator delete (void* ptr, fennec::align_t) noexcept { ::_aligned_free(ptr); } +void operator delete[](void* ptr, fennec::align_t) noexcept { ::_aligned_free(ptr); } +void operator delete (void* ptr, fennec::size_t, fennec::align_t) noexcept { ::_aligned_free(ptr); } +void operator delete[](void* ptr, fennec::size_t, fennec::align_t) noexcept { ::_aligned_free(ptr); } +void operator delete (void* ptr, fennec::align_t, const fennec::nothrow_t&) noexcept { _aligned_free(ptr); } +void operator delete[](void* ptr, fennec::align_t, const fennec::nothrow_t&) noexcept { _aligned_free(ptr); } -inline void* operator new (fennec::size_t size, fennec::align_t align) { return _aligned_malloc(static_cast(align), size); } -inline void* operator new[](fennec::size_t size, fennec::align_t align) { return _aligned_malloc(static_cast(align), size); } -inline void* operator new (fennec::size_t size, fennec::align_t align, const fennec::nothrow_t&) { return _aligned_malloc(static_cast(align), size); } -inline void* operator new[](fennec::size_t size, fennec::align_t align, const fennec::nothrow_t&) { return _aligned_malloc(static_cast(align), size); } +void* operator new (fennec::size_t size, fennec::align_t align) { return _aligned_malloc(static_cast(align), size); } +void* operator new[](fennec::size_t size, fennec::align_t align) { return _aligned_malloc(static_cast(align), size); } +void* operator new (fennec::size_t size, fennec::align_t align, const fennec::nothrow_t&) { return _aligned_malloc(static_cast(align), size); } +void* operator new[](fennec::size_t size, fennec::align_t align, const fennec::nothrow_t&) { return _aligned_malloc(static_cast(align), size); } #else -inline void operator delete (void* ptr) noexcept { ::free(ptr); } -inline void operator delete[](void* ptr) noexcept { ::free(ptr); } -inline void operator delete (void* ptr, fennec::align_t) noexcept { ::free(ptr); } -inline void operator delete[](void* ptr, fennec::align_t) noexcept { ::free(ptr); } -inline void operator delete (void* ptr, fennec::size_t, fennec::align_t) noexcept { ::free(ptr); } -inline void operator delete[](void* ptr, fennec::size_t, fennec::align_t) noexcept { ::free(ptr); } -inline void operator delete (void* ptr, fennec::align_t, const fennec::nothrow_t&) noexcept { ::free(ptr); } -inline void operator delete[](void* ptr, fennec::align_t, const fennec::nothrow_t&) noexcept { ::free(ptr); } +void operator delete (void* ptr) noexcept { ::free(ptr); } +void operator delete[](void* ptr) noexcept { ::free(ptr); } +void operator delete (void* ptr, fennec::align_t) noexcept { ::free(ptr); } +void operator delete[](void* ptr, fennec::align_t) noexcept { ::free(ptr); } +void operator delete (void* ptr, fennec::size_t, fennec::align_t) noexcept { ::free(ptr); } +void operator delete[](void* ptr, fennec::size_t, fennec::align_t) noexcept { ::free(ptr); } +void operator delete (void* ptr, fennec::align_t, const fennec::nothrow_t&) noexcept { ::free(ptr); } +void operator delete[](void* ptr, fennec::align_t, const fennec::nothrow_t&) noexcept { ::free(ptr); } -inline void* operator new (fennec::size_t size, fennec::align_t align) { return ::aligned_alloc(static_cast(align), size); } -inline void* operator new[](fennec::size_t size, fennec::align_t align) { return ::aligned_alloc(static_cast(align), size); } -inline void* operator new (fennec::size_t size, fennec::align_t align, const fennec::nothrow_t&) { return ::aligned_alloc(static_cast(align), size); } -inline void* operator new[](fennec::size_t size, fennec::align_t align, const fennec::nothrow_t&) { return ::aligned_alloc(static_cast(align), size); } +void* operator new (fennec::size_t size, fennec::align_t align) { return ::aligned_alloc(static_cast(align), size); } +void* operator new[](fennec::size_t size, fennec::align_t align) { return ::aligned_alloc(static_cast(align), size); } +void* operator new (fennec::size_t size, fennec::align_t align, const fennec::nothrow_t&) { return ::aligned_alloc(static_cast(align), size); } +void* operator new[](fennec::size_t size, fennec::align_t align, const fennec::nothrow_t&) { return ::aligned_alloc(static_cast(align), size); } #endif // Allocation functions -inline void* operator new (fennec::size_t size) { return ::malloc(size); } -inline void* operator new[](fennec::size_t size) { return ::malloc(size); } -inline void* operator new (fennec::size_t size, const fennec::nothrow_t&) { return ::malloc(size); } -inline void* operator new[](fennec::size_t size, const fennec::nothrow_t&) { return ::malloc(size); } +void* operator new (fennec::size_t size) { return ::malloc(size); } +void* operator new[](fennec::size_t size) { return ::malloc(size); } +void* operator new (fennec::size_t size, const fennec::nothrow_t&) { return ::malloc(size); } +void* operator new[](fennec::size_t size, const fennec::nothrow_t&) { return ::malloc(size); } // Deallocation Functions -inline void operator delete (void* ptr, fennec::size_t) noexcept { ::free(ptr); } -inline void operator delete[](void* ptr, fennec::size_t) noexcept { ::free(ptr); } -inline void operator delete (void* ptr, const fennec::nothrow_t&) noexcept { ::free(ptr); } -inline void operator delete[](void* ptr, const fennec::nothrow_t&) noexcept { ::free(ptr); } -inline void operator delete (void* ptr, fennec::size_t, const fennec::nothrow_t&) noexcept { ::free(ptr); } -inline void operator delete[](void* ptr, fennec::size_t, const fennec::nothrow_t&) noexcept { ::free(ptr); } - - -// Platform specific code -#ifdef _WIN32 - -#define WIN32_LEAN_AND_MEAN -#include - -namespace fennec -{ - - size_T pagesize() { - SYSTEM_INFO sysInfo; - GetSystemInfo(&sysInfo); - return sysInfo.dwPageSize; - } - -} - -#else - -#include - -namespace fennec -{ - - size_t pagesize() { - return sysconf(_SC_PAGESIZE); - } - -} - -#endif +void operator delete (void* ptr, fennec::size_t) noexcept { ::free(ptr); } +void operator delete[](void* ptr, fennec::size_t) noexcept { ::free(ptr); } +void operator delete (void* ptr, const fennec::nothrow_t&) noexcept { ::free(ptr); } +void operator delete[](void* ptr, const fennec::nothrow_t&) noexcept { ::free(ptr); } +void operator delete (void* ptr, fennec::size_t, const fennec::nothrow_t&) noexcept { ::free(ptr); } +void operator delete[](void* ptr, fennec::size_t, const fennec::nothrow_t&) noexcept { ::free(ptr); } #endif diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index c367baf..5bbaddf 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.30) project(fennec-test) set(CMAKE_CXX_STANDARD 26) +set(CMAKE_C_STANDARD 26) add_executable(fennec-test main.cpp test.h @@ -22,8 +23,11 @@ add_executable(fennec-test main.cpp tests/fproc/test_strings.h tests/fproc/strings/test_cstring.h tests/test_fproc.h + tests/fproc/test_io.h ) +target_compile_definitions(fennec-test PUBLIC FENNEC_TEST_CWD="${CMAKE_RUNTIME_OUTPUT_DIRECTORY}") + target_link_libraries(fennec-test PRIVATE fennec ) \ No newline at end of file diff --git a/test/tests/fproc/test_io.h b/test/tests/fproc/test_io.h new file mode 100644 index 0000000..badc0a4 --- /dev/null +++ b/test/tests/fproc/test_io.h @@ -0,0 +1,40 @@ +// ===================================================================================================================== +// 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_TEST_FPROC_IO_H +#define FENNEC_TEST_FPROC_IO_H + +#include "../../test.h" + +#include + +namespace fennec +{ + +namespace test +{ + +inline void fennec_test_fproc_io() { + fennec_test_run(getcwd(), string(FENNEC_TEST_CWD)); +} + +} + +} + +#endif // FENNEC_TEST_FPROC_IO_H diff --git a/test/tests/test_fproc.h b/test/tests/test_fproc.h index 566e491..1dd1c2e 100644 --- a/test/tests/test_fproc.h +++ b/test/tests/test_fproc.h @@ -20,7 +20,9 @@ #define FENNEC_TEST_FPROC_H #include "../test.h" + #include "./fproc/test_strings.h" +#include "./fproc/test_io.h" namespace fennec { @@ -28,13 +30,16 @@ namespace fennec namespace test { -inline void fennec_test_fproc() -{ +inline void fennec_test_fproc() { fennec_test_header("strings"); fennec_test_spacer(2); fennec_test_fproc_strings(); fennec_test_spacer(3); + fennec_test_header("io"); + fennec_test_spacer(2); + fennec_test_fproc_io(); + fennec_test_spacer(3); } }