Working on cmd bind
This commit is contained in:
@@ -1,15 +0,0 @@
|
|||||||
# 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
|
|
||||||
console.c
|
|
||||||
consolecmd.c
|
|
||||||
consolevar.c
|
|
||||||
)
|
|
||||||
|
|
||||||
# Subdirectories
|
|
||||||
add_subdirectory(cmd)
|
|
@@ -1,9 +0,0 @@
|
|||||||
# 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
|
|
||||||
)
|
|
@@ -1,18 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2025 Dominic Masters
|
|
||||||
*
|
|
||||||
* This software is released under the MIT License.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include "console/console.h"
|
|
||||||
|
|
||||||
void cmdEcho(const consolecmdexec_t *exec) {
|
|
||||||
assertTrue(
|
|
||||||
exec->argc >= 1,
|
|
||||||
"echo command requires 1 argument."
|
|
||||||
);
|
|
||||||
|
|
||||||
consolePrint("%s", exec->argv[0]);
|
|
||||||
}
|
|
@@ -1,25 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2025 Dominic Masters
|
|
||||||
*
|
|
||||||
* This software is released under the MIT License.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include "console/console.h"
|
|
||||||
|
|
||||||
void cmdGet(const consolecmdexec_t *exec) {
|
|
||||||
assertTrue(
|
|
||||||
exec->argc >= 1,
|
|
||||||
"Get command requires 1 argument."
|
|
||||||
);
|
|
||||||
|
|
||||||
for(uint32_t i = 0; i < CONSOLE.variableCount; i++) {
|
|
||||||
consolevar_t *var = &CONSOLE.variables[i];
|
|
||||||
if(stringCompare(var->name, exec->argv[0]) != 0) continue;
|
|
||||||
consolePrint("%s", var->value);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
consolePrint("Error: Variable '%s' not found.", exec->argv[0]);
|
|
||||||
}
|
|
@@ -1,15 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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 "game.h"
|
|
||||||
|
|
||||||
void cmdQuit(const consolecmdexec_t *exec) {
|
|
||||||
consolePrint("Quitting application...");
|
|
||||||
GAME.running = false;
|
|
||||||
}
|
|
@@ -1,27 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2025 Dominic Masters
|
|
||||||
*
|
|
||||||
* This software is released under the MIT License.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include "console/console.h"
|
|
||||||
|
|
||||||
void cmdSet(const consolecmdexec_t *exec) {
|
|
||||||
assertTrue(exec->argc >= 2, "set command requires 2 arguments.");
|
|
||||||
|
|
||||||
for(uint32_t i = 0; i < CONSOLE.variableCount; i++) {
|
|
||||||
consolevar_t *var = &CONSOLE.variables[i];
|
|
||||||
if(stringCompare(var->name, exec->argv[0]) != 0) continue;
|
|
||||||
consoleVarSetValue(var, exec->argv[1]);
|
|
||||||
consolePrint("%s %s", var->name, var->value);
|
|
||||||
for(i = 0; i < var->eventCount; i++) {
|
|
||||||
assertNotNull(var->events[i], "Event is NULL");
|
|
||||||
var->events[i](var);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
consolePrint("Error: Variable '%s' not found.", exec->argv[0]);
|
|
||||||
}
|
|
@@ -1,329 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2025 Dominic Masters
|
|
||||||
*
|
|
||||||
* This software is released under the MIT License.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "console.h"
|
|
||||||
#include "assert/assert.h"
|
|
||||||
#include "util/memory.h"
|
|
||||||
#include "util/string.h"
|
|
||||||
#include "console/cmd/cmdquit.h"
|
|
||||||
#include "console/cmd/cmdecho.h"
|
|
||||||
#include "console/cmd/cmdset.h"
|
|
||||||
#include "console/cmd/cmdget.h"
|
|
||||||
|
|
||||||
#include "input.h"
|
|
||||||
|
|
||||||
console_t CONSOLE;
|
|
||||||
|
|
||||||
void consoleInit() {
|
|
||||||
memoryZero(&CONSOLE, sizeof(console_t));
|
|
||||||
|
|
||||||
// Register the get and set command.
|
|
||||||
CONSOLE.cmdGet = consoleRegCmd("get", cmdGet);
|
|
||||||
CONSOLE.cmdSet = consoleRegCmd("set", cmdSet);
|
|
||||||
consoleRegCmd("quit", cmdQuit);
|
|
||||||
consoleRegCmd("echo", cmdEcho);
|
|
||||||
|
|
||||||
consolePrint(" = Dawn Console = ");
|
|
||||||
}
|
|
||||||
|
|
||||||
consolecmd_t * consoleRegCmd(const char_t *name, consolecmdfunc_t function) {
|
|
||||||
consolecmd_t *cmd = &CONSOLE.commands[CONSOLE.commandCount++];
|
|
||||||
consoleCmdInit(cmd, name, function);
|
|
||||||
return cmd;
|
|
||||||
}
|
|
||||||
|
|
||||||
consolevar_t * consoleRegVar(
|
|
||||||
const char_t *name,
|
|
||||||
const char_t *value,
|
|
||||||
consolevarchanged_t event
|
|
||||||
) {
|
|
||||||
consolevar_t *var = &CONSOLE.variables[CONSOLE.variableCount++];
|
|
||||||
consoleVarInitListener(var, name, value, event);
|
|
||||||
return var;
|
|
||||||
}
|
|
||||||
|
|
||||||
void consolePrint(const char_t *message, ...) {
|
|
||||||
char_t buffer[CONSOLE_LINE_MAX];
|
|
||||||
|
|
||||||
va_list args;
|
|
||||||
va_start(args, message);
|
|
||||||
int32_t len = stringFormatVA(buffer, CONSOLE_LINE_MAX, message, args);
|
|
||||||
va_end(args);
|
|
||||||
|
|
||||||
// Move all lines back
|
|
||||||
memoryMove(
|
|
||||||
CONSOLE.line[0],
|
|
||||||
CONSOLE.line[1],
|
|
||||||
(CONSOLE_HISTORY_MAX - 1) * CONSOLE_LINE_MAX
|
|
||||||
);
|
|
||||||
|
|
||||||
// Copy the new line
|
|
||||||
memoryCopy(
|
|
||||||
CONSOLE.line[CONSOLE_HISTORY_MAX - 1],
|
|
||||||
buffer,
|
|
||||||
len + 1
|
|
||||||
);
|
|
||||||
printf("%s\n", buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void consoleExec(const char_t *line) {
|
|
||||||
assertNotNull(line, "line must not be NULL");
|
|
||||||
assertTrue(
|
|
||||||
CONSOLE.execBufferCount < CONSOLE_EXEC_BUFFER_MAX,
|
|
||||||
"Too many commands in the buffer."
|
|
||||||
);
|
|
||||||
|
|
||||||
char_t buffer[CONSOLE_LINE_MAX];
|
|
||||||
size_t i = 0, j = 0;
|
|
||||||
char_t c;
|
|
||||||
consoleexecstate_t state = CONSOLE_EXEC_STATE_INITIAL;
|
|
||||||
consolecmdexec_t *exec = NULL;
|
|
||||||
|
|
||||||
while(state != CONSOLE_EXEC_STATE_FULLY_PARSED) {
|
|
||||||
c = line[i];
|
|
||||||
|
|
||||||
switch(state) {
|
|
||||||
case CONSOLE_EXEC_STATE_INITIAL:
|
|
||||||
assertTrue(j == 0, "Buffer not empty?");
|
|
||||||
|
|
||||||
if(c == '\0') {
|
|
||||||
state = CONSOLE_EXEC_STATE_FULLY_PARSED;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(stringIsWhitespace(c) || c == ';') {
|
|
||||||
i++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
state = CONSOLE_EXEC_STATE_PARSE_CMD;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONSOLE_EXEC_STATE_PARSE_CMD:
|
|
||||||
if(stringIsWhitespace(c) || c == '\0' || c == ';') {
|
|
||||||
state = CONSOLE_EXEC_STATE_CMD_PARSED;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(c == '"') {
|
|
||||||
// Can't handle quotes within the command.
|
|
||||||
consolePrint("Invalid command");
|
|
||||||
while(c != '\0' && c != ';') c = line[++i];
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer[j++] = c;
|
|
||||||
i++;
|
|
||||||
|
|
||||||
if(j >= CONSOLE_LINE_MAX) {
|
|
||||||
consolePrint("Command too long");
|
|
||||||
state = CONSOLE_EXEC_STATE_FULLY_PARSED;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONSOLE_EXEC_STATE_CMD_PARSED:
|
|
||||||
if(j == 0) {
|
|
||||||
state = CONSOLE_EXEC_STATE_INITIAL;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create exec
|
|
||||||
assertNull(exec, "Existing command parsing?");
|
|
||||||
|
|
||||||
exec = &CONSOLE.execBuffer[CONSOLE.execBufferCount];
|
|
||||||
memoryZero(exec, sizeof(consolecmdexec_t));
|
|
||||||
|
|
||||||
buffer[j] = '\0';
|
|
||||||
stringCopy(exec->command, buffer, CONSOLE_LINE_MAX);
|
|
||||||
state = CONSOLE_EXEC_STATE_FIND_ARG;
|
|
||||||
|
|
||||||
j = 0;// Free up buffer
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONSOLE_EXEC_STATE_FIND_ARG:
|
|
||||||
if(c == '\0' || c == ';') {
|
|
||||||
state = CONSOLE_EXEC_STATE_CMD_FINISHED;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(stringIsWhitespace(c)) {
|
|
||||||
i++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(c == '"') {
|
|
||||||
state = CONSOLE_EXEC_STATE_PARSE_ARG_QUOTED;
|
|
||||||
i++;
|
|
||||||
} else {
|
|
||||||
state = CONSOLE_EXEC_STATE_PARSE_ARG;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONSOLE_EXEC_STATE_PARSE_ARG:
|
|
||||||
if(stringIsWhitespace(c) || c == '\0' || c == ';') {
|
|
||||||
state = CONSOLE_EXEC_STATE_ARG_PARSED;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer[j++] = c;
|
|
||||||
i++;
|
|
||||||
|
|
||||||
if(j >= CONSOLE_LINE_MAX) {
|
|
||||||
consolePrint("Arg too long");
|
|
||||||
state = CONSOLE_EXEC_STATE_FULLY_PARSED;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONSOLE_EXEC_STATE_PARSE_ARG_QUOTED:
|
|
||||||
if(c == '"') {
|
|
||||||
state = CONSOLE_EXEC_STATE_ARG_PARSED;
|
|
||||||
i++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(c == '\0' || c == ';') {
|
|
||||||
consolePrint("Unterminated quote");
|
|
||||||
state = CONSOLE_EXEC_STATE_FULLY_PARSED;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(c == '\\') {
|
|
||||||
c = line[++i];
|
|
||||||
|
|
||||||
if(c == '\0' || c == ';') {
|
|
||||||
consolePrint("Unterminated quote");
|
|
||||||
state = CONSOLE_EXEC_STATE_FULLY_PARSED;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer[j++] = c;
|
|
||||||
i++;
|
|
||||||
|
|
||||||
if(j >= CONSOLE_LINE_MAX) {
|
|
||||||
consolePrint("Arg too long");
|
|
||||||
state = CONSOLE_EXEC_STATE_FULLY_PARSED;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONSOLE_EXEC_STATE_ARG_PARSED:
|
|
||||||
buffer[j] = '\0';
|
|
||||||
stringCopy(exec->argv[exec->argc++], buffer, CONSOLE_LINE_MAX);
|
|
||||||
state = CONSOLE_EXEC_STATE_FIND_ARG;
|
|
||||||
j = 0;// Free up buffer
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONSOLE_EXEC_STATE_CMD_FINISHED:
|
|
||||||
assertNotNull(exec, "No command found?");
|
|
||||||
|
|
||||||
// Now, is there a command that matches?
|
|
||||||
for(uint32_t k = 0; k < CONSOLE.commandCount; k++) {
|
|
||||||
consolecmd_t *cmd = &CONSOLE.commands[k];
|
|
||||||
if(stringCompare(cmd->name, exec->command) != 0) continue;
|
|
||||||
exec->cmd = cmd;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(exec->cmd == NULL) {
|
|
||||||
// Command wasn't found, is there a variable that matches?
|
|
||||||
for(uint32_t k = 0; k < CONSOLE.variableCount; k++) {
|
|
||||||
consolevar_t *var = &CONSOLE.variables[k];
|
|
||||||
if(stringCompare(var->name, exec->command) != 0) continue;
|
|
||||||
|
|
||||||
// Matching variable found, is this a GET or a SET?
|
|
||||||
if(exec->argc == 0) {
|
|
||||||
exec->cmd = CONSOLE.cmdGet;
|
|
||||||
stringCopy(exec->argv[0], exec->command, CONSOLE_LINE_MAX);
|
|
||||||
exec->argc = 1;
|
|
||||||
} else {
|
|
||||||
exec->cmd = CONSOLE.cmdSet;
|
|
||||||
stringCopy(exec->argv[1], exec->argv[0], CONSOLE_LINE_MAX);
|
|
||||||
stringCopy(exec->argv[0], exec->command, CONSOLE_LINE_MAX);
|
|
||||||
exec->argc = 2;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(exec->cmd == NULL) {
|
|
||||||
consolePrint("Command not found", exec->command);
|
|
||||||
exec = NULL;
|
|
||||||
state = CONSOLE_EXEC_STATE_INITIAL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prep for next command.
|
|
||||||
exec = NULL;
|
|
||||||
state = CONSOLE_EXEC_STATE_INITIAL;
|
|
||||||
CONSOLE.execBufferCount++;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
assertUnreachable("Invalid state.");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// May move these later
|
|
||||||
void consoleUpdate() {
|
|
||||||
if(inputPressed(INPUT_BIND_CONSOLE)) {
|
|
||||||
CONSOLE.visible = !CONSOLE.visible;
|
|
||||||
if(CONSOLE.visible) {
|
|
||||||
consolePrint("Console opened.");
|
|
||||||
} else {
|
|
||||||
consolePrint("Console closed.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// #if KEYBOARD_SUPPORT == 1
|
|
||||||
// uint8_t key;
|
|
||||||
// while((key = inputKeyboardPop()) != 0) {
|
|
||||||
// printf("Key pressed: %c\n", key);
|
|
||||||
// switch(key) {
|
|
||||||
// case 0:
|
|
||||||
// break;
|
|
||||||
|
|
||||||
// case INPUT_KEY_ENTER:
|
|
||||||
// consoleExec(CONSOLE.inputBuffer);
|
|
||||||
// CONSOLE.inputIndex = 0;
|
|
||||||
// CONSOLE.inputBuffer[0] = '\0';
|
|
||||||
// break;
|
|
||||||
|
|
||||||
// case INPUT_KEY_BACKSPACE:
|
|
||||||
// if(CONSOLE.inputIndex > 0) {
|
|
||||||
// CONSOLE.inputIndex--;
|
|
||||||
// CONSOLE.inputBuffer[CONSOLE.inputIndex] = '\0';
|
|
||||||
// }
|
|
||||||
// break;
|
|
||||||
|
|
||||||
// default:
|
|
||||||
// if(
|
|
||||||
// key >= INPUT_KEY_ASCII_START && key <= INPUT_KEY_ASCII_END &&
|
|
||||||
// CONSOLE.inputIndex < CONSOLE_LINE_MAX - 1
|
|
||||||
// ) {
|
|
||||||
// CONSOLE.inputBuffer[CONSOLE.inputIndex++] = key;
|
|
||||||
// CONSOLE.inputBuffer[CONSOLE.inputIndex] = '\0';
|
|
||||||
// }
|
|
||||||
// break;
|
|
||||||
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
// Clear the exec buffer
|
|
||||||
CONSOLE.execBufferCount = 0;
|
|
||||||
}
|
|
@@ -1,106 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2025 Dominic Masters
|
|
||||||
*
|
|
||||||
* This software is released under the MIT License.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include "consolevar.h"
|
|
||||||
#include "consolecmd.h"
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
CONSOLE_EXEC_STATE_INITIAL,
|
|
||||||
CONSOLE_EXEC_STATE_PARSE_CMD,
|
|
||||||
CONSOLE_EXEC_STATE_CMD_PARSED,
|
|
||||||
|
|
||||||
CONSOLE_EXEC_STATE_FIND_ARG,
|
|
||||||
CONSOLE_EXEC_STATE_PARSE_ARG,
|
|
||||||
CONSOLE_EXEC_STATE_PARSE_ARG_QUOTED,
|
|
||||||
CONSOLE_EXEC_STATE_ARG_PARSED,
|
|
||||||
|
|
||||||
CONSOLE_EXEC_STATE_CMD_FINISHED,
|
|
||||||
CONSOLE_EXEC_STATE_FULLY_PARSED
|
|
||||||
} consoleexecstate_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
consolecmd_t commands[CONSOLE_COMMANDS_MAX];
|
|
||||||
uint32_t commandCount;
|
|
||||||
|
|
||||||
consolevar_t variables[CONSOLE_VARIABLES_MAX];
|
|
||||||
uint32_t variableCount;
|
|
||||||
|
|
||||||
char_t line[CONSOLE_HISTORY_MAX][CONSOLE_LINE_MAX];
|
|
||||||
|
|
||||||
consolecmdexec_t execBuffer[CONSOLE_EXEC_BUFFER_MAX];
|
|
||||||
uint32_t execBufferCount;
|
|
||||||
|
|
||||||
consolecmd_t *cmdGet;
|
|
||||||
consolecmd_t *cmdSet;
|
|
||||||
|
|
||||||
bool_t visible;
|
|
||||||
|
|
||||||
// May move these later
|
|
||||||
// #if KEYBOARD_SUPPORT == 1
|
|
||||||
// char_t inputBuffer[CONSOLE_LINE_MAX];
|
|
||||||
// int32_t inputIndex;
|
|
||||||
// #endif
|
|
||||||
} console_t;
|
|
||||||
|
|
||||||
extern console_t CONSOLE;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes the console.
|
|
||||||
*/
|
|
||||||
void consoleInit();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers a console command.
|
|
||||||
*
|
|
||||||
* @param name The name of the command.
|
|
||||||
* @param function The function to execute when the command is called.
|
|
||||||
* @return The registered command.
|
|
||||||
*/
|
|
||||||
consolecmd_t * consoleRegCmd(const char_t *name, consolecmdfunc_t function);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers a console variable.
|
|
||||||
*
|
|
||||||
* @param name The name of the variable.
|
|
||||||
* @param value The initial value of the variable.
|
|
||||||
* @param event The event to register.
|
|
||||||
* @return The registered variable.
|
|
||||||
*/
|
|
||||||
consolevar_t * consoleRegVar(
|
|
||||||
const char_t *name,
|
|
||||||
const char_t *value,
|
|
||||||
consolevarchanged_t event
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the value of a console variable.
|
|
||||||
*
|
|
||||||
* @param name The name of the variable.
|
|
||||||
* @param value The new value of the variable.
|
|
||||||
*/
|
|
||||||
void consolePrint(
|
|
||||||
const char_t *message,
|
|
||||||
...
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executes a console command.
|
|
||||||
*
|
|
||||||
* @param line The line to execute.
|
|
||||||
*/
|
|
||||||
void consoleExec(const char_t *line);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Processes the console's pending commands.
|
|
||||||
*/
|
|
||||||
void consoleUpdate();
|
|
||||||
|
|
||||||
void cmdGet(const consolecmdexec_t *exec);
|
|
||||||
void cmdSet(const consolecmdexec_t *exec);
|
|
||||||
void cmdEcho(const consolecmdexec_t *exec);
|
|
||||||
void cmdQuit(const consolecmdexec_t *exec);
|
|
@@ -1,27 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2025 Dominic Masters
|
|
||||||
*
|
|
||||||
* This software is released under the MIT License.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "consolecmd.h"
|
|
||||||
#include "assert/assert.h"
|
|
||||||
#include "util/memory.h"
|
|
||||||
#include "util/string.h"
|
|
||||||
|
|
||||||
void consoleCmdInit(
|
|
||||||
consolecmd_t *cmd,
|
|
||||||
const char_t *name,
|
|
||||||
consolecmdfunc_t function
|
|
||||||
) {
|
|
||||||
assertNotNull(cmd, "Command is NULL.");
|
|
||||||
assertNotNull(name, "Name is NULL.");
|
|
||||||
assertNotNull(function, "Function is NULL.");
|
|
||||||
assertStrLenMin(name, 1, "Name is empty.");
|
|
||||||
assertStrLenMax(name, CONSOLE_CMD_NAME_MAX, "Name is too long.");
|
|
||||||
|
|
||||||
memoryZero(cmd, sizeof(consolecmd_t));
|
|
||||||
stringCopy(cmd->name, name, CONSOLE_CMD_NAME_MAX);
|
|
||||||
cmd->function = function;
|
|
||||||
}
|
|
@@ -1,39 +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"
|
|
||||||
#include "consoledefs.h"
|
|
||||||
|
|
||||||
typedef struct consolecmd_s consolecmd_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
consolecmd_t *cmd;
|
|
||||||
char_t command[CONSOLE_LINE_MAX];
|
|
||||||
char_t argv[CONSOLE_CMD_ARGC_MAX][CONSOLE_LINE_MAX];
|
|
||||||
uint32_t argc;
|
|
||||||
} consolecmdexec_t;
|
|
||||||
|
|
||||||
typedef void (*consolecmdfunc_t)(const consolecmdexec_t *exec);
|
|
||||||
|
|
||||||
typedef struct consolecmd_s {
|
|
||||||
char_t name[CONSOLE_CMD_NAME_MAX];
|
|
||||||
consolecmdfunc_t function;
|
|
||||||
} consolecmd_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes a console command.
|
|
||||||
*
|
|
||||||
* @param cmd Pointer to the console command.
|
|
||||||
* @param name The name of the command.
|
|
||||||
* @param function The function to execute when the command is called.
|
|
||||||
*/
|
|
||||||
void consoleCmdInit(
|
|
||||||
consolecmd_t *cmd,
|
|
||||||
const char_t *name,
|
|
||||||
consolecmdfunc_t function
|
|
||||||
);
|
|
@@ -1,21 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2025 Dominic Masters
|
|
||||||
*
|
|
||||||
* This software is released under the MIT License.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#define CONSOLE_CMD_NAME_MAX 32
|
|
||||||
#define CONSOLE_CMD_ARGC_MAX 16
|
|
||||||
|
|
||||||
#define CONSOLE_COMMANDS_MAX 128
|
|
||||||
#define CONSOLE_VARIABLES_MAX 128
|
|
||||||
#define CONSOLE_LINE_MAX 256
|
|
||||||
#define CONSOLE_HISTORY_MAX 32
|
|
||||||
#define CONSOLE_EXEC_BUFFER_MAX 16
|
|
||||||
|
|
||||||
#define CONSOLE_VAR_NAME_MAX 32
|
|
||||||
#define CONSOLE_VAR_VALUE_MAX 128
|
|
||||||
#define CONSOLE_VAR_EVENTS_MAX 8
|
|
@@ -1,64 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2025 Dominic Masters
|
|
||||||
*
|
|
||||||
* This software is released under the MIT License.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "consolevar.h"
|
|
||||||
#include "assert/assert.h"
|
|
||||||
#include "util/memory.h"
|
|
||||||
#include "util/string.h"
|
|
||||||
|
|
||||||
void consoleVarInit(
|
|
||||||
consolevar_t *var,
|
|
||||||
const char_t *name,
|
|
||||||
const char_t *value
|
|
||||||
) {
|
|
||||||
assertNotNull(var, "var must not be NULL");
|
|
||||||
assertNotNull(name, "name must not be NULL");
|
|
||||||
assertNotNull(value, "value must not be NULL");
|
|
||||||
|
|
||||||
assertStrLenMin(name, 1, "name must not be empty");
|
|
||||||
assertStrLenMax(name, CONSOLE_VAR_NAME_MAX, "name is too long");
|
|
||||||
assertStrLenMax(value, CONSOLE_VAR_VALUE_MAX, "value is too long");
|
|
||||||
|
|
||||||
memoryZero(var, sizeof(consolevar_t));
|
|
||||||
stringCopy(var->name, name, CONSOLE_VAR_NAME_MAX);
|
|
||||||
stringCopy(var->value, value, CONSOLE_VAR_VALUE_MAX);
|
|
||||||
}
|
|
||||||
|
|
||||||
void consoleVarInitListener(
|
|
||||||
consolevar_t *var,
|
|
||||||
const char_t *name,
|
|
||||||
const char_t *value,
|
|
||||||
consolevarchanged_t event
|
|
||||||
) {
|
|
||||||
consoleVarInit(var, name, value);
|
|
||||||
if(event) consoleVarListen(var, event);
|
|
||||||
}
|
|
||||||
|
|
||||||
void consoleVarSetValue(consolevar_t *var, const char_t *value) {
|
|
||||||
assertNotNull(var, "var must not be NULL");
|
|
||||||
assertNotNull(value, "value must not be NULL");
|
|
||||||
assertStrLenMax(value, CONSOLE_VAR_VALUE_MAX, "value is too long");
|
|
||||||
|
|
||||||
stringCopy(var->value, value, CONSOLE_VAR_VALUE_MAX);
|
|
||||||
|
|
||||||
uint8_t i = 0;
|
|
||||||
while (i < var->eventCount) {
|
|
||||||
var->events[i](var);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void consoleVarListen(consolevar_t *var, consolevarchanged_t event) {
|
|
||||||
assertNotNull(var, "var must not be NULL");
|
|
||||||
assertNotNull(event, "event must not be NULL");
|
|
||||||
assertTrue(
|
|
||||||
var->eventCount < CONSOLE_VAR_EVENTS_MAX,
|
|
||||||
"Event count is too high"
|
|
||||||
);
|
|
||||||
var->events[var->eventCount++] = event;
|
|
||||||
}
|
|
||||||
|
|
@@ -1,65 +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"
|
|
||||||
#include "consoledefs.h"
|
|
||||||
|
|
||||||
typedef struct consolevar_s consolevar_t;
|
|
||||||
|
|
||||||
typedef void (*consolevarchanged_t)(const consolevar_t *var);
|
|
||||||
|
|
||||||
typedef struct consolevar_s {
|
|
||||||
char_t name[CONSOLE_VAR_NAME_MAX];
|
|
||||||
char_t value[CONSOLE_VAR_VALUE_MAX];
|
|
||||||
consolevarchanged_t events[CONSOLE_VAR_EVENTS_MAX];
|
|
||||||
uint8_t eventCount;
|
|
||||||
} consolevar_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes a console variable.
|
|
||||||
*
|
|
||||||
* @param var Pointer to the console variable.
|
|
||||||
* @param name The name of the variable.
|
|
||||||
* @param value The initial value of the variable.
|
|
||||||
*/
|
|
||||||
void consoleVarInit(
|
|
||||||
consolevar_t *var,
|
|
||||||
const char_t *name,
|
|
||||||
const char_t *value
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes a console variable with a listener.
|
|
||||||
*
|
|
||||||
* @param var Pointer to the console variable.
|
|
||||||
* @param name The name of the variable.
|
|
||||||
* @param value The initial value of the variable.
|
|
||||||
* @param event The event to register.
|
|
||||||
*/
|
|
||||||
void consoleVarInitListener(
|
|
||||||
consolevar_t *var,
|
|
||||||
const char_t *name,
|
|
||||||
const char_t *value,
|
|
||||||
consolevarchanged_t event
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the value of a console variable.
|
|
||||||
*
|
|
||||||
* @param var Pointer to the console variable.
|
|
||||||
* @param value The new value of the variable.
|
|
||||||
*/
|
|
||||||
void consoleVarSetValue(consolevar_t *var, const char_t *value);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers an event to be called when the value of a console variable changes.
|
|
||||||
*
|
|
||||||
* @param var Pointer to the console variable.
|
|
||||||
* @param event The event to register.
|
|
||||||
*/
|
|
||||||
void consoleVarListen(consolevar_t *var, consolevarchanged_t event);
|
|
@@ -7,6 +7,4 @@ 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 init.dcf)
|
||||||
add_asset(CONFIG test.dcf)
|
|
||||||
|
|
||||||
# add_asset(TILESET entities.tsx)
|
# add_asset(TILESET entities.tsx)
|
@@ -1,3 +1 @@
|
|||||||
echo "test1";
|
bind ` console;
|
||||||
echo "test2";
|
|
||||||
exec "test";
|
|
@@ -1 +0,0 @@
|
|||||||
echo "test file"
|
|
35
src/console/cmd/cmdbind.h
Normal file
35
src/console/cmd/cmdbind.h
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
/**
|
||||||
|
* 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 "input/input.h"
|
||||||
|
|
||||||
|
void cmdBind(const consolecmdexec_t *exec) {
|
||||||
|
if(exec->argc < 1) {
|
||||||
|
consolePrint("Expected 1 argument: <key> <command]");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(exec->argc == 1) {
|
||||||
|
consolePrint("TODO: Show binds");
|
||||||
|
// consolePrint("Current binds:");
|
||||||
|
// inputbinddata_t *data = INPUT.binds;
|
||||||
|
// do {
|
||||||
|
|
||||||
|
// } while(data < INPUT.binds + INPUT_BIND_COUNT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
inputbind_t bind = inputBindGetByName(exec->argv[1]);
|
||||||
|
if(bind == INPUT_BIND_COUNT) {
|
||||||
|
consolePrint("Unknown bind \"%s\"", exec->argv[1]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
consolePrint("test");
|
||||||
|
}
|
@@ -14,6 +14,7 @@
|
|||||||
#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 "console/cmd/cmdexec.h"
|
||||||
|
#include "console/cmd/cmdbind.h"
|
||||||
#include "input/input.h"
|
#include "input/input.h"
|
||||||
|
|
||||||
console_t CONSOLE;
|
console_t CONSOLE;
|
||||||
@@ -27,6 +28,7 @@ void consoleInit() {
|
|||||||
consoleRegCmd("quit", cmdQuit);
|
consoleRegCmd("quit", cmdQuit);
|
||||||
consoleRegCmd("echo", cmdEcho);
|
consoleRegCmd("echo", cmdEcho);
|
||||||
consoleRegCmd("exec", cmdExec);
|
consoleRegCmd("exec", cmdExec);
|
||||||
|
consoleRegCmd("bind", cmdBind);
|
||||||
|
|
||||||
consolePrint(" = Dawn Console = ");
|
consolePrint(" = Dawn Console = ");
|
||||||
|
|
||||||
@@ -284,7 +286,7 @@ void consoleExec(const char_t *line) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(exec->cmd == NULL) {
|
if(exec->cmd == NULL) {
|
||||||
consolePrint("Command not found", exec->command);
|
consolePrint("Command \"%s\" not found", exec->command);
|
||||||
exec = NULL;
|
exec = NULL;
|
||||||
state = CONSOLE_EXEC_STATE_INITIAL;
|
state = CONSOLE_EXEC_STATE_INITIAL;
|
||||||
break;
|
break;
|
||||||
|
@@ -8,6 +8,17 @@
|
|||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "assert/assert.h"
|
#include "assert/assert.h"
|
||||||
#include "util/memory.h"
|
#include "util/memory.h"
|
||||||
|
#include "util/string.h"
|
||||||
|
|
||||||
|
char_t INPUT_BIND_NAMES[INPUT_BIND_COUNT][16] = {
|
||||||
|
[INPUT_BIND_UP] = "UP",
|
||||||
|
[INPUT_BIND_DOWN] = "DOWN",
|
||||||
|
[INPUT_BIND_LEFT] = "LEFT",
|
||||||
|
[INPUT_BIND_RIGHT] = "RIGHT",
|
||||||
|
[INPUT_BIND_ACCEPT] = "ACCEPT",
|
||||||
|
[INPUT_BIND_CANCEL] = "CANCEL",
|
||||||
|
[INPUT_BIND_CONSOLE] = "CONSOLE"
|
||||||
|
};
|
||||||
|
|
||||||
input_t INPUT;
|
input_t INPUT;
|
||||||
|
|
||||||
@@ -72,4 +83,14 @@ bool_t inputPressed(const inputbind_t bind) {
|
|||||||
|
|
||||||
bool_t inputReleased(const inputbind_t bind) {
|
bool_t inputReleased(const inputbind_t bind) {
|
||||||
return !inputIsDown(bind) && inputWasDown(bind);
|
return !inputIsDown(bind) && inputWasDown(bind);
|
||||||
|
}
|
||||||
|
|
||||||
|
inputbind_t inputBindGetByName(const char_t *name) {
|
||||||
|
assertNotNull(name, "name must not be NULL");
|
||||||
|
for(inputbind_t i = 0; i < INPUT_BIND_COUNT; i++) {
|
||||||
|
if(stringCompareInsensitive(INPUT_BIND_NAMES[i], name) == 0) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return INPUT_BIND_COUNT;
|
||||||
}
|
}
|
@@ -64,6 +64,7 @@ typedef struct {
|
|||||||
inputbinddata_t binds[INPUT_BIND_COUNT];
|
inputbinddata_t binds[INPUT_BIND_COUNT];
|
||||||
} input_t;
|
} input_t;
|
||||||
|
|
||||||
|
extern char_t INPUT_BIND_NAMES[INPUT_BIND_COUNT][16];
|
||||||
extern input_t INPUT;
|
extern input_t INPUT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -123,4 +124,12 @@ bool_t inputPressed(const inputbind_t bind);
|
|||||||
* @param bind The input bind to check.
|
* @param bind The input bind to check.
|
||||||
* @return true if the bind was released this frame, false otherwise.
|
* @return true if the bind was released this frame, false otherwise.
|
||||||
*/
|
*/
|
||||||
bool_t inputReleased(const inputbind_t bind);
|
bool_t inputReleased(const inputbind_t bind);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an input bind by its name.
|
||||||
|
*
|
||||||
|
* @param name The name of the input bind.
|
||||||
|
* @return The input bind, or INPUT_BIND_COUNT if not found.
|
||||||
|
*/
|
||||||
|
inputbind_t inputBindGetByName(const char_t *name);
|
@@ -27,6 +27,12 @@ int stringCompare(const char_t *str1, const char_t *str2) {
|
|||||||
return strcmp(str1, str2);
|
return strcmp(str1, str2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int stringCompareInsensitive(const char_t *str1, const char_t *str2) {
|
||||||
|
assertNotNull(str1, "str1 must not be NULL");
|
||||||
|
assertNotNull(str2, "str2 must not be NULL");
|
||||||
|
return strcasecmp(str1, str2);
|
||||||
|
}
|
||||||
|
|
||||||
void stringTrim(char_t *str) {
|
void stringTrim(char_t *str) {
|
||||||
assertNotNull(str, "str must not be NULL");
|
assertNotNull(str, "str must not be NULL");
|
||||||
|
|
||||||
|
@@ -36,6 +36,16 @@ void stringCopy(char_t *dest, const char_t *src, const size_t destSize);
|
|||||||
*/
|
*/
|
||||||
int stringCompare(const char_t *str1, const char_t *str2);
|
int stringCompare(const char_t *str1, const char_t *str2);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares two strings, ignoring case.
|
||||||
|
*
|
||||||
|
* @param str1 The first string.
|
||||||
|
* @param str2 The second string.
|
||||||
|
* @return 0 if the strings are equal, -1 if str1 is less than str2, 1 if str1
|
||||||
|
* is greater than str2.
|
||||||
|
*/
|
||||||
|
int stringCompareInsensitive(const char_t *str1, const char_t *str2);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Trims whitespace from the beginning and end of a string.
|
* Trims whitespace from the beginning and end of a string.
|
||||||
*
|
*
|
||||||
|
Reference in New Issue
Block a user