72 Commits
main ... reset

Author SHA1 Message Date
57995a0e00 Remove train station. 2024-11-24 11:18:08 -06:00
53dc496f2f Dawn progress 2024-11-07 18:28:54 -06:00
6a0ffd4a45 about to start work on downtown 2024-10-25 23:02:55 -05:00
ef84c85527 Cleaned a bit of the tile code. Built train station 2024-10-25 10:30:49 -05:00
39d74cc375 Map loading fixes and improvements 2024-10-22 08:00:48 -05:00
ddbef64f43 Started work on using tiled 2024-10-21 20:50:16 -05:00
b2a3ca4411 Example sign with conversation. 2024-10-20 15:31:04 -07:00
a74f285cb2 Memory functions 2024-10-17 09:30:36 -07:00
5fb36aad35 Moved tile interactions over. 2024-10-17 08:44:17 -07:00
258976b76c Made NPCs interactable with the conversation system. 2024-10-17 07:36:33 -07:00
7867076bbe Added language support to main menu and sign 2024-10-17 07:17:36 -07:00
3baafec9cb Adding language 2024-10-16 14:37:34 -07:00
6c062df9bb Added main menu. 2024-10-09 09:47:05 -05:00
825cc88e17 Moving some logic into separate files 2024-10-08 09:36:15 -05:00
9f4cb283c1 UI Menu more or less done perfectly. 2024-10-08 09:17:00 -05:00
86feb7e56a Mid menu coding 2024-10-07 09:49:22 -05:00
a7dc7fdcf8 Remove testmap2 2024-10-07 00:29:59 -05:00
cb3a58e456 Door and map changing 2024-10-07 00:27:20 -05:00
5334f0944e Add direction to the door 2024-10-06 23:21:28 -05:00
a1d4b0a1d7 Door 2024-10-06 23:11:45 -05:00
ecb3b9c5d1 Fixed JSON parsing throwing errors 2024-10-06 22:46:16 -05:00
bf3912bb7f Added sign 2024-10-06 22:23:26 -05:00
b5d7b7e229 Bit more cleanup 2024-10-06 21:01:05 -05:00
b7987401af Map loading basically done for now 2024-10-06 19:03:22 -05:00
ffc46c677c Added triggers to parsing. 2024-10-06 18:57:28 -05:00
7a8ca2fca1 Test loading asset data. 2024-10-06 18:52:52 -05:00
5751f7c83c Add asset loading support. 2024-10-06 18:27:54 -05:00
c69d0ec1cc Adding triggers, prepping for map loading. 2024-10-06 18:03:46 -05:00
e14445680f Add newlines to draw text 2024-10-06 17:30:04 -05:00
5256b32055 Textbox rendering back. 2024-10-06 17:16:24 -05:00
5444b0b8c7 Ensure linux terminal is still working 2024-10-06 16:43:54 -05:00
45b3cf9478 Cleaned old frame code. 2024-10-06 16:34:47 -05:00
0224ddd36b Getting around to cleaning drawing code finally. 2024-10-06 16:28:34 -05:00
40b0395552 idk what I coded 2024-10-06 01:30:45 -05:00
b7829fda5c Add tile interactions. 2024-10-05 10:29:15 -05:00
bdef59bbe1 Make map rendering centered 2024-10-05 10:17:12 -05:00
27ce6526e6 Vastly improve UI 2024-10-05 09:16:41 -05:00
704002e671 Moved TERM files around 2024-10-05 08:35:36 -05:00
cfe4cf6cad Testing mostly 2024-10-04 22:43:33 -05:00
69672cf8a6 Rendering working 2024-10-04 21:51:38 -05:00
c1345218a3 glfw 2024-10-04 16:41:01 -05:00
be27408cf4 Adding back GLFW 2024-10-04 09:37:32 -05:00
4205b919d4 Adding back GLFW 2024-10-04 09:37:24 -05:00
e14083b4b4 t 2024-10-03 22:35:22 -05:00
ad317da97e Reset 2024-10-03 20:09:10 -05:00
2ff1a159bc idk 2024-10-03 20:07:35 -05:00
c770953b2e VN Dummy 2024-09-29 00:47:12 -05:00
2cb1d745b2 Add JSON parser 2024-09-27 21:55:53 -05:00
8ce0e8f9f6 Changed more deps to use FetchContent 2024-09-25 15:11:04 -04:00
5101a856be Remove glm 2024-09-25 15:01:26 -04:00
303d0c0a6f Add camera pixel perfect. 2024-09-16 21:35:04 -05:00
e3a4368d1e Basic tile code ready. 2024-09-16 07:07:01 -05:00
7c34127900 Some more chunk work. 2024-09-16 06:50:47 -05:00
49d90b3362 Working on chunks 2024-09-15 08:41:44 -05:00
935398d45e Minigolf is pog 2024-09-15 08:06:45 -05:00
4065556d4a Switched map loops to weakptrs 2024-09-15 07:50:11 -05:00
fb8f6e3f95 Commit prog 2024-09-14 10:23:31 -05:00
b4c2ce16a0 idk if I like this structure. 2024-09-13 09:26:21 -05:00
b309478922 Trying to tune turning. 2024-09-11 10:07:23 -05:00
ad3974bde5 Testing walking. 2024-09-11 10:04:54 -05:00
e5349cc093 Created basic movement. 2024-09-11 09:21:56 -05:00
01c56477aa Basic movement example 2024-09-11 08:21:26 -05:00
916396e175 Fixed input 2024-09-10 20:17:32 -05:00
0e5b85633c Worked a bit on prefabs of all things 2024-09-10 18:26:14 -05:00
e5f3f69120 Restored UI Label support 2024-09-10 17:36:04 -05:00
ca240bc180 Moved poker code to main dawn code. 2024-09-10 08:46:57 -05:00
a3a891ddb2 Cleanup of poker code done, about to start testing. 2024-09-10 06:51:04 -05:00
5fae94c722 More refactoring 2024-09-10 00:07:15 -05:00
d5b3b6d619 Cleaning poker code pt 1. 2024-09-08 23:12:03 -05:00
b4e261d954 Move over old poker code 2024-09-08 21:54:19 -05:00
856bc306fe More cleanup complete 2024-09-08 15:30:41 -05:00
cffe7f73a2 Cleanup complete 2024-09-08 15:30:32 -05:00
370 changed files with 9068 additions and 10538 deletions

2
.gitignore vendored
View File

