Add exec command
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user