Basic window.
This commit is contained in:
91
.gitignore
vendored
Normal file
91
.gitignore
vendored
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
# Prerequisites
|
||||||
|
*.d
|
||||||
|
|
||||||
|
# Object files
|
||||||
|
*.o
|
||||||
|
*.ko
|
||||||
|
build/*.obj
|
||||||
|
*.elf
|
||||||
|
|
||||||
|
# Linker output
|
||||||
|
*.ilk
|
||||||
|
*.map
|
||||||
|
*.exp
|
||||||
|
|
||||||
|
# Precompiled Headers
|
||||||
|
*.gch
|
||||||
|
*.pch
|
||||||
|
|
||||||
|
# Libraries
|
||||||
|
*.lib
|
||||||
|
*.a
|
||||||
|
*.la
|
||||||
|
*.lo
|
||||||
|
|
||||||
|
# Shared objects (inc. Windows DLLs)
|
||||||
|
*.dll
|
||||||
|
*.so
|
||||||
|
*.so.*
|
||||||
|
*.dylib
|
||||||
|
|
||||||
|
# Executables
|
||||||
|
*.exe
|
||||||
|
*.out
|
||||||
|
*.app
|
||||||
|
*.i*86
|
||||||
|
*.x86_64
|
||||||
|
*.hex
|
||||||
|
|
||||||
|
# Debug files
|
||||||
|
*.dSYM/
|
||||||
|
*.su
|
||||||
|
*.idb
|
||||||
|
*.pdb
|
||||||
|
|
||||||
|
# Kernel Module Compile Results
|
||||||
|
*.mod*
|
||||||
|
*.cmd
|
||||||
|
.tmp_versions/
|
||||||
|
modules.order
|
||||||
|
Module.symvers
|
||||||
|
Mkfile.old
|
||||||
|
dkms.conf
|
||||||
|
|
||||||
|
# CMake
|
||||||
|
CMakeLists.txt.user
|
||||||
|
CMakeCache.txt
|
||||||
|
CMakeFiles
|
||||||
|
CMakeScripts
|
||||||
|
Testing
|
||||||
|
Makefile
|
||||||
|
cmake_install.cmake
|
||||||
|
install_manifest.txt
|
||||||
|
compile_commands.json
|
||||||
|
CTestTestfile.cmake
|
||||||
|
_deps
|
||||||
|
|
||||||
|
# Custom
|
||||||
|
build
|
||||||
|
.vscode
|
||||||
|
|
||||||
|
assets/testworld/tileset.png
|
||||||
|
oldsrc
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
yarn.lock
|
||||||
|
|
||||||
|
*.log
|
||||||
|
assets/borrowed
|
||||||
|
|
||||||
|
.~lock*
|
||||||
|
|
||||||
|
.vscode*
|
||||||
|
.VSCode*
|
||||||
|
|
||||||
|
/vita
|
||||||
|
|
||||||
|
._*
|
||||||
|
|
||||||
|
*~
|
||||||
|
|
||||||
|
/dist
|
55
CMakeLists.txt
Normal file
55
CMakeLists.txt
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
# Copyright (c) 2025 Dominic Masters
|
||||||
|
#
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
# https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
# Setup
|
||||||
|
cmake_minimum_required(VERSION 3.13)
|
||||||
|
set(CMAKE_C_STANDARD 99)
|
||||||
|
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
|
# Prep cache
|
||||||
|
set(DUSK_CACHE_TARGET "dusk-target")
|
||||||
|
|
||||||
|
# Platform configs
|
||||||
|
|
||||||
|
# Build variables
|
||||||
|
set(DUSK_ROOT_DIR "${CMAKE_SOURCE_DIR}")
|
||||||
|
set(DUSK_BUILD_DIR "${CMAKE_BINARY_DIR}")
|
||||||
|
set(DUSK_SOURCES_DIR "${DUSK_ROOT_DIR}/src")
|
||||||
|
set(DUSK_TEMP_DIR "${DUSK_BUILD_DIR}/temp")
|
||||||
|
set(DUSK_TOOLS_DIR "${DUSK_ROOT_DIR}/tools")
|
||||||
|
set(DUSK_ASSETS_DIR "${DUSK_ROOT_DIR}/assets")
|
||||||
|
set(DUSK_ASSETS_BUILD_DIR "${DUSK_BUILD_DIR}/assets")
|
||||||
|
set(DUSK_GENERATED_HEADERS_DIR "${DUSK_BUILD_DIR}/generated")
|
||||||
|
set(DUSK_TARGET_NAME "Dusk" CACHE INTERNAL ${DUSK_CACHE_TARGET})
|
||||||
|
set(DUSK_BUILD_BINARY ${DUSK_BUILD_DIR}/Dusk CACHE INTERNAL ${DUSK_CACHE_TARGET})
|
||||||
|
set(DUSK_ASSETS "" CACHE INTERNAL ${DUSK_CACHE_TARGET})
|
||||||
|
|
||||||
|
# Create directories
|
||||||
|
file(MAKE_DIRECTORY ${DUSK_GENERATED_HEADERS_DIR})
|
||||||
|
file(MAKE_DIRECTORY ${DUSK_ASSETS_BUILD_DIR})
|
||||||
|
|
||||||
|
# Init Project
|
||||||
|
project(${DUSK_TARGET_NAME}
|
||||||
|
VERSION 1.0.0
|
||||||
|
LANGUAGES C
|
||||||
|
)
|
||||||
|
|
||||||
|
# Executable
|
||||||
|
add_executable(${DUSK_TARGET_NAME})
|
||||||
|
|
||||||
|
# Get Libraries
|
||||||
|
add_subdirectory(lib)
|
||||||
|
|
||||||
|
# Add tools
|
||||||
|
add_subdirectory(tools)
|
||||||
|
|
||||||
|
# Add code
|
||||||
|
add_subdirectory(src)
|
||||||
|
|
||||||
|
# Include generated headers
|
||||||
|
target_include_directories(${DUSK_TARGET_NAME}
|
||||||
|
PUBLIC
|
||||||
|
${DUSK_GENERATED_HEADERS_DIR}
|
||||||
|
)
|
49
lib/CMakeLists.txt
Normal file
49
lib/CMakeLists.txt
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
# Copyright (c) 2025 Dominic Masters
|
||||||
|
#
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
# https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
include(FetchContent)
|
||||||
|
|
||||||
|
# GLFW
|
||||||
|
FetchContent_Declare(
|
||||||
|
glfw
|
||||||
|
GIT_REPOSITORY https://github.com/glfw/glfw
|
||||||
|
GIT_TAG 3.4
|
||||||
|
)
|
||||||
|
FetchContent_MakeAvailable(glfw)
|
||||||
|
|
||||||
|
# GLAD (For GLFW)
|
||||||
|
add_subdirectory(glad)
|
||||||
|
|
||||||
|
# CGLM
|
||||||
|
FetchContent_Declare(
|
||||||
|
cglm
|
||||||
|
GIT_REPOSITORY https://github.com/recp/cglm
|
||||||
|
GIT_TAG v0.9.4
|
||||||
|
)
|
||||||
|
FetchContent_MakeAvailable(cglm)
|
||||||
|
|
||||||
|
#LibArchive
|
||||||
|
FetchContent_Declare(
|
||||||
|
libarchive
|
||||||
|
GIT_REPOSITORY https://github.com/libarchive/libarchive
|
||||||
|
GIT_TAG v3.7.6
|
||||||
|
)
|
||||||
|
FetchContent_MakeAvailable(libarchive)
|
||||||
|
|
||||||
|
#libspng
|
||||||
|
FetchContent_Declare(
|
||||||
|
libspng
|
||||||
|
GIT_REPOSITORY https://github.com/randy408/libspng
|
||||||
|
GIT_TAG v0.7.4
|
||||||
|
)
|
||||||
|
FetchContent_MakeAvailable(libspng)
|
||||||
|
|
||||||
|
# SDL2
|
||||||
|
# FetchContent_Declare(
|
||||||
|
# SDL2
|
||||||
|
# GIT_REPOSITORY https://github.com/libsdl-org/SDL
|
||||||
|
# GIT_TAG release-2.0.14
|
||||||
|
# )
|
||||||
|
# FetchContent_MakeAvailable(SDL2)
|
12
lib/glad/CMakeLists.txt
Normal file
12
lib/glad/CMakeLists.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.11)
|
||||||
|
project(glad)
|
||||||
|
set(CMAKE_C_STANDARD 99)
|
||||||
|
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
|
add_library(${PROJECT_NAME}
|
||||||
|
src/glad.c
|
||||||
|
)
|
||||||
|
target_include_directories(${PROJECT_NAME}
|
||||||
|
PUBLIC
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||||
|
)
|
311
lib/glad/include/KHR/khrplatform.h
Normal file
311
lib/glad/include/KHR/khrplatform.h
Normal file
@ -0,0 +1,311 @@
|
|||||||
|
#ifndef __khrplatform_h_
|
||||||
|
#define __khrplatform_h_
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Copyright (c) 2008-2018 The Khronos Group Inc.
|
||||||
|
**
|
||||||
|
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
** copy of this software and/or associated documentation files (the
|
||||||
|
** "Materials"), to deal in the Materials without restriction, including
|
||||||
|
** without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||||
|
** permit persons to whom the Materials are furnished to do so, subject to
|
||||||
|
** the following conditions:
|
||||||
|
**
|
||||||
|
** The above copyright notice and this permission notice shall be included
|
||||||
|
** in all copies or substantial portions of the Materials.
|
||||||
|
**
|
||||||
|
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Khronos platform-specific types and definitions.
|
||||||
|
*
|
||||||
|
* The master copy of khrplatform.h is maintained in the Khronos EGL
|
||||||
|
* Registry repository at https://github.com/KhronosGroup/EGL-Registry
|
||||||
|
* The last semantic modification to khrplatform.h was at commit ID:
|
||||||
|
* 67a3e0864c2d75ea5287b9f3d2eb74a745936692
|
||||||
|
*
|
||||||
|
* Adopters may modify this file to suit their platform. Adopters are
|
||||||
|
* encouraged to submit platform specific modifications to the Khronos
|
||||||
|
* group so that they can be included in future versions of this file.
|
||||||
|
* Please submit changes by filing pull requests or issues on
|
||||||
|
* the EGL Registry repository linked above.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* See the Implementer's Guidelines for information about where this file
|
||||||
|
* should be located on your system and for more details of its use:
|
||||||
|
* http://www.khronos.org/registry/implementers_guide.pdf
|
||||||
|
*
|
||||||
|
* This file should be included as
|
||||||
|
* #include <KHR/khrplatform.h>
|
||||||
|
* by Khronos client API header files that use its types and defines.
|
||||||
|
*
|
||||||
|
* The types in khrplatform.h should only be used to define API-specific types.
|
||||||
|
*
|
||||||
|
* Types defined in khrplatform.h:
|
||||||
|
* khronos_int8_t signed 8 bit
|
||||||
|
* khronos_uint8_t unsigned 8 bit
|
||||||
|
* khronos_int16_t signed 16 bit
|
||||||
|
* khronos_uint16_t unsigned 16 bit
|
||||||
|
* khronos_int32_t signed 32 bit
|
||||||
|
* khronos_uint32_t unsigned 32 bit
|
||||||
|
* khronos_int64_t signed 64 bit
|
||||||
|
* khronos_uint64_t unsigned 64 bit
|
||||||
|
* khronos_intptr_t signed same number of bits as a pointer
|
||||||
|
* khronos_uintptr_t unsigned same number of bits as a pointer
|
||||||
|
* khronos_ssize_t signed size
|
||||||
|
* khronos_usize_t unsigned size
|
||||||
|
* khronos_float_t signed 32 bit floating point
|
||||||
|
* khronos_time_ns_t unsigned 64 bit time in nanoseconds
|
||||||
|
* khronos_utime_nanoseconds_t unsigned time interval or absolute time in
|
||||||
|
* nanoseconds
|
||||||
|
* khronos_stime_nanoseconds_t signed time interval in nanoseconds
|
||||||
|
* khronos_boolean_enum_t enumerated boolean type. This should
|
||||||
|
* only be used as a base type when a client API's boolean type is
|
||||||
|
* an enum. Client APIs which use an integer or other type for
|
||||||
|
* booleans cannot use this as the base type for their boolean.
|
||||||
|
*
|
||||||
|
* Tokens defined in khrplatform.h:
|
||||||
|
*
|
||||||
|
* KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
|
||||||
|
*
|
||||||
|
* KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
|
||||||
|
* KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
|
||||||
|
*
|
||||||
|
* Calling convention macros defined in this file:
|
||||||
|
* KHRONOS_APICALL
|
||||||
|
* KHRONOS_APIENTRY
|
||||||
|
* KHRONOS_APIATTRIBUTES
|
||||||
|
*
|
||||||
|
* These may be used in function prototypes as:
|
||||||
|
*
|
||||||
|
* KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
|
||||||
|
* int arg1,
|
||||||
|
* int arg2) KHRONOS_APIATTRIBUTES;
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC)
|
||||||
|
# define KHRONOS_STATIC 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
* Definition of KHRONOS_APICALL
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
* This precedes the return type of the function in the function prototype.
|
||||||
|
*/
|
||||||
|
#if defined(KHRONOS_STATIC)
|
||||||
|
/* If the preprocessor constant KHRONOS_STATIC is defined, make the
|
||||||
|
* header compatible with static linking. */
|
||||||
|
# define KHRONOS_APICALL
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
# define KHRONOS_APICALL __declspec(dllimport)
|
||||||
|
#elif defined (__SYMBIAN32__)
|
||||||
|
# define KHRONOS_APICALL IMPORT_C
|
||||||
|
#elif defined(__ANDROID__)
|
||||||
|
# define KHRONOS_APICALL __attribute__((visibility("default")))
|
||||||
|
#else
|
||||||
|
# define KHRONOS_APICALL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
* Definition of KHRONOS_APIENTRY
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
* This follows the return type of the function and precedes the function
|
||||||
|
* name in the function prototype.
|
||||||
|
*/
|
||||||
|
#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
|
||||||
|
/* Win32 but not WinCE */
|
||||||
|
# define KHRONOS_APIENTRY __stdcall
|
||||||
|
#else
|
||||||
|
# define KHRONOS_APIENTRY
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
* Definition of KHRONOS_APIATTRIBUTES
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
* This follows the closing parenthesis of the function prototype arguments.
|
||||||
|
*/
|
||||||
|
#if defined (__ARMCC_2__)
|
||||||
|
#define KHRONOS_APIATTRIBUTES __softfp
|
||||||
|
#else
|
||||||
|
#define KHRONOS_APIATTRIBUTES
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
* basic type definitions
|
||||||
|
*-----------------------------------------------------------------------*/
|
||||||
|
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Using <stdint.h>
|
||||||
|
*/
|
||||||
|
#include <stdint.h>
|
||||||
|
typedef int32_t khronos_int32_t;
|
||||||
|
typedef uint32_t khronos_uint32_t;
|
||||||
|
typedef int64_t khronos_int64_t;
|
||||||
|
typedef uint64_t khronos_uint64_t;
|
||||||
|
#define KHRONOS_SUPPORT_INT64 1
|
||||||
|
#define KHRONOS_SUPPORT_FLOAT 1
|
||||||
|
/*
|
||||||
|
* To support platform where unsigned long cannot be used interchangeably with
|
||||||
|
* inptr_t (e.g. CHERI-extended ISAs), we can use the stdint.h intptr_t.
|
||||||
|
* Ideally, we could just use (u)intptr_t everywhere, but this could result in
|
||||||
|
* ABI breakage if khronos_uintptr_t is changed from unsigned long to
|
||||||
|
* unsigned long long or similar (this results in different C++ name mangling).
|
||||||
|
* To avoid changes for existing platforms, we restrict usage of intptr_t to
|
||||||
|
* platforms where the size of a pointer is larger than the size of long.
|
||||||
|
*/
|
||||||
|
#if defined(__SIZEOF_LONG__) && defined(__SIZEOF_POINTER__)
|
||||||
|
#if __SIZEOF_POINTER__ > __SIZEOF_LONG__
|
||||||
|
#define KHRONOS_USE_INTPTR_T
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined(__VMS ) || defined(__sgi)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Using <inttypes.h>
|
||||||
|
*/
|
||||||
|
#include <inttypes.h>
|
||||||
|
typedef int32_t khronos_int32_t;
|
||||||
|
typedef uint32_t khronos_uint32_t;
|
||||||
|
typedef int64_t khronos_int64_t;
|
||||||
|
typedef uint64_t khronos_uint64_t;
|
||||||
|
#define KHRONOS_SUPPORT_INT64 1
|
||||||
|
#define KHRONOS_SUPPORT_FLOAT 1
|
||||||
|
|
||||||
|
#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Win32
|
||||||
|
*/
|
||||||
|
typedef __int32 khronos_int32_t;
|
||||||
|
typedef unsigned __int32 khronos_uint32_t;
|
||||||
|
typedef __int64 khronos_int64_t;
|
||||||
|
typedef unsigned __int64 khronos_uint64_t;
|
||||||
|
#define KHRONOS_SUPPORT_INT64 1
|
||||||
|
#define KHRONOS_SUPPORT_FLOAT 1
|
||||||
|
|
||||||
|
#elif defined(__sun__) || defined(__digital__)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sun or Digital
|
||||||
|
*/
|
||||||
|
typedef int khronos_int32_t;
|
||||||
|
typedef unsigned int khronos_uint32_t;
|
||||||
|
#if defined(__arch64__) || defined(_LP64)
|
||||||
|
typedef long int khronos_int64_t;
|
||||||
|
typedef unsigned long int khronos_uint64_t;
|
||||||
|
#else
|
||||||
|
typedef long long int khronos_int64_t;
|
||||||
|
typedef unsigned long long int khronos_uint64_t;
|
||||||
|
#endif /* __arch64__ */
|
||||||
|
#define KHRONOS_SUPPORT_INT64 1
|
||||||
|
#define KHRONOS_SUPPORT_FLOAT 1
|
||||||
|
|
||||||
|
#elif 0
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hypothetical platform with no float or int64 support
|
||||||
|
*/
|
||||||
|
typedef int khronos_int32_t;
|
||||||
|
typedef unsigned int khronos_uint32_t;
|
||||||
|
#define KHRONOS_SUPPORT_INT64 0
|
||||||
|
#define KHRONOS_SUPPORT_FLOAT 0
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generic fallback
|
||||||
|
*/
|
||||||
|
#include <stdint.h>
|
||||||
|
typedef int32_t khronos_int32_t;
|
||||||
|
typedef uint32_t khronos_uint32_t;
|
||||||
|
typedef int64_t khronos_int64_t;
|
||||||
|
typedef uint64_t khronos_uint64_t;
|
||||||
|
#define KHRONOS_SUPPORT_INT64 1
|
||||||
|
#define KHRONOS_SUPPORT_FLOAT 1
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Types that are (so far) the same on all platforms
|
||||||
|
*/
|
||||||
|
typedef signed char khronos_int8_t;
|
||||||
|
typedef unsigned char khronos_uint8_t;
|
||||||
|
typedef signed short int khronos_int16_t;
|
||||||
|
typedef unsigned short int khronos_uint16_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Types that differ between LLP64 and LP64 architectures - in LLP64,
|
||||||
|
* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
|
||||||
|
* to be the only LLP64 architecture in current use.
|
||||||
|
*/
|
||||||
|
#ifdef KHRONOS_USE_INTPTR_T
|
||||||
|
typedef intptr_t khronos_intptr_t;
|
||||||
|
typedef uintptr_t khronos_uintptr_t;
|
||||||
|
#elif defined(_WIN64)
|
||||||
|
typedef signed long long int khronos_intptr_t;
|
||||||
|
typedef unsigned long long int khronos_uintptr_t;
|
||||||
|
#else
|
||||||
|
typedef signed long int khronos_intptr_t;
|
||||||
|
typedef unsigned long int khronos_uintptr_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_WIN64)
|
||||||
|
typedef signed long long int khronos_ssize_t;
|
||||||
|
typedef unsigned long long int khronos_usize_t;
|
||||||
|
#else
|
||||||
|
typedef signed long int khronos_ssize_t;
|
||||||
|
typedef unsigned long int khronos_usize_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if KHRONOS_SUPPORT_FLOAT
|
||||||
|
/*
|
||||||
|
* Float type
|
||||||
|
*/
|
||||||
|
typedef float khronos_float_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if KHRONOS_SUPPORT_INT64
|
||||||
|
/* Time types
|
||||||
|
*
|
||||||
|
* These types can be used to represent a time interval in nanoseconds or
|
||||||
|
* an absolute Unadjusted System Time. Unadjusted System Time is the number
|
||||||
|
* of nanoseconds since some arbitrary system event (e.g. since the last
|
||||||
|
* time the system booted). The Unadjusted System Time is an unsigned
|
||||||
|
* 64 bit value that wraps back to 0 every 584 years. Time intervals
|
||||||
|
* may be either signed or unsigned.
|
||||||
|
*/
|
||||||
|
typedef khronos_uint64_t khronos_utime_nanoseconds_t;
|
||||||
|
typedef khronos_int64_t khronos_stime_nanoseconds_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Dummy value used to pad enum types to 32 bits.
|
||||||
|
*/
|
||||||
|
#ifndef KHRONOS_MAX_ENUM
|
||||||
|
#define KHRONOS_MAX_ENUM 0x7FFFFFFF
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enumerated boolean type
|
||||||
|
*
|
||||||
|
* Values other than zero should be considered to be true. Therefore
|
||||||
|
* comparisons should not be made against KHRONOS_TRUE.
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
KHRONOS_FALSE = 0,
|
||||||
|
KHRONOS_TRUE = 1,
|
||||||
|
KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
|
||||||
|
} khronos_boolean_enum_t;
|
||||||
|
|
||||||
|
#endif /* __khrplatform_h_ */
|
3694
lib/glad/include/glad/glad.h
Normal file
3694
lib/glad/include/glad/glad.h
Normal file
File diff suppressed because it is too large
Load Diff
1833
lib/glad/src/glad.c
Normal file
1833
lib/glad/src/glad.c
Normal file
File diff suppressed because it is too large
Load Diff
8
src/CMakeLists.txt
Normal file
8
src/CMakeLists.txt
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# Copyright (c) 2025 Dominic Masters
|
||||||
|
#
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
# https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
add_subdirectory(dusk)
|
||||||
|
add_subdirectory(duskgl)
|
||||||
|
add_subdirectory(duskglfw)
|
21
src/dusk/CMakeLists.txt
Normal file
21
src/dusk/CMakeLists.txt
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# Copyright (c) 2025 Dominic Masters
|
||||||
|
#
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
# https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
# Includes
|
||||||
|
target_include_directories(${DUSK_TARGET_NAME}
|
||||||
|
PUBLIC
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Sources
|
||||||
|
target_sources(${DUSK_TARGET_NAME}
|
||||||
|
PRIVATE
|
||||||
|
game.c
|
||||||
|
input.c
|
||||||
|
)
|
||||||
|
|
||||||
|
# Subdirs
|
||||||
|
add_subdirectory(assert)
|
||||||
|
add_subdirectory(display)
|
10
src/dusk/assert/CMakeLists.txt
Normal file
10
src/dusk/assert/CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# Copyright (c) 2025 Dominic Masters
|
||||||
|
#
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
# https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
# Sources
|
||||||
|
target_sources(${DUSK_TARGET_NAME}
|
||||||
|
PRIVATE
|
||||||
|
assert.c
|
||||||
|
)
|
79
src/dusk/assert/assert.c
Normal file
79
src/dusk/assert/assert.c
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2023 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "assert.h"
|
||||||
|
|
||||||
|
void assertTrueImpl(
|
||||||
|
const char *file,
|
||||||
|
const int32_t line,
|
||||||
|
const bool x,
|
||||||
|
const char *message
|
||||||
|
) {
|
||||||
|
if(x != true) {
|
||||||
|
fprintf(
|
||||||
|
stderr,
|
||||||
|
"Assertion Failed in %s:%i\n\n%s\n",
|
||||||
|
file,
|
||||||
|
line,
|
||||||
|
message
|
||||||
|
);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void assertFalseImpl(
|
||||||
|
const char *file,
|
||||||
|
const int32_t line,
|
||||||
|
bool x,
|
||||||
|
const char *message
|
||||||
|
) {
|
||||||
|
assertTrueImpl(file, line, !x, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
void assertUnreachableImpl(
|
||||||
|
const char *file,
|
||||||
|
const int32_t line,
|
||||||
|
const char *message
|
||||||
|
) {
|
||||||
|
assertTrueImpl(file, line, false, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
void assertNotNullImpl(
|
||||||
|
const char *file,
|
||||||
|
const int32_t line,
|
||||||
|
const void *pointer,
|
||||||
|
const char *message
|
||||||
|
) {
|
||||||
|
assertTrueImpl(
|
||||||
|
file,
|
||||||
|
line,
|
||||||
|
pointer != NULL,
|
||||||
|
message
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void assertNullImpl(
|
||||||
|
const char *file,
|
||||||
|
const int32_t line,
|
||||||
|
const void *pointer,
|
||||||
|
const char *message
|
||||||
|
) {
|
||||||
|
assertTrueImpl(
|
||||||
|
file,
|
||||||
|
line,
|
||||||
|
pointer == NULL,
|
||||||
|
message
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void assertDeprecatedImpl(
|
||||||
|
const char *file,
|
||||||
|
const int32_t line,
|
||||||
|
const char *message
|
||||||
|
) {
|
||||||
|
assertUnreachableImpl(file, line, message);
|
||||||
|
}
|
122
src/dusk/assert/assert.h
Normal file
122
src/dusk/assert/assert.h
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2023 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "dusk.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assert a given value to be true.
|
||||||
|
*
|
||||||
|
* @param file File that the assertion is being made from.
|
||||||
|
* @param line Line that the assertion is being made from.
|
||||||
|
* @param x Value to assert as true.
|
||||||
|
* @param message Message to throw against assertion failure.
|
||||||
|
*/
|
||||||
|
void assertTrueImpl(
|
||||||
|
const char *file,
|
||||||
|
const int32_t line,
|
||||||
|
const bool x,
|
||||||
|
const char *message
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts a given statement to be false.
|
||||||
|
*
|
||||||
|
* @param file File that the assertion is being made from.
|
||||||
|
* @param line Line that the assertion is being made from.
|
||||||
|
* @param x Value to assert as false.
|
||||||
|
* @param message Message to throw against assertion failure.
|
||||||
|
*/
|
||||||
|
void assertFalseImpl(
|
||||||
|
const char *file,
|
||||||
|
const int32_t line,
|
||||||
|
const bool x,
|
||||||
|
const char *message
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that a given line of code is unreachable. Essentially a forced
|
||||||
|
* assertion failure, good for "edge cases"
|
||||||
|
*
|
||||||
|
* @param file File that the assertion is being made from.
|
||||||
|
* @param line Line that the assertion is being made from.
|
||||||
|
* @param message Message to throw against assertion failure.
|
||||||
|
*/
|
||||||
|
void assertUnreachableImpl(
|
||||||
|
const char *file,
|
||||||
|
const int32_t line,
|
||||||
|
const char *message
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assert a given pointer to not point to a null pointer.
|
||||||
|
*
|
||||||
|
* @param file File that the assertion is being made from.
|
||||||
|
* @param line Line that the assertion is being made from.
|
||||||
|
* @param pointer Pointer to assert is not a null pointer.
|
||||||
|
* @param message Message to throw against assertion failure.
|
||||||
|
*/
|
||||||
|
void assertNotNullImpl(
|
||||||
|
const char *file,
|
||||||
|
const int32_t line,
|
||||||
|
const void *pointer,
|
||||||
|
const char *message
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts a given pointer to be a nullptr.
|
||||||
|
*
|
||||||
|
* @param file File that the assertion is being made from.
|
||||||
|
* @param line Line that the assertion is being made from.
|
||||||
|
* @param pointer Pointer to assert is nullptr.
|
||||||
|
* @param message Message to throw against assertion failure.
|
||||||
|
*/
|
||||||
|
void assertNullImpl(
|
||||||
|
const char *file,
|
||||||
|
const int32_t line,
|
||||||
|
const void *pointer,
|
||||||
|
const char *message
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts a function as being deprecated.
|
||||||
|
*
|
||||||
|
* @param file File that the assertion is being made from.
|
||||||
|
* @param line Line that the assertion is being made from.
|
||||||
|
* @param message Message to throw against assertion failure.
|
||||||
|
*/
|
||||||
|
void assertDeprecatedImpl(
|
||||||
|
const char *file,
|
||||||
|
const int32_t line,
|
||||||
|
const char *message
|
||||||
|
);
|
||||||
|
|
||||||
|
#define assertTrue(x, message) \
|
||||||
|
assertTrueImpl(__FILE__, __LINE__, x, message)
|
||||||
|
|
||||||
|
#define assertFalse(x, message) \
|
||||||
|
assertFalseImpl(__FILE__, __LINE__, x, message)
|
||||||
|
|
||||||
|
#define assertUnreachable(message) \
|
||||||
|
assertUnreachableImpl(__FILE__, __LINE__, message)
|
||||||
|
|
||||||
|
#define assertNotNull(pointer, message) \
|
||||||
|
assertNotNullImpl(__FILE__, __LINE__, pointer, message)
|
||||||
|
|
||||||
|
#define assertNull(pointer, message) \
|
||||||
|
assertNullImpl(__FILE__, __LINE__, pointer, message)
|
||||||
|
|
||||||
|
#define assertDeprecated(message) \
|
||||||
|
assertDeprecatedImpl(__FILE__, __LINE__, message)
|
||||||
|
|
||||||
|
#define assertStrLen(str, len, message) \
|
||||||
|
assertTrue(strlen(str) <= len, message)
|
||||||
|
|
||||||
|
#define assertStrLenMin(str, len, message) \
|
||||||
|
assertTrue(strlen(str) >= len, message)
|
||||||
|
|
||||||
|
// EOF
|
11
src/dusk/display/CMakeLists.txt
Normal file
11
src/dusk/display/CMakeLists.txt
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# Copyright (c) 2025 Dominic Masters
|
||||||
|
#
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
# https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
# Sources
|
||||||
|
target_sources(${DUSK_TARGET_NAME}
|
||||||
|
PRIVATE
|
||||||
|
)
|
||||||
|
|
||||||
|
# Subdirs
|
18
src/dusk/dusk.h
Normal file
18
src/dusk/dusk.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2024 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
typedef bool bool_t;
|
||||||
|
typedef char char_t;
|
17
src/dusk/game.c
Normal file
17
src/dusk/game.c
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "game.h"
|
||||||
|
#include "input.h"
|
||||||
|
|
||||||
|
void gameInit() {
|
||||||
|
inputInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void gameUpdate() {
|
||||||
|
inputUpdate();
|
||||||
|
}
|
19
src/dusk/game.h
Normal file
19
src/dusk/game.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "dusk.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the game.
|
||||||
|
*/
|
||||||
|
void gameInit();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the game.
|
||||||
|
*/
|
||||||
|
void gameUpdate();
|
46
src/dusk/input.c
Normal file
46
src/dusk/input.c
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "input.h"
|
||||||
|
|
||||||
|
inputstate_t INPUT;
|
||||||
|
|
||||||
|
void inputInit() {
|
||||||
|
memset(&INPUT, 0, sizeof(inputstate_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
void inputUpdate() {
|
||||||
|
memcpy(INPUT.previous, INPUT.current, sizeof(inputvalue_t) * INPUT_BIND_COUNT);
|
||||||
|
|
||||||
|
for(int i = 0; i < INPUT_BIND_COUNT; i++) {
|
||||||
|
INPUT.current[i] = inputStateGet(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inputvalue_t inputGet(inputbind_t bind) {
|
||||||
|
return INPUT.current[bind];
|
||||||
|
}
|
||||||
|
|
||||||
|
inputvalue_t inputGetPrevious(inputbind_t bind) {
|
||||||
|
return INPUT.previous[bind];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t inputWasPressed(inputbind_t bind) {
|
||||||
|
return inputGet(bind) != 0.0f && inputGetPrevious(bind) == 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t inputWasReleased(inputbind_t bind) {
|
||||||
|
return inputGet(bind) == 0.0f && inputGetPrevious(bind) != 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t inputIsDown(inputbind_t bind) {
|
||||||
|
return inputGet(bind) != 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t inputIsUp(inputbind_t bind) {
|
||||||
|
return inputGet(bind) == 0.0f;
|
||||||
|
}
|
96
src/dusk/input.h
Normal file
96
src/dusk/input.h
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "dusk.h"
|
||||||
|
|
||||||
|
typedef float_t inputvalue_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
INPUT_UP,
|
||||||
|
INPUT_DOWN,
|
||||||
|
INPUT_LEFT,
|
||||||
|
INPUT_RIGHT,
|
||||||
|
INPUT_ACCEPT,
|
||||||
|
INPUT_BACK,
|
||||||
|
INPUT_QUIT
|
||||||
|
} inputbind_t;
|
||||||
|
|
||||||
|
#define INPUT_BIND_COUNT INPUT_QUIT + 1
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
inputvalue_t current[INPUT_BIND_COUNT];
|
||||||
|
inputvalue_t previous[INPUT_BIND_COUNT];
|
||||||
|
} inputstate_t;
|
||||||
|
|
||||||
|
extern inputstate_t INPUT;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the input system.
|
||||||
|
*/
|
||||||
|
void inputInit();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the input system.
|
||||||
|
*/
|
||||||
|
void inputUpdate();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls on the platform to get the current state of a given input bind.
|
||||||
|
*
|
||||||
|
* @param input Input to check.
|
||||||
|
* @return Current state of the input.
|
||||||
|
*/
|
||||||
|
inputvalue_t inputStateGet(const inputbind_t input);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current value of the input bind.
|
||||||
|
*
|
||||||
|
* @param input Input to get.
|
||||||
|
* @return Current value of the input.
|
||||||
|
*/
|
||||||
|
inputvalue_t inputGet(const inputbind_t input);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the previous value of the input bind.
|
||||||
|
*
|
||||||
|
* @param input Input to get.
|
||||||
|
* @return Previous value of the input.
|
||||||
|
*/
|
||||||
|
inputvalue_t inputGetPrevious(const inputbind_t input);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the input was pressed this frame.
|
||||||
|
*
|
||||||
|
* @param input Input to check.
|
||||||
|
* @return Whether the input was pressed this frame.
|
||||||
|
*/
|
||||||
|
bool_t inputWasPressed(inputbind_t input);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the input was released this frame.
|
||||||
|
*
|
||||||
|
* @param input Input to check.
|
||||||
|
* @return Whether the input was released this frame.
|
||||||
|
*/
|
||||||
|
bool_t inputWasReleased(inputbind_t input);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the input is currently down.
|
||||||
|
*
|
||||||
|
* @param input Input to check.
|
||||||
|
* @return Whether the input is currently down.
|
||||||
|
*/
|
||||||
|
bool_t inputIsDown(inputbind_t input);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the input is currently up.
|
||||||
|
*
|
||||||
|
* @param input Input to check.
|
||||||
|
* @return Whether the input is currently up.
|
||||||
|
*/
|
||||||
|
bool_t inputIsUp(inputbind_t input);
|
11
src/dusk/util/CMakeLists.txt
Normal file
11
src/dusk/util/CMakeLists.txt
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# Copyright (c) 2023 Dominic Masters
|
||||||
|
#
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
# https:#opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
# Sources
|
||||||
|
target_sources(${DUSK_TARGET_NAME}
|
||||||
|
PRIVATE
|
||||||
|
math.c
|
||||||
|
random.c
|
||||||
|
)
|
24
src/dusk/util/math.c
Normal file
24
src/dusk/util/math.c
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2023 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "math.h"
|
||||||
|
#include "assert/assert.h"
|
||||||
|
|
||||||
|
int32_t mathClampi32(
|
||||||
|
const int32_t value,
|
||||||
|
const int32_t min,
|
||||||
|
const int32_t max
|
||||||
|
) {
|
||||||
|
assertTrue(max >= min, "mathClampi32: Max must be >= Min");
|
||||||
|
if(value < min) return min;
|
||||||
|
if(value > max) return max;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mathModi32(int32_t value, int32_t modulo) {
|
||||||
|
return ((value % modulo) + modulo) % modulo;
|
||||||
|
}
|
48
src/dusk/util/math.h
Normal file
48
src/dusk/util/math.h
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2023 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "dusk.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the minimum of two values.
|
||||||
|
* @param a First value.
|
||||||
|
* @param b Second value.
|
||||||
|
* @return The minimum of the two values.
|
||||||
|
*/
|
||||||
|
#define mathMin(a, b) ((a) < (b) ? (a) : (b))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the maximum of two values.
|
||||||
|
* @param a First value.
|
||||||
|
* @param b Second value.
|
||||||
|
* @return The maximum of the two values.
|
||||||
|
*/
|
||||||
|
#define mathMax(a, b) ((a) > (b) ? (a) : (b))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clamps a value between a min and max.
|
||||||
|
*
|
||||||
|
* @param value Value to clamp.
|
||||||
|
* @param min Minimum value to clamp value to.
|
||||||
|
* @param max Maximum value to clamp value to.
|
||||||
|
* @return The clamped value.
|
||||||
|
*/
|
||||||
|
int32_t mathClampi32(
|
||||||
|
const int32_t value,
|
||||||
|
const int32_t min,
|
||||||
|
const int32_t max
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the modulo of a value. For 32 bit integers.
|
||||||
|
*
|
||||||
|
* @param value Value to modulo.
|
||||||
|
* @param modulo Modulo value.
|
||||||
|
* @return The modulo of the value.
|
||||||
|
*/
|
||||||
|
int32_t mathModi32(int32_t value, int32_t modulo);
|
26
src/dusk/util/random.c
Normal file
26
src/dusk/util/random.c
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2024 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "random.h"
|
||||||
|
#include "assert/assert.h"
|
||||||
|
|
||||||
|
bool_t RANDOM_IS_INITIALIZED = false;
|
||||||
|
|
||||||
|
void randomInit() {
|
||||||
|
assertFalse(RANDOM_IS_INITIALIZED, "Random already initialized.");
|
||||||
|
srand(1234567890);
|
||||||
|
RANDOM_IS_INITIALIZED = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t randomInt32() {
|
||||||
|
assertTrue(RANDOM_IS_INITIALIZED, "Random not initialized.");
|
||||||
|
return rand();
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t randomInt32Range(int32_t min, int32_t max) {
|
||||||
|
return min + (rand() % (max - min));
|
||||||
|
}
|
32
src/dusk/util/random.h
Normal file
32
src/dusk/util/random.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2024 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "dusk.h"
|
||||||
|
|
||||||
|
extern bool_t RANDOM_IS_INITIALIZED;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the random number generator, and seeds it.
|
||||||
|
*/
|
||||||
|
void randomInit();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a random 32-bit integer.
|
||||||
|
*
|
||||||
|
* @return Random 32-bit integer.
|
||||||
|
*/
|
||||||
|
int32_t randomInt32();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a random 32-bit integer within a given range.
|
||||||
|
*
|
||||||
|
* @param min Minimum value.
|
||||||
|
* @param max Maximum value (exclusive).
|
||||||
|
* @return Random 32-bit integer within the given range.
|
||||||
|
*/
|
||||||
|
int32_t randomInt32Range(int32_t min, int32_t max);
|
29
src/duskgl/CMakeLists.txt
Normal file
29
src/duskgl/CMakeLists.txt
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# Copyright (c) 2025 Dominic Masters
|
||||||
|
#
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
# https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
# Libs
|
||||||
|
target_link_libraries(${DUSK_TARGET_NAME}
|
||||||
|
PUBLIC
|
||||||
|
cglm
|
||||||
|
archive_static
|
||||||
|
m
|
||||||
|
spng_static
|
||||||
|
)
|
||||||
|
|
||||||
|
# Includes
|
||||||
|
target_include_directories(${DUSK_TARGET_NAME}
|
||||||
|
PUBLIC
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Sources
|
||||||
|
target_sources(${DUSK_TARGET_NAME}
|
||||||
|
PRIVATE
|
||||||
|
asset.c
|
||||||
|
)
|
||||||
|
|
||||||
|
# Subdirs
|
||||||
|
add_subdirectory(assert)
|
||||||
|
add_subdirectory(display)
|
10
src/duskgl/assert/CMakeLists.txt
Normal file
10
src/duskgl/assert/CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# Copyright (c) 2025 Dominic Masters
|
||||||
|
#
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
# https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
# Sources
|
||||||
|
target_sources(${DUSK_TARGET_NAME}
|
||||||
|
PRIVATE
|
||||||
|
assertgl.c
|
||||||
|
)
|
68
src/duskgl/assert/assertgl.c
Normal file
68
src/duskgl/assert/assertgl.c
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2023 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "assert/assertgl.h"
|
||||||
|
#include "assert/assert.h"
|
||||||
|
|
||||||
|
void assertNotGLErrorCheck(const char_t *file, const int32_t line) {
|
||||||
|
assertNotNull(file, "File is an invlaid string");
|
||||||
|
assertTrue(line > 0, "assertNotGLErrorCheck: line is invalid");
|
||||||
|
|
||||||
|
char_t *buffer;
|
||||||
|
GLenum errorCode;
|
||||||
|
int32_t errorCount = 0;
|
||||||
|
|
||||||
|
while((errorCode = glGetError()) != GL_NO_ERROR) {
|
||||||
|
if(errorCount == 0) {
|
||||||
|
buffer = malloc(sizeof(char_t) * 4096);
|
||||||
|
sprintf(buffer, "assertNotGLErrorCheck: %s:%d\n", file, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
errorCount++;
|
||||||
|
|
||||||
|
switch (errorCode) {
|
||||||
|
case GL_INVALID_ENUM:
|
||||||
|
sprintf(buffer, "%s\nINVALID_ENUM", buffer);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GL_INVALID_VALUE:
|
||||||
|
sprintf(buffer, "%s\nINVALID_ENUM", buffer);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GL_INVALID_OPERATION:
|
||||||
|
sprintf(buffer, "%s\nINVALID_OPERATION", buffer);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// case GL_INVALID_FRAMEBUFFER_OPERATION:
|
||||||
|
// sprintf(buffer, "%s\nINVALID_FRAMEBUFFER_OPERATION", buffer);
|
||||||
|
// break;
|
||||||
|
|
||||||
|
case GL_OUT_OF_MEMORY:
|
||||||
|
sprintf(buffer, "%s\nOUT_OF_MEMORY", buffer);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GL_STACK_UNDERFLOW:
|
||||||
|
sprintf(buffer, "%s\nSTACK_UNDERFLOW", buffer);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GL_STACK_OVERFLOW:
|
||||||
|
sprintf(buffer, "%s\nSTACK_OVERFLOW", buffer);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
sprintf(buffer, "%s\nUNKNOWN_ERROR", buffer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(buffer, "%s (%i)\n", buffer, errorCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(errorCount > 0) {
|
||||||
|
assertUnreachable(buffer);
|
||||||
|
free(buffer);
|
||||||
|
}
|
||||||
|
}
|
22
src/duskgl/assert/assertgl.h
Normal file
22
src/duskgl/assert/assertgl.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "duskgl.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that there are no OpenGL errors.
|
||||||
|
*
|
||||||
|
* @param file The file the assertion is being made in.
|
||||||
|
* @param line The line the assertion is being made in.
|
||||||
|
*/
|
||||||
|
void assertNotGLErrorCheck(const char_t *file, const int32_t line);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that there are no OpenGL errors.
|
||||||
|
*/
|
||||||
|
#define assertNoGLError() assertNotGLErrorCheck(__FILE__, __LINE__)
|
222
src/duskgl/asset.c
Normal file
222
src/duskgl/asset.c
Normal file
@ -0,0 +1,222 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2024 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "asset.h"
|
||||||
|
#include "assert/assert.h"
|
||||||
|
#include "util/math.h"
|
||||||
|
|
||||||
|
asset_t ASSET;
|
||||||
|
|
||||||
|
void assetInit() {
|
||||||
|
const char_t *assetFilename = "dusk.tar";
|
||||||
|
char_t assetPath[FILENAME_MAX];
|
||||||
|
const char_t* scanLocations[] = {
|
||||||
|
EXECUTABLE_DIRECTORY
|
||||||
|
};
|
||||||
|
|
||||||
|
memset(&ASSET, 0, sizeof(asset_t));
|
||||||
|
|
||||||
|
// Try and find the asset file.
|
||||||
|
for(int32_t i = 0; i < sizeof(scanLocations) / sizeof(char_t*); i++) {
|
||||||
|
sprintf(assetPath, "%s/%s", scanLocations[i], assetFilename);
|
||||||
|
|
||||||
|
FILE *file = fopen(assetPath, "rb");
|
||||||
|
if(file == NULL) continue;
|
||||||
|
|
||||||
|
// File found.
|
||||||
|
ASSET.file = file;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure we found it.
|
||||||
|
assertNotNull(ASSET.file, "Failed to find asset file!");
|
||||||
|
}
|
||||||
|
|
||||||
|
void assetOpen(const char_t *path) {
|
||||||
|
assertNotNull(path, "Path is not valid!");
|
||||||
|
assertStrLen(path, FILENAME_MAX, "Path is too long!");
|
||||||
|
assertStrLenMin(path, 1, "Path is empty!");
|
||||||
|
|
||||||
|
// Make sure things are clean
|
||||||
|
assertNull(ASSET.archive, "Archive is not NULL!");
|
||||||
|
assertNull(ASSET.entry, "Entry is not NULL!");
|
||||||
|
assertNotNull(ASSET.file, "File is NULL!");
|
||||||
|
|
||||||
|
// Store path
|
||||||
|
strcpy(ASSET.path, path);
|
||||||
|
|
||||||
|
// Prepare data
|
||||||
|
ASSET.archive = archive_read_new();
|
||||||
|
assertNotNull(ASSET.archive, "Failed to init archive reader");
|
||||||
|
|
||||||
|
// Set up the reader
|
||||||
|
// archive_read_support_filter_bzip2(ASSET_ARCHIVE);
|
||||||
|
archive_read_support_format_tar(ASSET.archive);
|
||||||
|
|
||||||
|
// Set the archive reader callbacks
|
||||||
|
archive_read_set_open_callback(ASSET.archive, &assetArchiveOpen);
|
||||||
|
archive_read_set_read_callback(ASSET.archive, &assetArchiveRead);
|
||||||
|
archive_read_set_seek_callback(ASSET.archive, &assetArchiveSeek);
|
||||||
|
archive_read_set_close_callback(ASSET.archive, &assetArchiveClose);
|
||||||
|
archive_read_set_callback_data(ASSET.archive, ASSET.buffer);// TODO: Not needed?
|
||||||
|
|
||||||
|
// Open the archive
|
||||||
|
int32_t ret = archive_read_open1(ASSET.archive);
|
||||||
|
assertTrue(ret == ARCHIVE_OK, "Failed to open archive!");
|
||||||
|
|
||||||
|
// Iterate over each file.
|
||||||
|
while(archive_read_next_header(ASSET.archive, &ASSET.entry) == ARCHIVE_OK) {
|
||||||
|
// What file is at this position?
|
||||||
|
const char_t *headerFile = (char_t*)archive_entry_pathname(ASSET.entry);
|
||||||
|
|
||||||
|
// Compare if this is the file we are looking for, if it is just exit the
|
||||||
|
// function
|
||||||
|
if(strcmp(headerFile, ASSET.path) == 0) return;
|
||||||
|
|
||||||
|
// It is not, skip it.
|
||||||
|
int32_t ret = archive_read_data_skip(ASSET.archive);
|
||||||
|
assertTrue(ret == ARCHIVE_OK, "Failed to skip data!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we get here we did not find the find in the archive.
|
||||||
|
assertUnreachable("Failed to find file!");
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t assetGetSize() {
|
||||||
|
assertNotNull(ASSET.archive, "Archive is NULL!");
|
||||||
|
assertNotNull(ASSET.entry, "Entry is NULL!");
|
||||||
|
assertTrue(archive_entry_size_is_set(ASSET.entry), "Entry size is not set!");
|
||||||
|
return archive_entry_size(ASSET.entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t assetRead(
|
||||||
|
uint8_t *buffer,
|
||||||
|
const size_t bufferSize
|
||||||
|
) {
|
||||||
|
assertNotNull(ASSET.archive, "Archive is NULL!");
|
||||||
|
assertNotNull(ASSET.entry, "Entry is NULL!");
|
||||||
|
assertNotNull(buffer, "Buffer is NULL!");
|
||||||
|
assertTrue(bufferSize > 0, "Buffer size must be greater than 0!");
|
||||||
|
|
||||||
|
ssize_t read = archive_read_data(ASSET.archive, buffer, bufferSize);
|
||||||
|
if(read == ARCHIVE_FATAL) {
|
||||||
|
assertUnreachable(archive_error_string(ASSET.archive));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
assertTrue(read != ARCHIVE_RETRY, "Failed to read data (RETRY)!");
|
||||||
|
assertTrue(read != ARCHIVE_WARN, "Failed to read data (WARN)!");
|
||||||
|
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t assetReadUntil(
|
||||||
|
uint8_t *buffer,
|
||||||
|
const char_t c,
|
||||||
|
const size_t maxLength
|
||||||
|
) {
|
||||||
|
if(buffer == NULL) {
|
||||||
|
assertTrue(
|
||||||
|
maxLength == -1, "If no buffer is provided, maxLength must be -1."
|
||||||
|
);
|
||||||
|
uint8_t tBuffer[1];
|
||||||
|
size_t read = 0;
|
||||||
|
while(assetRead(tBuffer, 1) == 1 && (char_t)tBuffer[0] != c) read++;
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t read = 0;
|
||||||
|
while(read < maxLength) {
|
||||||
|
// TODO: Read more than 1 char at a time.
|
||||||
|
read += assetRead(buffer + read, 1);
|
||||||
|
if((char_t)buffer[read-1] == c) return read - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void assetSkip(const size_t length) {
|
||||||
|
assertNotNull(ASSET.archive, "Archive is NULL!");
|
||||||
|
assertNotNull(ASSET.entry, "Entry is NULL!");
|
||||||
|
|
||||||
|
// Asset archive does not support skipping, so we have to read and discard.
|
||||||
|
uint8_t buffer[ASSET_BUFFER_SIZE];
|
||||||
|
size_t remaining = length;
|
||||||
|
do {
|
||||||
|
size_t toRead = mathMin(remaining, ASSET_BUFFER_SIZE);
|
||||||
|
size_t read = assetRead(buffer, toRead);
|
||||||
|
assertTrue(read == toRead, "Failed to skip data! (overskip?)");
|
||||||
|
remaining -= read;
|
||||||
|
} while(remaining > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void assetClose() {
|
||||||
|
if(ASSET.archive == NULL) return;
|
||||||
|
|
||||||
|
assertNotNull(ASSET.archive, "Archive is NULL!");
|
||||||
|
assertNotNull(ASSET.entry, "Entry is NULL!");
|
||||||
|
|
||||||
|
int32_t ret = archive_read_free(ASSET.archive);
|
||||||
|
assertTrue(ret == ARCHIVE_OK, "Failed to close archive!");
|
||||||
|
|
||||||
|
assertNull(ASSET.archive, "Archive is not NULL? Cleanup incorrect.");
|
||||||
|
}
|
||||||
|
|
||||||
|
void assetDispose() {
|
||||||
|
assertNull(ASSET.archive, "Asset disposing but asset is currently open?");
|
||||||
|
assertNull(ASSET.entry, "Asset disposing but entry is currently open?");
|
||||||
|
assertNotNull(ASSET.file, "Asset disposing but file is NULL?");
|
||||||
|
|
||||||
|
fclose(ASSET.file);
|
||||||
|
memset(&ASSET, 0, sizeof(asset_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Libarchive callbacks
|
||||||
|
|
||||||
|
ssize_t assetArchiveRead(
|
||||||
|
struct archive *archive,
|
||||||
|
void *data,
|
||||||
|
const void **buffer
|
||||||
|
) {
|
||||||
|
assertNotNull(archive, "Archive is NULL!");
|
||||||
|
assertNotNull(data, "Data is NULL!");
|
||||||
|
assertNotNull(buffer, "Buffer is NULL!");
|
||||||
|
|
||||||
|
*buffer = data;
|
||||||
|
size_t read = fread(data, 1, ASSET_BUFFER_SIZE, ASSET.file);
|
||||||
|
if(ferror(ASSET.file)) return ARCHIVE_FATAL;
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t assetArchiveSeek(
|
||||||
|
struct archive *archive,
|
||||||
|
void *data,
|
||||||
|
int64_t offset,
|
||||||
|
int32_t whence
|
||||||
|
) {
|
||||||
|
assertNotNull(archive, "Archive is NULL!");
|
||||||
|
assertNotNull(data, "Data is NULL!");
|
||||||
|
assertTrue(offset > 0, "Offset must be greater than 0!");
|
||||||
|
assertNotNull(ASSET.file, "File is NULL!");
|
||||||
|
int32_t ret = fseek(ASSET.file, offset, whence);
|
||||||
|
assertTrue(ret == 0, "Failed to seek!");
|
||||||
|
return ftell(ASSET.file);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t assetArchiveOpen(struct archive *a, void *data) {
|
||||||
|
int32_t ret = fseek(ASSET.file, 0, SEEK_SET);
|
||||||
|
assertTrue(ret == 0, "Failed to seek to start of file!");
|
||||||
|
return ARCHIVE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t assetArchiveClose(struct archive *a, void *data) {
|
||||||
|
assertNotNull(ASSET.file, "File is NULL!");
|
||||||
|
|
||||||
|
ASSET.archive = NULL;
|
||||||
|
ASSET.entry = NULL;
|
||||||
|
|
||||||
|
return ARCHIVE_OK;
|
||||||
|
}
|
137
src/duskgl/asset.h
Normal file
137
src/duskgl/asset.h
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "duskgl.h"
|
||||||
|
#include <archive.h>
|
||||||
|
#include <archive_entry.h>
|
||||||
|
|
||||||
|
#define ASSET_BUFFER_SIZE 32768
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
FILE *file;
|
||||||
|
struct archive *archive;
|
||||||
|
struct archive_entry *entry;
|
||||||
|
uint8_t buffer[ASSET_BUFFER_SIZE];
|
||||||
|
|
||||||
|
// ?
|
||||||
|
char_t path[FILENAME_MAX];
|
||||||
|
} asset_t;
|
||||||
|
|
||||||
|
extern asset_t ASSET;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the asset manager.
|
||||||
|
*/
|
||||||
|
void assetInit();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens an asset by its filename (within the asset archive). Asset paths should
|
||||||
|
* always use the unix forward slash '/' as a path separator.
|
||||||
|
*
|
||||||
|
* @param path The path to the asset within the archive.
|
||||||
|
*/
|
||||||
|
void assetOpen(const char *path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the size of the asset.
|
||||||
|
*
|
||||||
|
* @return The size of the asset.
|
||||||
|
*/
|
||||||
|
size_t assetGetSize();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the asset into the buffer.
|
||||||
|
*
|
||||||
|
* @param buffer The buffer to read the asset into.
|
||||||
|
* @param bufferSize The size of the buffer.
|
||||||
|
* @return The amount of data read.
|
||||||
|
*/
|
||||||
|
size_t assetRead(uint8_t *buffer, const size_t bufferSize);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads ahead in the buffer until either the end of the buffer, or the
|
||||||
|
* specified character is found. Return value will be -1 if the character was
|
||||||
|
* not found.
|
||||||
|
*
|
||||||
|
* Buffer can be NULL if you just want to skip ahead.
|
||||||
|
*
|
||||||
|
* Returned value will be either the amount of data read into the buffer, which
|
||||||
|
* excludes the extra 1 character that was read from the asset. If the character
|
||||||
|
* was not found, -1 will be returned.
|
||||||
|
*
|
||||||
|
* @param buffer Buffer to read into.
|
||||||
|
* @param c Character to read until.
|
||||||
|
* @param maxLength Maximum length to read.
|
||||||
|
* @return -1 if the character was not found, otherwise the amount of data read.
|
||||||
|
*/
|
||||||
|
size_t assetReadUntil(uint8_t *buffer, const char c, const size_t maxLength);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Skips ahead in the buffer by the specified length.
|
||||||
|
*
|
||||||
|
* @param length The length to skip ahead by.
|
||||||
|
*/
|
||||||
|
void assetSkip(const size_t length);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes the asset.
|
||||||
|
*/
|
||||||
|
void assetClose();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys and cleans up the asset manager.
|
||||||
|
*/
|
||||||
|
void assetDispose();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal read method provided to libarchive api.
|
||||||
|
*
|
||||||
|
* @param archive The archive to read from.
|
||||||
|
* @param data The data to read into.
|
||||||
|
* @param buffer The buffer to read from.
|
||||||
|
* @return The amount of data read.
|
||||||
|
*/
|
||||||
|
ssize_t assetArchiveRead(
|
||||||
|
struct archive *archive,
|
||||||
|
void *data,
|
||||||
|
const void **buffer
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal seek method provided to libarchive api.
|
||||||
|
*
|
||||||
|
* @param archive The archive to seek in.
|
||||||
|
* @param data The data to seek in.
|
||||||
|
* @param offset Offset bytes to seek.
|
||||||
|
* @param whence Relative to whence to seek.
|
||||||
|
* @return The new position.
|
||||||
|
*/
|
||||||
|
int64_t assetArchiveSeek(
|
||||||
|
struct archive *archive,
|
||||||
|
void *data,
|
||||||
|
int64_t offset,
|
||||||
|
int32_t whence
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal open method provided to libarchive api.
|
||||||
|
*
|
||||||
|
* @param archive The archive to open.
|
||||||
|
* @param data The data to open.
|
||||||
|
* @return The result of the open.
|
||||||
|
*/
|
||||||
|
int32_t assetArchiveOpen(struct archive *a, void *data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal close method provided to libarchive api.
|
||||||
|
*
|
||||||
|
* @param archive The archive to close.
|
||||||
|
* @param data The data to close.
|
||||||
|
* @return The result of the close.
|
||||||
|
*/
|
||||||
|
int32_t assetArchiveClose(struct archive *a, void *data);
|
12
src/duskgl/display/CMakeLists.txt
Normal file
12
src/duskgl/display/CMakeLists.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# Copyright (c) 2025 Dominic Masters
|
||||||
|
#
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
# https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
# Sources
|
||||||
|
target_sources(${DUSK_TARGET_NAME}
|
||||||
|
PRIVATE
|
||||||
|
render.c
|
||||||
|
)
|
||||||
|
|
||||||
|
# Subdirs
|
24
src/duskgl/display/render.c
Normal file
24
src/duskgl/display/render.c
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "assert/assertgl.h"
|
||||||
|
#include "render.h"
|
||||||
|
|
||||||
|
render_t RENDER;
|
||||||
|
|
||||||
|
void renderInit() {
|
||||||
|
memset(&RENDER, 0, sizeof(render_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
void renderUpdate() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void renderOverworld() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void renderDispose() {
|
||||||
|
}
|
35
src/duskgl/display/render.h
Normal file
35
src/duskgl/display/render.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "duskgl.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int32_t nothing;
|
||||||
|
} render_t;
|
||||||
|
|
||||||
|
extern render_t RENDER;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the render system.
|
||||||
|
*/
|
||||||
|
void renderInit();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the render system.
|
||||||
|
*/
|
||||||
|
void renderUpdate();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders the overworld scene.
|
||||||
|
*/
|
||||||
|
void renderOverworld();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disposes of the render system.
|
||||||
|
*/
|
||||||
|
void renderDispose();
|
20
src/duskgl/duskgl.h
Normal file
20
src/duskgl/duskgl.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "dusk.h"
|
||||||
|
#include "duskglimpl.h"
|
||||||
|
|
||||||
|
#include <cglm/cglm.h>
|
||||||
|
#include <libgen.h>
|
||||||
|
#include <float.h>
|
||||||
|
|
||||||
|
typedef float float_t;
|
||||||
|
typedef double double_t;
|
||||||
|
|
||||||
|
extern char_t EXECUTABLE_PATH[];
|
||||||
|
extern char_t EXECUTABLE_DIRECTORY[];
|
27
src/duskglfw/CMakeLists.txt
Normal file
27
src/duskglfw/CMakeLists.txt
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# Copyright (c) 2025 Dominic Masters
|
||||||
|
#
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
# https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
# Libs
|
||||||
|
target_link_libraries(${DUSK_TARGET_NAME}
|
||||||
|
PUBLIC
|
||||||
|
glfw
|
||||||
|
glad
|
||||||
|
)
|
||||||
|
|
||||||
|
# Includes
|
||||||
|
target_include_directories(${DUSK_TARGET_NAME}
|
||||||
|
PUBLIC
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Sources
|
||||||
|
target_sources(${DUSK_TARGET_NAME}
|
||||||
|
PRIVATE
|
||||||
|
main.c
|
||||||
|
input.c
|
||||||
|
)
|
||||||
|
|
||||||
|
# Subdirs
|
||||||
|
add_subdirectory(display)
|
10
src/duskglfw/display/CMakeLists.txt
Normal file
10
src/duskglfw/display/CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# Copyright (c) 2025 Dominic Masters
|
||||||
|
#
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
# https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
# Sources
|
||||||
|
target_sources(${DUSK_TARGET_NAME}
|
||||||
|
PRIVATE
|
||||||
|
window.c
|
||||||
|
)
|
71
src/duskglfw/display/window.c
Normal file
71
src/duskglfw/display/window.c
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "window.h"
|
||||||
|
|
||||||
|
GLFWwindow* window;
|
||||||
|
int32_t WINDOW_WIDTH;
|
||||||
|
int32_t WINDOW_HEIGHT;
|
||||||
|
|
||||||
|
int32_t windowInit() {
|
||||||
|
// Initialize GLFW
|
||||||
|
if(!glfwInit()) {
|
||||||
|
const char* description;
|
||||||
|
int code = glfwGetError(&description);
|
||||||
|
if (description) {
|
||||||
|
printf("GLFW Error %d: %s\n", code, description);
|
||||||
|
} else {
|
||||||
|
printf("GLFW Error: Unknown error\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a windowed mode window and its OpenGL contex
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||||
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||||
|
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
|
||||||
|
glfwWindowHint(GLFW_MAXIMIZED, GLFW_FALSE);
|
||||||
|
|
||||||
|
window = glfwCreateWindow(
|
||||||
|
WINDOW_WIDTH_DEFAULT, WINDOW_HEIGHT_DEFAULT,
|
||||||
|
"Dusk",
|
||||||
|
NULL, NULL
|
||||||
|
);
|
||||||
|
if(!window) {
|
||||||
|
glfwTerminate();
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make the window's context current
|
||||||
|
glfwMakeContextCurrent(window);
|
||||||
|
|
||||||
|
// Get initial framebuffer size
|
||||||
|
glfwGetFramebufferSize(window, &WINDOW_WIDTH, &WINDOW_HEIGHT);
|
||||||
|
|
||||||
|
// Load OpenGL functions using glad or another loader here if necessary
|
||||||
|
if(!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) return -3;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t windowShouldClose() {
|
||||||
|
return glfwWindowShouldClose(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
void windowUpdate() {
|
||||||
|
glfwSwapBuffers(window);
|
||||||
|
glfwPollEvents();
|
||||||
|
|
||||||
|
glfwGetFramebufferSize(window, &WINDOW_WIDTH, &WINDOW_HEIGHT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void windowDispose() {
|
||||||
|
glfwDestroyWindow(window);
|
||||||
|
glfwTerminate();
|
||||||
|
}
|
40
src/duskglfw/display/window.h
Normal file
40
src/duskglfw/display/window.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "duskglfw.h"
|
||||||
|
|
||||||
|
#define WINDOW_WIDTH_DEFAULT 800
|
||||||
|
#define WINDOW_HEIGHT_DEFAULT 600
|
||||||
|
|
||||||
|
extern GLFWwindow* window;
|
||||||
|
extern int32_t WINDOW_WIDTH;
|
||||||
|
extern int32_t WINDOW_HEIGHT;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the game render window.
|
||||||
|
*
|
||||||
|
* @return 0 on success, any other value on failure.
|
||||||
|
*/
|
||||||
|
int32_t windowInit();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the window should close.
|
||||||
|
*
|
||||||
|
* @return true if the window should close, false otherwise.
|
||||||
|
*/
|
||||||
|
bool_t windowShouldClose();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the window subsystem.
|
||||||
|
*/
|
||||||
|
void windowUpdate();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disposes of the window.
|
||||||
|
*/
|
||||||
|
void windowDispose();
|
9
src/duskglfw/duskglfw.h
Normal file
9
src/duskglfw/duskglfw.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "duskgl.h"
|
11
src/duskglfw/duskglimpl.h
Normal file
11
src/duskglfw/duskglimpl.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "dusk.h"
|
||||||
|
#include <glad/glad.h>
|
||||||
|
#include <GLFW/glfw3.h>
|
52
src/duskglfw/input.c
Normal file
52
src/duskglfw/input.c
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "input.h"
|
||||||
|
#include "display/window.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint16_t glfw;
|
||||||
|
inputbind_t bind;
|
||||||
|
} glfwkeybindmap_t;
|
||||||
|
|
||||||
|
glfwkeybindmap_t GLFW_KEY_BIND_MAP[] = {
|
||||||
|
{GLFW_KEY_W, INPUT_UP},
|
||||||
|
{GLFW_KEY_UP, INPUT_UP},
|
||||||
|
|
||||||
|
{GLFW_KEY_S, INPUT_DOWN},
|
||||||
|
{GLFW_KEY_DOWN, INPUT_DOWN},
|
||||||
|
|
||||||
|
{GLFW_KEY_A, INPUT_LEFT},
|
||||||
|
{GLFW_KEY_LEFT, INPUT_LEFT},
|
||||||
|
|
||||||
|
{GLFW_KEY_D, INPUT_RIGHT},
|
||||||
|
{GLFW_KEY_RIGHT, INPUT_RIGHT},
|
||||||
|
|
||||||
|
{GLFW_KEY_ENTER, INPUT_ACCEPT},
|
||||||
|
{GLFW_KEY_E, INPUT_ACCEPT},
|
||||||
|
{GLFW_KEY_SPACE, INPUT_ACCEPT},
|
||||||
|
|
||||||
|
{GLFW_KEY_ESCAPE, INPUT_BACK},
|
||||||
|
{GLFW_KEY_BACKSPACE, INPUT_BACK},
|
||||||
|
{GLFW_KEY_Q, INPUT_BACK},
|
||||||
|
|
||||||
|
{0, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
inputvalue_t inputStateGet(const inputbind_t input) {
|
||||||
|
|
||||||
|
// Handle keybinds
|
||||||
|
glfwkeybindmap_t *map = GLFW_KEY_BIND_MAP;
|
||||||
|
do {
|
||||||
|
if(map->bind == input && glfwGetKey(window, map->glfw) == GLFW_PRESS) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
map++;
|
||||||
|
} while(map->glfw != 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
72
src/duskglfw/main.c
Normal file
72
src/duskglfw/main.c
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "assert/assert.h"
|
||||||
|
#include "display/window.h"
|
||||||
|
#include "display/render.h"
|
||||||
|
#include "game.h"
|
||||||
|
#include "asset.h"
|
||||||
|
|
||||||
|
#define TIME_BETWEEN_UPDATES (1.0f / 60.0f)
|
||||||
|
|
||||||
|
float_t timeUntilNextUpdate;
|
||||||
|
|
||||||
|
char_t EXECUTABLE_PATH[FILENAME_MAX];
|
||||||
|
char_t EXECUTABLE_DIRECTORY[FILENAME_MAX];
|
||||||
|
|
||||||
|
int32_t main(int32_t argc, char_t **argv) {
|
||||||
|
// Get launch args
|
||||||
|
assertTrue(argc > 0, "argc is not valid!");
|
||||||
|
assertNotNull(argv, "argv is not valid!");
|
||||||
|
assertNotNull(argv[0], "argv[0] is not valid!");
|
||||||
|
assertStrLen(argv[0], FILENAME_MAX, "argv[0] is too long!");
|
||||||
|
assertStrLenMin(argv[0], 1, "argv[0] is empty!");
|
||||||
|
|
||||||
|
// Store the executable path and directory.
|
||||||
|
strcpy(EXECUTABLE_PATH, argv[0]);
|
||||||
|
strcpy(EXECUTABLE_DIRECTORY, dirname(EXECUTABLE_PATH));
|
||||||
|
|
||||||
|
// Init systems
|
||||||
|
int32_t ret;
|
||||||
|
if((ret = windowInit()) != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
assetInit();
|
||||||
|
renderInit();
|
||||||
|
gameInit();
|
||||||
|
|
||||||
|
// Prepare for time tracking
|
||||||
|
double_t time, newTime;
|
||||||
|
float_t fDelta;
|
||||||
|
int32_t updateResult;
|
||||||
|
timeUntilNextUpdate = 0.0f;
|
||||||
|
|
||||||
|
// Main loop
|
||||||
|
while(!windowShouldClose()) {
|
||||||
|
// Determine the delta.
|
||||||
|
newTime = glfwGetTime();
|
||||||
|
fDelta = (float_t)(newTime - time);
|
||||||
|
time = newTime;
|
||||||
|
timeUntilNextUpdate -= fDelta;
|
||||||
|
|
||||||
|
// Should game tick?
|
||||||
|
if(timeUntilNextUpdate <= 0) {
|
||||||
|
gameUpdate();
|
||||||
|
timeUntilNextUpdate = TIME_BETWEEN_UPDATES;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
renderUpdate();
|
||||||
|
windowUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
renderDispose();
|
||||||
|
windowDispose();
|
||||||
|
assetDispose();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
9
tools/CMakeLists.txt
Normal file
9
tools/CMakeLists.txt
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# Copyright (c) 2023 Dominic Msters
|
||||||
|
#
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
# https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
# Tools
|
||||||
|
add_subdirectory(assetstool)
|
||||||
|
add_subdirectory(copytool)
|
||||||
|
add_subdirectory(glsltool)
|
19
tools/assetstool/CMakeLists.txt
Normal file
19
tools/assetstool/CMakeLists.txt
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# Copyright (c) 2023 Dominic Masters
|
||||||
|
#
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
# https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
find_package(Python3 REQUIRED COMPONENTS Interpreter)
|
||||||
|
|
||||||
|
add_custom_target(duskassets
|
||||||
|
COMMAND
|
||||||
|
${Python3_EXECUTABLE}
|
||||||
|
${DUSK_TOOLS_DIR}/assetstool/assetstool.py
|
||||||
|
--input=${DUSK_ASSETS_BUILD_DIR}
|
||||||
|
--output=${DUSK_BUILD_DIR}/dusk.tar
|
||||||
|
COMMENT "Bundling assets..."
|
||||||
|
USES_TERMINAL
|
||||||
|
DEPENDS ${DUSK_ASSETS}
|
||||||
|
)
|
||||||
|
|
||||||
|
add_dependencies(${DUSK_TARGET_NAME} duskassets)
|
67
tools/assetstool/assetstool.py
Executable file
67
tools/assetstool/assetstool.py
Executable file
@ -0,0 +1,67 @@
|
|||||||
|
# Copyright (c) 2023 Dominic Masters
|
||||||
|
#
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
# https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
import os
|
||||||
|
import tarfile
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
# Args
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description='Bundles all assets into the internal archive format.'
|
||||||
|
)
|
||||||
|
parser.add_argument('-i', '--input');
|
||||||
|
parser.add_argument('-o', '--output');
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
# Ensure the directory for the output path exists
|
||||||
|
if not os.path.exists(os.path.dirname(args.output)):
|
||||||
|
os.makedirs(os.path.dirname(args.output))
|
||||||
|
|
||||||
|
# Create a ZIP archive and add the specified directory
|
||||||
|
# archive = tarfile.open(args.output, 'w:bz2') # BZ2 Compression
|
||||||
|
|
||||||
|
# Does the archive already exist?
|
||||||
|
filesInArchive = []
|
||||||
|
|
||||||
|
if os.path.exists(args.output) and False:
|
||||||
|
# if os.path.exists(args.output):
|
||||||
|
# Yes, open it
|
||||||
|
archive = tarfile.open(args.output, 'a:')
|
||||||
|
|
||||||
|
# Get all the files in the archive
|
||||||
|
for member in archive.getmembers():
|
||||||
|
filesInArchive.append(member.name)
|
||||||
|
|
||||||
|
archive.close()
|
||||||
|
|
||||||
|
# Open archive for appending.
|
||||||
|
archive = tarfile.open(args.output, 'a:')
|
||||||
|
else:
|
||||||
|
# No, create it
|
||||||
|
archive = tarfile.open(args.output, 'w:')
|
||||||
|
|
||||||
|
# Add all files in the input directory
|
||||||
|
for foldername, subfolders, filenames in os.walk(args.input):
|
||||||
|
for filename in filenames:
|
||||||
|
|
||||||
|
# Is the file already in the archive?
|
||||||
|
absolute_path = os.path.join(foldername, filename)
|
||||||
|
relative_path = os.path.relpath(absolute_path, args.input)
|
||||||
|
|
||||||
|
if relative_path in filesInArchive:
|
||||||
|
if relative_path.endswith('.texture'):
|
||||||
|
print(f"Skipping {filename}...")
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
print(f"Overwriting {filename}...")
|
||||||
|
# Does not work in python, throw error
|
||||||
|
exit (1)
|
||||||
|
else:
|
||||||
|
print(f"Archiving asset {filename}...")
|
||||||
|
|
||||||
|
archive.add(absolute_path, arcname=relative_path)
|
||||||
|
|
||||||
|
# Close the archive
|
||||||
|
archive.close()
|
16
tools/copytool/CMakeLists.txt
Normal file
16
tools/copytool/CMakeLists.txt
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# Copyright (c) 2023 Dominic Msters
|
||||||
|
#
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
# https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
function(copytool file)
|
||||||
|
set(TARGET_NAME "copytool_${file}")
|
||||||
|
|
||||||
|
# Replace slashes with underscores
|
||||||
|
string(REPLACE "/" "_" TARGET_NAME ${TARGET_NAME})
|
||||||
|
|
||||||
|
add_custom_target(${TARGET_NAME}
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy ${DUSK_ASSETS_DIR}/${file} ${DUSK_ASSETS_BUILD_DIR}/${file}
|
||||||
|
)
|
||||||
|
add_dependencies(duskassets ${TARGET_NAME})
|
||||||
|
endfunction()
|
45
tools/glsltool/CMakeLists.txt
Normal file
45
tools/glsltool/CMakeLists.txt
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
# Copyright (c) 2025 Dominic Masters
|
||||||
|
#
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
# https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
# Path to the CMake script for converting GLSL to header
|
||||||
|
set(DUSK_GLSL_TOOL_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/glsltool.cmake CACHE INTERNAL ${DUSK_CACHE_TARGET})
|
||||||
|
|
||||||
|
# GLSL to C-code
|
||||||
|
function(glsltool GLSL_FILE)
|
||||||
|
get_filename_component(GLSL_FILE_NAME_WE ${GLSL_FILE} NAME_WE)
|
||||||
|
set(GLSL_SOURCE_DIRECTORY ${CMAKE_CURRENT_LIST_DIR})
|
||||||
|
set(GLSL_FILE_ABSOLUTE ${GLSL_SOURCE_DIRECTORY}/${GLSL_FILE})
|
||||||
|
set(GLSL_FILE_PATH ${CMAKE_CURRENT_LIST_DIR}/${GLSL_FILE})
|
||||||
|
set(GLSL_FILE_HEADER ${DUSK_GENERATED_HEADERS_DIR}/${GLSL_FILE}.h)
|
||||||
|
set(GLSL_MISSING_FILE ${DUSK_GENERATED_HEADERS_DIR}/missing_${GLSL_FILE}.h)
|
||||||
|
|
||||||
|
# Ensure the generated files are recompiled
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT
|
||||||
|
${GLSL_FILE_HEADER}
|
||||||
|
${GLSL_MISSING_FILE}
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E make_directory ${DUSK_GENERATED_HEADERS_DIR}
|
||||||
|
COMMAND ${CMAKE_COMMAND}
|
||||||
|
-DGLSL_FILE_ABSOLUTE=${GLSL_FILE_ABSOLUTE}
|
||||||
|
-DGLSL_FILE_HEADER=${GLSL_FILE_HEADER}
|
||||||
|
-DGLSL_FILE_NAME_WE=${GLSL_FILE_NAME_WE}
|
||||||
|
-DGLSL_SOURCE_DIRECTORY=${GLSL_SOURCE_DIRECTORY}
|
||||||
|
-P ${DUSK_GLSL_TOOL_SCRIPT}
|
||||||
|
DEPENDS ${GLSL_FILE_PATH}
|
||||||
|
COMMENT "Converting ${GLSL_FILE} to header"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Trick to always run the command
|
||||||
|
add_custom_target(GLSL_TOOL_ALWAYS_RUN_${GLSL_FILE}
|
||||||
|
ALL
|
||||||
|
DEPENDS
|
||||||
|
${GLSL_MISSING_FILE}
|
||||||
|
${GLSL_FILE_HEADER}
|
||||||
|
)
|
||||||
|
|
||||||
|
add_dependencies(${DUSK_TARGET_NAME}
|
||||||
|
GLSL_TOOL_ALWAYS_RUN_${GLSL_FILE}
|
||||||
|
)
|
||||||
|
endfunction()
|
36
tools/glsltool/glsltool.cmake
Normal file
36
tools/glsltool/glsltool.cmake
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
file(READ ${GLSL_FILE_ABSOLUTE} GLSL_FILE_CONTENTS)
|
||||||
|
|
||||||
|
set(INCLUDED_FILES)
|
||||||
|
|
||||||
|
function(resolve_includes CONTENTS OUTPUT)
|
||||||
|
string(REGEX MATCHALL "#include \"([^\"]+)\"" INCLUDES "${CONTENTS}")
|
||||||
|
|
||||||
|
foreach(INCLUDE ${INCLUDES})
|
||||||
|
string(REGEX REPLACE "#include \"([^\"]+)\"" "\\1" INCLUDE_FILE ${INCLUDE})
|
||||||
|
get_filename_component(INCLUDE_FILE_ABSOLUTE ${GLSL_SOURCE_DIRECTORY}/${INCLUDE_FILE} ABSOLUTE)
|
||||||
|
list(FIND INCLUDED_FILES ${INCLUDE_FILE_ABSOLUTE} INCLUDE_FILE_INDEX)
|
||||||
|
|
||||||
|
if(INCLUDE_FILE_INDEX EQUAL -1)
|
||||||
|
list(APPEND INCLUDED_FILES ${INCLUDE_FILE_ABSOLUTE})
|
||||||
|
file(READ ${INCLUDE_FILE_ABSOLUTE} INCLUDED_FILE_CONTENTS)
|
||||||
|
resolve_includes("${INCLUDED_FILE_CONTENTS}" RESOLVED_CONTENTS)
|
||||||
|
string(REPLACE "${INCLUDE}" "${RESOLVED_CONTENTS}" CONTENTS "${CONTENTS}")
|
||||||
|
else()
|
||||||
|
string(REPLACE "${INCLUDE}" "" CONTENTS "${CONTENTS}")
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
set(${OUTPUT} "${CONTENTS}" PARENT_SCOPE)
|
||||||
|
set(INCLUDED_FILES ${INCLUDED_FILES} PARENT_SCOPE)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
list(APPEND INCLUDED_FILES ${GLSL_FILE_ABSOLUTE})
|
||||||
|
resolve_includes("${GLSL_FILE_CONTENTS}" RESOLVED_GLSL_FILE_CONTENTS)
|
||||||
|
|
||||||
|
# Convert to C string
|
||||||
|
string(REPLACE "\"" "\\\"" RESOLVED_GLSL_FILE_CONTENTS "${RESOLVED_GLSL_FILE_CONTENTS}")
|
||||||
|
string(REPLACE "\n" "\\n\"\n\"" RESOLVED_GLSL_FILE_CONTENTS "${RESOLVED_GLSL_FILE_CONTENTS}")
|
||||||
|
set(RESOLVED_GLSL_FILE_CONTENTS "\"${RESOLVED_GLSL_FILE_CONTENTS}\\n\"")
|
||||||
|
|
||||||
|
# Write to header file
|
||||||
|
file(WRITE ${GLSL_FILE_HEADER} "const char* ${GLSL_FILE_NAME_WE}ShaderSource = ${RESOLVED_GLSL_FILE_CONTENTS};")
|
Reference in New Issue
Block a user