@ -65,7 +65,7 @@ CTestTestfile.cmake
_deps _deps
# Custom # Custom
build /build/*
.vscode .vscode
assets/testworld/tileset.png assets/testworld/tileset.png

24
.gitmodules vendored
View File

@ -1,21 +1,3 @@
[submodule "lib/glfw"] [submodule "lib/font8x8"]
path = lib/glfw path = lib/font8x8
url = https://github.com/glfw/glfw.git url = https://github.com/dhepper/font8x8
[submodule "lib/glm"]
path = lib/glm
url = https://github.com/g-truc/glm.git
[submodule "lib/SDL"]
path = lib/SDL
url = https://github.com/libsdl-org/SDL.git
[submodule "lib/openal-soft"]
path = lib/openal-soft
url = https://github.com/kcat/openal-soft
[submodule "lib/AudioFile"]
path = lib/AudioFile
url = https://github.com/adamstark/AudioFile.git
[submodule "lib/freetype"]
path = lib/freetype
url = https://gitlab.freedesktop.org/freetype/freetype.git
[submodule "lib/libarchive"]
path = lib/libarchive
url = https://github.com/libarchive/libarchive

View File

@ -1,4 +1,4 @@
# Copyright (c) 2022 Dominic Masters # Copyright (c) 2024 Dominic Masters
# #
# This software is released under the MIT License. # This software is released under the MIT License.
# https://opensource.org/licenses/MIT # https://opensource.org/licenses/MIT
@ -6,12 +6,15 @@
cmake_minimum_required(VERSION 3.13) cmake_minimum_required(VERSION 3.13)
set(CMAKE_C_STANDARD 99) set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED ON) set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/modules/")
# Variable Caches # Variable Caches
set(DAWN_CACHE_TARGET "dawn-target") set(DAWN_CACHE_TARGET "dawn-target")
set(DAWN_TARGET_NAME "Dawn")
if(NOT DEFINED DAWN_TARGET)
set(DAWN_TARGET linux-x64-glfw CACHE INTERNAL ${DAWN_CACHE_TARGET})
# set(DAWN_TARGET linux-x64-terminal CACHE INTERNAL ${DAWN_CACHE_TARGET})
endif()
# Set Common Build Variables # Set Common Build Variables
set(DAWN_ROOT_DIR "${CMAKE_SOURCE_DIR}") set(DAWN_ROOT_DIR "${CMAKE_SOURCE_DIR}")
@ -23,15 +26,10 @@ set(DAWN_ASSETS_BUILD_DIR "${DAWN_BUILD_DIR}/assets")
set(DAWN_GENERATED_DIR "${DAWN_BUILD_DIR}/generated") set(DAWN_GENERATED_DIR "${DAWN_BUILD_DIR}/generated")
set(DAWN_TEMP_DIR "${DAWN_BUILD_DIR}/temp") set(DAWN_TEMP_DIR "${DAWN_BUILD_DIR}/temp")
# Add CMake Tools # Initialize Project.
add_subdirectory(cmake)
set(DAWN_BUILD_BINARY ${DAWN_BUILD_DIR}/src/${DAWN_BUILDING}/${DAWN_TARGET_NAME})
# Initialize Project First.
project(Dawn project(Dawn
VERSION 1.0.0 VERSION 1.0.0
LANGUAGES C CXX LANGUAGES C
) )
# Add tools # Add tools

View File

@ -1,3 +0,0 @@
# Dawn Project
Simple in code, complex in structure game engine for creating small, fast and
reusable games.

42
assets/en.json Normal file
View File

@ -0,0 +1,42 @@
{
"main_menu": {
"new_game": "New Game",
"load_game": "Load Game",
"options": "Options",
"exit": "Exit"
},
"tiles": {
"water": {
"interact": "A refreshing body of water."
},
"lamp": {
"interact": "An electric lamp.\nA real lightbulb idea."
},
"rail": {
"interact": "Train tracks.\n...Better not cross them."
}
},
"entities": {
"sign": {
"name": "Sign"
}
},
"maps": {
"testmap": {
"bob": "Hello, I am Bob.",
"sign": "This is a sign.",
"sign2": {
"1": "This is another sign.",
"2": "It has two lines."
}
},
"train_station": {
"stair_sign": {
"0": "Stairs slippery when wet.\n\n<- West to Town.\n-> East to lakefront."
}
}
},
"battle": {
"start": "Battle Start!"
}
}

46
assets/maps/testmap.tmx Normal file
View File

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.10" tiledversion="1.11.0" orientation="orthogonal" renderorder="right-down" width="30" height="20" tilewidth="8" tileheight="8" infinite="0" nextlayerid="3" nextobjectid="7">
<tileset firstgid="1" source="../tilemaps/tilemap.tsx"/>
<tileset firstgid="65" source="../tilemaps/entities.tsx"/>
<layer id="1" name="Map" width="30" height="20" locked="1">
<data encoding="csv">
1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,2,2,2,
1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,2,2,2,
1,1,1,1,1,1,2,2,2,2,2,2,6,6,6,6,6,2,2,2,2,2,2,3,3,3,2,2,2,2,
1,1,1,1,1,1,2,2,2,2,2,2,6,6,6,6,6,2,2,2,2,2,3,3,3,3,2,2,2,2,
1,1,1,1,1,2,2,2,2,2,2,2,5,5,5,5,5,2,2,2,2,2,3,3,3,2,2,2,2,2,
1,1,1,1,1,2,2,2,2,2,2,2,5,5,5,5,5,2,2,2,2,2,3,3,3,2,2,2,2,2,
1,1,1,1,1,1,2,2,2,2,2,2,5,5,1,5,5,2,2,2,2,3,3,3,3,2,2,2,2,2,
1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,2,2,2,2,
1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,2,2,2,2,2,
1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,2,2,2,2,2,
1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,2,2,2,2,2,2,
1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,2,2,2,2,2,2,
1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,
1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,2,2,2,2,2,2,2,
1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,2,2,2,2,2,2,2,2,
1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,2,2,2,2,2,2,2,2,
1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,3,3,3,2,2,2,2,2,2,2,2,2,2,
1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,
1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,
1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2
</data>
</layer>
<objectgroup id="2" name="Entities">
<object id="4" name="Player" type="player" gid="66" x="87.7275" y="119.497" width="8" height="8"/>
<object id="5" name="Sign" type="sign" gid="68" x="86.8498" y="55.0415" width="8" height="8">
<properties>
<property name="texts_0" value="maps.testmap.sign2.1"/>
<property name="texts_1" value="maps.testmap.sign2.2"/>
</properties>
</object>
<object id="6" name="Door" type="door" gid="69" x="111.791" y="55.7608" width="8" height="8">
<properties>
<property name="direction" type="int" value="2"/>
<property name="map" value="testmap2.map"/>
<property name="x" type="int" value="11"/>
<property name="y" type="int" value="2"/>
</properties>
</object>
</objectgroup>
</map>

17
assets/maps/testmap2.tmx Normal file
View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.10" tiledversion="1.11.0" orientation="orthogonal" renderorder="right-down" width="5" height="5" tilewidth="8" tileheight="8" infinite="0" nextlayerid="2" nextobjectid="1">
<tileset firstgid="1" source="../tilemaps/tilemap.tsx"/>
<tileset firstgid="67" source="../tilemaps/entities.tsx"/>
<layer id="1" name="Tile Layer 1" width="5" height="5">
<data encoding="csv">
2,2,2,2,2,
2,2,2,3,2,
2,2,3,3,2,
2,2,3,2,2,
2,3,3,2,2
</data>
</layer>
<objectgroup id="2" name="Entities">
<object id="4" name="Player" type="player" gid="68" x="6.54983" y="15.3437" width="8" height="8"/>
</objectgroup>
</map>

View File

@ -0,0 +1,14 @@
{
"automappingRulesFile": "",
"commands": [
],
"compatibilityVersion": 1100,
"extensionsPath": "extensions",
"folders": [
"."
],
"properties": [
],
"propertyTypes": [
]
}

View File

@ -0,0 +1,114 @@
{
"Map/SizeTest": {
"height": 4300,
"width": 2
},
"activeFile": "maps/testmap.tmx",
"expandedProjectPaths": [
".",
"maps"
],
"file.lastUsedOpenFilter": "All Files (*)",
"fileStates": {
"": {
"scaleInDock": 1
},
"entities.tsx": {
"scaleInDock": 1,
"scaleInEditor": 1
},
"maps/downtown.tmx": {
"scale": 4.9072,
"selectedLayer": 0,
"viewCenter": {
"x": 39.94131072709489,
"y": 40.0432018258885
}
},
"maps/testmap.tmx": {
"expandedObjectLayers": [
2
],
"scale": 3.404166666666667,
"selectedLayer": 1,
"viewCenter": {
"x": 95.17747858017135,
"y": 86.80538555691552
}
},
"maps/testmap2.tmx": {
"expandedObjectLayers": [
2
],
"scale": 5.0383,
"selectedLayer": 1,
"viewCenter": {
"x": 19.84796459123116,
"y": 19.947204414187325
}
},
"maps/train_station.tmx": {
"expandedObjectLayers": [
2
],
"scale": 2.7603,
"selectedLayer": 1,
"viewCenter": {
"x": 160.48980183313407,
"y": 120.4579212404449
}
},
"testmap.tmx": {
"scale": 3.23,
"selectedLayer": 1,
"viewCenter": {
"x": 122.60061919504646,
"y": 56.965944272445824
}
},
"testmap2.tmx": {
"scale": 3.281458333333333,
"selectedLayer": 0,
"viewCenter": {
"x": 119.91619579709226,
"y": 80.14729223541363
}
},
"tilemap.tsx": {
"scaleInDock": 1,
"scaleInEditor": 4
},
"tilemaps/entities.tsx": {
"scaleInDock": 2,
"scaleInEditor": 9.7785
},
"tilemaps/tilemap.tsx": {
"scaleInDock": 2
}
},
"last.externalTilesetPath": "/home/yourwishes/htdocs/Dawn/assets",
"last.imagePath": "/home/yourwishes/htdocs/Dawn/assets",
"map.height": 10,
"map.lastUsedFormat": "tmx",
"map.tileHeight": 8,
"map.tileWidth": 8,
"map.width": 10,
"openFiles": [
"maps/testmap.tmx"
],
"project": "tiled_project.tiled-project",
"property.type": "string",
"recentFiles": [
"maps/testmap.tmx",
"maps/downtown.tmx",
"maps/testmap2.tmx",
"maps/train_station.tmx",
"tilemaps/entities.tsx"
],
"tileset.lastUsedFilter": "All Files (*)",
"tileset.lastUsedFormat": "tsx",
"tileset.tileSize": {
"height": 8,
"width": 8
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<tileset version="1.10" tiledversion="1.11.0" name="entities" tilewidth="8" tileheight="8" tilecount="64" columns="8">
<image source="entities.png" width="64" height="64"/>
<tile id="1" type="player"/>
<tile id="2" type="npc"/>
<tile id="3" type="sign"/>
<tile id="4" type="door"/>
</tileset>

BIN
assets/tilemaps/tilemap.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 408 B

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<tileset version="1.10" tiledversion="1.11.0" name="tilemap" tilewidth="8" tileheight="8" tilecount="64" columns="8">
<image source="tilemap.png" width="64" height="64"/>
</tileset>

View File

@ -1,5 +0,0 @@
#!/bin/bash
mkdir tools
cd tools
cmake .. -DDAWN_BUILD_TARGET=target-tools
make

View File

@ -1,2 +0,0 @@
#!/bin/bash
git submodule update --init --recursive

View File

@ -1,2 +0,0 @@
#!/bin/bash
sudo apt install build-essential

View File

@ -1,38 +0,0 @@
#!/bin/bash
sudo apt-get install cmake libarchive-tools
git clone https://github.com/vitasdk/vdpm ~/vdpm
cd ~/vdpm
./bootstrap-vitasdk.sh
export PATH=$VITASDK/bin:$PATH
git clone https://github.com/vitasdk/packages.git ~/vitapackages
cd ~/vitapackages
dir_array=(
zlib
bzip2
henkaku
taihen
kubridge
openal-soft
openssl
curl
curlpp
expat
opus
opusfile
glm
kuio
vitaShaRK
libmathneon
vitaGL
SceShaccCgExt
)
curdir=$(pwd)
for d in "${dir_array[@]}";do
echo "${curdir}${d}"
cd "${curdir}/${d}"
vita-makepkg
vdpm *-arm.tar.xz
done

View File

@ -1,10 +0,0 @@
#!/bin/bash
mkdir -p vita/build
cd vita/build
if [ ! -d "src" ]
then
cmake ../.. -DDAWN_BUILD_TARGET=target-helloworld-vita -DCMAKE_BUILD_TYPE=Debug
fi
make
cp ./src/dawnvita/*.vpk ../
cd ../..

View File

@ -1,8 +0,0 @@
# Copyright (c) 2022 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Includes
add_subdirectory(hosts)
add_subdirectory(targets)

View File

@ -1,15 +0,0 @@
# Copyright (c) 2022 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Check for build target, or default
if(WIN32)
set(DAWN_BUILD_HOST "build-host-win32")
elseif(UNIX AND NOT APPLE)
set(DAWN_BUILD_HOST "build-host-linux")
elseif(UNIX AND APPLE)
set(DAWN_BUILD_HOST "build-host-osx")
endif()
add_subdirectory(${DAWN_BUILD_HOST})

View File

@ -1,4 +0,0 @@
# CMake Hosts
CMake Hosts help the build system define how a HOST (Not the target/client) does
its building. Host would be the system you are using, right now, to do the build
with.

View File

@ -1,6 +0,0 @@
# Copyright (c) 2022 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
set(DAWN_BUILD_HOST_LIBS "m" CACHE INTERNAL ${DAWN_CACHE_TARGET})

View File

@ -1,6 +0,0 @@
# Copyright (c) 2022 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
set(DAWN_BUILD_HOST_LIBS "" CACHE INTERNAL ${DAWN_CACHE_TARGET})

View File

@ -1,6 +0,0 @@
# Copyright (c) 2022 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
set(DAWN_BUILD_HOST_LIBS "" CACHE INTERNAL ${DAWN_CACHE_TARGET})

View File

@ -1,49 +0,0 @@
find_path(GLFW_INCLUDE_DIR GLFW/glfw3.h
HINTS
ENV GLFWDIR
PATHS
"/usr"
"/usr/local"
"~/Library/Frameworks"
"/Library/Frameworks"
"/opt"
"$ENV{PROGRAMFILES}/glfw"
"$ENV{PROGRAMFILES}/glfw3"
PATH_SUFFIXES
include
)
# Search for the library
FIND_LIBRARY(GLFW_LIBRARY
NAMES
glfw glfw3 GLFW GLFW3
HINTS
ENV GLFWDIR
PATHS
"/usr"
"/usr/local"
"~/Library/Frameworks"
"/Library/Frameworks"
"/opt"
"$ENV{PROGRAMFILES}/glfw"
"$ENV{PROGRAMFILES}/glfw3"
PATH_SUFFIXES
lib
lib32
lib64
libs
lib-vc2012
lib-vc2013
lib-vc2015
lib-vc2017
lib-vc2019
lib-vc2022
)
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(
GLFW
REQUIRED_VARS GLFW_LIBRARY GLFW_INCLUDE_DIR
)
mark_as_advanced(GLFW_LIBRARY GLFW_INCLUDE_DIR)

View File

@ -1,49 +0,0 @@
find_path(OPENAL_INCLUDE_DIR al.h
HINTS
ENV OPENALDIR
PATHS
"/usr"
"/usr/local"
"~/Library/Frameworks"
"/Library/Frameworks"
"/opt"
"$ENV{PROGRAMFILES}/openal"
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Creative\ Labs\\OpenAL\ 1.1\ Software\ Development\ Kit\\1.00.0000;InstallDir]"
PATH_SUFFIXES
include/AL
AL/AL
include/OpenAL
include
AL
OpenAL
)
# Search for the library
FIND_LIBRARY(OPENAL_LIBRARY
NAMES
OpenAL al openal OpenAL32
HINTS
ENV OPENALDIR
PATHS
"/usr"
"/usr/local"
"~/Library/Frameworks"
"/Library/Frameworks"
"/opt"
"$ENV{PROGRAMFILES}/openal"
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Creative\ Labs\\OpenAL\ 1.1\ Software\ Development\ Kit\\1.00.0000;InstallDir]"
PATH_SUFFIXES
lib
lib32
lib64
libs
${_OpenAL_ARCH_DIR}
)
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(
OpenAL
REQUIRED_VARS OPENAL_LIBRARY OPENAL_INCLUDE_DIR
)
mark_as_advanced(OPENAL_LIBRARY OPENAL_INCLUDE_DIR)

View File

@ -1,14 +0,0 @@
# Copyright (c) 2022 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Now validate we have a build target for real
if(NOT DEFINED DAWN_BUILD_TARGET)
set(DAWN_BUILD_TARGET "target-rpg-linux-glfw" CACHE INTERNAL ${DAWN_CACHE_TARGET})
endif()
message("Building target ${DAWN_BUILD_TARGET}")
# Include the build target
add_subdirectory(${DAWN_BUILD_TARGET})

View File

@ -1,40 +0,0 @@
# CMake Targets
CMake Targets decide what you are intending to build. Targets are (usually) a
specific system, like vita, 3ds, switch, or a specific OS with a library, e.g.
targetting vulkan on linux vs targetting opengl on linux, or targetting opengl
on windows, etc.
In addition the target also decides what project(s) to build. Usually this is
just the specific game and/or systems to be built, so if you are building a VN
game the target would need to let the build system know you want to rollup the
VN parts of the engine also.
Note this is one of the very few build args that is required during the
configuration of cmake to make it build properly, failure to specify a target
will result in a build error.
```
-DDAWN_BUILD_TARGET=target-helloworld-linux64-glfw
```
## Target Systems
- vita
- linux
- osx
- windows
- emscripten (Web)
## Target Libraries
- vita (Includes OGL)
- glfw (Includes OGL)
- sdl2 (Includes OGL)
## Target games
- liminal
- helloworld
## Target Arcitectures
- vita (form of armv7)
- linux (x64 only)
- windows (x64 only)
- osx (targetting arm64 currently)

View File

@ -1,15 +0,0 @@
# Copyright (c) 2023 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
set(DAWN_BUILDING dawnhelloworld CACHE INTERNAL ${DAWN_CACHE_TARGET})
set(DAWN_BUILD_HOST_LIBS "" CACHE INTERNAL ${DAWN_CACHE_TARGET})
set(DAWN_TARGET_EMSCRIPTEN true CACHE INTERNAL ${DAWN_CACHE_TARGET})
set(DAWN_TARGET_GLFW true CACHE INTERNAL ${DAWN_CACHE_TARGET})
set(DAWN_TARGET_NAME "HelloWorld" CACHE INTERNAL ${DAWN_CACHE_TARGET})
set(DAWN_EMSCRIPTEN_FLAGS "" CACHE INTERNAL ${DAWN_CACHE_TARGET})
# Ensures a .HTML file is generated.
set(CMAKE_EXECUTABLE_SUFFIX ".html" CACHE INTERNAL ${DAWN_CACHE_TARGET})

View File

@ -1,10 +0,0 @@
# Copyright (c) 2023 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
set(DAWN_BUILDING dawnhelloworld CACHE INTERNAL ${DAWN_CACHE_TARGET})
set(DAWN_TARGET_LINUX true CACHE INTERNAL ${DAWN_CACHE_TARGET})
set(DAWN_TARGET_GLFW true CACHE INTERNAL ${DAWN_CACHE_TARGET})
set(DAWN_TARGET_NAME "HelloWorld" CACHE INTERNAL ${DAWN_CACHE_TARGET})
set(DAWN_TARGET_ARCHIVE true CACHE INTERNAL ${DAWN_CACHE_TARGET})

View File

@ -1,21 +0,0 @@
# Copyright (c) 2023 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
set(DAWN_BUILDING dawnhelloworld CACHE INTERNAL ${DAWN_CACHE_TARGET})
set(DAWN_TARGET_VITA true CACHE INTERNAL ${DAWN_CACHE_TARGET})
set(DAWN_BUILD_HOST_LIBS "" CACHE INTERNAL ${DAWN_CACHE_TARGET})
set(DAWN_TARGET_NAME "HelloWorld" CACHE INTERNAL ${DAWN_CACHE_TARGET})
# Properties
set(DAWN_VITA_APP_NAME "Hello Vita" CACHE INTERNAL ${DAWN_CACHE_TARGET})
set(DAWN_VITA_TITLEID "DAWN00000" CACHE INTERNAL ${DAWN_CACHE_TARGET})
set(DAWN_VITA_VERSION "01.00" CACHE INTERNAL ${DAWN_CACHE_TARGET})
# Toolchain
if(DEFINED ENV{VITASDK})
set(CMAKE_TOOLCHAIN_FILE "$ENV{VITASDK}/share/vita.toolchain.cmake" CACHE INTERNAL ${DAWN_CACHE_TARGET})
else()
message(FATAL_ERROR "VITASDK Environment variable is missing! Either you do not have the VITASDK installed, or it is not set up with the env vars correctly.")
endif()

View File

@ -1,11 +0,0 @@
# Copyright (c) 2023 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
set(DAWN_BUILDING dawnrpg CACHE INTERNAL ${DAWN_CACHE_TARGET})
set(DAWN_TARGET_LINUX true CACHE INTERNAL ${DAWN_CACHE_TARGET})
set(DAWN_TARGET_GLFW true CACHE INTERNAL ${DAWN_CACHE_TARGET})
set(DAWN_TARGET_NAME "DawnRPG" CACHE INTERNAL ${DAWN_CACHE_TARGET})
set(DAWN_TARGET_ARCHIVE true CACHE INTERNAL ${DAWN_CACHE_TARGET})
set(DAWN_TARGET_TRUETYPE false CACHE INTERNAL ${DAWN_CACHE_TARGET})

View File

@ -1,340 +0,0 @@
# Compiling, Debugging and Running
This document's purpose is to explain how to compile, debug and run the project
on your machine. It is assumed that you have a basic understanding of the
fundamentals of your operating system and how to use a terminal.
## Preamble
The Dawn project is written almost entirely in C and C++. This includes all of
the tooling used to generate the project and assets. The only non-C/C++ code is
used by CMake to generate the output compilation files. This provides the Dawn
project an extremely high level of portability not typically seen in other
projects.
## TLDR; Version
This document is going to go over the installation and configuration of the
following items. If you are already familiar with these tools, you can skip to
the "Downloading the Source Code" section.
- C/C++ Compiler
- CMake
- Git
- IDE
You may also need *python*, since we depend on third-party libraries that may use
python scripts to generate their own build files. This is not required for the
Dawn project itself.
## Pre-Configuration
In order to compile the Dawn project, you are required to have the following
tools installed on your machine.
### 1. A C/C++ Compiler
The exact tool(s) will depend on your specific scenario. The compiler is used to
take the .cpp/.hpp files and generating binaries that execute on the target
machine. Typically you will use your own C/C++ compiler for the machine that you
are currently running, e.g. if you are running Windows, you will use the Visual
Studio compiler. If you are running Linux, you will use GCC or Clang. If you are
running macOS, you will use Clang, and so-on.
If you are intending to compile on a different machine than the one you are
currently running, you will need to use a cross-compiler that is specific for
your use-case. You will also need to refer to the documentation for creating a
new Dawn engine target.
Please follow the instructions for your specific operating system to install the
appropriate C/C++ compiler.
**Windows**
You will need to download and install [Visual Studio](https://visualstudio.microsoft.com/downloads/).
Visual Studio (not to be confused with Visual Studio Code) is a full IDE that
bundles the official Microsoft C/C++ compiler. It is the recommended compiler
for building the Dawn project on Windows.
Advanced used can also use [MinGW](http://www.mingw.org/) or another compiler if
they wish, however this is not officially supported.
After installing Visual Studio, you will need to install the C++ development
tools. This can be done by opening the Visual Studio Installer and selecting
the "Desktop development with C++" workload.
**Linux**
You will need to install the GCC and Clang compilers. The compilers are usually
installed either by default or by installing the necessary packages for your
Linux distribution.
For example, on Ubuntu, you can install the GCC and Clang compilers by running
the following command:
```bash
sudo apt install build-essential clang
```
On Arch Linux, you can install the GCC and Clang compilers by running the
following command:
```bash
sudo pacman -S base-devel clang
```
And on Fedora, you can install the GCC and Clang compilers by running the
following command:
```bash
sudo dnf install @development-tools clang
```
For other distributions, please refer to your distribution's documentation.
**macOS**
You will need to install the Xcode command line tools. This can be done by done
by running the following command in your terminal:
```bash
xcode-select --install
```
Afterwards you will need to install and enable [Brew](https://brew.sh/). This
can be done by running the following command in your terminal:
```bash
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```
### 2. CMake
CMake is a tool that is used to generate the compilation files for the Dawn
project. In short this is used to create versions of the Dawn project that can
be compiled on all different sets of compilers, so if you are compiling on, for
example, Windows, you can use CMake to generate the compilation files for the
Visual Studio compiler, or if you are compiling on Linux, you can use CMake to
generate the compilation files for the GCC or Clang compilers, and so-on.
To install CMake, please follow the instructions for your specific operating
system. All other operating systems can be found on the [CMake downloads page](https://cmake.org/download/).
**Windows**
You will need to download and install [CMake](https://cmake.org/download/). The
installer will guide you through the installation process and will install the
CMake executable to your system. It is recommended that you add CMake to your
system PATH if requested by the installer.
**Linux**
Like installing the C/C++ compilers, you will need to install CMake using your
specific Linux distribution's package manager, there is also a chance that CMake
can be installed using flatpak or snap. Please refer to your distribution's
documentation for more information.
For Ubuntu and other Debian-based distributions, you can install CMake by using
the following command:
```bash
sudo apt install cmake
```
For Arch Linux, you can install CMake by using the following command:
```bash
sudo pacman -S cmake
```
And for Fedora, you can install CMake by using the following command:
```bash
sudo dnf install cmake
```
**macOS**
You will install CMake using brew. We detailed how to install brew in the C/C++
compiler section. To install CMake, run the following command in your terminal:
```bash
brew install cmake
```
### 3. Git
Git is a version control system that is used to manage the Dawn project's source
code. It is used to download the source code, and to update the source code to
the latest version. It is also used to manage the project's dependencies. Git is
a standard tool in the programming industry and is used to manage complex
projects, especially those that are worked on by multiple people.
Git, like all of the above tools, is installed slightly differently depending on
your operating system. Please follow the instructions for your specific
operating system.
**Windows**
You will need to download and install [Git](https://git-scm.com/downloads). The
installer will guide you through the installation process and will install the
Git executable to your system. It is recommended that you add Git to your system
PATH if requested by the installer. You do not need to add the Context-menu
items to your system.
**Linux**
Like installing the C/C++ compilers, you will need to install Git using your
specific Linux distribution's package manager. It is also likely that git would
have been installed by default. Please refer to your distribution's docs for
more information.
For Ubuntu and other Debian-based distributions, you can install Git by using
the following command:
```bash
sudo apt install git
```
For Arch Linux, you can install Git by using the following command:
```bash
sudo pacman -S git
```
And for Fedora, you can install Git by using the following command:
```bash
sudo dnf install git
```
**macOS**
You will install Git using brew. We detailed how to install brew in the C/C++
compiler section. To install Git, run the following command in your terminal:
```bash
brew install git
```
### 4. An IDE
An IDE (Integrated Development Environment) is a tool that is used to view and
edit code of projects. While it is not required to use an IDE, it is recommended
since it can make the process of editing and running the project much easier.
There are many different IDEs available, and often people chose an IDE that will
suit their preferences and needs, however if you are unsure of which IDE you
should be using, the Dawn project recommends using [Visual Studio Code](https://code.visualstudio.com/),
not to be confused with Visual Studio.
Visual Studio Code is a free and open-source IDE that is widely used in the
industry for its simple, modern and configurable interface. For example you can
configure VSCode to work on Web Projects, Game Projects, and more. It acts like
a text editor with a bunch of extra tools.
In addition to installing the VSCode IDE, we will add several recommended
plugins that will make editing the Dawn project easier and more seamless.
To install VSCode follow the instructions for your specific operating system on
the [VSCode downloads page](https://code.visualstudio.com/download), as it can
vary a lot between operating systems.
After installing VSCode, you will need to install the following plugins, by
clicking on the "Extensions" icon on the left-hand side of the VSCode window,
and searching for the following plugins. You may also be able to click on the
following links to install the plugins directly, but it may not work.
- [C/C++](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools)
- [CMake](https://marketplace.visualstudio.com/items?itemName=twxs.cmake)
- [CMake Tools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools)
## Downloading the Source Code
Now that you have all of the necessary tools installed, you can download the
source code of the project and using it to build. The source code contains all
of the code of the project, as well as the assets and the build scripts. This is
confidential information and should not be shared with anyone.
### 1. Cloning the Repository
We previously installed the git tool, which is used to download the source code
of the project, and some third-party libraries. To download the source code, you
will need to open a terminal and navigate to the directory where you want to
download the source code to.
Afterwards, you will need to run the following command:
```bash
git clone https://git.wish.moe/YourWishes/Dawn.git
```
This will download the source code of the project to a new subdirectory called
"Dawn" and put all of the projects' source code within there.
### 2. Installing the Dependencies / Libraries.
I try to keep dependencies on third-party libraries to a minimum, however there
are a few libraries that are required to build the Dawn project. These libraries
are not included in the source code, and must be downloaded separately. This is
done using the git tool.
After you have cloned the above repository, you will need to open a terminal and
navigate to the directory where you downloaded the source code to. Afterwards,
you will need to run the following command:
```bash
git submodule update --init --recursive
```
This will fetch all of the third-party libraries that are required to build the
Dawn project. This may take a while depending on your internet connection.
### 3. Loading the Project
This step is semi-optional. We are aiming to build the project using CMake, and
the easiest way to do this is to use the CMake Tools plugin for VSCode that we
installed earlier. This plugin will automatically detect the CMake files in the
project and will allow us to build the project using the VSCode interface.
If you opted out of using VSCode, you will need to set up your CMake environment
to suit your IDE or needs. This is outside of the scope of this document, and
you will need to refer to your IDE's documentation for more information.
To load the project, you will need to open VSCode and open the Dawn project
directory. Most operating systems will allow you to do this by dragging the
Dawn project directory onto the VSCode window. If this does not work, you can
open VSCode and click on the "File" menu, and click on "Open Folder". You will
then need to navigate to the Dawn project directory and click "Open".
Afterwards you will likely be prompted autometically to configure the CMake
Tools plugin. If you are not, you can click on the "CMake" icon on the left-hand
side of the VSCode window, and click on "Configure". This will configure the
CMake Tools plugin to use the CMake files in the Dawn project directory.
You may also be asked to select a compiler. If you are using Windows, you will
need to select the Visual Studio compiler. If you are using Linux, you will need
to select the GCC or Clang compiler. If you are using macOS, you will need to
select the Clang compiler. If you are using a different compiler, you will need
to select the appropriate compiler.
If prompted to select a build type, select "Debug".
## Compiling the Project
Now that we have the project loaded into our IDE, we can compile the project.
This is done using the CMake Tools plugin for VSCode. If you are not using
VSCode you will need to refer to your IDE's documentation for more information.
Firstly, you will need to create a settings file to configure the project. In
VSCode you can create a new folder called `.vscode` (Including the leading `.`)
in the Dawn project root directory. Afterwards, you will need to create a new
file called `settings.json` in the `.vscode` directory. You will then need to
paste the following into the file:
```json
{
"cmake.configureArgs": [
"-DDAWN_BUILD_TOOLS=true",
"-DDAWN_BUILD_TARGET=target-liminal-win32-glfw",
"-DDAWN_DEBUG_BUILD=true"
]
}
```
And save the file. You may want to alter the values to suit your needs. For
example, if you are compiling on Linux, you will need to change
`target-liminal-win32-glfw` to `target-liminal-linux-glfw`. If you are compiling
on macOS, you will need to change it to `target-liminal-osx-glfw`. The specific
configure arguments are outside of the scope of this document, and you will need
to refer to the specific target documentation for more information.
After you have created the settings file, you will need to configure and build
the project. To perform the build you need to click "Build" button the bottom of
the VSCode window. This will compile the project and will output the resulting
binaries in to a "build" directory within the Dawn project directory.
Upon clicking the "Build" button, you will see an output panel appear at the
bottom of the VSCode window. This will show the process of the build, and will
show any errors that may occur. This is used to debug and fix any issues that
may occur during the build process.
If the build was successful, you will see a "Build finished" message in the
output panel, typically read as;
```bash
[build] Build finished with exit code 0
```
If you do not see this message, or if the exit code is not 0, you will need to
debug the issue. The output panel will show the error message which is helpful
so we can debug the issue. If you are unable to debug the issue, you can ask for
help in the Discord server.
## Running the built project
After the build process succeeds you will be able to run the project. This is
done by clicking on the Run icon, which looks like a play button, on the bottom
of the VSCode window. This will run the project in production mode and will not
show any debug information.
If the program hangs, crashes or does not run, you can click the Debug icon,
which looks like a ladybug, on the bottom of the VSCode window. This will run
the project in debug mode and will show debug information and HALT the program
if there is an error detected. If program HALTS in debug mode you can use this
information to debug the issue. If you are unable to debug the issue, you can
ask for help in the Discord server.

234
gentileset.py Normal file
View File

@ -0,0 +1,234 @@
# font is a 2D array of 8x8 pixel characters where each bit is a pixel on the
# row.
font8x8_basic = [
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0000 (nul)
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0001
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0002
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0003
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0004
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0005
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0006
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0007
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0008
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0009
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+000A
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+000B
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+000C
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+000D
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+000E
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+000F
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0010
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0011
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0012
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0013
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0014
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0015
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0016
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0017
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0018
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0019
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+001A
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+001B
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+001C
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+001D
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+001E
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+001F
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0020 (space)
[0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00], # U+0021 (!)
[0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0022 (")
[0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00], # U+0023 (#)
[0x0C, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x0C, 0x00], # U+0024 ($)
[0x00, 0x63, 0x33, 0x18, 0x0C, 0x66, 0x63, 0x00], # U+0025 (%)
[0x1C, 0x36, 0x1C, 0x6E, 0x3B, 0x33, 0x6E, 0x00], # U+0026 (&)
[0x06, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0027 (')
[0x18, 0x0C, 0x06, 0x06, 0x06, 0x0C, 0x18, 0x00], # U+0028 (()
[0x06, 0x0C, 0x18, 0x18, 0x18, 0x0C, 0x06, 0x00], # U+0029 ())
[0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00], # U+002A (*)
[0x00, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x00, 0x00], # U+002B (+)
[0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x06], # U+002C (,)
[0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00], # U+002D (-)
[0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00], # U+002E (.)
[0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00], # U+002F (/)
[0x3E, 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x3E, 0x00], # U+0030 (0)
[0x0C, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x3F, 0x00], # U+0031 (1)
[0x1E, 0x33, 0x30, 0x1C, 0x06, 0x33, 0x3F, 0x00], # U+0032 (2)
[0x1E, 0x33, 0x30, 0x1C, 0x30, 0x33, 0x1E, 0x00], # U+0033 (3)
[0x38, 0x3C, 0x36, 0x33, 0x7F, 0x30, 0x78, 0x00], # U+0034 (4)
[0x3F, 0x03, 0x1F, 0x30, 0x30, 0x33, 0x1E, 0x00], # U+0035 (5)
[0x1C, 0x06, 0x03, 0x1F, 0x33, 0x33, 0x1E, 0x00], # U+0036 (6)
[0x3F, 0x33, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x00], # U+0037 (7)
[0x1E, 0x33, 0x33, 0x1E, 0x33, 0x33, 0x1E, 0x00], # U+0038 (8)
[0x1E, 0x33, 0x33, 0x3E, 0x30, 0x18, 0x0E, 0x00], # U+0039 (9)
[0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00], # U+003A (:)
[0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x06], # U+003B (;)
[0x18, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x18, 0x00], # U+003C (<)
[0x00, 0x00, 0x3F, 0x00, 0x00, 0x3F, 0x00, 0x00], # U+003D (=)
[0x06, 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x06, 0x00], # U+003E (>)
[0x1E, 0x33, 0x30, 0x18, 0x0C, 0x00, 0x0C, 0x00], # U+003F (?)
[0x3E, 0x63, 0x7B, 0x7B, 0x7B, 0x03, 0x1E, 0x00], # U+0040 (@)
[0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00], # U+0041 (A)
[0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3F, 0x00], # U+0042 (B)
[0x3C, 0x66, 0x03, 0x03, 0x03, 0x66, 0x3C, 0x00], # U+0043 (C)
[0x1F, 0x36, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x00], # U+0044 (D)
[0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x00], # U+0045 (E)
[0x7F, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x0F, 0x00], # U+0046 (F)
[0x3C, 0x66, 0x03, 0x03, 0x73, 0x66, 0x7C, 0x00], # U+0047 (G)
[0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00], # U+0048 (H)
[0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00], # U+0049 (I)
[0x78, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E, 0x00], # U+004A (J)
[0x67, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x67, 0x00], # U+004B (K)
[0x0F, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x00], # U+004C (L)
[0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0x00], # U+004D (M)
[0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x63, 0x00], # U+004E (N)
[0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00], # U+004F (O)
[0x3F, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x0F, 0x00], # U+0050 (P)
[0x1E, 0x33, 0x33, 0x33, 0x3B, 0x1E, 0x38, 0x00], # U+0051 (Q)
[0x3F, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x67, 0x00], # U+0052 (R)
[0x1E, 0x33, 0x07, 0x1E, 0x38, 0x33, 0x1E, 0x00], # U+0053 (S)
[0x3F, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x00], # U+0054 (T)
[0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0x00], # U+0055 (U)
[0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00], # U+0056 (V)
[0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00], # U+0057 (W)
[0x63, 0x63, 0x36, 0x1C, 0x1C, 0x36, 0x63, 0x00], # U+0058 (X)
[0x33, 0x33, 0x33, 0x1E, 0x0C, 0x0C, 0x0C, 0x00], # U+0059 (Y)
[0x3F, 0x33, 0x19, 0x0C, 0x26, 0x33, 0x3F, 0x00], # U+005A (Z)
[0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00], # U+005B ([)
[0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x00], # U+005C (\)
[0x1E, 0x30, 0x30, 0x30, 0x30, 0x30, 0x1E, 0x00], # U+005D (])
[0x08, 0x1C, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00], # U+005E (^)
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF], # U+005F (_)
[0x0C, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00], # U+0060 (`)
[0x00, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x6E, 0x00], # U+0061 (a)
[0x07, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3B, 0x00], # U+0062 (b)
[0x00, 0x00, 0x1E, 0x33, 0x03, 0x33, 0x1E, 0x00], # U+0063 (c)
[0x38, 0x30, 0x30, 0x3E, 0x33, 0x33, 0x6E, 0x00], # U+0064 (d)
[0x00, 0x00, 0x1E, 0x33, 0x3F, 0x03, 0x1E, 0x00], # U+0065 (e)
[0x1C, 0x36, 0x06, 0x0F, 0x06, 0x06, 0x0F, 0x00], # U+0066 (f)
[0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x1E], # U+0067 (g)
[0x07, 0x06, 0x36, 0x6E, 0x66, 0x66, 0x67, 0x00], # U+0068 (h)
[0x0C, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00], # U+0069 (i)
[0x30, 0x00, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E], # U+006A (j)
[0x07, 0x06, 0x66, 0x36, 0x1E, 0x36, 0x67, 0x00], # U+006B (k)
[0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00], # U+006C (l)
[0x00, 0x00, 0x33, 0x7F, 0x7F, 0x6B, 0x63, 0x00], # U+006D (m)
[0x00, 0x00, 0x1B, 0x37, 0x33, 0x33, 0x33, 0x00], # U+006E (n)
[0x00, 0x00, 0x1E, 0x33, 0x33, 0x33, 0x1E, 0x00], # U+006F (o)
[0x00, 0x00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x0F], # U+0070 (p)
[0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x78], # U+0071 (q)
[0x00, 0x00, 0x1B, 0x36, 0x36, 0x06, 0x0F, 0x00], # U+0072 (r)
[0x00, 0x00, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x00], # U+0073 (s)
[0x08, 0x0C, 0x3E, 0x0C, 0x0C, 0x2C, 0x18, 0x00], # U+0074 (t)
[0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x00], # U+0075 (u)
[0x00, 0x00, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00], # U+0076 (v)
[0x00, 0x00, 0x63, 0x6B, 0x7F, 0x7F, 0x36, 0x00], # U+0077 (w)
[0x00, 0x00, 0x63, 0x36, 0x1C, 0x36, 0x63, 0x00], # U+0078 (x)
[0x00, 0x00, 0x33, 0x33, 0x33, 0x3E, 0x30, 0x1E], # U+0079 (y)
[0x00, 0x00, 0x3F, 0x19, 0x0C, 0x26, 0x3F, 0x00], # U+007A (z)
[0x38, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, 0x38, 0x00], # U+007B ({)
[0x0C, 0x0C, 0x0C, 0x00, 0x0C, 0x0C, 0x0C, 0x00], # U+007C (|)
[0x07, 0x0C, 0x0C, 0x38, 0x0C, 0x0C, 0x07, 0x00], # U+007D (})
[0x6E, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], # U+007E (~)
]
# COLOR4F(0.0f, 0.0f, 0.0f, 1.0f), # Black
# COLOR4F(1.0f, 1.0f, 1.0f, 1.0f), # White
# COLOR4F(0.8f, 0.0f, 0.0f, 1.0f), # Red
# COLOR4F(0.0f, 0.5f, 0.0f, 1.0f), # Green
# COLOR4F(0.0f, 0.0f, 0.8f, 1.0f), # Blue
# COLOR4F(0.8f, 0.8f, 0.0f, 1.0f), # Yellow
# COLOR4F(0.8f, 0.0f, 0.8f, 1.0f), # Magenta
# COLOR4F(0.0f, 0.8f, 0.8f, 1.0f), # Cyan
# COLOR4F(0.5f, 0.5f, 0.5f, 1.0f), # Gray
# COLOR4F(0.5f, 0.25f, 0.0f, 1.0f) # Brown
# Tilemap
COLORS = {
"BLACK": [ 0, 0, 0 ],
"WHITE": [ 255, 255, 255 ],
"RED": [ 204, 0, 0 ],
"GREEN": [ 0, 128, 0 ],
"BLUE": [ 0, 0, 204 ],
"YELLOW": [ 204, 204, 0 ],
"MAGENTA": [ 204, 0, 204 ],
"CYAN": [ 0, 204, 204 ],
"GRAY": [ 128, 128, 128 ],
"BROWN": [ 128, 64, 0 ]
}
TILES = {
# NAME: [ id, symbol, color ]
"NULL": [ 0, 'N', COLORS["RED"] ],
"GRASS": [ 1, '#', COLORS["GREEN"] ],
"WATER": [ 2, '\\', COLORS["BLUE"] ],
# "DOOR": [ 3, 'D', COLORS["BROWN"] ],
"BUILDING_WALL": [ 4, '-', COLORS["GRAY"] ],
"ROOF": [ 5, '/', COLORS["BROWN"] ],
"WALKABLE_NULL": [ 6, ' ', COLORS["BLACK"] ],
"COBBLESTONE": [ 7, '#', COLORS["GRAY"] ],
"STAIRS": [ 8, '=', COLORS["GRAY"] ],
"RAILING": [ 9, 'n', COLORS["BROWN"] ],
"COLUMN": [ 10, 'I', COLORS["WHITE"] ],
"RAIL_TRACK": [ 11, '|', COLORS["GRAY"] ],
"RAIL_SLEEPER": [ 12, '-', COLORS["BROWN"] ],
"CARPET": [ 13, '#', COLORS["RED"] ],
"LAMP": [ 14, 'i', COLORS["YELLOW"] ],
}
ENTITIES = {
"NULL": [ 0, 'N', COLORS["RED"] ],
"PLAYER": [ 1, 'v', COLORS["RED"] ],
"NPC": [ 2, 'V', COLORS["RED"] ],
"SIGN": [ 3, '+', COLORS["YELLOW"] ],
"DOOR": [ 4, 'D', COLORS["BROWN"] ],
}
# Create 64 x 64 RGB pixel buffer.
import png
WIDTH = 64
HEIGHT = 64
def genTileset(filename, tileset, background):
# Create 64x64 pixel buffer with black
PIXEL_BUFFER = []
for y in range(HEIGHT):
row = []
for x in range(WIDTH):
row.append(background)
PIXEL_BUFFER.append(row)
# For each TILES
for tile in tileset:
# Get the tile data
tile_data = tileset[tile]
tile_id = tile_data[0]
tile_char = tile_data[1]
tile_color = tile_data[2]
# Get char pixels
char_pixels = font8x8_basic[ord(tile_char)]
tile_color_rgba = [ tile_color[0], tile_color[1], tile_color[2], 255 ]
# Write char pixels to output buffer, using tile_id to determine pixels with
# each row holding 8 characters of 8 pixels
for y in range(8):
row = char_pixels[y]
for x in range(8):
if row & (1 << x):
PIXEL_BUFFER[(tile_id // 8) * 8 + y][(tile_id % 8) * 8 + x] = tile_color_rgba
# Convert from [ [ [ r, g, b ], [ r, g, b] ], [ [ r, g, b ], [ r, g, b ] ] ] to
# [ [R, G, B, A, R, G, B, A] ] (Flatten level 2 and add alpha channel)
FLATTENED_PIXEL_BUFFER = [ [ 0 for i in range(WIDTH * 4) ] for j in range(HEIGHT) ]
for y in range(HEIGHT):
for x in range(WIDTH):
FLATTENED_PIXEL_BUFFER[y][x * 4 + 0] = PIXEL_BUFFER[y][x][0]
FLATTENED_PIXEL_BUFFER[y][x * 4 + 1] = PIXEL_BUFFER[y][x][1]
FLATTENED_PIXEL_BUFFER[y][x * 4 + 2] = PIXEL_BUFFER[y][x][2]
FLATTENED_PIXEL_BUFFER[y][x * 4 + 3] = PIXEL_BUFFER[y][x][3]
# Now write PIXEL_BUFFER to png
png.from_array(FLATTENED_PIXEL_BUFFER, 'RGBA').save(filename)
genTileset("./assets/tilemaps/tilemap.png", TILES, [ 0, 0, 0, 255 ])
genTileset("./assets/tilemaps/entities.png", ENTITIES, [ 0, 0, 0, 100 ])

Submodule lib/AudioFile deleted from 004065d01e

View File

@ -1,53 +1,31 @@
# Copyright (c) 2021 Dominic Msters # Copyright (c) 2024 Dominic Masters
# #
# This software is released under the MIT License. # This software is released under the MIT License.
# https://opensource.org/licenses/MIT # https://opensource.org/licenses/MIT
# GLFW include(FetchContent)
if(DAWN_TARGET_GLFW)
if(${CMAKE_SYSTEM_NAME} MATCHES "Emscripten") add_library(font8x8 INTERFACE)
set(DAWN_EMSCRIPTEN_FLAGS "${DAWN_EMSCRIPTEN_FLAGS} -s USE_GLFW=3" CACHE INTERNAL ${DAWN_CACHE_TARGET}) target_include_directories(font8x8 INTERFACE font8x8)
add_subdirectory(glad)
else()
add_subdirectory(glad)
add_subdirectory(glfw)
endif()
endif()
# SDL
if(DAWN_TARGET_SDL2)
add_subdirectory(glad) add_subdirectory(glad)
add_subdirectory(SDL)
endif() # GLFW
FetchContent_Declare(glfw URL https://github.com/glfw/glfw/releases/download/3.4/glfw-3.4.zip)
FetchContent_MakeAvailable(glfw)
# GLM # GLM
add_subdirectory(glm) FetchContent_Declare(
cglm
# FreeType GIT_REPOSITORY https://github.com/recp/cglm
if(${CMAKE_SYSTEM_NAME} MATCHES "Emscripten") GIT_TAG 1796cc5ce298235b615dc7a4750b8c3ba56a05dd
set(DAWN_EMSCRIPTEN_FLAGS "${DAWN_EMSCRIPTEN_FLAGS} -s USE_FREETYPE=1" CACHE INTERNAL ${DAWN_CACHE_TARGET}) )
else() FetchContent_MakeAvailable(cglm)
add_subdirectory(freetype)
endif()
#LibArchive #LibArchive
if(DAWN_TARGET_ARCHIVE) FetchContent_Declare(
add_subdirectory(libarchive) libarchive
endif() GIT_REPOSITORY https://github.com/libarchive/libarchive
GIT_TAG v3.7.6
# OpenAL )
if(DAWN_TARGET_OPENAL) FetchContent_MakeAvailable(libarchive)
set(LIBTYPE "STATIC")
add_subdirectory(openal-soft)
set(BUILD_TESTS OFF CACHE BOOL "Build tests" FORCE)
set(BUILD_EXAMPLES OFF CACHE BOOL "Build examples" FORCE)
add_subdirectory(AudioFile)
endif()
# Emscripten (TESTING ONLY)
if(DEFINED DAWN_EMSCRIPTEN_FLAGS)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${DAWN_EMSCRIPTEN_FLAGS}" CACHE INTERNAL ${DAWN_CACHE_TARGET})
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${DAWN_EMSCRIPTEN_FLAGS}" CACHE INTERNAL ${DAWN_CACHE_TARGET})
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${DAWN_EMSCRIPTEN_FLAGS}" CACHE INTERNAL ${DAWN_CACHE_TARGET})
endif()

Submodule lib/SDL deleted from fb1497566c

1
lib/font8x8 Submodule

Submodule lib/font8x8 added at 8e279d2d86

Submodule lib/freetype deleted from 7ff43d3e9f

Submodule lib/glfw deleted from b35641f4a3

Submodule lib/glm deleted from 45008b225e

Submodule lib/libarchive deleted from 313aa1fa10

Submodule lib/openal-soft deleted from d3875f333f

View File

@ -1,77 +1,22 @@
# Copyright (c) 2022 Dominic Masters # Copyright (c) 2024 Dominic Masters
# #
# This software is released under the MIT License. # This software is released under the MIT License.
# https://opensource.org/licenses/MIT # https://opensource.org/licenses/MIT
# Custom variables
set(
DAWN_TARGET_DEPENDENCIES_LAST
CACHE INTERNAL ${DAWN_CACHE_TARGET}
)
# Build Project # Build Project
add_executable(${DAWN_TARGET_NAME}) add_executable(${DAWN_TARGET_NAME})
# Change what we are building. Pulled from the cmake/targets dir. # Add base
if(DEFINED DAWN_BUILDING)
add_subdirectory(${DAWN_BUILDING})
endif()
# Validate game project includes the target name
if(DEFINED DAWN_TARGET_NAME)
# Add in base library
add_subdirectory(dawn) add_subdirectory(dawn)
# Compile entry targets # Compile entries
if(DAWN_TARGET_WIN32) if(DAWN_TARGET STREQUAL "linux-x64-terminal")
add_subdirectory(dawnwin32) add_subdirectory(dawnlinux)
elseif(DAWN_TARGET_LINUX) add_subdirectory(dawntermlinux)
elseif(DAWN_TARGET STREQUAL "linux-x64-glfw")
add_subdirectory(dawnlinux) add_subdirectory(dawnlinux)
elseif(DAWN_TARGET_OSX)
add_subdirectory(dawnosx)
elseif(DAWN_TARGET_VITA)
add_subdirectory(dawnvita)
elseif(DAWN_TARGET_EMSCRIPTEN)
add_subdirectory(dawnemscripten)
else()
message(FATAL_ERROR "You need to define an entry target")
endif()
# Host Libraries
target_link_libraries(${DAWN_TARGET_NAME}
PUBLIC
${DAWN_BUILD_HOST_LIBS}
)
# Compile support targets
if(DAWN_TARGET_GLFW)
add_subdirectory(dawnglfw) add_subdirectory(dawnglfw)
add_subdirectory(dawnopengl) add_subdirectory(dawnopengl)
endif()
if(DAWN_TARGET_TRUETYPE)
add_subdirectory(dawntruetype)
endif()
if(DAWN_TARGET_SDL2)
add_subdirectory(dawnsdl2)
add_subdirectory(dawnopengl)
endif()
if(DAWN_TARGET_VITA)
add_subdirectory(dawnopengl)
endif()
if(DAWN_TARGET_OPENAL)
add_subdirectory(dawnopenal)
endif()
# Late definitions, used by tools
if(NOT DAWN_TARGET_DEPENDENCIES_LAST)
else() else()
add_dependencies(${DAWN_TARGET_NAME} ${DAWN_TARGET_DEPENDENCIES_LAST}) message(FATAL_ERROR "Unknown target: ${DAWN_TARGET}")
endif()
# Compress the game assets.
add_dependencies(${DAWN_TARGET_NAME} dawnassets)
endif() endif()

View File

@ -1,4 +1,4 @@
# Copyright (c) 2022 Dominic Masters # Copyright (c) 2024 Dominic Masters
# #
# This software is released under the MIT License. # This software is released under the MIT License.
# https://opensource.org/licenses/MIT # https://opensource.org/licenses/MIT
@ -6,7 +6,6 @@
# Libraries # Libraries
target_link_libraries(${DAWN_TARGET_NAME} target_link_libraries(${DAWN_TARGET_NAME}
PUBLIC PUBLIC
glm
archive_static archive_static
) )
@ -19,19 +18,22 @@ target_include_directories(${DAWN_TARGET_NAME}
# Subdirs # Subdirs
add_subdirectory(assert) add_subdirectory(assert)
add_subdirectory(asset) add_subdirectory(asset)
add_subdirectory(audio)
add_subdirectory(component)
add_subdirectory(display) add_subdirectory(display)
add_subdirectory(environment)
add_subdirectory(game) add_subdirectory(game)
# add_subdirectory(games) add_subdirectory(rpg)
# add_subdirectory(input)
add_subdirectory(locale)
add_subdirectory(prefab)
# add_subdirectory(physics)
add_subdirectory(save)
add_subdirectory(scene)
# add_subdirectory(state)
add_subdirectory(time)
add_subdirectory(util)
add_subdirectory(ui) add_subdirectory(ui)
add_subdirectory(locale)
add_subdirectory(util)
# Sources
target_sources(${DAWN_TARGET_NAME}
PRIVATE
input.c
)
# Assets
tool_map(testmap maps/testmap.tmx)
tool_map(testmap2 maps/testmap2.tmx)
tool_copy(en en.json)
add_dependencies(${DAWN_TARGET_NAME} dawnassets)

View File

@ -1,9 +1,12 @@
# Copyright (c) 2022 Dominic Masters # Copyright (c) 2024 Dominic Masters
# #
# This software is released under the MIT License. # This software is released under the MIT License.
# https://opensource.org/licenses/MIT # https://opensource.org/licenses/MIT
# Subdirs
# Sources
target_sources(${DAWN_TARGET_NAME} target_sources(${DAWN_TARGET_NAME}
PRIVATE PRIVATE
assert.cpp assert.c
) )

View File

@ -5,7 +5,8 @@
* https://opensource.org/licenses/MIT * https://opensource.org/licenses/MIT
*/ */
#include "assert.hpp" #include "assert.h"
#include <stdarg.h>
void assertTrueImplement( void assertTrueImplement(
const char *file, const char *file,
@ -26,10 +27,11 @@ void assertTrueImplement(
func func
); );
va_list argptr; // Print message.
va_start(argptr, message); va_list args;
vfprintf(stderr, message, argptr); va_start(args, message);
va_end(argptr); vfprintf(stderr, message, args);
va_end(args);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
throw std::runtime_error("Assert failed."); abort();
} }

