Add exec command
This commit is contained in:
@@ -6,5 +6,7 @@
|
||||
add_asset(PALETTE first.palette.png)
|
||||
add_asset(IMAGE font_minogram.png type=ALPHA)
|
||||
add_asset(IMAGE entities.png type=PALETTIZED)
|
||||
add_asset(CONFIG init.dcf)
|
||||
add_asset(CONFIG test.dcf)
|
||||
|
||||
# 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"
|
@@ -15,9 +15,12 @@ assetdef_t ASSET_DEFINITIONS[ASSET_TYPE_COUNT] = {
|
||||
[ASSET_TYPE_PALETTE_IMAGE] = {
|
||||
"DPI", assetPaletteImageLoad, assetPaletteImageDispose
|
||||
},
|
||||
[ASSET_TYPE_ALPHA_IMAGE] = {
|
||||
[ASSET_TYPE_ALPHA_IMAGE] = {
|
||||
"DAI", assetAlphaImageLoad, assetAlphaImageDispose
|
||||
},
|
||||
[ASSET_TYPE_CONFIG] = {
|
||||
"DCF", assetConfigLoad, assetConfigDispose
|
||||
}
|
||||
};
|
||||
|
||||
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);
|
||||
zip_fclose(asset->file);
|
||||
asset->file = NULL;
|
||||
|
||||
consolePrint("Initialized asset: %s", filename);
|
||||
errorOk();
|
||||
}
|
||||
|
||||
|
@@ -12,6 +12,7 @@
|
||||
|
||||
#include "asset/type/assetpaletteimage.h"
|
||||
#include "asset/type/assetalphaimage.h"
|
||||
#include "asset/type/assetconfig.h"
|
||||
|
||||
#define ASSET_HEADER_SIZE 3
|
||||
#define ASSET_REFERENCE_COUNT_MAX 8
|
||||
@@ -31,6 +32,7 @@ typedef enum {
|
||||
ASSET_TYPE_UNKNOWN,
|
||||
ASSET_TYPE_PALETTE_IMAGE,
|
||||
ASSET_TYPE_ALPHA_IMAGE,
|
||||
ASSET_TYPE_CONFIG,
|
||||
|
||||
ASSET_TYPE_COUNT
|
||||
} assettype_t;
|
||||
@@ -46,6 +48,7 @@ typedef struct asset_s {
|
||||
union {
|
||||
assetpaletteimage_t paletteImage;
|
||||
assetalphaimager_t alphaImage;
|
||||
assetconfig_t config;
|
||||
};
|
||||
} asset_t;
|
||||
|
||||
|
@@ -33,7 +33,6 @@ errorret_t assetManagerInit(void) {
|
||||
// Try open
|
||||
ASSET_MANAGER.zip = zip_open(searchPath, ZIP_RDONLY, NULL);
|
||||
if(ASSET_MANAGER.zip == NULL) continue;
|
||||
consolePrint("Opened asset file: %s", searchPath);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -51,7 +50,6 @@ void assetManagerUpdate(void) {
|
||||
// Check if the asset is loaded
|
||||
if(asset->file != NULL) {
|
||||
asset->state = ASSET_STATE_LOADED;
|
||||
consolePrint("Asset loaded: %s", asset->filename);
|
||||
}
|
||||
}
|
||||
++asset;
|
||||
|
@@ -7,5 +7,6 @@
|
||||
target_sources(${DUSK_TARGET_NAME}
|
||||
PRIVATE
|
||||
assetalphaimage.c
|
||||
assetconfig.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"
|
||||
|
||||
void cmdEcho(const consolecmdexec_t *exec) {
|
||||
assertTrue(
|
||||
exec->argc >= 1,
|
||||
"echo command requires 1 argument."
|
||||
);
|
||||
if(exec->argc < 1) {
|
||||
consolePrint("Expected 1 argument: <message>");
|
||||
return;
|
||||
}
|
||||
|
||||
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/cmdset.h"
|
||||
#include "console/cmd/cmdget.h"
|
||||
#include "console/cmd/cmdexec.h"
|
||||
#include "input/input.h"
|
||||
|
||||
console_t CONSOLE;
|
||||
@@ -25,6 +26,7 @@ void consoleInit() {
|
||||
CONSOLE.cmdSet = consoleRegCmd("set", cmdSet);
|
||||
consoleRegCmd("quit", cmdQuit);
|
||||
consoleRegCmd("echo", cmdEcho);
|
||||
consoleRegCmd("exec", cmdExec);
|
||||
|
||||
consolePrint(" = Dawn Console = ");
|
||||
|
||||
@@ -316,19 +318,36 @@ void consoleUpdate() {
|
||||
CONSOLE.visible = !CONSOLE.visible;
|
||||
}
|
||||
|
||||
// Exec pending buffer.
|
||||
for(uint32_t i = 0; i < CONSOLE.execBufferCount; i++) {
|
||||
consolecmdexec_t *exec = &CONSOLE.execBuffer[i];
|
||||
assertNotNull(exec->cmd, "Command execution has no command.");
|
||||
exec->cmd->function(exec);
|
||||
// Anything to exec?
|
||||
if(CONSOLE.execBufferCount == 0) {
|
||||
#if CONSOLE_POSIX
|
||||
threadMutexUnlock(&CONSOLE.execMutex);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
// Clear the exec buffer
|
||||
CONSOLE.execBufferCount = 0;
|
||||
// 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) {
|
||||
|
@@ -16,6 +16,8 @@
|
||||
|
||||
engine_t ENGINE;
|
||||
|
||||
asset_t *outAsset;
|
||||
ref_t outRef;
|
||||
|
||||
errorret_t engineInit(void) {
|
||||
memoryZero(&ENGINE, sizeof(engine_t));
|
||||
@@ -23,12 +25,14 @@ errorret_t engineInit(void) {
|
||||
|
||||
// Init systems. Order is important.
|
||||
timeInit();
|
||||
inputInit();
|
||||
consoleInit();
|
||||
inputInit();
|
||||
errorChain(assetManagerInit());
|
||||
errorChain(displayInit());
|
||||
rpgInit();
|
||||
|
||||
consoleExec("exec init.dcf");
|
||||
|
||||
errorOk();
|
||||
}
|
||||
|
||||
|
@@ -2,6 +2,7 @@ import sys
|
||||
# from processtileset import processTileset
|
||||
from processimage import processImage
|
||||
from processpalette import processPalette
|
||||
from processconfig import processConfig
|
||||
|
||||
processedAssets = []
|
||||
|
||||
@@ -17,6 +18,8 @@ def processAsset(asset):
|
||||
return processPalette(asset)
|
||||
elif t == 'image':
|
||||
return processImage(asset)
|
||||
elif t == 'config':
|
||||
return processConfig(asset)
|
||||
# elif t == 'tileset':
|
||||
# return processTileset(asset)
|
||||
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