Add asset, resource system, mesh formats, color, SDL3 display and example game

Asset directory with CMake add_asset (extension dispatched), plain file asset
access, resource/resource manager with async load thread and text loader,
URI utilities, mesh format helpers, generated color header, and example game
hooks wired through the engine.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
This commit is contained in:
YourWishesandClaude Sonnet 5.5 committed 2026-11-07 20:12:40 -06:00
1 parent 65c4a9c051
commit cad41e456b
47 files changed
+2335 -7

No files matched your search

+65
View File
@@ -0,0 +1,65 @@
# Copyright (c) 2026 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Asset building. Include this from the root CMakeLists.txt.
#
# Assets are registered with add_asset() and built by dusk_assets_finalize().
# Each asset is dispatched on its file extension to a handler function named
# dusk_asset_<extension> (e.g. dusk_asset_obj), defined in its own file in this
# directory. Extensions without a handler fall back to a plain copy.
include(${CMAKE_CURRENT_LIST_DIR}/copy.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/obj.cmake)
# Registers an asset to be built into the project. The path is relative to the
# calling CMakeLists.txt, and is kept relative to the root assets directory in
# the output, so assets/models/a.obj ends up at <build>/assets/models/a.obj.
#
# This only records the asset. The build rules are created by
# dusk_assets_finalize() from the root CMakeLists.txt, because a custom command
# output can only be used by targets in the directory it was defined in.
function(add_asset ASSET_PATH)
set(ASSET_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/${ASSET_PATH}")
if(NOT EXISTS "${ASSET_SOURCE}")
message(FATAL_ERROR "add_asset: ${ASSET_SOURCE} does not exist")
endif()
set_property(GLOBAL APPEND PROPERTY DUSK_ASSET_SOURCES "${ASSET_SOURCE}")
endfunction()
# Determines the lowercase extension of an asset, without the leading dot.
function(dusk_asset_extension ASSET_SOURCE OUT_VAR)
get_filename_component(ASSET_EXT "${ASSET_SOURCE}" LAST_EXT)
string(TOLOWER "${ASSET_EXT}" ASSET_EXT)
string(REGEX REPLACE "^\\." "" ASSET_EXT "${ASSET_EXT}")
set(${OUT_VAR} "${ASSET_EXT}" PARENT_SCOPE)
endfunction()
# Creates the TARGET_NAME target, which builds every asset registered with
# add_asset(). Call once from the root CMakeLists.txt after adding the assets.
function(dusk_assets_finalize TARGET_NAME)
get_property(ASSET_SOURCES GLOBAL PROPERTY DUSK_ASSET_SOURCES)
set(ASSET_OUTPUTS "")
foreach(ASSET_SOURCE IN LISTS ASSET_SOURCES)
file(RELATIVE_PATH ASSET_RELATIVE "${DUSK_ASSETS_DIR}" "${ASSET_SOURCE}")
dusk_asset_extension("${ASSET_SOURCE}" ASSET_EXT)
# Dispatch on the extension, falling back to a plain copy.
set(ASSET_OUTPUT "")
if(COMMAND dusk_asset_${ASSET_EXT})
cmake_language(CALL dusk_asset_${ASSET_EXT}
"${ASSET_SOURCE}" "${ASSET_RELATIVE}" ASSET_OUTPUT
)
else()
message(STATUS "Asset ${ASSET_RELATIVE}: no handler for '.${ASSET_EXT}', copying")
dusk_asset_copy("${ASSET_SOURCE}" "${ASSET_RELATIVE}" ASSET_OUTPUT)
endif()
list(APPEND ASSET_OUTPUTS "${ASSET_OUTPUT}")
endforeach()
add_custom_target(${TARGET_NAME} ALL DEPENDS ${ASSET_OUTPUTS})
endfunction()
+22
View File
@@ -0,0 +1,22 @@
# Copyright (c) 2026 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Handler that copies an asset into the built assets directory as is. Every
# handler has the signature (SOURCE RELATIVE OUT_VAR) and must set OUT_VAR, in
# the caller's scope, to the file it produces.
function(dusk_asset_copy ASSET_SOURCE ASSET_RELATIVE OUT_VAR)
set(ASSET_OUTPUT "${DUSK_BUILT_ASSETS_DIR}/${ASSET_RELATIVE}")
add_custom_command(
OUTPUT "${ASSET_OUTPUT}"
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${ASSET_SOURCE}" "${ASSET_OUTPUT}"
DEPENDS "${ASSET_SOURCE}"
COMMENT "Copying asset ${ASSET_RELATIVE}"
VERBATIM
)
set(${OUT_VAR} "${ASSET_OUTPUT}" PARENT_SCOPE)
endfunction()
+10
View File
@@ -0,0 +1,10 @@
# Copyright (c) 2026 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Handler for .obj (Wavefront mesh) assets. Currently just copies the file.
function(dusk_asset_obj ASSET_SOURCE ASSET_RELATIVE OUT_VAR)
dusk_asset_copy("${ASSET_SOURCE}" "${ASSET_RELATIVE}" ASSET_OUTPUT)
set(${OUT_VAR} "${ASSET_OUTPUT}" PARENT_SCOPE)
endfunction()
+3
View File
@@ -13,6 +13,9 @@ option(DUSK_BUILD_TESTS "Enable tests." OFF)
option(DUSK_NETWORK "Enable network support." ON)
# Game metadata
set(DUSK_GAME "duskexample" CACHE STRING
"Directory under src/ containing the game to build (provides game/game.c)."
)
set(DUSK_GAME_NAME "Dusk" CACHE STRING "Game display name.")
set(DUSK_GAME_AUTHOR "YourWishes" CACHE STRING "Game author / coder.")
if(NOT DEFINED DUSK_VERSION)