View File

@ -6,7 +6,7 @@
*/ */
#pragma once #pragma once
#include "dawnlibs.hpp" #include "dawn.h"
/** /**
* Asserts that a given statement must evaluate to true or the assertion fails * Asserts that a given statement must evaluate to true or the assertion fails
@ -63,7 +63,7 @@ void assertTrueImplement(
* @param message Message (sprintf format) to send to the logger. * @param message Message (sprintf format) to send to the logger.
* @param args Optional TParam args for the sprintf message to accept. * @param args Optional TParam args for the sprintf message to accept.
*/ */
#define assertNotNull(x, ...) assertTrue(x != nullptr, __VA_ARGS__) #define assertNotNull(x, ...) assertTrue(x != NULL, __VA_ARGS__)
/** /**
* Asserts that a given pointer is null. * Asserts that a given pointer is null.
@ -71,18 +71,7 @@ void assertTrueImplement(
* @param message Message (sprintf format) to send to the logger. * @param message Message (sprintf format) to send to the logger.
* @param args Optional TParam args for the sprintf message to accept. * @param args Optional TParam args for the sprintf message to accept.
*/ */
#define assertNull(x, ...) assertTrue(x == nullptr, __VA_ARGS__) #define assertNull(x, ...) assertTrue(x == NULL, __VA_ARGS__)
/**
* Asserts that a given map has a specific key.
* @param map Map to check.
* @param key Key to check for.
* @param message Message (sprintf format) to send to the logger.
* @param args Optional TParam args for the sprintf message to accept.
*/
#define assertMapHasKey(map, key, ...) assertTrue( \
map.find(key) != map.end(), __VA_ARGS__ \
)
/** /**
* Asserts that a given value has a specific flag turned off. * Asserts that a given value has a specific flag turned off.
@ -108,6 +97,19 @@ void assertTrueImplement(
(value & flag) == flag, __VA_ARGS__ \ (value & flag) == flag, __VA_ARGS__ \
) )
/**
* Asserts that the given string is not null, and has a length that is less
* the maximum buffer size, including the NULL terminator.
*
* @param str String to check.
* @param bufferSize Maximum buffer size.
* @param message Message (sprintf format) to send to the logger.
* @param args Optional TParam args for the sprintf message to accept.
*/
#define assertStringValid(str, bufferSize, ...) assertTrue( \
((str != NULL) && ((strlen(str)+1) < bufferSize)), __VA_ARGS__ \
)
/** /**
* Asserts that the current code is deprecated and should not be used anymore. * Asserts that the current code is deprecated and should not be used anymore.
* @deprecated * @deprecated

View File

@ -1,200 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "assert/assert.hpp"
#include "AssetDataLoader.hpp"
#include "util/Math.hpp"
using namespace Dawn;
ssize_t assetDataLoaderArchiveRead(
struct archive *archive,
void *d,
const void **buffer
) {
assertNotNull(archive, "Archive is NULL!");
assertNotNull(d, "Data is NULL!");
assertNotNull(buffer, "Buffer is NULL!");
AssetDataLoader *loader = (AssetDataLoader*)d;
*buffer = loader->buffer;
size_t read = fread(
loader->buffer, 1, ASSET_LOADER_BUFFER_SIZE, loader->assetArchiveFile
);
if(ferror(loader->assetArchiveFile)) return ARCHIVE_FATAL;
return read;
}
int64_t assetDataLoaderArchiveSeek(
struct archive *archive,
void *d,
int64_t offset,
int32_t whence
) {
assertNotNull(archive, "Archive is NULL!");
assertNotNull(d, "Data is NULL!");
assertTrue(offset > 0, "Offset must be greater than 0!");
AssetDataLoader *loader = (AssetDataLoader*)d;
int32_t ret = fseek(loader->assetArchiveFile, offset, whence);
assertTrue(ret == 0, "Failed to seek!");
return ftell(loader->assetArchiveFile);
}
int32_t assetDataLoaderArchiveOpen(struct archive *a, void *d) {
assertNotNull(a, "Archive is NULL!");
assertNotNull(d, "Data is NULL!");
AssetDataLoader *loader = (AssetDataLoader*)d;
int32_t ret = fseek(loader->assetArchiveFile, 0, SEEK_SET);
assertTrue(ret == 0, "Failed to seek to start of file!");
return ARCHIVE_OK;
}
int32_t assetDataLoaderArchiveClose(struct archive *a, void *d) {
assertNotNull(a, "Archive is NULL!");
assertNotNull(d, "Data is NULL!");
return assetDataLoaderArchiveOpen(a, d);
}
// // // // // // // // // // // // // // // // // // // // // // // // // // //
AssetDataLoader::AssetDataLoader(std::string fileName) : fileName(fileName) {
assertTrue(
fileName.size() > 0,
"IAssetDataLoader::IAssetDataLoader: fileName must be greater than 0"
);
}
void AssetDataLoader::open() {
assertNull(this->assetArchiveFile, "AssetDataLoader::open: File is already open");
assertNull(this->assetArchive, "AssetDataLoader::open: Archive is already open");
assertNull(this->assetArchiveEntry, "AssetDataLoader::open: Entry is already open");
this->assetArchiveFile = this->openAssetArchiveFile();
assertNotNull(this->assetArchiveFile, "AssetDataLoader::open: Failed to open archive file!");
// Open archive reader
assetArchive = archive_read_new();
assertNotNull(assetArchive, "AssetDataLoader::open: Failed to create archive reader");
// Set up the reader
archive_read_support_format_tar(assetArchive);
// Open reader
archive_read_set_open_callback(assetArchive, &assetDataLoaderArchiveOpen);
archive_read_set_read_callback(assetArchive, &assetDataLoaderArchiveRead);
archive_read_set_seek_callback(assetArchive, &assetDataLoaderArchiveSeek);
archive_read_set_close_callback(assetArchive, &assetDataLoaderArchiveClose);
archive_read_set_callback_data(assetArchive, this);
int32_t ret = archive_read_open1(assetArchive);
assertTrue(ret == ARCHIVE_OK, "AssetDataLoader::open: Failed to open archive!");
position = 0;
// Iterate over each file to find the one for this asset loader.
while(archive_read_next_header(assetArchive, &assetArchiveEntry) == ARCHIVE_OK) {
const char_t *headerFile = (char_t*)archive_entry_pathname(assetArchiveEntry);
if(std::string(headerFile) == this->fileName) return;
int32_t ret = archive_read_data_skip(assetArchive);
assertTrue(ret == ARCHIVE_OK, "AssetDataLoader::open: Failed to skip data!");
}
assertUnreachable("AssetDataLoader::open: Failed to find file!");
}
int32_t AssetDataLoader::close() {
assertNotNull(this->assetArchiveFile, "AssetDataLoader::close: File is NULL");
assertNotNull(this->assetArchive, "AssetDataLoader::close: Archive is NULL!");
assertNotNull(this->assetArchiveEntry, "AssetDataLoader::close: Entry is NULL!");
// Close the archive
int32_t ret = archive_read_free(this->assetArchive);
assertTrue(ret == ARCHIVE_OK, "AssetDataLoader::close: Failed to close archive!");
this->assetArchive = nullptr;
this->assetArchiveEntry = nullptr;
// Close the file
int32_t res = fclose(this->assetArchiveFile);
this->assetArchiveFile = nullptr;
return res;
}
size_t AssetDataLoader::read(uint8_t *buffer, size_t size) {
assertNotNull(buffer, "Buffer is NULL!");
assertTrue(size > 0, "Size must be greater than 0!");
assertNotNull(this->assetArchive, "assetRead: Archive is NULL!");
assertNotNull(this->assetArchiveEntry, "assetRead: Entry is NULL!");
ssize_t read = archive_read_data(this->assetArchive, buffer, size);
this->position += read;
if(read == ARCHIVE_FATAL) {
assertUnreachable(archive_error_string(this->assetArchive));
}
assertTrue(read != ARCHIVE_RETRY, "assetRead: Failed to read data (RETRY)!");
assertTrue(read != ARCHIVE_WARN, "assetRead: Failed to read data (WARN)!");
return read;
}
size_t AssetDataLoader::readUntil(
uint8_t *buffer,
const size_t maxSize,
const char_t delimiter
) {
size_t totalRead = this->read(buffer, maxSize);
size_t i = 0;
while(i < totalRead) {
if(buffer[i] == delimiter) break;
i++;
}
buffer[i++] = '\0';
return i;
}
size_t AssetDataLoader::getSize() {
assertTrue(this->assetArchiveEntry != nullptr, "AssetDataLoader::getSize: Entry is NULL!");
assertTrue(archive_entry_size_is_set(assetArchiveEntry), "assetGetSize: Entry size is not set!");
return archive_entry_size(assetArchiveEntry);
}
size_t AssetDataLoader::skip(size_t n) {
assertTrue(n >= 0, "AssetDataLoader::skip: Byte count must be greater than 0.");
uint8_t dumpBuffer[ASSET_LOADER_BUFFER_SIZE];
size_t skipped = 0;
size_t n2, n3;
while(n != 0) {
n2 = Math::min<size_t>(n, ASSET_LOADER_BUFFER_SIZE);
n3 = this->read(dumpBuffer, n2);
assertTrue(n3 == n2, "AssetDataLoader::skip: Failed to skip bytes!");
n -= n3;
}
return skipped;
}
size_t AssetDataLoader::setPosition(const size_t position) {
assertTrue(position >= 0, "Position must be greater than or equal to 0");
this->rewind();
return this->skip(position);
}
void AssetDataLoader::rewind() {
// TODO: See if I can optimize this
this->close();
this->open();
}
size_t AssetDataLoader::getPosition() {
assertNotNull(this->assetArchiveFile, "AssetDataLoader::getPosition: File is not open!");
return this->position;
}
AssetDataLoader::~AssetDataLoader() {
if(this->assetArchiveFile != nullptr) this->close();
}

View File

@ -1,166 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "dawnlibs.hpp"
extern "C" {
#include <archive.h>
#include <archive_entry.h>
}
#define ASSET_LOADER_BUFFER_SIZE 32768
/**
* Method invoked by the libarchive internals to read bytes from the archive
* file pointer.
*
* @param archive Archive requesting the read.
* @param data Data pointer passed to the archive.
* @param buffer Pointer to where the buffer pointer should be stored.
* @return Count of bytes read.
*/
ssize_t assetDataLoaderArchiveRead(
struct archive *archive,
void *data,
const void **buffer
);
/**
* Method invoked by the libarchive internals to seek the archive file pointer.
*
* @param archive Archive requesting the seek.
* @param data Data pointer passed to the archive.
* @param offset Offset to seek to.
* @param whence Whence to seek from.
* @return The new offset.
*/
int64_t assetDataLoaderArchiveSeek(
struct archive *archive,
void *data,
int64_t offset,
int32_t whence
);
/**
* Method invoked by the libarchive internals to open the archive file pointer.
*
* @param archive Archive requesting the open.
* @param data Data pointer passed to the archive.
* @return 0 if success, otherwise for failure.
*/
int32_t assetDataLoaderArchiveOpen(struct archive *a, void *data);
/**
* Method invoked by the libarchive internals to close the archive file pointer.
*
* @param archive Archive requesting the close.
* @param data Data pointer passed to the archive.
* @return 0 if success, otherwise for failure.
*/
int32_t assetDataLoaderArchiveClose(struct archive *a, void *data);
namespace Dawn {
class AssetDataLoader {
protected:
struct archive *assetArchive = nullptr;
struct archive_entry *assetArchiveEntry = nullptr;
size_t position;
std::string fileName;
public:
uint8_t buffer[ASSET_LOADER_BUFFER_SIZE];
FILE *assetArchiveFile = nullptr;
/**
* Unimplemented method intended to be implemented by the platform that
* will be used to request a File pointer to the asset.
*
* @return Pointer to the opened asset archive.
*/
FILE * openAssetArchiveFile();
/**
* Create a new asset loader. Asset Loaders can be used to load data from
* a file in a myriad of ways.
*
* @param fileName File name of the asset that is to be loaded.
*/
AssetDataLoader(std::string filename);
/**
* Platform-centric method to open a file buffer to an asset.
*/
void open();
/**
* Closes the previously ppened asset.
* @return 0 if successful, otherwise false.
*/
int32_t close();
/**
* Read bytes from buffer.
* @param buffer Pointer to a ubyte array to buffer data into.
* @param size Length of the data buffer (How many bytes to read).
* @return The count of bytes read.
*/
size_t read(uint8_t *buffer, size_t size);
/**
* Reads bytes from the buffer until a given delimiter is found. Returned
* position will be the index of the delimiter within the buffer.
*
* @param buffer Buffer to read into.
* @param maxSize Maximum size of the buffer.
* @param delimiter Delimiter to read until.
* @return The count of bytes read (including null terminator)
*/
size_t readUntil(
uint8_t *buffer,
const size_t maxSize,
const char_t delimiter
);
/**
* Get the size of the asset.
* @return The size of the asset in bytes.
*/
size_t getSize();
/**
* Skips the read head forward to a given position.
*
* @param n Count of bytes to progress the read head by.
* @return Count of bytes progressed.
*/
size_t skip(size_t n);
/**
* Rewind the read head to the beginning of the file.
*/
void rewind();
/**
* Sets the absolute position of the read head within the buffer of the
* file.
*
* @param absolutePosition Absolute position to set the read head to.
*/
size_t setPosition(const size_t absolutePosition);
/**
* Returns the current position of the read head.
*
* @return The current read head position.
*/
size_t getPosition();
/**
* Cleanup the asset loader.
*/
virtual ~AssetDataLoader();
};
}

