Compare commits
72 Commits
Author | SHA1 | Date | |
---|---|---|---|
57995a0e00 | |||
53dc496f2f | |||
6a0ffd4a45 | |||
ef84c85527 | |||
39d74cc375 | |||
ddbef64f43 | |||
b2a3ca4411 | |||
a74f285cb2 | |||
5fb36aad35 | |||
258976b76c | |||
7867076bbe | |||
3baafec9cb | |||
6c062df9bb | |||
825cc88e17 | |||
9f4cb283c1 | |||
86feb7e56a | |||
a7dc7fdcf8 | |||
cb3a58e456 | |||
5334f0944e | |||
a1d4b0a1d7 | |||
ecb3b9c5d1 | |||
bf3912bb7f | |||
b5d7b7e229 | |||
b7987401af | |||
ffc46c677c | |||
7a8ca2fca1 | |||
5751f7c83c | |||
c69d0ec1cc | |||
e14445680f | |||
5256b32055 | |||
5444b0b8c7 | |||
45b3cf9478 | |||
0224ddd36b | |||
40b0395552 | |||
b7829fda5c | |||
bdef59bbe1 | |||
27ce6526e6 | |||
704002e671 | |||
cfe4cf6cad | |||
69672cf8a6 | |||
c1345218a3 | |||
be27408cf4 | |||
4205b919d4 | |||
e14083b4b4 | |||
ad317da97e | |||
2ff1a159bc | |||
c770953b2e | |||
2cb1d745b2 | |||
8ce0e8f9f6 | |||
5101a856be | |||
303d0c0a6f | |||
e3a4368d1e | |||
7c34127900 | |||
49d90b3362 | |||
935398d45e | |||
4065556d4a | |||
fb8f6e3f95 | |||
b4c2ce16a0 | |||
b309478922 | |||
ad3974bde5 | |||
e5349cc093 | |||
01c56477aa | |||
916396e175 | |||
0e5b85633c | |||
e5f3f69120 | |||
ca240bc180 | |||
a3a891ddb2 | |||
5fae94c722 | |||
d5b3b6d619 | |||
b4e261d954 | |||
856bc306fe | |||
cffe7f73a2 |
2
.gitignore
vendored
2
.gitignore
vendored
@ -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
24
.gitmodules
vendored
@ -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
|
|
||||||
|
@ -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
|
||||||
|
@ -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
42
assets/en.json
Normal 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
46
assets/maps/testmap.tmx
Normal 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
17
assets/maps/testmap2.tmx
Normal 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>
|
14
assets/tiled_project.tiled-project
Normal file
14
assets/tiled_project.tiled-project
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"automappingRulesFile": "",
|
||||||
|
"commands": [
|
||||||
|
],
|
||||||
|
"compatibilityVersion": 1100,
|
||||||
|
"extensionsPath": "extensions",
|
||||||
|
"folders": [
|
||||||
|
"."
|
||||||
|
],
|
||||||
|
"properties": [
|
||||||
|
],
|
||||||
|
"propertyTypes": [
|
||||||
|
]
|
||||||
|
}
|
114
assets/tiled_project.tiled-session
Normal file
114
assets/tiled_project.tiled-session
Normal 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
|
||||||
|
}
|
||||||
|
}
|
BIN
assets/tilemaps/entities.png
Normal file
BIN
assets/tilemaps/entities.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 326 B |
8
assets/tilemaps/entities.tsx
Normal file
8
assets/tilemaps/entities.tsx
Normal 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
BIN
assets/tilemaps/tilemap.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 408 B |
4
assets/tilemaps/tilemap.tsx
Normal file
4
assets/tilemaps/tilemap.tsx
Normal 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>
|
@ -1,5 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
mkdir tools
|
|
||||||
cd tools
|
|
||||||
cmake .. -DDAWN_BUILD_TARGET=target-tools
|
|
||||||
make
|
|
@ -1,2 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
git submodule update --init --recursive
|
|
@ -1,2 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
sudo apt install build-essential
|
|
@ -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
|
|
@ -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 ../..
|
|
@ -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)
|
|
@ -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})
|
|
@ -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.
|
|
@ -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})
|
|
@ -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})
|
|
@ -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})
|
|
@ -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)
|
|
@ -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)
|
|
@ -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})
|
|
@ -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)
|
|
@ -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})
|
|
@ -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})
|
|
@ -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()
|
|
@ -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})
|
|
@ -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
234
gentileset.py
Normal 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
@ -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()
|
|
1
lib/SDL
1
lib/SDL
Submodule lib/SDL deleted from fb1497566c
1
lib/font8x8
Submodule
1
lib/font8x8
Submodule
Submodule lib/font8x8 added at 8e279d2d86
Submodule lib/freetype deleted from 7ff43d3e9f
1
lib/glfw
1
lib/glfw
Submodule lib/glfw deleted from b35641f4a3
1
lib/glm
1
lib/glm
Submodule lib/glm deleted from 45008b225e
Submodule lib/libarchive deleted from 313aa1fa10
Submodule lib/openal-soft deleted from d3875f333f
@ -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()
|
@ -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)
|
||||||
|
@ -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
|
||||||
)
|
)
|
@ -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();
|
||||||
}
|
}
|
@ -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
|
@ -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();
|
|
||||||
}
|
|
@ -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();
|
|
||||||
};
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
@ -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();
|
|
||||||
};
|
|
||||||
}
|
|
@ -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() {
|
|
||||||
|
|
||||||
}
|
|
@ -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();
|
|
||||||
};
|
|
||||||
}
|
|
@ -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
159
src/dawn/asset/asset.c
Normal 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
73
src/dawn/asset/asset.h
Normal 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();
|
55
src/dawn/asset/assetarchive.c
Normal file
55
src/dawn/asset/assetarchive.c
Normal 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);
|
||||||
|
}
|
68
src/dawn/asset/assetarchive.h
Normal file
68
src/dawn/asset/assetarchive.h
Normal 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
560
src/dawn/asset/assetjson.c
Normal 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
140
src/dawn/asset/assetjson.h
Normal 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);
|
70
src/dawn/asset/assetlanguage.c
Normal file
70
src/dawn/asset/assetlanguage.c
Normal 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);
|
||||||
|
}
|
27
src/dawn/asset/assetlanguage.h
Normal file
27
src/dawn/asset/assetlanguage.h
Normal 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
236
src/dawn/asset/assetmap.c
Normal 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
32
src/dawn/asset/assetmap.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2024 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "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
|
||||||
|
);
|
@ -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
|
|
||||||
)
|
|
@ -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;
|
|
||||||
}
|
|
@ -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();
|
|
||||||
};
|
|
||||||
}
|
|
@ -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() {
|
|
||||||
}
|
|
@ -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();
|
|
||||||
};
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
@ -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
|
|
||||||
);
|
|
||||||
}
|
|
@ -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);
|
|
||||||
});
|
|
||||||
}
|
|
@ -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);
|
|
||||||
};
|
|
||||||
}
|
|
@ -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
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
@ -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;
|
|
||||||
};
|
|
||||||
}
|
|
@ -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
|
|
||||||
)
|
|
@ -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() {
|
|
||||||
|
|
||||||
}
|
|
@ -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;
|
|
||||||
};
|
|
||||||
}
|
|
@ -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
|
|
||||||
)
|
|
||||||
};
|
|
||||||
}
|
|
@ -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;
|
|
||||||
};
|
|
||||||
}
|
|
@ -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
|
|
||||||
)
|
|
@ -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);
|
|
||||||
}
|
|
@ -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
22
src/dawn/dawn.h
Normal 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;
|
@ -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>
|
|
@ -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)
|
|
@ -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 {};
|
|
||||||
}
|
|
@ -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
|
|
||||||
}
|
|
@ -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() {
|
|
||||||
}
|
|
@ -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();
|
|
||||||
};
|
|
||||||
}
|
|
@ -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() {
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
@ -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() {
|
|
||||||
|
|
||||||
}
|
|
@ -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();
|
|
||||||
};
|
|
||||||
}
|
|
@ -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() {
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
41
src/dawn/display/animation/animation.h
Normal file
41
src/dawn/display/animation/animation.h
Normal 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);
|
20
src/dawn/display/animation/animationitem.h
Normal file
20
src/dawn/display/animation/animationitem.h
Normal 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
26
src/dawn/display/color.c
Normal 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
81
src/dawn/display/color.h
Normal 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
Reference in New Issue
Block a user