Going to redo assets.

This commit is contained in:
YourWishes committed 2025-08-24 13:57:12 -05:00
1 parent 329925ea54
commit 479aad2f06
36 files changed
+285 -128

No files matched your search

+23 -11
View File
@@ -29,13 +29,13 @@ set(DUSK_TARGET_NAME "Dusk" CACHE INTERNAL ${DUSK_CACHE_TARGET})
set(DUSK_BUILD_BINARY ${DUSK_BUILD_DIR}/Dusk CACHE INTERNAL ${DUSK_CACHE_TARGET})
set(DUSK_ASSETS "" CACHE INTERNAL ${DUSK_CACHE_TARGET})
# Toolchain
# Create directories
file(MAKE_DIRECTORY ${DUSK_GENERATED_HEADERS_DIR})
file(MAKE_DIRECTORY ${DUSK_ASSETS_BUILD_DIR})
# Compilers
# Find packages
find_package(Python3 COMPONENTS Interpreter REQUIRED)
# Toolchains
if(DUSK_TARGET_SYSTEM STREQUAL "psp")
find_package(pspsdk REQUIRED)
endif()
@@ -52,6 +52,9 @@ add_executable(${DUSK_TARGET_NAME})
# Add tools
add_subdirectory(tools)
# Assets
add_subdirectory(assets)
# Add libraries
if(DUSK_TARGET_SYSTEM STREQUAL "linux")
find_package(SDL2 REQUIRED)
@@ -64,14 +67,11 @@ if(DUSK_TARGET_SYSTEM STREQUAL "linux")
elseif(DUSK_TARGET_SYSTEM STREQUAL "psp")
find_package(SDL2 REQUIRED)
target_link_libraries(${DUSK_TARGET_NAME}
PRIVATE
# pspsdk
${SDL2_LIBRARIES}
target_link_libraries(${DUSK_TARGET_NAME} PRIVATE
${SDL2_LIBRARIES}
)
target_include_directories(${DUSK_TARGET_NAME}
PRIVATE
${SDL2_INCLUDE_DIRS}
target_include_directories(${DUSK_TARGET_NAME} PRIVATE
${SDL2_INCLUDE_DIRS}
)
endif()
@@ -83,6 +83,18 @@ target_include_directories(${DUSK_TARGET_NAME} PUBLIC
${DUSK_GENERATED_HEADERS_DIR}
)
# Build assets
string(JOIN "," DUSK_ASSETS_ARGUMENTS ${DUSK_ASSETS})
add_custom_target(DUSK_ASSETS_BUILT ALL
COMMAND
${Python3_EXECUTABLE} ${DUSK_TOOLS_DIR}/assetstool/assets.py
--output ${DUSK_GENERATED_HEADERS_DIR}/assets
--input ${DUSK_ASSETS_ARGUMENTS}
COMMENT
"Creating assets build directory ${DUSK_ASSETS}"
)
add_dependencies(${DUSK_TARGET_NAME} DUSK_ASSETS_BUILT)
# Postbuild, create PBP file for PSP.
if(DUSK_TARGET_SYSTEM STREQUAL "psp")
create_pbp_file(
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+6
View File
@@ -0,0 +1,6 @@
# Copyright (c) 2025 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
add_asset(entities.tsx)
Binary file not shown.

After

Width:  |  Height:  |  Size: 336 B

+4
View File
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<tileset version="1.10" tiledversion="1.11.1" name="entities" tilewidth="16" tileheight="16" tilecount="64" columns="8">
<image source="entities.png" width="128" height="128"/>
</tileset>
+2 -1
View File
@@ -26,13 +26,14 @@ target_sources(${DUSK_TARGET_NAME}
# Subdirs
add_subdirectory(assert)
add_subdirectory(asset)
add_subdirectory(console)
add_subdirectory(display)
add_subdirectory(ecs)
add_subdirectory(engine)
add_subdirectory(error)
add_subdirectory(input)
add_subdirectory(locale)
# add_subdirectory(locale)
add_subdirectory(scene)
add_subdirectory(thread)
add_subdirectory(time)
+12
View File
@@ -0,0 +1,12 @@
# Copyright (c) 2025 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DUSK_TARGET_NAME}
PRIVATE
asset.c
assetraw.c
assetsystem.c
)
+1 -45
View File
@@ -7,56 +7,12 @@
#include "asset.h"
assetcallbacks_t ASSET_CALLBACKS[ASSET_TYPE_COUNT] = {
assetcallbacks_t ASSET_CALLBACKS[] = {
{
.init = assetRawInit,
.loadAsync = assetRawLoadAsync,
.loadSync = assetRawLoadSync,
.dispose = assetRawDispose
},
{
.init = NULL,
.loadAsync = NULL,
.loadSync = NULL,
.dispose = NULL
},
{
.init = NULL,
.loadAsync = NULL,
.loadSync = NULL,
.dispose = NULL
},
{
.init = NULL,
.loadAsync = NULL,
.loadSync = NULL,
.dispose = NULL
},
{
.init = NULL,
.loadAsync = NULL,
.loadSync = NULL,
.dispose = NULL
},
{
.init = NULL,
.loadAsync = NULL,
.loadSync = NULL,
.dispose = NULL
},
{
.init = NULL,
.loadAsync = NULL,
.loadSync = NULL,
.dispose = NULL
},
{
.init = NULL,
.loadAsync = NULL,
.loadSync = NULL,
.dispose = NULL
}
};
+2 -21
View File
@@ -6,31 +6,12 @@
*/
#pragma once
#include "assetraw.h"
typedef enum {
ASSET_TYPE_RAW,
ASSET_TYPE_TEXTURE,
ASSET_TYPE_JSON,
ASSET_TYPE_MODEL,
ASSET_TYPE_AUDIO,
ASSET_TYPE_COUNT
} assettype_t;
typedef struct {
void (*init)(asset_t *asset);
void (*loadAsync)(asset_t *asset);
void (*loadSync)(asset_t *asset);
void (*dispose)(asset_t *asset);
} assetcallbacks_t;
#include "dusk.h"
typedef struct asset_s {
void *arg;
int32_t nothing;
} asset_t;
extern assetcallbacks_t ASSET_CALLBACKS[];
void assetInit(void);
void assetDispose(void);
+14
View File
@@ -0,0 +1,14 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "dusk.h"
typedef struct {
const int32_t width;
const int32_t height;
} assetimage_t;
-24
View File
@@ -1,24 +0,0 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "assetraw.h"
void assetRawInit(asset_t *asset) {
}
void assetRawLoadAsync(asset_t *asset) {
}
void assetRawLoadSync(asset_t *asset) {
}
void assetRawDispose(asset_t *asset) {
}
-16
View File
@@ -1,16 +0,0 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "dusk.h"
typedef struct asset_s asset_t;
void assetRawInit(asset_t *asset);
void assetRawLoadAsync(asset_t *asset);
void assetRawLoadSync(asset_t *asset);
void assetRawDispose(asset_t *asset);
+20
View File
@@ -0,0 +1,20 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "assetsystem.h"
#include "util/memory.h"
assetsystem_t ASSET_SYSTEM;
void assetSystemInit(void) {
memoryZero(&ASSET_SYSTEM, sizeof(assetsystem_t));
// threadInit(&ASSET_SYSTEM.thread, NULL);
}
void assetSystemDispose(void) {
// threadDispose(&ASSET_SYSTEM.thread);
}
+1 -3
View File
@@ -7,11 +7,9 @@
#pragma once
#include "asset.h"
#include "thread/thread.h"
typedef struct {
void *args;
thread_t loadThread;
int32_t nothing;
} assetsystem_t;
extern assetsystem_t ASSET_SYSTEM;
+19
View File
@@ -0,0 +1,19 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "dusk.h"
typedef struct assetimage_s assetimage_t;
typedef struct {
const int32_t tileWidth;
const int32_t tileHeight;
const int32_t tileCount;
const int32_t columns;
const assetimage_t *image;
} assettileset_t;
+3
View File
@@ -12,6 +12,7 @@
#include "display/display.h"
#include "ecs/ecssystem.h"
#include "scene/node.h"
#include "asset/assetsystem.h"
#include "scene/test/scenetest.h"
@@ -25,6 +26,7 @@ errorret_t engineInit(void) {
timeInit();
consoleInit();
ecsSystemInit();
assetSystemInit();
errorChain(displayInit());
sceneTestAdd();
@@ -43,6 +45,7 @@ errorret_t engineUpdate(void) {
errorret_t engineDispose(void) {
ecsSystemDispose();
errorChain(displayDispose());
assetSystemDispose();
consoleDispose();
errorOk();
+7 -7
View File
@@ -1,11 +1,11 @@
# Copyright (c) 2023 Dominic Msters
# Copyright (c) 2025 Dominic Msters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Tools
add_subdirectory(eventcompile)
add_subdirectory(fontcompile)
add_subdirectory(languagecompile)
add_subdirectory(mapcompile)
add_subdirectory(tilecompile)
# Function that adds an asset to be compiled
function(add_asset ASSET_PATH)
set(FULL_ASSET_PATH "${CMAKE_CURRENT_LIST_DIR}/${ASSET_PATH}")
list(APPEND DUSK_ASSETS ${FULL_ASSET_PATH})
set(DUSK_ASSETS ${DUSK_ASSETS} CACHE INTERNAL ${DUSK_CACHE_TARGET})
endfunction()
+17
View File
@@ -0,0 +1,17 @@
import os
import sys
from tilesetparser import parseTileset
from imageparser import parseImage
def parseAsset(assetPath):
if not os.path.isfile(assetPath):
print(f"Error: Input asset '{assetPath}' does not exist.")
sys.exit(1)
if assetPath.endswith(".tsx"):
return parseTileset(assetPath)
elif assetPath.endswith(".png"):
return parseImage(assetPath)
else:
print(f"Warning: Unsupported asset type for '{assetPath}'. Skipping.")
return []
+31
View File
@@ -0,0 +1,31 @@
import sys, os
import argparse
from assetparser import parseAsset
from header import setOutputDir
# Check if the script is run with the correct arguments
parser = argparse.ArgumentParser(description="Generate chunk header files")
parser.add_argument('--output', required=True, help='Dir to output headers')
parser.add_argument('--input', required=True, help='Input assets to process', nargs='+')
args = parser.parse_args()
# Setup headers directory.
setOutputDir(args.output)
outputHeaders = []
# Create output directory if it doesn't exist
if not os.path.exists(args.output):
os.makedirs(args.output)
# Split input assets by comma
inputAssets = []
for inputArg in args.input:
inputAssets.extend(inputArg.split(','))
# Begin processing assets
if not inputAssets:
print("Error: No input assets provided.")
sys.exit(1)
for asset in inputAssets:
outputHeaders.extend(parseAsset(asset))
+15
View File
@@ -0,0 +1,15 @@
import os
def setOutputDir(outputDir):
global OUTPUT_DIR
OUTPUT_DIR = outputDir
def getOutputDir():
return OUTPUT_DIR
def getHeaderInclude(headerPath):
outputDir = getOutputDir()
relPath = os.path.relpath(headerPath, outputDir)
path = relPath.replace('\\', '/') # Use forward slashes for includes
print(f" Including header: {path}")
return f'#include "{path}"'
+34
View File
@@ -0,0 +1,34 @@
import os
from os import abort
from header import getOutputDir
from PIL import Image
def parseImage(imagePath):
print(f"Parsing image: {imagePath}")
if not os.path.isfile(imagePath):
abort(f"Error: Image file {imagePath} does not exist")
outputFile = os.path.join(getOutputDir(), f"image_{os.path.basename(imagePath)}.h")
dataOut = ""
dataOut += f"// Auto-generated image header for {os.path.basename(imagePath)}\n"
dataOut += f"#pragma once\n"
dataOut += f"#include \"asset/assetimage.h\"\n\n"
name = os.path.splitext(os.path.basename(imagePath))[0]
name = name.upper().replace(' ', '_')
dataOut += f"static const assetimage_t IMAGE_{name} = {{\n"
try:
with Image.open(imagePath) as img:
width, height = img.size
dataOut += f" .width = {width},\n"
dataOut += f" .height = {height},\n"
except Exception as e:
abort(f"Error: Unable to open image {imagePath}: {e}")
dataOut += f"}};\n"
with open(outputFile, 'w') as f:
f.write(dataOut)
return [ outputFile ]
+74
View File
@@ -0,0 +1,74 @@
from os import abort
import os
import xml.etree.ElementTree as ET
from imageparser import parseImage
from header import getOutputDir, getHeaderInclude
def parseTileset(assetPath):
tree = ET.parse(assetPath)
root = tree.getroot()
# Should have tilewidth, tileheight, tilecount and columns attributes
if not all(attr in root.attrib for attr in ['tilewidth', 'tileheight', 'tilecount', 'columns']):
print(f"Error: Missing required attributes in tileset {assetPath}")
return []
tileWidth = int(root.attrib['tilewidth'])
tileHeight = int(root.attrib['tileheight'])
tileCount = int(root.attrib['tilecount'])
columns = int(root.attrib['columns'])
# Find image elements
images = root.findall('image')
if not images:
abort(f"Error: No image elements found in tileset {assetPath}")
imageSources = []
for image in images:
imageSource = image.attrib.get('source')
if not imageSource:
abort(f"Error: Image element missing 'source' attribute in tileset {assetPath}")
# Get relative dir from this assetPath
assetDir = os.path.dirname(assetPath)
imageSource = os.path.normpath(os.path.join(assetDir, imageSource))
imageSources.extend(parseImage(imageSource))
# Now do our own header.
headers = []
print(f"Generating tileset header for {assetPath}")
name = os.path.splitext(os.path.basename(assetPath))[0]
name = name.upper().replace(' ', '_')
imageNameWithoutExtension = os.path.splitext(os.path.splitext(os.path.basename(imageSources[0]))[0])[0]
imageNameWithoutExtension = imageNameWithoutExtension.upper().replace(' ', '_')
dataOut = ""
dataOut += f"// Auto-generated tileset header for {os.path.basename(assetPath)}\n"
dataOut += f"#pragma once\n"
dataOut += f"#include \"asset/assettileset.h\"\n"
for imgHeader in imageSources:
dataOut += getHeaderInclude(imgHeader) + "\n"
dataOut += f"\n"
dataOut += f"static const assettileset_t TILESET_{name} = {{\n"
dataOut += f" .tileCount = {tileCount},\n"
dataOut += f" .columns = {columns},\n"
dataOut += f" .tileHeight = {tileHeight},\n"
dataOut += f" .tileWidth = {tileWidth},\n"
dataOut += f" .image = &{imageNameWithoutExtension},\n"
dataOut += f"}};\n"
# Write out to output dir
outputDir = getOutputDir()
if not os.path.isdir(outputDir):
os.makedirs(outputDir)
outputFile = os.path.join(outputDir, f"tileset_{os.path.basename(assetPath)}.h")
with open(outputFile, 'w') as f:
f.write(dataOut)
headers.append(outputFile)
headers.extend(imageSources)
return headers