View File

@ -1,17 +0,0 @@
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "AssetLoader.hpp"
#include "assert/assert.hpp"
using namespace Dawn;
AssetLoader::AssetLoader(const std::string name) : name(name) {
assertTrue(name.size() > 0, "Asset::Asset: Name cannot be empty");
}
AssetLoader::~AssetLoader() {
this->loaded = false;
}

View File

@ -1,41 +0,0 @@
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "dawnlibs.hpp"
namespace Dawn {
class AssetLoader {
public:
const std::string name;
bool_t loaded = false;
/**
* Create an abstract Asset object.
*
* @param name Name of the asset.
*/
AssetLoader(const std::string name);
/**
* Virtual function that will be called by the asset manager on a
* synchronous basis. This will only trigger if the blocks are false and
* the loaded is also false.
*/
virtual void updateSync() = 0;
/**
* Virtual function called by the asset manager asynchronously every tick.
* This will only trigger if blocks are false and the loaded state is also
* false.
*/
virtual void updateAsync() = 0;
/**
* Dispose the asset item.
*/
virtual ~AssetLoader();
};
}

View File

@ -1,64 +0,0 @@
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "AssetManager.hpp"
#include "loaders/TextureLoader.hpp"
using namespace Dawn;
void AssetManager::init() {
}
void AssetManager::update() {
auto itPending = pendingAssetLoaders.begin();
while(itPending != pendingAssetLoaders.end()) {
auto loader = *itPending;
loader->updateSync();
loader->updateAsync();
if(loader->loaded) {
finishedAssetLoaders.push_back(loader);
itPending = pendingAssetLoaders.erase(itPending);
} else {
itPending++;
}
}
}
void AssetManager::removeExisting(const std::string filename) {
auto existing = std::find_if(
pendingAssetLoaders.begin(), pendingAssetLoaders.end(),
[&](auto &loader) {
return loader->name == filename;
}
);
if(existing != pendingAssetLoaders.end()) {
pendingAssetLoaders.erase(existing);
}
existing = std::find_if(
finishedAssetLoaders.begin(), finishedAssetLoaders.end(),
[&](auto &loader) {
return loader->name == filename;
}
);
if(existing != finishedAssetLoaders.end()) {
finishedAssetLoaders.erase(existing);
}
}
bool_t AssetManager::isEverythingLoaded() {
return pendingAssetLoaders.size() == 0;
}
bool_t AssetManager::isLoaded(const std::string filename) {
auto existing = this->getExisting<AssetLoader>(filename);
if(existing) return existing->loaded;
return false;
}
AssetManager::~AssetManager() {
}

View File

@ -1,106 +0,0 @@
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "dawnlibs.hpp"
#include "asset/AssetLoader.hpp"
namespace Dawn {
class AssetManager final {
private:
std::vector<std::shared_ptr<AssetLoader>> pendingAssetLoaders;
std::vector<std::shared_ptr<AssetLoader>> finishedAssetLoaders;
/**
* Returns an existing asset loader if it exists.
*
* @param filename The filename of the asset to get.
* @return The asset loader if it exists, otherwise nullptr.
*/
template<class T>
std::shared_ptr<T> getExisting(const std::string filename) {
auto existing = std::find_if(
pendingAssetLoaders.begin(), pendingAssetLoaders.end(),
[&](auto &loader) {
return loader->name == filename;
}
);
if(existing == finishedAssetLoaders.end()) {
existing = std::find_if(
finishedAssetLoaders.begin(), finishedAssetLoaders.end(),
[&](auto &loader) {
return loader->name == filename;
}
);
if(existing == finishedAssetLoaders.end()) return nullptr;
}
return std::static_pointer_cast<T>(*existing);
}
/**
* Removes an existing asset loader if it exists.
*
* @param filename The filename of the asset to remove.
*/
void removeExisting(const std::string filename);
public:
/**
* Initializes this asset manager so it can begin accepting assets.
*/
void init();
/**
* Updates the asset manager.
*/
void update();
/**
* Returns whether the asset manager has loaded all of the currently
* managed assets.
*
* @return True if all assets have been loaded.
*/
bool_t isEverythingLoaded();
/**
* Returns whether the asset manager has loaded the given asset.
*
* @param filename The filename of the asset to check.
* @return True if the asset has been loaded.
*/
bool_t isLoaded(const std::string filename);
/**
* Returns the asset loader for the given asset.
*
* @param filename The filename of the asset to get.
* @return The asset loader for the given asset.
*/
template<class T>
std::shared_ptr<T> get(const std::string filename);
/**
* Returns the asset loader for the given asset.
*
* @param filename The filename of the asset to get.
* @param fontSize The font size to get the truetype asset of.
* @return The asset loader for the given asset.
*/
template<class T>
std::shared_ptr<T> get(
const std::string filename,
const uint32_t fontSize
);
/**
* Dispose the asset manager, and all attached assets.
*/
~AssetManager();
};
}

View File

