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 entities.png type=PALETTIZED)
|
||||
add_asset(CONFIG init.dcf)
|
||||
add_asset(CONFIG test.dcf)
|
||||
|
||||
# add_asset(TILESET entities.tsx)
|
@@ -1,3 +1 @@
|
||||
echo "test1";
|
||||
echo "test2";
|
||||
exec "test";
|
||||
bind ` console;
|
@@ -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/cmdget.h"
|
||||
#include "console/cmd/cmdexec.h"
|
||||
#include "console/cmd/cmdbind.h"
|
||||
#include "input/input.h"
|
||||
|
||||
console_t CONSOLE;
|
||||
@@ -27,6 +28,7 @@ void consoleInit() {
|
||||
consoleRegCmd("quit", cmdQuit);
|
||||
consoleRegCmd("echo", cmdEcho);
|
||||
consoleRegCmd("exec", cmdExec);
|
||||
consoleRegCmd("bind", cmdBind);
|
||||
|
||||
consolePrint(" = Dawn Console = ");
|
||||
|
||||
@@ -284,7 +286,7 @@ void consoleExec(const char_t *line) {
|
||||
}
|
||||
|
||||
if(exec->cmd == NULL) {
|
||||
consolePrint("Command not found", exec->command);
|
||||
consolePrint("Command \"%s\" not found", exec->command);
|
||||
exec = NULL;
|
||||
state = CONSOLE_EXEC_STATE_INITIAL;
|
||||
break;
|
||||
|
@@ -8,6 +8,17 @@
|
||||
#include "input.h"
|
||||
#include "assert/assert.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;
|
||||
|
||||
@@ -72,4 +83,14 @@ bool_t inputPressed(const inputbind_t bind) {
|
||||
|
||||
bool_t inputReleased(const inputbind_t 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];
|
||||
} input_t;
|
||||
|
||||
extern char_t INPUT_BIND_NAMES[INPUT_BIND_COUNT][16];
|
||||
extern input_t INPUT;
|
||||
|
||||
/**
|
||||
@@ -123,4 +124,12 @@ bool_t inputPressed(const inputbind_t bind);
|
||||
* @param bind The input bind to check.
|
||||
* @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);
|
||||
}
|
||||
|
||||
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) {
|
||||
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);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
|
Reference in New Issue
Block a user