diff --git a/CMakeLists.txt b/CMakeLists.txt index df6e432..4fcb031 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -92,9 +92,8 @@ add_subdirectory(src) # Build assets add_custom_target(DUSK_ASSETS_BUILT ALL COMMAND - ${Python3_EXECUTABLE} ${DUSK_TOOLS_DIR}/assetstool/main.py + ${Python3_EXECUTABLE} ${DUSK_TOOLS_DIR}/assettool.py --assets ${DUSK_GAME_ASSETS_DIR} - --build-type wad --output-assets ${DUSK_BUILT_ASSETS_DIR} --output-file ${DUSK_BUILD_DIR}/dusk.dsk --headers-dir ${DUSK_GENERATED_HEADERS_DIR} diff --git a/cmake/modules/envtoh.cmake b/cmake/modules/envtoh.cmake index 4c003e1..bad6c2d 100644 --- a/cmake/modules/envtoh.cmake +++ b/cmake/modules/envtoh.cmake @@ -24,8 +24,8 @@ foreach(line IN LISTS ENV_LINES) continue() endif() - # Expect KEY=VALUE - if(NOT line MATCHES "^[A-Za-z_][A-Za-z0-9_]*=") + # Expect KEY=VALUE (allow spaces around '=') + if(NOT line MATCHES "^[A-Za-z_][A-Za-z0-9_]*[ \t]*=[ \t]*") message(WARNING "Skipping invalid line in ${ENV_FILE}: '${line}'") continue() endif() @@ -34,9 +34,8 @@ foreach(line IN LISTS ENV_LINES) string(REGEX MATCH "^[A-Za-z_][A-Za-z0-9_]*" KEY "${line}") string(LENGTH "${KEY}" key_len) - # Extract value - string(SUBSTRING "${line}" ${key_len} -1 rest) - string(REGEX REPLACE "^[ \t]*=[ \t]*" "" RAW_VALUE "${rest}") + # Extract value (allow spaces around '=') + string(REGEX REPLACE "^[A-Za-z_][A-Za-z0-9_]*[ \t]*=[ \t]*" "" RAW_VALUE "${line}") # Lowercase copy for boolean detection string(TOLOWER "${RAW_VALUE}" VALUE_LC) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index fcec72a..578f39b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -29,7 +29,7 @@ target_sources(${DUSK_TARGET_NAME} ) # Defs -add_defs(dawndefs.env dawndefs.h) +add_defs(duskdefs.env duskdefs.h) # Subdirs add_subdirectory(assert) diff --git a/src/dawndefs.env b/src/duskdefs.env similarity index 55% rename from src/dawndefs.env rename to src/duskdefs.env index 4864180..c94bef6 100644 --- a/src/dawndefs.env +++ b/src/duskdefs.env @@ -3,3 +3,9 @@ # This software is released under the MIT License. # https://opensource.org/licenses/MIT +CHUNK_WIDTH = 16 +CHUNK_HEIGHT = 16 +CHUNK_DEPTH = 4 +TILE_WIDTH = 16.0 +TILE_HEIGHT = 16.0 +TILE_DEPTH = 11.36 \ No newline at end of file diff --git a/src/rpg/world/worldpos.h b/src/rpg/world/worldpos.h index ba73555..d0a809c 100644 --- a/src/rpg/world/worldpos.h +++ b/src/rpg/world/worldpos.h @@ -7,10 +7,8 @@ #pragma once #include "dusk.h" +#include "duskdefs.h" -#define CHUNK_WIDTH 16 -#define CHUNK_HEIGHT 16 -#define CHUNK_DEPTH 4 #define CHUNK_TILE_COUNT (CHUNK_WIDTH * CHUNK_HEIGHT * CHUNK_DEPTH) #define MAP_CHUNK_WIDTH 3 diff --git a/tools/assetstool/args.py b/tools/assetstool/args.py index db7e529..d086b95 100644 --- a/tools/assetstool/args.py +++ b/tools/assetstool/args.py @@ -1,50 +1,12 @@ -import os +import sys, os import argparse -import sys # Check if the script is run with the correct arguments parser = argparse.ArgumentParser(description="Generate chunk header files") parser.add_argument('--assets', required=True, help='Dir to output built assets') -parser.add_argument('--build-type', choices=['wad', 'header'], default='raw', help='Type of build to perform') -parser.add_argument('--output-file', required=True, help='Output file for built assets (required for wad build)') parser.add_argument('--headers-dir', required=True, help='Directory to output individual asset headers (required for header build)') parser.add_argument('--output-headers', help='Output header file for built assets (required for header build)') parser.add_argument('--output-assets', required=True, help='Output directory for built assets') +parser.add_argument('--output-file', required=True, help='Output file for built assets (required for wad build)') parser.add_argument('--input', required=True, help='Input assets to process', nargs='+') -args = parser.parse_args() - -inputAssets = [] -for inputArg in args.input: - files = inputArg.split('$') - for file in files: - if str(file).strip() == '': - continue - - pieces = file.split('#') - - if len(pieces) < 2: - print(f"Error: Invalid input asset format '{file}'. Expected format: type#path[#option1%option2...]") - sys.exit(1) - - options = {} - if len(pieces) > 2: - optionParts = pieces[2].split('%') - for part in optionParts: - partSplit = part.split('=') - - if len(partSplit) < 1: - continue - if len(partSplit) == 2: - options[partSplit[0]] = partSplit[1] - else: - options[partSplit[0]] = True - - inputAssets.append({ - 'type': pieces[0], - 'path': pieces[1], - 'options': options - }) - -if not inputAssets: - print("Error: No input assets provided.") - sys.exit(1) \ No newline at end of file +args = parser.parse_args() \ No newline at end of file diff --git a/tools/assetstool/assethelpers.py b/tools/assetstool/assethelpers.py index 8ae56c9..231dca8 100644 --- a/tools/assetstool/assethelpers.py +++ b/tools/assetstool/assethelpers.py @@ -1,5 +1,5 @@ import os -from args import args +from assetstool.args import args def getAssetRelativePath(fullPath): # Get the relative path to the asset diff --git a/tools/assetstool/constants.py b/tools/assetstool/constants.py deleted file mode 100644 index 4537adb..0000000 --- a/tools/assetstool/constants.py +++ /dev/null @@ -1 +0,0 @@ -ASSET_FILE_NAME_MAX_LENGTH = 256 \ No newline at end of file diff --git a/tools/assetstool/main.py b/tools/assetstool/main.py deleted file mode 100644 index 2207202..0000000 --- a/tools/assetstool/main.py +++ /dev/null @@ -1,49 +0,0 @@ -import sys, os -from args import inputAssets, args -from processasset import processAsset -from processpalette import processPaletteList -from processtileset import processTilesetList -from processlanguage import processLanguageList -from assethelpers import getBuiltAssetsRelativePath -import zipfile - -# 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) - -files = [] - -for asset in inputAssets: - asset = processAsset(asset) - files.extend(asset['files']) - -files.extend(processLanguageList()['files']) - -# Take assets and add to a zip archive. -outputFileName = args.output_file -print(f"Creating output file: {outputFileName}") -with zipfile.ZipFile(outputFileName, 'w') as zipf: - for file in files: - relativeOutputPath = getBuiltAssetsRelativePath(file) - zipf.write(file, arcname=relativeOutputPath) - -# Generate additional headers. -processPaletteList() -processTilesetList() - -# Finalize build -if args.build_type == 'header': - print("Error: Header build not implemented yet.") - sys.exit(1) - -elif args.build_type == 'wad': - # Nothing to do, already created above! - pass - -else: - print("Error: Unknown build type.") - sys.exit(1) \ No newline at end of file diff --git a/tools/assetstool/processasset.py b/tools/assetstool/processasset.py index 0ae2ee9..f355b91 100644 --- a/tools/assetstool/processasset.py +++ b/tools/assetstool/processasset.py @@ -1,10 +1,10 @@ import sys # from processtileset import processTileset -from processimage import processImage -from processpalette import processPalette -from processtileset import processTileset -from processmap import processMap -from processlanguage import processLanguage +from assetstool.processimage import processImage +from assetstool.processpalette import processPalette +from assetstool.processtileset import processTileset +from assetstool.processmap import processMap +from assetstool.processlanguage import processLanguage processedAssets = [] diff --git a/tools/assetstool/processimage.py b/tools/assetstool/processimage.py index 8038cd7..139b0b1 100644 --- a/tools/assetstool/processimage.py +++ b/tools/assetstool/processimage.py @@ -1,10 +1,10 @@ import os import sys from PIL import Image -from processpalette import extractPaletteFromImage, palettes -from args import args -from assethelpers import getAssetRelativePath -from assetcache import assetGetCache, assetCache +from assetstool.processpalette import extractPaletteFromImage, palettes +from assetstool.args import args +from assetstool.assethelpers import getAssetRelativePath +from assetstool.assetcache import assetGetCache, assetCache images = [] diff --git a/tools/assetstool/processlanguage.py b/tools/assetstool/processlanguage.py index 98c6f92..2cb40d0 100644 --- a/tools/assetstool/processlanguage.py +++ b/tools/assetstool/processlanguage.py @@ -1,8 +1,8 @@ import sys import os -from args import args -from assetcache import assetCache, assetGetCache -from assethelpers import getAssetRelativePath +from assetstool.args import args +from assetstool.assetcache import assetCache, assetGetCache +from assetstool.assethelpers import getAssetRelativePath import polib import re diff --git a/tools/assetstool/processmap.py b/tools/assetstool/processmap.py index 6a921d7..406d47c 100644 --- a/tools/assetstool/processmap.py +++ b/tools/assetstool/processmap.py @@ -2,17 +2,19 @@ import struct import sys import os import json -from args import args -from assetcache import assetCache, assetGetCache -from assethelpers import getAssetRelativePath +from assetstool.args import args +from assetstool.assetcache import assetCache, assetGetCache +from assetstool.assethelpers import getAssetRelativePath +from dusk.defs import defs -CHUNK_WIDTH = 16 -CHUNK_HEIGHT = 16 -CHUNK_DEPTH = 4 +CHUNK_WIDTH = int(defs.get('CHUNK_WIDTH')) +CHUNK_HEIGHT = int(defs.get('CHUNK_HEIGHT')) +CHUNK_DEPTH = int(defs.get('CHUNK_DEPTH')) CHUNK_TILE_COUNT = CHUNK_WIDTH * CHUNK_HEIGHT * CHUNK_DEPTH -TILE_WIDTH = 16.0 -TILE_HEIGHT = 16.0 -TILE_DEPTH = 11.36 + +TILE_WIDTH = float(defs.get('TILE_WIDTH')) +TILE_HEIGHT = float(defs.get('TILE_HEIGHT')) +TILE_DEPTH = float(defs.get('TILE_DEPTH')) def processTile(tileIndex, x=0, y=0, z=0, chunkX=0, chunkY=0, chunkZ=0): vertices = [] diff --git a/tools/assetstool/processpalette.py b/tools/assetstool/processpalette.py index 7abbd50..487a95b 100644 --- a/tools/assetstool/processpalette.py +++ b/tools/assetstool/processpalette.py @@ -1,9 +1,8 @@ import os from PIL import Image -from args import args -import sys import datetime -from assetcache import assetCache, assetGetCache +from assetstool.args import args +from assetstool.assetcache import assetCache, assetGetCache palettes = [] diff --git a/tools/assetstool/processtileset.py b/tools/assetstool/processtileset.py index 242471c..1208d1a 100644 --- a/tools/assetstool/processtileset.py +++ b/tools/assetstool/processtileset.py @@ -1,12 +1,12 @@ import json -from processimage import processImage import sys -from assethelpers import getAssetRelativePath import os import datetime -from args import args from xml.etree import ElementTree -from assetcache import assetGetCache, assetCache +from assetstool.processimage import processImage +from assetstool.assethelpers import getAssetRelativePath +from assetstool.args import args +from assetstool.assetcache import assetGetCache, assetCache tilesets = [] diff --git a/tools/assettool.py b/tools/assettool.py new file mode 100644 index 0000000..87c9d5d --- /dev/null +++ b/tools/assettool.py @@ -0,0 +1,66 @@ +import sys, os +from assetstool.args import args +from assetstool.processasset import processAsset +from assetstool.processpalette import processPaletteList +from assetstool.processtileset import processTilesetList +from assetstool.processlanguage import processLanguageList +from assetstool.assethelpers import getBuiltAssetsRelativePath +import zipfile + +# Parse input file args. +inputAssets = [] +for inputArg in args.input: + files = inputArg.split('$') + for file in files: + if str(file).strip() == '': + continue + + pieces = file.split('#') + + if len(pieces) < 2: + print(f"Error: Invalid input asset format '{file}'. Expected format: type#path[#option1%option2...]") + sys.exit(1) + + options = {} + if len(pieces) > 2: + optionParts = pieces[2].split('%') + for part in optionParts: + partSplit = part.split('=') + + if len(partSplit) < 1: + continue + if len(partSplit) == 2: + options[partSplit[0]] = partSplit[1] + else: + options[partSplit[0]] = True + + inputAssets.append({ + 'type': pieces[0], + 'path': pieces[1], + 'options': options + }) + +if not inputAssets: + print("Error: No input assets provided.") + sys.exit(1) + +# Process each asset. +files = [] +for asset in inputAssets: + asset = processAsset(asset) + files.extend(asset['files']) + +# Generate additional files +files.extend(processLanguageList()['files']) + +# Take assets and add to a zip archive. +outputFileName = args.output_file +print(f"Creating output file: {outputFileName}") +with zipfile.ZipFile(outputFileName, 'w') as zipf: + for file in files: + relativeOutputPath = getBuiltAssetsRelativePath(file) + zipf.write(file, arcname=relativeOutputPath) + +# Generate additional headers. +processPaletteList() +processTilesetList() \ No newline at end of file diff --git a/tools/dusk/defs.py b/tools/dusk/defs.py new file mode 100644 index 0000000..9e6182f --- /dev/null +++ b/tools/dusk/defs.py @@ -0,0 +1,20 @@ +from dotenv import load_dotenv +import os +import sys + +current_file_path = os.path.abspath(__file__) +print(current_file_path) + +ASSET_FILE_NAME_MAX_LENGTH = 256 + + +duskDefsPath = os.path.join(os.path.dirname(current_file_path), "..", "..", "src", "duskdefs.env") + +# Ensure the .env file exists +if not os.path.isfile(duskDefsPath): + print(f"Error: .env file not found at {duskDefsPath}") + sys.exit(1) + +load_dotenv(dotenv_path=duskDefsPath) + +defs = {key: os.getenv(key) for key in os.environ.keys()} \ No newline at end of file