@ -1,15 +1,14 @@
# Copyright (c) 2022 Dominic Msters # Copyright (c) 2024 Dominic Masters
# #
# This software is released under the MIT License. # This software is released under the MIT License.
# https://opensource.org/licenses/MIT # https:#opensource.org/licenses/MIT
# Sources # Sources
target_sources(${DAWN_TARGET_NAME} target_sources(${DAWN_TARGET_NAME}
PRIVATE PRIVATE
AssetLoader.cpp asset.c
AssetDataLoader.cpp assetarchive.c
AssetManager.cpp assetjson.c
assetmap.c
assetlanguage.c
) )
# Subdirs
add_subdirectory(loaders)

159
src/dawn/asset/asset.c Normal file
View File

@ -0,0 +1,159 @@
/**
* Copyright (c) 2024 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "asset.h"
#include "assetarchive.h"
#include "assert/assert.h"
#include "util/math.h"
void assetInit() {
// TODO: Works on Windows? path sep probs wrong.
// const char_t *assetFilename = "dawn.tar";
// char_t *assetPath = malloc(sizeof(char_t) * (
// strlen(SYSTEM.executableDirectory) + strlen(assetFilename) + 1
// ));
// sprintf(assetPath, "%s/%s", SYSTEM.executableDirectory, assetFilename);
char_t *assetPath = "/home/yourwishes/htdocs/Dawn/build/dawn.tar";
ASSET_FILE = fopen(assetPath, "rb");
// free(assetPath);
assertNotNull(ASSET_FILE, "assetInit: Failed to open asset file!");
ASSET_ARCHIVE = NULL;
ASSET_ENTRY = NULL;
}
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;
} else {
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 assetOpen(const char_t *path) {
assertNull(ASSET_ARCHIVE, "assetOpenFile: Archive is not NULL!");
assertNull(ASSET_ENTRY, "assetOpenFile: Entry is not NULL!");
assertStringValid(path, 1024, "assetOpenFile: Path is not valid!");
// Store path
strcpy(ASSET_PATH_CURRENT, path);
// Prepare data
ASSET_ARCHIVE = archive_read_new();
assertNotNull(ASSET_ARCHIVE, "assetOpenFile: Failed to create archive!");
// Set up the reader
// archive_read_support_filter_bzip2(ASSET_ARCHIVE);
archive_read_support_format_tar(ASSET_ARCHIVE);
// Open reader
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, &assetArchiveOpen);
archive_read_set_callback_data(ASSET_ARCHIVE, ASSET_ARCHIVE_BUFFER);
int32_t ret = archive_read_open1(ASSET_ARCHIVE);
assertTrue(ret == ARCHIVE_OK, "assetOpenFile: Failed to open archive!");
// Iterate over each file.
while(archive_read_next_header(ASSET_ARCHIVE, &ASSET_ENTRY) == ARCHIVE_OK) {
const char_t *headerFile = (char_t*)archive_entry_pathname(ASSET_ENTRY);
if(strcmp(headerFile, ASSET_PATH_CURRENT) == 0) return;
int32_t ret = archive_read_data_skip(ASSET_ARCHIVE);
assertTrue(ret == ARCHIVE_OK, "assetOpenFile: Failed to skip data!");
}
assertUnreachable("assetOpenFile: Failed to find file!");
}
size_t assetGetSize() {
assertNotNull(ASSET_ARCHIVE, "assetGetSize: Archive is NULL!");
assertNotNull(ASSET_ENTRY, "assetGetSize: Entry is NULL!");
assertTrue(
archive_entry_size_is_set(ASSET_ENTRY),
"assetGetSize: Entry size is not set!"
);
size_t n = archive_entry_size(ASSET_ENTRY);
// Remnant when get size was doing some incorrect stuff.
// char_t path[2048];
// sprintf(
// path, "/home/yourwishes/htdocs/dusk/build/assets/%s", ASSET_PATH_CURRENT
// );
// FILE *temp = fopen(path, "rb");
// assertNotNull(temp, "assetGetSize: Failed to open temp file!");
// fseek(temp, 0, SEEK_END);
// size_t size = ftell(temp);
// assertTrue(size == n, "assetGetSize: Size is not equal!");
// fclose(temp);
return n;
}
size_t assetRead(uint8_t *buffer, size_t bufferSize) {
assertNotNull(ASSET_ARCHIVE, "assetRead: Archive is NULL!");
assertNotNull(ASSET_ENTRY, "assetRead: Entry is NULL!");
assertNotNull(buffer, "assetRead: Buffer is NULL!");
assertTrue(bufferSize > 0, "assetRead: 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));
}
assertTrue(read != ARCHIVE_RETRY, "assetRead: Failed to read data (RETRY)!");
assertTrue(read != ARCHIVE_WARN, "assetRead: Failed to read data (WARN)!");
return read;
}
void assetSkip(const size_t length) {
assertNotNull(ASSET_ARCHIVE, "assetSkip: Archive is NULL!");
assertNotNull(ASSET_ENTRY, "assetSkip: Entry is NULL!");
assertTrue(length > 0, "assetSkip: Length must be greater than 0!");
// Asset archive does not support skipping, so we have to read and discard.
uint8_t buffer[1024];
size_t remaining = length;
do {
size_t toRead = mathMin(remaining, 1024);
size_t read = assetRead(buffer, toRead);
assertTrue(read == toRead, "assetSkip: Failed to skip data! (overskip?)");
remaining -= read;
} while(remaining > 0);
}
void assetClose() {
assertNotNull(ASSET_ARCHIVE, "assetClose: Archive is NULL!");
assertNotNull(ASSET_ENTRY, "assetClose: Entry is NULL!");
int32_t ret = archive_read_free(ASSET_ARCHIVE);
assertTrue(ret == ARCHIVE_OK, "assetClose: Failed to close archive!");
ASSET_ARCHIVE = NULL;
ASSET_ENTRY = NULL;
}
void assetDispose() {
assertNull(ASSET_ARCHIVE, "assetDestroy: Archive is not NULL!");
assertNull(ASSET_ENTRY, "assetDestroy: Entry is not NULL!");
int32_t result = fclose(ASSET_FILE);
assertTrue(result == 0, "assetDestroy: Failed to close asset file!");
}

73
src/dawn/asset/asset.h Normal file
View File

@ -0,0 +1,73 @@
/**
* Copyright (c) 2023 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "dawn.h"
/**
* 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_t *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, 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_t 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();

View File

@ -0,0 +1,55 @@
/**
* Copyright (c) 2023 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "asset/assetarchive.h"
#include "assert/assert.h"
#include "util/math.h"
FILE *ASSET_FILE;
struct archive *ASSET_ARCHIVE;
struct archive_entry *ASSET_ENTRY;
uint8_t ASSET_ARCHIVE_BUFFER[ASSET_BUFFER_SIZE];
char_t ASSET_PATH_CURRENT[ASSET_PATH_MAX];
ssize_t assetArchiveRead(
struct archive *archive,
void *data,
const void **buffer
) {
assertNotNull(archive, "assetArchiveRead: Archive is NULL!");
assertNotNull(data, "assetArchiveRead: Data is NULL!");
assertNotNull(buffer, "assetArchiveRead: 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, "assetArchiveSeek: Archive is NULL!");
assertNotNull(data, "assetArchiveSeek: Data is NULL!");
assertTrue(offset > 0, "assetArchiveSeek: Offset must be greater than 0!");
int32_t ret = fseek(ASSET_FILE, offset, whence);
assertTrue(ret == 0, "assetArchiveSeek: 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, "assetArchiveOpen: Failed to seek to start of file!");
return ARCHIVE_OK;
}
int32_t assetArchiveClose(struct archive *a, void *data) {
return assetArchiveOpen(a, data);
}

View File

@ -0,0 +1,68 @@
/**
* Copyright (c) 2023 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "asset/asset.h"
#include <archive.h>
#include <archive_entry.h>
#define ASSET_BUFFER_SIZE 32768
#define ASSET_PATH_MAX 1024
extern FILE *ASSET_FILE;
extern struct archive *ASSET_ARCHIVE;
extern struct archive_entry *ASSET_ENTRY;
extern uint8_t ASSET_ARCHIVE_BUFFER[ASSET_BUFFER_SIZE];
extern char_t ASSET_PATH_CURRENT[ASSET_PATH_MAX];
/**
* 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);

560
src/dawn/asset/assetjson.c Normal file
View File

@ -0,0 +1,560 @@
/**
* Copyright (c) 2024 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "assetjson.h"
#include "assert/assert.h"
#include "util/memory.h"
size_t assetJsonParse(const char_t *json, assetjson_t **out) {
size_t offset = assetJsonParseSub(json, out);
// We only expect whitespace or EOF here
char_t c;
size_t len = strlen(json);
while(offset <= len) {
c = json[offset];
if(c == '\0') break;
if(c == ' ' || c == '\t' || c == '\n' || c == '\r') {
offset++;
continue;
}
assertUnreachable("Unexpected character found after JSON data.");
}
assertTrue(c == '\0', "Unexpected character found after JSON data.");
assertTrue(offset == len, "Unexpected character found after JSON data.");
return offset;
}
size_t assetJsonParseSub(
const char_t *json,
assetjson_t **out
) {
size_t offset = 0;
char_t c;
// Skip whitespace
while((c = json[offset]) == ' ' || c == '\t' || c == '\n' || c == '\r') {
if(c == '\0') assertUnreachable("Unexpected end of JSON data.");
offset++;
}
// Read first character
c = json[offset];
switch(c) {
case '{':
offset += assetJsonParseAsObject(json + offset, out);
break;
case '[':
offset += assetJsonParseAsArray(json + offset, out);
break;
case '"':
offset += assetJsonParseAsString(json + offset, out);
break;
case '-':
case '0' ... '9':
case '.':
offset += assetJsonParseAsNumber(json + offset, out);
break;
case 't':
case 'f':
offset += assetJsonParseAsBoolean(json + offset, out);
break;
case 'n':
offset += assetJsonParseAsNull(json + offset, out);
break;
default:
assertUnreachable("Invalid JSON data type found.");
break;
}
return offset;
}
size_t assetJsonParseAsNull(
const char_t *json,
assetjson_t **out
) {
assetjson_t *obj = (assetjson_t*)memoryAllocate(sizeof(assetjson_t));
// Read "null"
assertTrue(json[0] == 'n', "Expected NULL data type. (n0)");
assertTrue(json[1] == 'u', "Expected NULL data type. (u0)");
assertTrue(json[2] == 'l', "Expected NULL data type. (l0)");
assertTrue(json[3] == 'l', "Expected NULL data type. (l1)");
obj->type = ASSET_JSON_DATA_TYPE_NULL;
*out = obj;
return 4;
}
size_t assetJsonParseAsBoolean(
const char_t *json,
assetjson_t **out
) {
assetjson_t *obj = (assetjson_t*)memoryAllocate(sizeof(assetjson_t));
obj->type = ASSET_JSON_DATA_TYPE_BOOLEAN;
*out = obj;
if(json[0] == 't') {
// Read "true"
assertTrue(json[0] == 't', "Expected TRUE data type. (t0)");
assertTrue(json[1] == 'r', "Expected TRUE data type. (r0)");
assertTrue(json[2] == 'u', "Expected TRUE data type. (u0)");
assertTrue(json[3] == 'e', "Expected TRUE data type. (e0)");
obj->boolean = true;
return 4;
} else {
// Read "false"
assertTrue(json[0] == 'f', "Expected FALSE data type. (f0)");
assertTrue(json[1] == 'a', "Expected FALSE data type. (a0)");
assertTrue(json[2] == 'l', "Expected FALSE data type. (l0)");
assertTrue(json[3] == 's', "Expected FALSE data type. (s0)");
assertTrue(json[4] == 'e', "Expected FALSE data type. (e0)");
obj->boolean = false;
return 5;
}
}
size_t assetJsonParseAsString(
const char_t *json,
assetjson_t **out
) {
assetjson_t *obj = memoryAllocate(sizeof(assetjson_t));
obj->type = ASSET_JSON_DATA_TYPE_STRING;
// For each char
size_t offset = 1;// Skip opening quote
size_t outOffset = 0;
char c;
bool_t inEscape = false;
size_t bufferSize = 2;
char_t *string = (char_t*)memoryAllocate(bufferSize * sizeof(char_t));
while(true) {
c = json[offset];
if(c == '\0') assertUnreachable("Unexpected end of string.");
if(inEscape) {
inEscape = false;
switch(c) {
case 'n':
c = '\n';
break;
case 'r':
c = '\r';
break;
case 't':
c = '\t';
break;
case 'b':
c = '\b';
break;
case 'f':
c = '\f';
break;
case 'u':
assertUnreachable("Unicode escape sequences are not supported.");
break;
default:
break;
}
if(outOffset >= bufferSize) {
bufferSize *= 2;
string = memoryReallocate(string, bufferSize * sizeof(char_t));
}
string[outOffset] = c;
offset++;
outOffset++;
continue;
}
if(c == '\\') {
inEscape = true;
offset++;
continue;
}
if(c == '"') break;
if(outOffset >= bufferSize) {
bufferSize *= 2;
string = memoryReallocate(string, bufferSize * sizeof(char_t));
}
string[outOffset] = c;
offset++;
outOffset++;
}
string[outOffset] = '\0';
outOffset++;
*out = obj;
obj->string = string;
return offset + 1;// For closing string quote
}
size_t assetJsonParseAsObject(
const char_t *json,
assetjson_t **out
) {
assetjson_t *obj = memoryAllocate(sizeof(assetjson_t));
obj->type = ASSET_JSON_DATA_TYPE_OBJECT;
size_t bufferSize = 2;
char_t **keys = memoryAllocate(bufferSize * sizeof(char_t*));
assetjson_t **values = memoryAllocate(bufferSize * sizeof(assetjson_t*));
size_t length = 0;
// Skip whitespace
size_t offset = 1;// Skip opening bracket
char_t c;
while(true) {
while((c = json[offset]) == ' ' || c == '\t' || c == '\n' || c == '\r') {
if(c == '\0') assertUnreachable("Unexpected end of JSON data.");
offset++;
}
// Only expect opening string or closing brace
if(c == '}') break;
assertTrue(c == '"', "Expected opening string for JSON object key.");
char_t *bufferKey;
// Skip "
offset++;
offset += assetJsonReadString(json + offset, &bufferKey);
// Skip whitespace
while((c = json[offset]) == ' ' || c == '\t' || c == '\n' || c == '\r') {
if(c == '\0') assertUnreachable("Unexpected end of JSON data.");
offset++;
}
// Only expect colon
assertTrue(c == ':', "Expected colon after JSON object key.");
offset++;
// Skip whitespace
while((c = json[offset]) == ' ' || c == '\t' || c == '\n' || c == '\r') {
if(c == '\0') assertUnreachable("Unexpected end of JSON data.");
offset++;
}
// Parse sub
assetjson_t *value;
offset += assetJsonParseSub(json + offset, &value);
// Need to resize?
if(length >= bufferSize) {
bufferSize *= 2;
keys = memoryReallocate(keys, bufferSize * sizeof(char_t*));
values = memoryReallocate(values, bufferSize * sizeof(assetjson_t*));
}
keys[length] = bufferKey;
values[length] = value;
length++;
// Skip whitespace
while((c = json[offset]) == ' ' || c == '\t' || c == '\n' || c == '\r') {
if(c == '\0') assertUnreachable("Unexpected end of JSON data.");
offset++;
}
// Expect either comma or closing bracket
assertTrue(
c == ',' || c == '}',
"Expected comma or closing bracket after JSON object value."
);
if(c == '}') break;
offset++;
}
obj->object.keys = keys;
obj->object.values = values;
obj->object.length = length;
*out = obj;
return offset + 1;// Skip closing bracket
}
size_t assetJsonParseAsArray(
const char_t *json,
assetjson_t **out
) {
assetjson_t *obj = (assetjson_t*)memoryAllocate(sizeof(assetjson_t));
obj->type = ASSET_JSON_DATA_TYPE_ARRAY;
size_t offset = 1;// Skip opening bracket
char_t c;
// Create array
size_t arraySize = 2;
obj->array.value = (assetjson_t**)memoryAllocate(
arraySize * sizeof(assetjson_t*)
);
obj->array.length = 0;
// Until closing bracket
while(true) {
c = json[offset];
if(c == '\0') assertUnreachable("Unexpected end of JSON array.");
if(c == ']') break;
// Skip whitespace ONLY
if(c == ' ' || c == '\t' || c == '\n' || c == '\r') {
offset++;
continue;
}
// Need to expand?
if(obj->array.length >= arraySize) {
arraySize *= 2;
obj->array.value = memoryReallocate(
obj->array.value, arraySize * sizeof(assetjson_t*)
);
}
// Parse sub
offset += assetJsonParseSub(
json + offset,
&obj->array.value[obj->array.length++]
);
// Skip whitespace ONLY
while((c = json[offset]) == ' ' || c == '\t' || c == '\n' || c == '\r') {
if(c == '\0') assertUnreachable("Unexpected end of JSON data.");
offset++;
}
// If comma, continue
if(c == ',') {
offset++;
continue;
}
// If closing bracket, break
if(c == ']') break;
// Else, error
assertUnreachable("Unexpected character found in JSON array.");
}
// End of array
*out = obj;
return offset + 1;// Skip closing bracket
}
size_t assetJsonParseAsNumber(
const char_t *json,
assetjson_t **out
) {
assetjson_t *obj = (assetjson_t*)memoryAllocate(sizeof(assetjson_t));
obj->type = ASSET_JSON_DATA_TYPE_NUMBER;
// For each char
size_t offset = 0;
size_t outOffset = 0;
char_t c;
size_t bufferSize = 2;
char_t *buffer = (char_t*)memoryAllocate(bufferSize * sizeof(char_t));
bool_t hasDecimal = false;
bool_t hasNumber = false;
// Read number
while(true) {
c = json[offset];
if(c == '\0') assertUnreachable("Unexpected end of number.");
if(c == '-') {
// only accepted on first input
assertTrue(outOffset == 0, "Unexpected - after first digit");
} else if(c == '.') {
// only accepted once
assertTrue(!hasDecimal, "Unexpected . after first decimal");
hasDecimal = true;
if(!hasNumber) {
// If no number before decimal, add a 0
if(outOffset >= bufferSize) {
bufferSize *= 2;
buffer = memoryReallocate(buffer, bufferSize * sizeof(char_t));
}
buffer[outOffset] = '0';
outOffset++;
}
} else if(c >= '0' && c <= '9') {
hasNumber = true;
} else {
break;
}
// Need to expand?
if(outOffset >= bufferSize) {
bufferSize *= 2;
buffer = memoryReallocate(buffer, bufferSize * sizeof(char_t));
}
buffer[outOffset] = c;
offset++;
outOffset++;
}
// Seal the buffer, parse and cleanup
buffer[outOffset] = '\0';
obj->number = strtod(buffer, NULL);
memoryFree(buffer);
*out = obj;
return offset;
}
size_t assetJsonReadString(
const char_t *json,
char_t **buffer
) {
size_t offset = 0;
size_t outOffset = 0;
char_t c;
size_t bufferSize = 32;
char_t *string = (char_t*)memoryAllocate(sizeof(char_t) * bufferSize);
bool_t inEscape = false;
// For each char
while(true) {
c = json[offset];
if(c == '\0') assertUnreachable("Unexpected end of string.");
if(inEscape) {
inEscape = false;
switch(c) {
case 'n':
c = '\n';
break;
case 'r':
c = '\r';
break;
case 't':
c = '\t';
break;
case 'b':
c = '\b';
break;
case 'f':
c = '\f';
break;
case 'u':
assertUnreachable("Unicode escape sequences are not supported.");
break;
default:
break;
}
if(outOffset >= bufferSize) {
bufferSize *= 2;
string = memoryReallocate(string, bufferSize);
}
string[outOffset] = c;
offset++;
outOffset++;
continue;
}
if(c == '\\') {
inEscape = true;
offset++;
continue;
}
if(c == '"') break;
if(outOffset >= bufferSize) {
bufferSize *= 2;
string = memoryReallocate(string, bufferSize);
}
string[outOffset] = c;
offset++;
outOffset++;
}
string[outOffset] = '\0';
outOffset++;
*buffer = string;
return offset + 1;
}
assetjson_t * assetJsonGetObjectValue(assetjson_t *json, const char_t *key) {
assertTrue(json->type == ASSET_JSON_DATA_TYPE_OBJECT, "Expected JSON object.");
for(size_t i = 0; i < json->object.length; i++) {
if(strcmp(json->object.keys[i], key) == 0) {
return json->object.values[i];
}
}
return NULL;
}
void assetJsonDispose(assetjson_t *json) {
switch(json->type) {
case ASSET_JSON_DATA_TYPE_OBJECT:
for(size_t i = 0; i < json->object.length; i++) {
memoryFree(json->object.keys[i]);
assetJsonDispose(json->object.values[i]);
}
memoryFree(json->object.keys);
memoryFree(json->object.values);
break;
case ASSET_JSON_DATA_TYPE_ARRAY:
for(size_t i = 0; i < json->array.length; i++) {
assetJsonDispose(json->array.value[i]);
}
memoryFree(json->array.value);
break;
case ASSET_JSON_DATA_TYPE_STRING:
memoryFree(json->string);
break;
case ASSET_JSON_DATA_TYPE_NUMBER:
break;
case ASSET_JSON_DATA_TYPE_BOOLEAN:
break;
case ASSET_JSON_DATA_TYPE_NULL:
break;
}
memoryFree(json);
}

140
src/dawn/asset/assetjson.h Normal file
View File

@ -0,0 +1,140 @@
/**
* Copyright (c) 2024 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "dawn.h"
typedef enum {
ASSET_JSON_DATA_TYPE_OBJECT,
ASSET_JSON_DATA_TYPE_ARRAY,
ASSET_JSON_DATA_TYPE_STRING,
ASSET_JSON_DATA_TYPE_NUMBER,
ASSET_JSON_DATA_TYPE_BOOLEAN,
ASSET_JSON_DATA_TYPE_NULL
} assetjsondatatype_t;
typedef struct _assetjson_t assetjson_t;
typedef struct _assetjson_t {
assetjsondatatype_t type;
union {
struct {
char_t **keys;
assetjson_t **values;
size_t length;
} object;
struct {
assetjson_t **value;
size_t length;
} array;
double_t number;
char_t *string;
bool_t boolean;
};
} assetjson_t;
/**
* Parses a JSON string.
*
* @param json JSON string to parse.
* @param out Pointer to store the parsed JSON object.
* @return The number of characters parsed.
*/
size_t assetJsonParse(const char_t *json, assetjson_t **out);
/**
* Parses a JSON string as a sub-object.
*
* @param json JSON string to parse.
* @param out Pointer to store the parsed JSON object.
* @return The number of characters parsed.
*/
size_t assetJsonParseSub(const char_t *json, assetjson_t **out);
/**
* Parses a JSON string as a NULL value.
*
* @param json JSON string to parse.
* @param out Pointer to store the parsed JSON object.
* @return The number of characters parsed.
*/
size_t assetJsonParseAsNull(const char_t *json, assetjson_t **out);
/**
* Parses a JSON string as a boolean value.
*
* @param json JSON string to parse.
* @param out Pointer to store the parsed JSON object.
* @return The number of characters parsed.
*/
size_t assetJsonParseAsBoolean(const char_t *json, assetjson_t **out);
/**
* Parses a JSON string as an object.
*
* @param json JSON string to parse.
* @param out Pointer to store the parsed JSON object.
* @return The number of characters parsed.
*/
size_t assetJsonParseAsObject(const char_t *json, assetjson_t **out);
/**
* Parses a JSON string as an array.
*
* @param json JSON string to parse.
* @param out Pointer to store the parsed JSON object.
* @return The number of characters parsed.
*/
size_t assetJsonParseAsArray(const char_t *json, assetjson_t **out);
/**
* Parses a JSON string as a string.
*
* @param json JSON string to parse.
* @param out Pointer to store the parsed JSON object.
* @return The number of characters parsed.
*/
size_t assetJsonParseAsString(const char_t *json, assetjson_t **out);
/**
* Parses a JSON string as a number.
*
* @param json JSON string to parse.
* @param out Pointer to store the parsed JSON object.
* @return The number of characters parsed.
*/
size_t assetJsonParseAsNumber(const char_t *json, assetjson_t **out);
/**
* Parses a JSON string as a string.
*
* @param json JSON string to parse.
* @param out Pointer to store the parsed JSON object.
* @return The number of characters parsed.
*/
size_t assetJsonReadString(const char_t *json, char_t **out);
/**
* Parses a JSON string as a number.
*
* @param json JSON string to parse.
* @param out Pointer to store the parsed JSON object.
* @return The number of characters parsed.
*/
assetjson_t *assetJsonGetObjectValue(assetjson_t *object, const char_t *key);
/**
* Parses a JSON string as a number.
*
* @param json JSON string to parse.
* @param out Pointer to store the parsed JSON object.
* @return The number of characters parsed.
*/
void assetJsonDispose(assetjson_t *json);

