Add exec command
This commit is contained in:
@@ -6,5 +6,7 @@
|
|||||||
add_asset(PALETTE first.palette.png)
|
add_asset(PALETTE first.palette.png)
|
||||||
add_asset(IMAGE font_minogram.png type=ALPHA)
|
add_asset(IMAGE font_minogram.png type=ALPHA)
|
||||||
add_asset(IMAGE entities.png type=PALETTIZED)
|
add_asset(IMAGE entities.png type=PALETTIZED)
|
||||||
|
add_asset(CONFIG init.dcf)
|
||||||
|
add_asset(CONFIG test.dcf)
|
||||||
|
|
||||||
# add_asset(TILESET entities.tsx)
|
# add_asset(TILESET entities.tsx)
|
@@ -1 +0,0 @@
|
|||||||
bind w up;
|
|
3
assets/init.dcf
Normal file
3
assets/init.dcf
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
echo "test1";
|
||||||
|
echo "test2";
|
||||||
|
exec "test";
|
1
assets/test.dcf
Normal file
1
assets/test.dcf
Normal file
@@ -0,0 +1 @@
|
|||||||
|
echo "test file"
|
@@ -18,6 +18,9 @@ assetdef_t ASSET_DEFINITIONS[ASSET_TYPE_COUNT] = {
|
|||||||
[ASSET_TYPE_ALPHA_IMAGE] = {
|
[ASSET_TYPE_ALPHA_IMAGE] = {
|
||||||
"DAI", assetAlphaImageLoad, assetAlphaImageDispose
|
"DAI", assetAlphaImageLoad, assetAlphaImageDispose
|
||||||
},
|
},
|
||||||
|
[ASSET_TYPE_CONFIG] = {
|
||||||
|
"DCF", assetConfigLoad, assetConfigDispose
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
errorret_t assetInit(asset_t *asset, const char_t *filename) {
|
errorret_t assetInit(asset_t *asset, const char_t *filename) {
|
||||||
@@ -42,8 +45,6 @@ errorret_t assetInit(asset_t *asset, const char_t *filename) {
|
|||||||
if(asset->file == NULL) errorThrow("Failed to open asset file: %s", filename);
|
if(asset->file == NULL) errorThrow("Failed to open asset file: %s", filename);
|
||||||
zip_fclose(asset->file);
|
zip_fclose(asset->file);
|
||||||
asset->file = NULL;
|
asset->file = NULL;
|
||||||
|
|
||||||
consolePrint("Initialized asset: %s", filename);
|
|
||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include "asset/type/assetpaletteimage.h"
|
#include "asset/type/assetpaletteimage.h"
|
||||||
#include "asset/type/assetalphaimage.h"
|
#include "asset/type/assetalphaimage.h"
|
||||||
|
#include "asset/type/assetconfig.h"
|
||||||
|
|
||||||
#define ASSET_HEADER_SIZE 3
|
#define ASSET_HEADER_SIZE 3
|
||||||
#define ASSET_REFERENCE_COUNT_MAX 8
|
#define ASSET_REFERENCE_COUNT_MAX 8
|
||||||
@@ -31,6 +32,7 @@ typedef enum {
|
|||||||
ASSET_TYPE_UNKNOWN,
|
ASSET_TYPE_UNKNOWN,
|
||||||
ASSET_TYPE_PALETTE_IMAGE,
|
ASSET_TYPE_PALETTE_IMAGE,
|
||||||
ASSET_TYPE_ALPHA_IMAGE,
|
ASSET_TYPE_ALPHA_IMAGE,
|
||||||
|
ASSET_TYPE_CONFIG,
|
||||||
|
|
||||||
ASSET_TYPE_COUNT
|
ASSET_TYPE_COUNT
|
||||||
} assettype_t;
|
} assettype_t;
|
||||||
@@ -46,6 +48,7 @@ typedef struct asset_s {
|
|||||||
union {
|
union {
|
||||||
assetpaletteimage_t paletteImage;
|
assetpaletteimage_t paletteImage;
|
||||||
assetalphaimager_t alphaImage;
|
assetalphaimager_t alphaImage;
|
||||||
|
assetconfig_t config;
|
||||||
};
|
};
|
||||||
} asset_t;
|
} asset_t;
|
||||||
|
|
||||||
|
@@ -33,7 +33,6 @@ errorret_t assetManagerInit(void) {
|
|||||||
// Try open
|
// Try open
|
||||||
ASSET_MANAGER.zip = zip_open(searchPath, ZIP_RDONLY, NULL);
|
ASSET_MANAGER.zip = zip_open(searchPath, ZIP_RDONLY, NULL);
|
||||||
if(ASSET_MANAGER.zip == NULL) continue;
|
if(ASSET_MANAGER.zip == NULL) continue;
|
||||||
consolePrint("Opened asset file: %s", searchPath);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,7 +50,6 @@ void assetManagerUpdate(void) {
|
|||||||
// Check if the asset is loaded
|
// Check if the asset is loaded
|
||||||
if(asset->file != NULL) {
|
if(asset->file != NULL) {
|
||||||
asset->state = ASSET_STATE_LOADED;
|
asset->state = ASSET_STATE_LOADED;
|
||||||
consolePrint("Asset loaded: %s", asset->filename);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
++asset;
|
++asset;
|
||||||
|
@@ -7,5 +7,6 @@
|
|||||||
target_sources(${DUSK_TARGET_NAME}
|
target_sources(${DUSK_TARGET_NAME}
|
||||||
PRIVATE
|
PRIVATE
|
||||||
assetalphaimage.c
|
assetalphaimage.c
|
||||||
|
assetconfig.c
|
||||||
assetpaletteimage.c
|
assetpaletteimage.c
|
||||||
)
|
)
|
61
src/asset/type/assetconfig.c
Normal file
61
src/asset/type/assetconfig.c
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "asset/asset.h"
|
||||||
|
#include "console/console.h"
|
||||||
|
#include "assert/assert.h"
|
||||||
|
|
||||||
|
errorret_t assetConfigLoad(asset_t *asset) {
|
||||||
|
char_t buffer[CONSOLE_LINE_MAX + 1];
|
||||||
|
|
||||||
|
// Read byte by byte.
|
||||||
|
zip_int64_t bytesRead = 0;
|
||||||
|
zip_int64_t totalBytesRead = 0;
|
||||||
|
char_t c;
|
||||||
|
while(1) {
|
||||||
|
bytesRead = zip_fread(
|
||||||
|
asset->file,
|
||||||
|
&c,
|
||||||
|
1
|
||||||
|
);
|
||||||
|
|
||||||
|
if(bytesRead < 0) errorThrow("Failed to read from config asset file");
|
||||||
|
|
||||||
|
// Is byte execute?
|
||||||
|
if(c != ';' && c != '\n' && c != '\r' && bytesRead == 1) {
|
||||||
|
// Not execute, add to buffer.
|
||||||
|
buffer[totalBytesRead] = c;
|
||||||
|
if(++totalBytesRead >= CONSOLE_LINE_MAX) {
|
||||||
|
errorThrow("Config line too long!");
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute buffer.
|
||||||
|
buffer[totalBytesRead] = '\0';
|
||||||
|
consoleExec(buffer);
|
||||||
|
totalBytesRead = 0;
|
||||||
|
|
||||||
|
if(bytesRead == 0) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(totalBytesRead > 0) {
|
||||||
|
// Execute remaining buffer.
|
||||||
|
buffer[totalBytesRead] = '\0';
|
||||||
|
consoleExec(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
errorOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
errorret_t assetConfigExecute(asset_t *asset) {
|
||||||
|
errorOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
errorret_t assetConfigDispose(asset_t *asset) {
|
||||||
|
errorOk();
|
||||||
|
}
|
42
src/asset/type/assetconfig.h
Normal file
42
src/asset/type/assetconfig.h
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "error/error.h"
|
||||||
|
|
||||||
|
typedef struct asset_s asset_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
zip_int64_t pos;
|
||||||
|
zip_int64_t size;
|
||||||
|
} assetconfig_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads a config asset from the given asset structure. The asset must be of
|
||||||
|
* type ASSET_TYPE_CONFIG and must be loaded.
|
||||||
|
*
|
||||||
|
* @param asset The asset to load the config from.
|
||||||
|
* @return An error code.
|
||||||
|
*/
|
||||||
|
errorret_t assetConfigLoad(asset_t *asset);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes the config commands in the given asset. The asset must be of type
|
||||||
|
* ASSET_TYPE_CONFIG and must be loaded.
|
||||||
|
*
|
||||||
|
* @param asset The asset to execute the config from.
|
||||||
|
* @return An error code.
|
||||||
|
*/
|
||||||
|
errorret_t assetConfigExecute(asset_t *asset);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disposes of a config asset, freeing any allocated resources.
|
||||||
|
*
|
||||||
|
* @param asset The asset to dispose of.
|
||||||
|
* @return An error code.
|
||||||
|
*/
|
||||||
|
errorret_t assetConfigDispose(asset_t *asset);
|
@@ -9,10 +9,10 @@
|
|||||||
#include "console/console.h"
|
#include "console/console.h"
|
||||||
|
|
||||||
void cmdEcho(const consolecmdexec_t *exec) {
|
void cmdEcho(const consolecmdexec_t *exec) {
|
||||||
assertTrue(
|
if(exec->argc < 1) {
|
||||||
exec->argc >= 1,
|
consolePrint("Expected 1 argument: <message>");
|
||||||
"echo command requires 1 argument."
|
return;
|
||||||
);
|
}
|
||||||
|
|
||||||
consolePrint("%s", exec->argv[0]);
|
consolePrint("%s", exec->argv[0]);
|
||||||
}
|
}
|
50
src/console/cmd/cmdexec.h
Normal file
50
src/console/cmd/cmdexec.h
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "console/console.h"
|
||||||
|
#include "asset/assetmanager.h"
|
||||||
|
|
||||||
|
void cmdExec(const consolecmdexec_t *exec) {
|
||||||
|
if(exec->argc < 1) {
|
||||||
|
consolePrint("Expected 1 argument: <filename>");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char_t file[FILENAME_MAX];
|
||||||
|
stringCopy(file, exec->argv[0], FILENAME_MAX);
|
||||||
|
if(!stringEndsWith(file, ".dcf")) {
|
||||||
|
sprintf(
|
||||||
|
file,
|
||||||
|
"%s.dcf",
|
||||||
|
exec->argv[0]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
ref_t ref;
|
||||||
|
asset_t asset;
|
||||||
|
errorret_t ret = assetInit(&asset, file);
|
||||||
|
if(ret.code != ERROR_OK) {
|
||||||
|
errorPrint(ret);
|
||||||
|
consolePrint("Failed to load asset %s", file);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = assetLoad(&asset);
|
||||||
|
if(asset.type != ASSET_TYPE_CONFIG) {
|
||||||
|
consolePrint("Asset is not a config: %s", file);
|
||||||
|
assetDispose(&asset);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
assetDispose(&asset);
|
||||||
|
if(ret.code != ERROR_OK) {
|
||||||
|
errorPrint(ret);
|
||||||
|
consolePrint("Failed to load asset %s", file);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
@@ -13,6 +13,7 @@
|
|||||||
#include "console/cmd/cmdecho.h"
|
#include "console/cmd/cmdecho.h"
|
||||||
#include "console/cmd/cmdset.h"
|
#include "console/cmd/cmdset.h"
|
||||||
#include "console/cmd/cmdget.h"
|
#include "console/cmd/cmdget.h"
|
||||||
|
#include "console/cmd/cmdexec.h"
|
||||||
#include "input/input.h"
|
#include "input/input.h"
|
||||||
|
|
||||||
console_t CONSOLE;
|
console_t CONSOLE;
|
||||||
@@ -25,6 +26,7 @@ void consoleInit() {
|
|||||||
CONSOLE.cmdSet = consoleRegCmd("set", cmdSet);
|
CONSOLE.cmdSet = consoleRegCmd("set", cmdSet);
|
||||||
consoleRegCmd("quit", cmdQuit);
|
consoleRegCmd("quit", cmdQuit);
|
||||||
consoleRegCmd("echo", cmdEcho);
|
consoleRegCmd("echo", cmdEcho);
|
||||||
|
consoleRegCmd("exec", cmdExec);
|
||||||
|
|
||||||
consolePrint(" = Dawn Console = ");
|
consolePrint(" = Dawn Console = ");
|
||||||
|
|
||||||
@@ -316,19 +318,36 @@ void consoleUpdate() {
|
|||||||
CONSOLE.visible = !CONSOLE.visible;
|
CONSOLE.visible = !CONSOLE.visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exec pending buffer.
|
// Anything to exec?
|
||||||
for(uint32_t i = 0; i < CONSOLE.execBufferCount; i++) {
|
if(CONSOLE.execBufferCount == 0) {
|
||||||
consolecmdexec_t *exec = &CONSOLE.execBuffer[i];
|
|
||||||
assertNotNull(exec->cmd, "Command execution has no command.");
|
|
||||||
exec->cmd->function(exec);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear the exec buffer
|
|
||||||
CONSOLE.execBufferCount = 0;
|
|
||||||
|
|
||||||
#if CONSOLE_POSIX
|
#if CONSOLE_POSIX
|
||||||
threadMutexUnlock(&CONSOLE.execMutex);
|
threadMutexUnlock(&CONSOLE.execMutex);
|
||||||
#endif
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy the exec buffer, this allows exec command to work
|
||||||
|
consolecmdexec_t execBuffer[CONSOLE_EXEC_BUFFER_MAX];
|
||||||
|
uint32_t execBufferCount = CONSOLE.execBufferCount;
|
||||||
|
memoryCopy(
|
||||||
|
execBuffer,
|
||||||
|
CONSOLE.execBuffer,
|
||||||
|
sizeof(consolecmdexec_t) * execBufferCount
|
||||||
|
);
|
||||||
|
|
||||||
|
// Clear the exec buffer and unlock so new commands can be added while we
|
||||||
|
// process the current ones.
|
||||||
|
CONSOLE.execBufferCount = 0;
|
||||||
|
#if CONSOLE_POSIX
|
||||||
|
threadMutexUnlock(&CONSOLE.execMutex);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Exec pending buffer.
|
||||||
|
for(uint32_t i = 0; i < execBufferCount; i++) {
|
||||||
|
consolecmdexec_t *exec = &execBuffer[i];
|
||||||
|
assertNotNull(exec->cmd, "Command execution has no command.");
|
||||||
|
exec->cmd->function(exec);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void consoleDispose(void) {
|
void consoleDispose(void) {
|
||||||
|
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
engine_t ENGINE;
|
engine_t ENGINE;
|
||||||
|
|
||||||
|
asset_t *outAsset;
|
||||||
|
ref_t outRef;
|
||||||
|
|
||||||
errorret_t engineInit(void) {
|
errorret_t engineInit(void) {
|
||||||
memoryZero(&ENGINE, sizeof(engine_t));
|
memoryZero(&ENGINE, sizeof(engine_t));
|
||||||
@@ -23,12 +25,14 @@ errorret_t engineInit(void) {
|
|||||||
|
|
||||||
// Init systems. Order is important.
|
// Init systems. Order is important.
|
||||||
timeInit();
|
timeInit();
|
||||||
inputInit();
|
|
||||||
consoleInit();
|
consoleInit();
|
||||||
|
inputInit();
|
||||||
errorChain(assetManagerInit());
|
errorChain(assetManagerInit());
|
||||||
errorChain(displayInit());
|
errorChain(displayInit());
|
||||||
rpgInit();
|
rpgInit();
|
||||||
|
|
||||||
|
consoleExec("exec init.dcf");
|
||||||
|
|
||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -2,6 +2,7 @@ import sys
|
|||||||
# from processtileset import processTileset
|
# from processtileset import processTileset
|
||||||
from processimage import processImage
|
from processimage import processImage
|
||||||
from processpalette import processPalette
|
from processpalette import processPalette
|
||||||
|
from processconfig import processConfig
|
||||||
|
|
||||||
processedAssets = []
|
processedAssets = []
|
||||||
|
|
||||||
@@ -17,6 +18,8 @@ def processAsset(asset):
|
|||||||
return processPalette(asset)
|
return processPalette(asset)
|
||||||
elif t == 'image':
|
elif t == 'image':
|
||||||
return processImage(asset)
|
return processImage(asset)
|
||||||
|
elif t == 'config':
|
||||||
|
return processConfig(asset)
|
||||||
# elif t == 'tileset':
|
# elif t == 'tileset':
|
||||||
# return processTileset(asset)
|
# return processTileset(asset)
|
||||||
else:
|
else:
|
||||||
|
44
tools/assetstool/processconfig.py
Normal file
44
tools/assetstool/processconfig.py
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
import os
|
||||||
|
import sys
|
||||||
|
from args import args
|
||||||
|
from assethelpers import getAssetRelativePath
|
||||||
|
|
||||||
|
def processConfig(asset):
|
||||||
|
assetPath = asset['path']
|
||||||
|
print(f"Processing config: {assetPath}")
|
||||||
|
|
||||||
|
# Takes each line, seperates it by either semicolon or newline,
|
||||||
|
# trims whitespace. Then outputs it to a file.
|
||||||
|
with open(assetPath, "r") as f:
|
||||||
|
lines = f.read().replace('\r', '').split('\n')
|
||||||
|
|
||||||
|
commands = []
|
||||||
|
for line in lines:
|
||||||
|
lineCommands = line.split(';')
|
||||||
|
for command in lineCommands:
|
||||||
|
command = command.strip()
|
||||||
|
if command != '':
|
||||||
|
commands.append(command)
|
||||||
|
|
||||||
|
data = bytearray()
|
||||||
|
data.extend(b"DCF") # Dusk Config File
|
||||||
|
for command in commands:
|
||||||
|
# Convert to string and seperate each command with semicolon
|
||||||
|
data.extend(command.encode('utf-8'))
|
||||||
|
data.append(0x3B) # Semicolon
|
||||||
|
|
||||||
|
if len(commands) > 0:
|
||||||
|
data.pop() # Remove last semicolon
|
||||||
|
|
||||||
|
relative = getAssetRelativePath(assetPath)
|
||||||
|
fileNameWithoutExt = os.path.splitext(os.path.basename(assetPath))[0]
|
||||||
|
outputFileRelative = os.path.join(os.path.dirname(relative), f"{fileNameWithoutExt}.dcf")
|
||||||
|
outputFilePath = os.path.join(args.output_assets, outputFileRelative)
|
||||||
|
os.makedirs(os.path.dirname(outputFilePath), exist_ok=True)
|
||||||
|
with open(outputFilePath, "wb") as f:
|
||||||
|
f.write(data)
|
||||||
|
|
||||||
|
outConfig = {
|
||||||
|
"files": [ outputFilePath ],
|
||||||
|
}
|
||||||
|
return outConfig
|
Reference in New Issue
Block a user