View File

@ -0,0 +1,70 @@
/**
* Copyright (c) 2024 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "assetlanguage.h"
#include "asset/asset.h"
#include "assert/assert.h"
#include "locale/language.h"
#include "util/memory.h"
void assetLanguageObjectLoad(
const char_t *key,
assetjson_t *json
) {
char_t tKey[LANGUAGE_STRING_KEY_LENGTH_MAX];
size_t keyLength = strlen(key);
strcpy(tKey, key);
if(keyLength > 0) {
tKey[keyLength] = '.';
keyLength++;
}
for(int32_t i = 0; i < json->object.length; i++) {
const char_t *subKey = json->object.keys[i];
assetjson_t *value = json->object.values[i];
strcpy(tKey + keyLength, subKey);
if(json->object.values[i]->type == ASSET_JSON_DATA_TYPE_OBJECT) {
assetLanguageObjectLoad(tKey, value);
continue;
}
if(json->object.values[i]->type == ASSET_JSON_DATA_TYPE_STRING) {
strcpy(LANGUAGE.keys[LANGUAGE.count], tKey);
strcpy(LANGUAGE.strings[LANGUAGE.count], value->string);
LANGUAGE.count++;
continue;
}
assertUnreachable("Language value is not a string or object!");
}
}
void assetLanguageLoad(const char_t *path) {
assertNotNull(path, "Path cannot be NULL.");
assetOpen(path);
size_t length = assetGetSize();
char_t *buffer = memoryAllocate(sizeof(char_t) * (length + 1));
buffer[length] = '\0';
size_t read = assetRead((uint8_t*)buffer, length);
assertTrue(read == length, "Failed to read language file!");
assetClose();
assetjson_t *json;
read = assetJsonParse(buffer, &json);
memoryFree(buffer);
assertTrue(
json->type == ASSET_JSON_DATA_TYPE_OBJECT,
"Language file is not an object!"
);
languageInit();
assetLanguageObjectLoad("", json);
assetJsonDispose(json);
}

View File

@ -0,0 +1,27 @@
/**
* Copyright (c) 2024 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "asset/assetjson.h"
/**
* Loads a JSON object from the asset file.
*
* @param key The key to load.
* @param json The value to load into.
*/
void assetLanguageObjectLoad(
const char_t *key,
assetjson_t *json
);
/**
* Loads the language file from the specified path.
*
* @param path Path to the language file.
*/
void assetLanguageLoad(const char_t *path);

236
src/dawn/asset/assetmap.c Normal file
View File

@ -0,0 +1,236 @@
/**
* Copyright (c) 2024 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "assetmap.h"
#include "asset/asset.h"
#include "assert/assert.h"
#include "util/memory.h"
void assetMapLoadEntity(
assetjson_t *jEnt,
map_t *map
) {
int32_t x = (int32_t)assetJsonGetObjectValue(jEnt, "x")->number;
int32_t y = (int32_t)assetJsonGetObjectValue(jEnt, "y")->number;
entitytype_t type = (entitytype_t)assetJsonGetObjectValue(
jEnt, "type"
)->number;
entity_t *ent = mapEntityAdd(map);
entityInit(ent, type, map);
entityPositionSet(ent, x, y);
assetjson_t *val;
switch(type) {
case ENTITY_TYPE_NPC:
val = assetJsonGetObjectValue(jEnt, "name");
if(val != NULL) {
assertTrue(
val->type == ASSET_JSON_DATA_TYPE_STRING,
"assetMapLoad: NPC name is not a string!"
);
npcNameSet(&ent->npc, val->string);
}
val = assetJsonGetObjectValue(jEnt, "text");
if(val != NULL) {
assertTrue(
val->type == ASSET_JSON_DATA_TYPE_STRING,
"assetMapLoad: NPC text is not a string!"
);
npcTextSet(&ent->npc, val->string);
}
break;
case ENTITY_TYPE_SIGN:
val = assetJsonGetObjectValue(jEnt, "text");
if(val != NULL) {
assertTrue(
val->type == ASSET_JSON_DATA_TYPE_STRING,
"assetMapLoad: Sign text is not a string!"
);
signTextAppend(&ent->sign, val->string);
}
val = assetJsonGetObjectValue(jEnt, "texts");
if(val != NULL) {
assertTrue(
val->type == ASSET_JSON_DATA_TYPE_ARRAY,
"assetMapLoad: Sign texts is not an array!"
);
assertTrue(
val->array.length <= SIGN_TEXT_COUNT_MAX,
"assetMapLoad: Too many sign texts!"
);
for(int32_t i = 0; i < val->array.length; i++) {
assetjson_t *subVal = val->array.value[i];
assertTrue(
subVal->type == ASSET_JSON_DATA_TYPE_STRING,
"assetMapLoad: Sign text is not a string!"
);
signTextAppend(&ent->sign, subVal->string);
}
}
break;
case ENTITY_TYPE_DOOR:
val = assetJsonGetObjectValue(jEnt, "door");
if(val != NULL) {
assetjson_t *door = assetJsonGetObjectValue(val, "x");
x = (int32_t)door->number;
assertTrue(
door->type == ASSET_JSON_DATA_TYPE_NUMBER,
"assetMapLoad: Door x is not a number!"
);
door = assetJsonGetObjectValue(val, "y");
y = (int32_t)door->number;
assertTrue(
door->type == ASSET_JSON_DATA_TYPE_NUMBER,
"assetMapLoad: Door y is not a number!"
);
door = assetJsonGetObjectValue(val, "direction");
entitydirection_t direction = ENTITY_DIRECTION_SOUTH;
if(door != NULL) {
direction = (entitydirection_t)(
assetJsonGetObjectValue(val, "direction")->number
);
}
door = assetJsonGetObjectValue(val, "map");
maplist_t list;
if(door == NULL) {
list = map->list;
} else if(door->type == ASSET_JSON_DATA_TYPE_STRING) {
list = mapListGet(door->string);
} else if(door->type == ASSET_JSON_DATA_TYPE_NUMBER) {
list = (maplist_t)door->number;
} else {
assertUnreachable("assetMapLoad: Door map not string or number!");
}
doorDestinationSet(&ent->door, x, y, direction, list);
}
break;
default:
break;
}
}
void assetMapLoad(
const char_t *path,
map_t *map
) {
assertNotNull(map, "assetMapLoad: Map is NULL!");
// Read in the string data.
assetOpen(path);
size_t length = assetGetSize();
char_t *buffer = memoryAllocate(sizeof(char_t) * (length + 1));
size_t read = assetRead((uint8_t*)buffer, length);
buffer[length] = '\0';
assertTrue(read == length, "assetMapLoad: Failed to read map data!");
assetClose();
// Begin parsing JSON data.
assetjson_t *json;
read = assetJsonParse(buffer, &json);
memoryFree(buffer);
assertTrue(
json->type == ASSET_JSON_DATA_TYPE_OBJECT,
"assetMapLoad: Map data is not an object!"
);
int32_t width = (int32_t)assetJsonGetObjectValue(json, "width")->number;
int32_t height = (int32_t)assetJsonGetObjectValue(json, "height")->number;
assetjson_t *layers = assetJsonGetObjectValue(json, "layers");
assertTrue(
layers->type == ASSET_JSON_DATA_TYPE_ARRAY,
"assetMapLoad: Layers is not an array!"
);
int32_t layerCount = layers->array.length;
assertTrue(layerCount == MAP_LAYERS_MAX, "assetMapLoad: No layers found!");
mapInit(map, mapListGet(path), width, height, layerCount);
// Load tile data.
for(int32_t i = 0; i < layerCount; i++) {
assetjson_t *layer = layers->array.value[i];
assertTrue(
layer->type == ASSET_JSON_DATA_TYPE_OBJECT,
"assetMapLoad: Layer is not an object!"
);
assetjson_t *tiles = assetJsonGetObjectValue(layer, "tiles");
assertTrue(
tiles->type == ASSET_JSON_DATA_TYPE_ARRAY,
"assetMapLoad: Tiles is not an array!"
);
assertTrue(
tiles->array.length == width * height,
"assetMapLoad: Tile count does not match map size!"
);
for(int32_t j = 0; j < width * height; j++) {
map->tiles[j] = (tile_t)tiles->array.value[j]->number;
}
}
// Load entity data
assetjson_t *entities = assetJsonGetObjectValue(json, "entities");
if(entities != NULL) {
assertTrue(
entities->type == ASSET_JSON_DATA_TYPE_ARRAY,
"assetMapLoad: Entities is not an array!"
);
for(int32_t i = 0; i < entities->array.length; i++) {
assetjson_t *jEnt = entities->array.value[i];
assertTrue(
jEnt->type == ASSET_JSON_DATA_TYPE_OBJECT,
"assetMapLoad: Entity is not an object!"
);
assetMapLoadEntity(jEnt, map);
}
}
// Load trigger data
assetjson_t *triggers = assetJsonGetObjectValue(json, "triggers");
if(triggers != NULL) {
assertTrue(
triggers->type == ASSET_JSON_DATA_TYPE_ARRAY,
"assetMapLoad: Triggers is not an array!"
);
for(int32_t i = 0; i < triggers->array.length; i++) {
assetjson_t *jTrig = triggers->array.value[i];
assertTrue(
jTrig->type == ASSET_JSON_DATA_TYPE_OBJECT,
"assetMapLoad: Trigger is not an object!"
);
int32_t x = (int32_t)assetJsonGetObjectValue(jTrig, "x")->number;
int32_t y = (int32_t)assetJsonGetObjectValue(jTrig, "y")->number;
int32_t width = (int32_t)assetJsonGetObjectValue(jTrig, "width")->number;
int32_t height = (int32_t)assetJsonGetObjectValue(
jTrig, "height"
)->number;
triggertype_t type = (triggertype_t)assetJsonGetObjectValue(
jTrig, "type"
)->number;
trigger_t *trigger = mapTriggerAdd(map);
triggerInit(trigger, type, x, y, width, height);
}
}
assetJsonDispose(json);
}

32
src/dawn/asset/assetmap.h Normal file
View 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 "rpg/world/map.h"
#include "asset/assetjson.h"
/**
* Loads an entity from the specified JSON object.
*
* @param jEnt JSON object to load the entity from.
* @param map Map to load the entity into.
*/
void assetMapLoadEntity(
assetjson_t *jEnt,
map_t *map
);
/**
* Loads a map from the specified path.
*
* @param path Path to the map file.
* @param map Map to load the data into.
*/
void assetMapLoad(
const char_t *path,
map_t *map
);

View File

@ -1,10 +0,0 @@
# Copyright (c) 2022 Dominic Msters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DAWN_TARGET_NAME}
PRIVATE
TextureLoader.cpp
)

View File

@ -1,147 +0,0 @@
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "TextureLoader.hpp"
#include "assert/assert.hpp"
using namespace Dawn;
TextureLoader::TextureLoader(const std::string name) :
AssetLoader(name),
loader(name + ".texture"),
state(TextureLoaderLoadState::INITIAL)
{
sharedTexture = std::make_shared<Texture>();
weakTexture = sharedTexture;
}
void TextureLoader::updateAsync() {
if(this->state != TextureLoaderLoadState::INITIAL) return;
this->state = TextureLoaderLoadState::ASYNC_LOADING;
this->loader.open();
// Read in the header.
uint8_t buffer[TEXTURE_LOADER_HEADER_SIZE];
size_t pos = 0;
// Read Version
pos += this->loader.readUntil(buffer, TEXTURE_LOADER_HEADER_SIZE, '|');
std::string version = std::string((char*)buffer);
assertTrue(version == "DT_2.00", "Invalid Texture Version!");
// Read Texture Width
this->loader.setPosition(pos);
pos += this->loader.readUntil(buffer, TEXTURE_LOADER_HEADER_SIZE, '|');
width = std::stoi(std::string((char*)buffer));
assertTrue(width > 0, "Invalid Texture Width!");
// Read Texture Height
this->loader.setPosition(pos);
pos += this->loader.readUntil(buffer, TEXTURE_LOADER_HEADER_SIZE, '|');
height = std::stoi(std::string((char*)buffer));
assertTrue(height > 0, "Invalid Texture Height!");
// Texture Format (RGBA, RGB, etc)
this->loader.setPosition(pos);
pos += this->loader.readUntil(buffer, TEXTURE_LOADER_HEADER_SIZE, '|');
int32_t iFormat = std::stoi(std::string((char*)buffer));
switch(iFormat) {
case 1: format = TextureFormat::R; break;
case 2: format = TextureFormat::RG; break;
case 3: format = TextureFormat::RGB; break;
case 4: format = TextureFormat::RGBA; break;
default: assertUnreachable("Invalid Texture Format %i!", iFormat);
}
// Wrap X
this->loader.setPosition(pos);
pos += this->loader.readUntil(buffer, TEXTURE_LOADER_HEADER_SIZE, '|');
int32_t iWrapX = std::stoi(std::string((char*)buffer));
switch(iWrapX) {
case 0: wrapX = TextureWrapMode::REPEAT; break;
case 1: wrapX = TextureWrapMode::MIRRORED_REPEAT; break;
case 2: wrapX = TextureWrapMode::CLAMP_TO_EDGE; break;
case 3: wrapX = TextureWrapMode::CLAMP_TO_BORDER; break;
default: assertUnreachable("Invalid Texture Wrap X %i!", iWrapX);
}
// Wrap Y
this->loader.setPosition(pos);
pos += this->loader.readUntil(buffer, TEXTURE_LOADER_HEADER_SIZE, '|');
int32_t iWrapY = std::stoi(std::string((char*)buffer));
switch(iWrapY) {
case 0: wrapY = TextureWrapMode::REPEAT; break;
case 1: wrapY = TextureWrapMode::MIRRORED_REPEAT; break;
case 2: wrapY = TextureWrapMode::CLAMP_TO_EDGE; break;
case 3: wrapY = TextureWrapMode::CLAMP_TO_BORDER; break;
default: assertUnreachable("Invalid Texture Wrap Y %i!", iWrapY);
}
// Filter Min
this->loader.setPosition(pos);
pos += this->loader.readUntil(buffer, TEXTURE_LOADER_HEADER_SIZE, '|');
int32_t iFilterMin = std::stoi(std::string((char*)buffer));
switch(iFilterMin) {
case 0: filterMin = TextureFilterMode::NEAREST; break;
case 1: filterMin = TextureFilterMode::LINEAR; break;
default: assertUnreachable("Invalid Texture Filter Min %i!", iFilterMin);
}
// Filter Mag
this->loader.setPosition(pos);
pos += this->loader.readUntil(buffer, TEXTURE_LOADER_HEADER_SIZE, '|');
int32_t iFilterMag = std::stoi(std::string((char*)buffer));
switch(iFilterMag) {
case 0: filterMag = TextureFilterMode::NEAREST; break;
case 1: filterMag = TextureFilterMode::LINEAR; break;
default: assertUnreachable("Invalid Texture Filter Mag %i!", iFilterMag);
}
// Data begins here. This part is done synchronously directly to the GPU.
this->loader.setPosition(pos);
size_t bufferSize = width * height * iFormat;
data = new uint8_t[bufferSize];
assertNotNull(data, "Failed to allocate texture data!");
this->loader.read(data, bufferSize);
// Handoff to sync to buffer to GPU.
this->state = TextureLoaderLoadState::ASYNC_DONE;
}
void TextureLoader::updateSync() {
if(this->state != TextureLoaderLoadState::ASYNC_DONE) return;
this->state = TextureLoaderLoadState::SYNC_LOADING;
assertNotNull(this->sharedTexture, "Texture is null!");
assertNotNull(this->data, "Texture data is null!");
// Setup Texture
this->sharedTexture->setSize(
this->width,
this->height,
this->format,
TextureDataFormat::UNSIGNED_BYTE
);
this->sharedTexture->buffer(this->data);
// Free data buffer
delete[] this->data;
this->data = nullptr;
// Leat go of the held pointer
this->sharedTexture = nullptr;
// Hand off and call done
this->state = TextureLoaderLoadState::SYNC_DONE;
this->loaded = true;
}
TextureLoader::~TextureLoader() {
if(this->data != nullptr) {
delete[] this->data;
this->data = nullptr;
}
this->sharedTexture = nullptr;
}

View File

@ -1,55 +0,0 @@
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "asset/AssetLoader.hpp"
#include "asset/AssetDataLoader.hpp"
#include "display/Texture.hpp"
#define TEXTURE_LOADER_HEADER_SIZE 256
namespace Dawn {
enum class TextureLoaderLoadState {
INITIAL,
ASYNC_LOADING,
ASYNC_DONE,
SYNC_LOADING,
SYNC_DONE
};
class TextureLoader : public AssetLoader {
protected:
AssetDataLoader loader;
enum TextureLoaderLoadState state;
uint8_t *data = nullptr;
int32_t width = -1, height = -1;
enum TextureFormat format;
enum TextureWrapMode wrapX;
enum TextureWrapMode wrapY;
enum TextureFilterMode filterMin;
enum TextureFilterMode filterMag;
public:
std::shared_ptr<Texture> sharedTexture;
std::weak_ptr<Texture> weakTexture;
/**
* Constructs a texture asset loader. You should instead use the parent
* asset managers' abstracted load method
*
* @param name File name asset to load, omitting the extension.
*/
TextureLoader(const std::string name);
void updateSync() override;
void updateAsync() override;
/**
* Dispose / Cleanup the texture asset. Will also dispose the underlying
* texture itself.
*/
~TextureLoader();
};
}

View File

@ -1,14 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "IAudioManager.hpp"
using namespace Dawn;
IAudioManager::IAudioManager() {
}
IAudioManager::~IAudioManager() {
}

View File

@ -1,32 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "dawnlibs.hpp"
namespace Dawn {
class IAudioManager {
public:
/**
* Construct a new IAudioManager.
*/
IAudioManager();
/**
* Initializes the audio manager system.
*/
virtual void init() = 0;
/**
* Ticks/Update the audio manager system.
*/
virtual void update() = 0;
/**
* Deinitializes the audio manager system.
*/
virtual ~IAudioManager();
};
}

View File

@ -1,27 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "SimpleComponent.hpp"
using namespace Dawn;
void SimpleComponent::onInit() {
this->initMethod(*this, events);
}
void SimpleComponent::onDispose() {
for(auto &event : events) {
event();
}
}
std::shared_ptr<SimpleComponent> Dawn::addSimpleComponent(
std::shared_ptr<SceneItem> item,
std::function<void(SceneComponent&, std::vector<std::function<void()>>&)> init
) {
auto cmp = item->addComponent<SimpleComponent>();
cmp->initMethod = init;
return cmp;
}

View File

@ -1,31 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "scene/Scene.hpp"
namespace Dawn {
class SimpleComponent final : public SceneComponent {
private:
std::vector<std::function<void()>> events;
public:
std::function<void(
SceneComponent&,
std::vector<std::function<void()>>&
)> initMethod;
void onInit() override;
void onDispose() override;
};
std::shared_ptr<SimpleComponent> addSimpleComponent(
std::shared_ptr<SceneItem> item,
std::function<void(
SceneComponent&,
std::vector<std::function<void()>>&
)> init
);
}

View File

@ -1,67 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "assert/assert.hpp"
#include "Camera.hpp"
#include "game/Game.hpp"
using namespace Dawn;
void Camera::onInit() {
this->onResizeListener = this->getRenderTarget()->onResize.listen([&](
float_t width, float_t height
) {
this->onResize.emit(this->getRenderTarget(), width, height);
});
}
void Camera::onDispose() {
renderTarget = nullptr;
}
std::shared_ptr<RenderTarget> Camera::getRenderTarget() {
if(this->renderTarget) return this->renderTarget;
return getGame()->renderHost.getBackBufferRenderTarget();
}
glm::mat4 Camera::getProjection() {
switch(this->type) {
case CameraType::ORTHOGONAL:
return glm::ortho(
(float_t)this->orthoLeft,
(float_t)this->orthoRight,
(float_t)this->orthoBottom,
(float_t)this->orthoTop,
(float_t)this->clipNear,
(float_t)this->clipFar
);
case CameraType::PERSPECTIVE:
return glm::perspective(
(float_t)this->fov,
this->getAspect(),
(float_t)this->clipNear,
(float_t)this->clipFar
);
}
assertUnreachable("Invalid Camera Type!");
return glm::mat4(1.0f);
}
float_t Camera::getAspect() {
auto rt = this->getRenderTarget();
return rt->getWidth() / rt->getHeight();
}
void Camera::setRenderTarget(std::shared_ptr<RenderTarget> renderTarget) {
onResizeListener();
this->renderTarget = renderTarget;
this->onResizeListener = this->getRenderTarget()->onResize.listen([&](
float_t width, float_t height
) {
this->onResize.emit(this->getRenderTarget(), width, height);
});
}

View File

@ -1,67 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "scene/SceneItem.hpp"
#include "display/RenderTarget.hpp"
namespace Dawn {
enum CameraType {
PERSPECTIVE,
ORTHOGONAL
};
class Camera final : public SceneComponent {
private:
std::shared_ptr<RenderTarget> renderTarget;
std::function<void()> onResizeListener;
public:
Event<std::shared_ptr<RenderTarget>, float_t, float_t> onResize;
float_t clipNear = 0.01f;
float_t clipFar = 1000.0f;
enum CameraType type = CameraType::PERSPECTIVE;
float_t fov = 0.785398f;
float_t orthoLeft = -1.0f;
float_t orthoRight = 1.0f;
float_t orthoBottom = -1.0f;
float_t orthoTop = 1.0f;
void onInit() override;
void onDispose() override;
/**
* Returns the aspect ratio that the camera is using. In future I may
* allow you to specify a custom ratio for stylistic reasons but for now I
* just take the ratio of the specific frame buffer.
*
* @return The aspect ratio as a ratio of w/h.
*/
float_t getAspect();
/**
* Returns the render target for this camera.
*
* @return Render target.
*/
std::shared_ptr<RenderTarget> getRenderTarget();
/**
* Returns the projection matrix for this camera.
*
* @return Projection matrix.
*/
glm::mat4 getProjection();
/**
* Sets the render target for this camera.
*
* @param renderTarget The render target to set.
*/
void setRenderTarget(std::shared_ptr<RenderTarget> renderTarget);
};
}

View File

@ -1,56 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "display/pass/RenderPass.hpp"
#include "display/pass/RenderPassContext.hpp"
#include "display/mesh/Mesh.hpp"
namespace Dawn {
class IRenderableComponent {
public:
/**
* Retreive the list of render passes for this component.
*
* @param ctx Context for the render pass.
* @return List of render passes.
*/
virtual std::vector<std::shared_ptr<IRenderPass>> getPasses(
struct RenderPassContext &ctx
) = 0;
};
/**
* Short-hand function to create a render pass.
*
* @tparam S Shader type.
* @tparam D Shader's data type
* @param self Instance of the IRenderableComponent that is creating the pass.
* @param data Data to use for the render pass.
* @return Created render pass.
*/
template<class S, typename D>
std::shared_ptr<IRenderPass> createRenderPass(
SceneComponent &self,
const D data,
const std::unordered_map<
shadertexturebinding_t, std::shared_ptr<Texture>
> textures = {},
const std::shared_ptr<Mesh> mesh = nullptr,
const enum MeshDrawMode drawMode = MeshDrawMode::TRIANGLES,
int32_t indiceStart = 0,
int32_t indiceCount = -1
) {
return std::make_shared<RenderPass<S,D>>(
self,
data,
textures,
mesh,
drawMode,
indiceStart,
indiceCount
);
}
}

View File

@ -1,16 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "MeshRenderer.hpp"
using namespace Dawn;
void MeshRenderer::onInit() {
}
void MeshRenderer::onDispose() {
mesh = nullptr;
}

View File

@ -1,18 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "display/mesh/Mesh.hpp"
#include "scene/SceneItem.hpp"
namespace Dawn {
class MeshRenderer final : public SceneComponent {
public:
std::shared_ptr<Mesh> mesh;
void onInit() override;
void onDispose() override;
};
}

View File

@ -1,10 +0,0 @@
# Copyright (c) 2023 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
target_sources(${DAWN_TARGET_NAME}
PRIVATE
Material.cpp
SimpleTexturedMaterial.cpp
)

View File

@ -1,16 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "Material.hpp"
using namespace Dawn;
void Material::onInit() {
}
void Material::onDispose() {
}

View File

@ -1,21 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "scene/SceneComponent.hpp"
#include "component/display/IRenderableComponent.hpp"
namespace Dawn {
class Material :
public SceneComponent,
public IRenderableComponent
{
protected:
public:
void onInit() override;
void onDispose() override;
};
}

View File

@ -1,51 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "SimpleTexturedMaterial.hpp"
using namespace Dawn;
struct Color SimpleTexturedMaterial::getColor() {
return this->data.color;
}
std::shared_ptr<Texture> SimpleTexturedMaterial::getTexture() {
return this->texture;
}
void SimpleTexturedMaterial::setTexture(std::shared_ptr<Texture> texture) {
this->texture = texture;
}
void SimpleTexturedMaterial::setColor(const struct Color color) {
this->data.color = color;
}
std::vector<std::shared_ptr<IRenderPass>> SimpleTexturedMaterial::getPasses(
struct RenderPassContext &ctx
) {
this->data.model = this->getItem()->getWorldTransform();
this->data.projection = ctx.camera->getProjection();
this->data.view = ctx.camera->getItem()->getWorldTransform();
auto textures = std::unordered_map<
shadertexturebinding_t, std::shared_ptr<Texture>
>();
if(this->texture) {
this->data.hasTexture = true;
this->data.texture = 0;
textures[this->data.texture] = this->texture;
} else {
this->data.hasTexture = false;
}
return {
createRenderPass<SimpleTexturedShader, struct SimpleTexturedShaderData>(
*this,
data,
textures
)
};
}

View File

@ -1,48 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "component/display/material/Material.hpp"
#include "display/shader/SimpleTexturedShader.hpp"
#include "display/Texture.hpp"
namespace Dawn {
class SimpleTexturedMaterial : public Material {
private:
struct SimpleTexturedShaderData data;
std::shared_ptr<Texture> texture;
public:
/**
* Returns the color of this material.
*/
struct Color getColor();
/**
* Returns the texture of this material.
*
* @return The texture of this material.
*/
std::shared_ptr<Texture> getTexture();
/**
* Sets the texture of this material.
*
* @param texture The texture to set.
*/
void setTexture(std::shared_ptr<Texture> texture);
/**
* Sets the color of this material.
*
* @param color The color to set.
*/
void setColor(const struct Color color);
std::vector<std::shared_ptr<IRenderPass>> getPasses(
struct RenderPassContext &ctx
) override;
};
}

View File

@ -1,9 +0,0 @@
# Copyright (c) 2023 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
target_sources(${DAWN_TARGET_NAME}
PRIVATE
UICanvas.cpp
)

View File

@ -1,144 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "UICanvas.hpp"
#include "display/pass/RenderPass.hpp"
#include "display/mesh/QuadMesh.hpp"
#include "ui/UIElement.hpp"
using namespace Dawn;
void UICanvas::onInit() {
mesh = std::make_shared<Mesh>();
mesh->createBuffers(
QUAD_VERTICE_COUNT * UI_SHADER_QUAD_COUNT,
QUAD_INDICE_COUNT * UI_SHADER_QUAD_COUNT
);
for(int32_t i = 0; i < UI_SHADER_QUAD_COUNT; i++) {
QuadMesh::bufferWithIndex(
mesh,
glm::vec4(0, 0, 1, 1),
glm::vec4(0, 0, 1, 1),
i * QUAD_VERTICE_COUNT,
i * QUAD_INDICE_COUNT,
i * QUAD_VERTICE_COUNT
);
}
}
void UICanvas::onDispose() {
mesh = nullptr;
}
std::vector<std::shared_ptr<IRenderPass>> UICanvas::getPasses(
struct RenderPassContext &ctx
) {
if(this->elements.empty()) return {};
glm::mat4 projection;
glm::mat4 view;
// Setup the projection and views
data.projection = glm::ortho(
0.0f, ctx.renderTarget->getWidth(),
ctx.renderTarget->getHeight(), 0.0f,
0.0f, 1.0f
);
data.view = glm::mat4(1.0f);
data.model = glm::mat4(1.0f);
// Reset the passes
this->passes.clear();
this->textureBindings.clear();
this->textures.clear();
quadCount = 0;
nextBinding = 0;
// Alignment root
const glm::vec2 rootPosition = { 0, 0 };
const glm::vec2 rootSize = {
ctx.renderTarget->getWidth(),
ctx.renderTarget->getHeight()
};
const float_t rootScale = 1.0f;
// Get the quads for each component
auto itComponents = elements.begin();
auto self = std::ref(*this);
while(itComponents != elements.end()) {
auto component = *itComponents;
component->updateAlignment(rootPosition, rootSize, rootScale);
component->getQuads(self);
++itComponents;
}
// Flush the remaining quads
flushPass();
return passes;
}
void UICanvas::addQuad(
const glm::vec4 quad,
const glm::vec4 uvs,
const struct Color color,
const enum UIShaderQuadStyle style,
const std::shared_ptr<Texture> text
) {
glm::vec4 styleData;
styleData[0] = (float_t)style;
if(text == nullptr) {
styleData[1] = -1;
} else {
shadertexturebinding_t texture;
auto bindingIt = textureBindings.find(text);
if(bindingIt == textureBindings.end()) {
if(nextBinding >= UI_SHADER_TEXTURE_COUNT) {
flushPass();
}
textureBindings[text] = nextBinding;
textures[nextBinding] = text;
data.textures[nextBinding] = nextBinding;
texture = nextBinding++;
} else {
texture = bindingIt->second;
}
styleData[1] = (float_t)texture;
}
data.quads[quadCount] = {
quad,
uvs,
color,
styleData
};
quadCount++;
if(quadCount == UI_SHADER_QUAD_COUNT) flushPass();
}
void UICanvas::flushPass() {
if(quadCount == 0) return;
auto pass = createRenderPass<UIShader, UIShaderData>(
std::ref(*this),
data,
textures,
mesh,
MeshDrawMode::TRIANGLES,
0,
quadCount * QUAD_INDICE_COUNT
);
passes.push_back(pass);
quadCount = 0;
nextBinding = 0;
textures.clear();
textureBindings.clear();
}
void UICanvas::addElement(std::shared_ptr<UIElement> element) {
elements.push_back(element);
}

View File

@ -1,73 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "scene/SceneItem.hpp"
#include "component/display/IRenderableComponent.hpp"
#include "display/shader/UIShader.hpp"
namespace Dawn {
class UIElement;
class UICanvas :
public SceneComponent,
public IRenderableComponent
{
private:
std::shared_ptr<Mesh> mesh;
UIShaderData data;
std::vector<std::shared_ptr<UIElement>> elements;
size_t quadCount = 0;
shadertexturebinding_t nextBinding = 0;
std::unordered_map<
shadertexturebinding_t, std::shared_ptr<Texture>
> textures;
std::map<
std::shared_ptr<Texture>, shadertexturebinding_t
> textureBindings;
std::vector<std::shared_ptr<IRenderPass>> passes;
protected:
virtual void onInit() override;
virtual void onDispose() override;
/**
* Flushes all pending quads to the render pass. This doesn't actually
* render anything, it just flushes the data buffer to a new pass.
*/
void flushPass();
public:
std::vector<std::shared_ptr<IRenderPass>> getPasses(
struct RenderPassContext &ctx
) override;
/**
* Adds a quad to the canvas and performs a flush if necessary.
*
* @param quad The quad to add.
* @param uvs The UVs to use for the quad.
* @param color The color to use for the quad.
* @param style Style that the quad should be rendered in.
* @param texture The texture to use for the quad, can be null.
*/
void addQuad(
const glm::vec4 quad,
const glm::vec4 uvs,
const struct Color color,
const enum UIShaderQuadStyle style,
const std::shared_ptr<Texture> texture = nullptr
);
/**
* Adds a component to the canvas.
*
* @param component The component to add.
*/
void addElement(std::shared_ptr<UIElement> component);
};
}

22
src/dawn/dawn.h Normal file
View File

@ -0,0 +1,22 @@
/**
* Copyright (c) 2024 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <assert.h>
#include <float.h>
#include <errno.h>
typedef bool bool_t;
typedef char char_t;
typedef unsigned char uchar_t;
typedef uint_fast32_t flag_t;

View File

@ -1,50 +0,0 @@
/**
* Copyright (c) 2022 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
// Static Libs
extern "C" {
// Standard Libs
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <assert.h>
#include <float.h>
#include <errno.h>
typedef bool bool_t;
typedef char char_t;
}
#include <vector>
#include <iostream>
#include <thread>
#include <map>
#include <array>
#include <memory>
#include <algorithm>
#include <sstream>
#include <string>
#include <functional>
#include <cstdarg>
#include <glm/glm.hpp>
#include <glm/vec3.hpp>
#include <glm/vec4.hpp>
#include <glm/mat4x4.hpp>
// #include <glm/gtx/component_wise.hpp>
#include <glm/gtc/quaternion.hpp>
#include <glm/ext/matrix_transform.hpp>
#include <glm/ext/matrix_clip_space.hpp>
#include <glm/ext/scalar_constants.hpp>
// #include <glm/gtx/intersect.hpp>
#include <glm/gtc/type_ptr.hpp>
#define GLM_ENABLE_EXPERIMENTAL 1
#include <glm/gtx/matrix_decompose.hpp>

View File

@ -1,16 +1,15 @@
# Copyright (c) 2022 Dominic Masters # Copyright (c) 2024 Dominic Masters
# #
# This software is released under the MIT License. # This software is released under the MIT License.
# https://opensource.org/licenses/MIT # https://opensource.org/licenses/MIT
# Subdirs
add_subdirectory(draw)
# Sources # Sources
target_sources(${DAWN_TARGET_NAME} target_sources(${DAWN_TARGET_NAME}
PRIVATE PRIVATE
Color.cpp color.c
RenderPipeline.cpp frame.c
IRenderHost.cpp symbol.c
) )
# Subdirs
add_subdirectory(mesh)
add_subdirectory(shader)

View File

@ -1,84 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "Color.hpp"
#include "util/String.hpp"
#include "assert/assert.hpp"
using namespace Dawn;
struct Color Color::fromString(const std::string str) {
// Convert to lowercase
auto lower = String::toLowercase(str);
if(String::includes(lower, "cornflower")) {
return COLOR_CORNFLOWER_BLUE;
} else if(String::includes(lower, "magenta")) {
return COLOR_MAGENTA;
} else if(String::includes(lower, "white")) {
return COLOR_WHITE;
} else if(String::includes(lower, "black")) {
return COLOR_BLACK;
} else if(String::includes(lower, "red")) {
return COLOR_RED;
} else if(String::includes(lower, "green")) {
return COLOR_GREEN;
} else if(String::includes(lower, "blue")) {
return COLOR_BLUE;
} else if(String::includes(lower, "transparent")) {
return COLOR_TRANSPARENT;
}
// Hex code?
if(lower[0] == '#') {
// Remove the hash
lower = lower.substr(1);
// Convert to RGB
if(lower.length() == 3) {
// Convert to 6 digit hex
lower = lower[0] + lower[0] + lower[1] + lower[1] + lower[2] + lower[2];
}
// Convert to RGB
return {
(float_t)std::stoi(lower.substr(0, 2), nullptr, 16) / 255.0f,
(float_t)std::stoi(lower.substr(2, 2), nullptr, 16) / 255.0f,
(float_t)std::stoi(lower.substr(4, 2), nullptr, 16) / 255.0f,
1.0f
};
}
// Split by comma
auto splitByComma = String::split(str, ",");
if(splitByComma.size() == 3) {
// RGB
return {
(float_t)std::stof(splitByComma[0]),
(float_t)std::stof(splitByComma[1]),
(float_t)std::stof(splitByComma[2]),
1.0f
};
} else if(splitByComma.size() == 4) {
// RGBA
return {
(float_t)std::stof(splitByComma[0]),
(float_t)std::stof(splitByComma[1]),
(float_t)std::stof(splitByComma[2]),
(float_t)std::stof(splitByComma[3])
};
}
// TODO: Parse other kinds of colors
assertUnreachable("Failed to find a color match for %s", str);
return {};
}

View File

@ -1,89 +0,0 @@
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "dawnlibs.hpp"
namespace Dawn {
struct ColorU8 {
uint8_t r, g, b, a;
};
struct Color final {
/**
* Returns a color from a string.
*
* @param str String to parse.
* @return Color parsed.
*/
static struct Color fromString(const std::string str);
float_t r, g, b, a;
const struct Color& operator = (const struct Color &val) {
this->r = val.r;
this->g = val.g;
this->b = val.b;
this->a = val.a;
return *this;
}
struct Color operator * (const float_t &x) {
return {
r * x,
g * x,
b * x,
a * x
};
}
struct Color operator - (const struct Color &color) {
return {
r - color.r,
g - color.g,
b - color.b,
a - color.a
};
}
struct Color operator + (const struct Color &color) {
return {
r + color.r,
g + color.g,
b + color.b,
a + color.a
};
}
const bool_t operator == (const struct Color &other) {
return r == other.r && g == other.g && b == other.b && a == other.a;
}
operator struct ColorU8() const {
return {
(uint8_t)(r * 255),
(uint8_t)(g * 255),
(uint8_t)(b * 255),
(uint8_t)(a * 255)
};
}
};
#define COLOR_DEF(r,g,b,a) { r, g, b, a }
#define COLOR_WHITE COLOR_DEF(1.0f, 1.0f, 1.0f, 1.0f)
#define COLOR_RED COLOR_DEF(1.0f, 0, 0, 1.0f)
#define COLOR_GREEN COLOR_DEF(0, 1.0f, 0, 1.0f)
#define COLOR_BLUE COLOR_DEF(0, 0, 1.0f, 1.0f)
#define COLOR_BLACK COLOR_DEF(0, 0, 0, 1.0f)
#define COLOR_MAGENTA COLOR_DEF(1.0f, 0, 1.0f, 1.0f)
#define COLOR_DARK_GREY COLOR_DEF(0.2f, 0.2f, 0.2f, 1.0f)
#define COLOR_LIGHT_GREY COLOR_DEF(0.8f, 0.8f, 0.8f, 1.0f)
#define COLOR_CORNFLOWER_BLUE COLOR_DEF(0.4f, 0.6f, 0.9f, 1.0f)
#define COLOR_WHITE_TRANSPARENT COLOR_DEF(1.0f, 1.0f, 1.0f, 0.0f)
#define COLOR_BLACK_TRANSPARENT COLOR_DEF(0.0f, 0.0f, 0.0f, 0.0f)
#define COLOR_YELLOW COLOR_DEF(1.0f, 1.0f, 0.0f, 1.0f)
#define COLOR_CYAN COLOR_DEF(0.0f, 1.0f, 1.0f, 1.0f)
#define COLOR_TRANSPARENT COLOR_WHITE_TRANSPARENT
}

View File

@ -1,14 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "IRenderHost.hpp"
using namespace Dawn;
IRenderHost::IRenderHost() : renderPipeline(), shaderManager() {
}
IRenderHost::~IRenderHost() {
}

View File

@ -1,61 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "dawnlibs.hpp"
#include "display/RenderTarget.hpp"
#include "display/RenderPipeline.hpp"
#include "display/shader/ShaderManager.hpp"
namespace Dawn {
class Game;
class IRenderHost {
public:
RenderPipeline renderPipeline;
ShaderManager shaderManager;
/**
* Creates a render host.
*/
IRenderHost();
/**
* Initializes the render host, called by the game during the initial
* set up of the engine.
*
* @param game Game that requested the render host to initialize.
*/
virtual void init(const std::shared_ptr<Game> game) = 0;
/**
* Performs an update/tick of the render host. This would be the game
* asking the RenderHost to do the rendering.
*/
virtual void update(const std::shared_ptr<Game> game) = 0;
/**
* Overridable request from the game that asks if the RenderHost has any
* reason that it should need to close. For most libraries this would be
* whether or not the window was closed.
*
* @return True if the render host requests the game to gracefully exit.
*/
virtual bool_t isCloseRequested() = 0;
/**
* Returns the back buffer render target. This is the render target that
* is used to render to the screen.
*
* @return The back buffer render target.
*/
virtual std::shared_ptr<RenderTarget> getBackBufferRenderTarget() = 0;
/**
* Destroys the render host.
*/
virtual ~IRenderHost();
};
}

View File

@ -1,117 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "display/Color.hpp"
namespace Dawn {
enum class TextureFormat {
R = 1,
RG = 2,
RGB = 3,
RGBA = 4
};
enum class TextureWrapMode {
REPEAT = 0,
MIRRORED_REPEAT = 1,
CLAMP_TO_EDGE = 2,
CLAMP_TO_BORDER = 3
};
enum class TextureFilterMode {
NEAREST = 0,
LINEAR = 1
};
enum class TextureDataFormat {
UNSIGNED_BYTE = sizeof(uint8_t),
FLOAT = sizeof(float_t)
};
class ITexture {
public:
enum TextureWrapMode wrapModeX = TextureWrapMode::REPEAT;
enum TextureWrapMode wrapModeY = TextureWrapMode::REPEAT;
enum TextureFilterMode filterModeMin = TextureFilterMode::NEAREST;
enum TextureFilterMode filterModeMag = TextureFilterMode::NEAREST;
enum TextureFilterMode mipMapFilterModeMin = TextureFilterMode::NEAREST;
enum TextureFilterMode mipMapFilterModeMag = TextureFilterMode::NEAREST;
/**
* Returns the width of the texture.
*
* @return Width of the texture.
*/
virtual int32_t getWidth() = 0;
/**
* Returns the height of the texture.
*
* @return Height of the texture.
*/
virtual int32_t getHeight() = 0;
/**
* Initializes a texture.
*
* @param width Width of the texture (in pixels).
* @param height Height of the texture (in pixels).
* @param format Data format of the texture to use.
* @param dataFormat Data format of the texture to use.
*/
virtual void setSize(
const int32_t width,
const int32_t height,
const enum TextureFormat format,
const enum TextureDataFormat dataFormat
) = 0;
/**
* Returns true only when the texture has been loaded, sized and put on
* the gpu for rendering.
*
* @return True if ready, otherwise false.
*/
virtual bool_t isReady() = 0;
/**
* Buffer pixel data onto the GPU. Pixel buffering is rather costly so
* avoid doing this too often.
*
* @param pixels Array of pixels you're trying to buffer.
*/
virtual void buffer(const struct ColorU8 pixels[]) = 0;
/**
* Buffer pixel data onto the GPU. Pixel buffering is rather costly so
* avoid doing this too often.
*
* @param pixels Array of pixels you're trying to buffer.
*/
virtual void buffer(const struct Color pixels[]) = 0;
/**
* Buffer pixel data onto the GPU. Pixel buffering is rather costly so
* avoid doing this too often.
*
* @param pixels Array of pixels you're trying to buffer.
*/
virtual void buffer(const uint8_t pixels[]) = 0;
/**
* Binds the texture to the given slot (for use by the shaders).
*
* @param slot Slot to bind to.
*/
virtual void bind(const uint8_t slot) = 0;
/**
* Disposes of the texture.
*/
virtual ~ITexture() {
}
};
}

View File

@ -1,105 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "assert/assert.hpp"
#include "RenderPipeline.hpp"
#include "game/Game.hpp"
#include "scene/Scene.hpp"
#include "component/display/Camera.hpp"
#include "component/display/IRenderableComponent.hpp"
using namespace Dawn;
RenderPipeline::RenderPipeline() {
}
void RenderPipeline::render(
const std::shared_ptr<Game> game
) {
assertNotNull(game, "Game cannot be null");
auto scene = game->getCurrentScene();
if(!scene) return;
this->renderScene(game, scene);
}
void RenderPipeline::renderScene(
const std::shared_ptr<Game> game,
const std::shared_ptr<Scene> scene
) {
assertNotNull(game, "Game cannot be null");
assertNotNull(scene, "Scene cannot be null");
// TODO: Render Subscenes First
// Get a list of all cameras in the scene
auto cameras = scene->findComponents<Camera>();
auto backBuffer = scene->getGame()->renderHost.getBackBufferRenderTarget();
std::shared_ptr<Camera> backbufferCamera = nullptr;
for(auto camera : cameras) {
auto rt = camera->getRenderTarget();
// Is this camera the backbuffer camera?
if(rt == backBuffer) {
backbufferCamera = camera;
continue;
}
// Render scene with this camera
renderSceneCamera(game, scene, camera, rt);
}
if(backbufferCamera) {
// Render the backbuffer camera
renderSceneCamera(game, scene, backbufferCamera, backBuffer);
}
}
void RenderPipeline::renderSceneCamera(
const std::shared_ptr<Game> game,
const std::shared_ptr<Scene> scene,
const std::shared_ptr<Camera> camera,
const std::shared_ptr<RenderTarget> renderTarget
) {
assertNotNull(game, "Game cannot be null");
assertNotNull(scene, "Scene cannot be null");
assertNotNull(camera, "Camera cannot be null");
assertNotNull(renderTarget, "RenderTarget cannot be null");
struct RenderPassContext ctx = {
game,
scene,
camera,
renderTarget
};
// Get list of renderables
std::vector<std::shared_ptr<IRenderPass>> renderPasses;
auto renderables = scene->findComponents<IRenderableComponent>();
for(auto renderable : renderables) {
auto rp = renderable->getPasses(ctx);
renderPasses.insert(renderPasses.end(), rp.begin(), rp.end());
}
// TODO: Make clearing the buffers editable!
renderTarget->bind();
renderTarget->clear(
RENDER_TARGET_CLEAR_COLOR |
RENDER_TARGET_CLEAR_DEPTH
);
for(auto renderPass : renderPasses) {
renderPass->bind();
renderPass->setData();
renderPass->upload();
renderPass->draw();
}
}
RenderPipeline::~RenderPipeline() {
}

View File

@ -1,63 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "dawnlibs.hpp"
namespace Dawn {
class Game;
class Scene;
class Camera;
class RenderTarget;
class RenderPipeline {
public:
/**
* Creates a new RenderPipeline.
*/
RenderPipeline();
/**
* Renders the game. This will render the current scene.
*
* @param game Game to render.
*/
void render(
const std::shared_ptr<Game> game
);
/**
* Renders a specific scene. This will render all cameras within the
* scene.
*
* @param game Game to render.
* @param scene Scene to render.
*/
void renderScene(
const std::shared_ptr<Game> game,
const std::shared_ptr<Scene> scene
);
/**
* Renders a specific scene with a specific camera.
*
* @param game Game to render.
* @param scene Scene to render.
* @param camera Camera to render.
* @param renderTarget Render target to render to.
*/
void renderSceneCamera(
const std::shared_ptr<Game> game,
const std::shared_ptr<Scene> scene,
const std::shared_ptr<Camera> camera,
const std::shared_ptr<RenderTarget> renderTarget
);
/**
* Destroys the RenderPipeline.
*/
virtual ~RenderPipeline();
};
}

View File

@ -1,71 +0,0 @@
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "event/Event.hpp"
#define RENDER_TARGET_CLEAR_COLOR (1 << 0)
#define RENDER_TARGET_CLEAR_DEPTH (1 << 1)
namespace Dawn {
class RenderTarget {
public:
Event<float_t, float_t> onResize;
/**
* Return the width of the render target.
*
* @return The width of the render target.
*/
virtual float_t getWidth() = 0;
/**
* Return the height of the render target.
*
* @return The height of the render target.
*/
virtual float_t getHeight() = 0;
/**
* Returns the scale (as in pixel density) of the render target. This is
* typically 1.0f, but on high DPI displays this may be 2.0f or higher.
*
* @return The scale of the render target.
*/
virtual float_t getScale() = 0;
/**
* Sets the clear color of the render target when the clear method for
* the color buffer is requested.
*
* @param color Color to use for the clear operation.
*/
virtual void setClearColor(const struct Color color) = 0;
/**
* Request the existing data in the render target to be cleared out. We
* typically assume the render target can support multiple buffer types,
* so you can opt to only clear certain buffer types.
*
* @param clearFlags Flags to request what is going to be cleared.
*/
virtual void clear(const int32_t clearFlags) = 0;
/**
* Bind the render target for rendering to. The proceeding render requests
* will want to render to this render target directly. In future I may
* see if we can have multiple render targets bound at once to make this
* operation perform faster.
*/
virtual void bind() = 0;
/**
* Destroys the render target.
*/
virtual ~RenderTarget() {
}
};
}

View File

@ -0,0 +1,41 @@
/**
* Copyright (c) 2024 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "animationitem.h"
#define ANIMATION_ITEM_COUNT_MAX 64
typedef struct _animation_t {
float_t time;
bool_t loop;
float_t duration;
animationitem_t items[ANIMATION_ITEM_COUNT_MAX];
uint8_t itemCount;
} animation_t;
/**
* Initializes an animation.
* @param anim The animation to initialize.
*/
void animationInit(animation_t *anim);
/**
* Updates an animation.
* @param anim The animation to update.
* @param delta The time since the last update.
*/
void animationUpdate(animation_t *anim, const float_t delta);
/**
* Returns the total duration of the animation.
*
* @param anim The animation to get the duration of.
* @return The total duration of the animation.
*/
float_t animationDurationGet(const animation_t *anim);

View File

@ -0,0 +1,20 @@
/**
* Copyright (c) 2024 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "dawn.h"
typedef struct _animation_t animation_t;
typedef struct _animationitem_t {
float_t time;
float_t duration;
void *user;
void (*start)(animation_t *anim, animationitem_t *item);
void (*update)(animation_t *anim,animationitem_t *item,const float_t rDelta);
} animationitem_t;

26
src/dawn/display/color.c Normal file
View File

@ -0,0 +1,26 @@
/**
* Copyright (c) 2023 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "color.h"
#include "assert/assert.h"
const color4f_t COLOR4F_COLOR_MAP[COLOR_COUNT] = {
COLOR4F_BLACK,
COLOR4F_WHITE,
COLOR4F(0.8f, 0.0f, 0.0f, 1.0f),
COLOR4F(0.0f, 0.5f, 0.0f, 1.0f),
COLOR4F(0.0f, 0.0f, 0.8f, 1.0f),
COLOR4F(0.8f, 0.8f, 0.0f, 1.0f),
COLOR4F(0.8f, 0.0f, 0.8f, 1.0f),
COLOR4F(0.0f, 0.8f, 0.8f, 1.0f),
COLOR4F(0.5f, 0.5f, 0.5f, 1.0f),
COLOR4F(0.5f, 0.25f, 0.0f, 1.0f)
};
void color4fCopy(const color4f_t src, color4f_t dest) {
memcpy(dest, src, sizeof(color4f_t));
}

81
src/dawn/display/color.h Normal file
View File

@ -0,0 +1,81 @@
/**
* Copyright (c) 2024 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "dawn.h"
typedef float_t color3f_t[3];
typedef float_t color4f_t[4];
// Simple colors, used by the frame system.
#define COLOR_BLACK 0x00
#define COLOR_WHITE 0x01
#define COLOR_RED 0x02
#define COLOR_GREEN 0x03
#define COLOR_BLUE 0x04
#define COLOR_YELLOW 0x05
#define COLOR_MAGENTA 0x06
#define COLOR_CYAN 0x07
#define COLOR_GRAY 0x08
#define COLOR_BROWN 0x09
#define COLOR_COUNT COLOR_BROWN+1
#define COLOR3F(r,g,b) ((color3f_t){ r, g, b })
#define COLOR3F_RED COLOR3F(1, 0, 0)
#define COLOR3F_GREEN COLOR3F(0, 1, 0)
#define COLOR3F_BLUE COLOR3F(0, 0, 1)
#define COLOR3F_BLACK COLOR3F(0, 0, 0)
#define COLOR3F_WHITE COLOR3F(1, 1, 1)
#define COLOR3F_MAGENTA COLOR3F(1, 0, 1)
#define COLOR3F_YELLOW COLOR3F(1, 1, 0)
#define COLOR3F_CYAN COLOR3F(0, 1, 1)
#define COLOR3F_GRAY COLOR3F(0.5f, 0.5f, 0.5f)
#define COLOR3F_DARKGRAY COLOR3F(0.25f, 0.25f, 0.25f)
#define COLOR3F_LIGHTGRAY COLOR3F(0.75f, 0.75f, 0.75f)
#define COLOR3F_ORANGE COLOR3F(1, 0.5f, 0)
#define COLOR3F_PURPLE COLOR3F(0.5f, 0, 1)
#define COLOR3F_PINK COLOR3F(1, 0, 0.5f)
#define COLOR3F_BROWN COLOR3F(0.5f, 0.25f, 0)
#define COLOR3F_GOLD COLOR3F(1, 0.75f, 0)
#define COLOR3F_SILVER COLOR3F(0.75f, 0.75f, 0.75f)
#define COLOR3F_BRONZE COLOR3F(0.75f, 0.5f, 0.25f)
#define COLOR3F_CORNFLOWERBLUE COLOR3F(0.4f, 0.6f, 0.9f)
#define COLOR4F(r,g,b,a) ((color4f_t){ r, g, b, a })
#define COLOR4F_RED COLOR4F(1, 0, 0, 1)
#define COLOR4F_GREEN COLOR4F(0, 1, 0, 1)
#define COLOR4F_BLUE COLOR4F(0, 0, 1, 1)
#define COLOR4F_BLACK COLOR4F(0, 0, 0, 1)
#define COLOR4F_WHITE COLOR4F(1, 1, 1, 1)
#define COLOR4F_MAGENTA COLOR4F(1, 0, 1, 1)
#define COLOR4F_YELLOW COLOR4F(1, 1, 0, 1)
#define COLOR4F_CYAN COLOR4F(0, 1, 1, 1)
#define COLOR4F_GRAY COLOR4F(0.5f, 0.5f, 0.5f, 1)
#define COLOR4F_DARKGRAY COLOR4F(0.25f, 0.25f, 0.25f, 1)
#define COLOR4F_LIGHTGRAY COLOR4F(0.75f, 0.75f, 0.75f, 1)
#define COLOR4F_ORANGE COLOR4F(1, 0.5f, 0, 1)
#define COLOR4F_PURPLE COLOR4F(0.5f, 0, 1, 1)
#define COLOR4F_PINK COLOR4F(1, 0, 0.5f, 1)
#define COLOR4F_BROWN COLOR4F(0.5f, 0.25f, 0, 1)
#define COLOR4F_GOLD COLOR4F(1, 0.75f, 0, 1)
#define COLOR4F_SILVER COLOR4F(0.75f, 0.75f, 0.75f, 1)
#define COLOR4F_BRONZE COLOR4F(0.75f, 0.5f, 0.25f, 1)
#define COLOR4F_CORNFLOWERBLUE COLOR4F(0.4f, 0.6f, 0.9f, 1)
#define COLOR4F_TRANSPARENT_BLACK COLOR4F(0, 0, 0, 0)
#define COLOR4F_TRANSPARENT_WHITE COLOR4F(1, 1, 1, 0)
#define COLOR4F_TRANSPARENT COLOR4F_TRANSPARENT_BLACK
extern const color4f_t COLOR4F_COLOR_MAP[COLOR_COUNT];
/**
* Copies a color.
*
* @param src Source color.
* @param dest Destination color.
*/
void color4fCopy(const color4f_t src, color4f_t dest);

Some files were not shown because too many files have changed in this diff Show More