Some adjustments
This commit is contained in:
@@ -1,3 +1,5 @@
|
|||||||
|
Console.visible = true;
|
||||||
|
|
||||||
// Default input bindings.
|
// Default input bindings.
|
||||||
if (typeof PSP !== 'undefined') {
|
if (typeof PSP !== 'undefined') {
|
||||||
Input.bind("up", INPUT_ACTION_UP);
|
Input.bind("up", INPUT_ACTION_UP);
|
||||||
|
|||||||
@@ -9,6 +9,11 @@ function CubeScene() {
|
|||||||
this.cam.position.lookAt(new Vec3(0, 0, 0));
|
this.cam.position.lookAt(new Vec3(0, 0, 0));
|
||||||
|
|
||||||
this.cube = new CubeEntity();
|
this.cube = new CubeEntity();
|
||||||
|
|
||||||
|
this.spriteEnt = new Entity();
|
||||||
|
this.spriteEnt.add(POSITION);
|
||||||
|
this.spriteEnt.position.position = new Vec3(16, 16, 0);
|
||||||
|
// this.spriteEnt.sprite.setTexture('ui/minogram.png');
|
||||||
}
|
}
|
||||||
|
|
||||||
CubeScene.prototype = Object.create(Scene.prototype);
|
CubeScene.prototype = Object.create(Scene.prototype);
|
||||||
@@ -21,6 +26,7 @@ CubeScene.prototype.update = function() {
|
|||||||
CubeScene.prototype.dispose = function() {
|
CubeScene.prototype.dispose = function() {
|
||||||
this.cam.dispose();
|
this.cam.dispose();
|
||||||
this.cube.dispose();
|
this.cube.dispose();
|
||||||
|
this.spriteEnt.dispose();
|
||||||
};
|
};
|
||||||
|
|
||||||
module = CubeScene;
|
module = CubeScene;
|
||||||
|
|||||||
@@ -1,15 +1,9 @@
|
|||||||
# Copyright (c) 2025 Dominic Masters
|
# Copyright (c) 2026 Dominic Masters
|
||||||
#
|
#
|
||||||
# This software is released under the MIT License.
|
# This software is released under the MIT License.
|
||||||
# https://opensource.org/licenses/MIT
|
# https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
# Sources
|
|
||||||
target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
||||||
PUBLIC
|
PUBLIC
|
||||||
console.c
|
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_LIBRARY_TARGET_NAME}
|
|
||||||
PUBLIC
|
|
||||||
)
|
|
||||||
@@ -1,45 +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 "input/input.h"
|
|
||||||
|
|
||||||
void cmdBind(const consolecmdexec_t *exec) {
|
|
||||||
if(exec->argc < 1) {
|
|
||||||
consolePrint("Expected 1 argument: <key> <command]");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
inputbutton_t button = inputButtonGetByName(exec->argv[0]);
|
|
||||||
if(button.type == INPUT_BUTTON_TYPE_NONE) {
|
|
||||||
consolePrint("Unknown button \"%s\"", exec->argv[0]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(exec->argc == 1) {
|
|
||||||
// Get the button data for this button.
|
|
||||||
inputbuttondata_t *data = inputButtonGetData(button);
|
|
||||||
assertNotNull(data, "Input button not found");
|
|
||||||
|
|
||||||
inputaction_t act = data->action;
|
|
||||||
if(act == INPUT_ACTION_NULL || act >= INPUT_ACTION_COUNT) {
|
|
||||||
consolePrint("%s is not bound.", data->name);
|
|
||||||
} else {
|
|
||||||
consolePrint("%s is bound to %s.", data->name, INPUT_ACTION_IDS[act]);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
inputaction_t action = inputActionGetByName(exec->argv[1]);
|
|
||||||
if(action == INPUT_ACTION_COUNT) {
|
|
||||||
consolePrint("Unknown action \"%s\"", exec->argv[1]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
inputBind(button, action);
|
|
||||||
}
|
|
||||||
@@ -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) {
|
|
||||||
if(exec->argc < 1) {
|
|
||||||
consolePrint("Expected 1 argument: <message>");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
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,14 +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 "engine/engine.h"
|
|
||||||
|
|
||||||
void cmdQuit(const consolecmdexec_t *exec) {
|
|
||||||
ENGINE.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,14 +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 "time/time.h"
|
|
||||||
|
|
||||||
void cmdTime(const consolecmdexec_t *exec) {
|
|
||||||
consolePrint("Time: %.2f", TIME.time);
|
|
||||||
}
|
|
||||||
+40
-336
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2025 Dominic Masters
|
* Copyright (c) 2026 Dominic Masters
|
||||||
*
|
*
|
||||||
* This software is released under the MIT License.
|
* This software is released under the MIT License.
|
||||||
* https://opensource.org/licenses/MIT
|
* https://opensource.org/licenses/MIT
|
||||||
@@ -12,40 +12,16 @@
|
|||||||
#include "input/input.h"
|
#include "input/input.h"
|
||||||
#include "log/log.h"
|
#include "log/log.h"
|
||||||
#include "engine/engine.h"
|
#include "engine/engine.h"
|
||||||
|
#include "script/scriptmanager.h"
|
||||||
#include "console/cmd/cmdecho.h"
|
|
||||||
#include "console/cmd/cmdset.h"
|
|
||||||
#include "console/cmd/cmdget.h"
|
|
||||||
#include "console/cmd/cmdquit.h"
|
|
||||||
#include "console/cmd/cmdbind.h"
|
|
||||||
#include "console/cmd/cmdtime.h"
|
|
||||||
|
|
||||||
#include "display/shader/shaderunlit.h"
|
#include "display/shader/shaderunlit.h"
|
||||||
#include "display/text/text.h"
|
#include "display/text/text.h"
|
||||||
#include "display/spritebatch/spritebatch.h"
|
#include "display/spritebatch/spritebatch.h"
|
||||||
|
|
||||||
console_t CONSOLE;
|
console_t CONSOLE;
|
||||||
|
|
||||||
void consoleInit() {
|
void consoleInit(void) {
|
||||||
memoryZero(&CONSOLE, sizeof(console_t));
|
memoryZero(&CONSOLE, sizeof(console_t));
|
||||||
|
|
||||||
// Register vars
|
|
||||||
#define REG(name, value) consoleRegVar(name, value, NULL)
|
|
||||||
REG("console", "1");
|
|
||||||
#undef REG
|
|
||||||
|
|
||||||
// Register cmdss
|
|
||||||
CONSOLE.cmdGet = consoleRegCmd("get", cmdGet);
|
|
||||||
CONSOLE.cmdSet = consoleRegCmd("set", cmdSet);
|
|
||||||
|
|
||||||
#define REG(name, func) consoleRegCmd(name, func)
|
|
||||||
REG("echo", cmdEcho);
|
|
||||||
REG("quit", cmdQuit);
|
|
||||||
REG("exit", cmdQuit);
|
|
||||||
REG("bind", cmdBind);
|
|
||||||
REG("time", cmdTime);
|
|
||||||
#undef REG
|
|
||||||
|
|
||||||
#ifdef DUSK_CONSOLE_POSIX
|
#ifdef DUSK_CONSOLE_POSIX
|
||||||
threadInit(&CONSOLE.thread, consoleInputThread);
|
threadInit(&CONSOLE.thread, consoleInputThread);
|
||||||
threadMutexInit(&CONSOLE.execMutex);
|
threadMutexInit(&CONSOLE.execMutex);
|
||||||
@@ -54,68 +30,6 @@ void consoleInit() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
// Existing?
|
|
||||||
var = consoleVarGet(name);
|
|
||||||
if(var != NULL) return var;
|
|
||||||
|
|
||||||
assertTrue(
|
|
||||||
CONSOLE.variableCount < CONSOLE_VARIABLES_MAX,
|
|
||||||
"Too many console variables registered."
|
|
||||||
);
|
|
||||||
|
|
||||||
// Create
|
|
||||||
var = &CONSOLE.variables[CONSOLE.variableCount++];
|
|
||||||
consoleVarInitListener(var, name, value, event);
|
|
||||||
return var;
|
|
||||||
}
|
|
||||||
|
|
||||||
consolevar_t * consoleVarGet(const char_t *name) {
|
|
||||||
assertNotNull(name, "name must not be NULL");
|
|
||||||
for(uint32_t i = 0; i < CONSOLE.variableCount; i++) {
|
|
||||||
consolevar_t *var = &CONSOLE.variables[i];
|
|
||||||
if(stringCompare(var->name, name) == 0) return var;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t consoleVarGetInt(const char_t *name, const int32_t initial) {
|
|
||||||
consolevar_t *var = consoleVarGet(name);
|
|
||||||
if(var == NULL) return initial;
|
|
||||||
char *end;
|
|
||||||
int32_t value = (int32_t)strtol(var->value, &end, 10);
|
|
||||||
if(*end != '\0') return initial;
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool_t consoleVarGetBool(const char_t *name, const bool_t initial) {
|
|
||||||
return consoleVarGetInt(name, initial ? 1 : 0) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void consoleVarSetInt(const char_t *name, const int32_t value) {
|
|
||||||
consolevar_t *existing = consoleVarGet(name);
|
|
||||||
assertNotNull(existing, "Variable not found");
|
|
||||||
char_t buffer[CONSOLE_VAR_VALUE_MAX];
|
|
||||||
stringFormat(buffer, CONSOLE_VAR_VALUE_MAX, "%d", value);
|
|
||||||
consoleVarSetValue(existing, buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void consoleVarSetBool(const char_t *name, const bool_t value) {
|
|
||||||
consoleVarSetInt(name, value ? 1 : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void consolePrint(const char_t *message, ...) {
|
void consolePrint(const char_t *message, ...) {
|
||||||
char_t buffer[CONSOLE_LINE_MAX];
|
char_t buffer[CONSOLE_LINE_MAX];
|
||||||
|
|
||||||
@@ -128,19 +42,12 @@ void consolePrint(const char_t *message, ...) {
|
|||||||
threadMutexLock(&CONSOLE.printMutex);
|
threadMutexLock(&CONSOLE.printMutex);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Move all lines back
|
|
||||||
memoryMove(
|
memoryMove(
|
||||||
CONSOLE.line[0],
|
CONSOLE.line[0],
|
||||||
CONSOLE.line[1],
|
CONSOLE.line[1],
|
||||||
(CONSOLE_HISTORY_MAX - 1) * CONSOLE_LINE_MAX
|
(CONSOLE_HISTORY_MAX - 1) * CONSOLE_LINE_MAX
|
||||||
);
|
);
|
||||||
|
memoryCopy(CONSOLE.line[CONSOLE_HISTORY_MAX - 1], buffer, len + 1);
|
||||||
// Copy the new line
|
|
||||||
memoryCopy(
|
|
||||||
CONSOLE.line[CONSOLE_HISTORY_MAX - 1],
|
|
||||||
buffer,
|
|
||||||
len + 1
|
|
||||||
);
|
|
||||||
|
|
||||||
#ifdef DUSK_CONSOLE_POSIX
|
#ifdef DUSK_CONSOLE_POSIX
|
||||||
threadMutexUnlock(&CONSOLE.printMutex);
|
threadMutexUnlock(&CONSOLE.printMutex);
|
||||||
@@ -150,272 +57,75 @@ void consolePrint(const char_t *message, ...) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void consoleExec(const char_t *line) {
|
void consoleExec(const char_t *line) {
|
||||||
|
assertNotNull(line, "line must not be NULL");
|
||||||
|
|
||||||
#ifdef DUSK_CONSOLE_POSIX
|
#ifdef DUSK_CONSOLE_POSIX
|
||||||
threadMutexLock(&CONSOLE.execMutex);
|
threadMutexLock(&CONSOLE.execMutex);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
assertNotNull(line, "line must not be NULL");
|
|
||||||
assertTrue(
|
assertTrue(
|
||||||
CONSOLE.execBufferCount < CONSOLE_EXEC_BUFFER_MAX,
|
CONSOLE.execBufferCount < CONSOLE_EXEC_BUFFER_MAX,
|
||||||
"Too many commands in the buffer."
|
"Console exec buffer is full"
|
||||||
);
|
);
|
||||||
|
|
||||||
char_t buffer[CONSOLE_LINE_MAX];
|
stringCopy(
|
||||||
char_t pendingPrint[CONSOLE_LINE_MAX];
|
CONSOLE.execBuffer[CONSOLE.execBufferCount],
|
||||||
size_t i = 0, j = 0;
|
line,
|
||||||
char_t c;
|
CONSOLE_LINE_MAX
|
||||||
consoleexecstate_t state = CONSOLE_EXEC_STATE_INITIAL;
|
|
||||||
consolecmdexec_t *exec = NULL;
|
|
||||||
|
|
||||||
pendingPrint[0] = '\0';
|
|
||||||
|
|
||||||
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.
|
|
||||||
stringCopy(pendingPrint, "Invalid command", CONSOLE_LINE_MAX);
|
|
||||||
while(c != '\0' && c != ';') c = line[++i];
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer[j++] = c;
|
|
||||||
i++;
|
|
||||||
|
|
||||||
if(j >= CONSOLE_LINE_MAX) {
|
|
||||||
stringCopy(pendingPrint, "Command too long", CONSOLE_LINE_MAX);
|
|
||||||
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) {
|
|
||||||
stringCopy(pendingPrint, "Arg too long", CONSOLE_LINE_MAX);
|
|
||||||
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 == ';') {
|
|
||||||
stringCopy(pendingPrint, "Unterminated quote", CONSOLE_LINE_MAX);
|
|
||||||
state = CONSOLE_EXEC_STATE_FULLY_PARSED;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(c == '\\') {
|
|
||||||
c = line[++i];
|
|
||||||
|
|
||||||
if(c == '\0' || c == ';') {
|
|
||||||
stringCopy(pendingPrint, "Unterminated quote", CONSOLE_LINE_MAX);
|
|
||||||
state = CONSOLE_EXEC_STATE_FULLY_PARSED;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer[j++] = c;
|
|
||||||
i++;
|
|
||||||
|
|
||||||
if(j >= CONSOLE_LINE_MAX) {
|
|
||||||
stringCopy(pendingPrint, "Arg too long", CONSOLE_LINE_MAX);
|
|
||||||
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) {
|
|
||||||
stringFormat(
|
|
||||||
pendingPrint, CONSOLE_LINE_MAX,
|
|
||||||
"Command \"%s\" not found", exec->command
|
|
||||||
);
|
);
|
||||||
exec = NULL;
|
|
||||||
state = CONSOLE_EXEC_STATE_INITIAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prep for next command.
|
|
||||||
exec = NULL;
|
|
||||||
state = CONSOLE_EXEC_STATE_INITIAL;
|
|
||||||
CONSOLE.execBufferCount++;
|
CONSOLE.execBufferCount++;
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
assertUnreachable("Invalid state.");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DUSK_CONSOLE_POSIX
|
#ifdef DUSK_CONSOLE_POSIX
|
||||||
threadMutexUnlock(&CONSOLE.execMutex);
|
threadMutexUnlock(&CONSOLE.execMutex);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(pendingPrint[0] != '\0') consolePrint("%s", pendingPrint);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void consoleUpdate() {
|
void consoleUpdate(void) {
|
||||||
#ifdef DUSK_TIME_DYNAMIC
|
#ifdef DUSK_TIME_DYNAMIC
|
||||||
if(TIME.dynamicUpdate) return;
|
if(TIME.dynamicUpdate) return;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if(inputPressed(INPUT_ACTION_CONSOLE)) {
|
||||||
|
CONSOLE.visible = !CONSOLE.visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(CONSOLE.execBufferCount == 0) return;
|
||||||
|
|
||||||
#ifdef DUSK_CONSOLE_POSIX
|
#ifdef DUSK_CONSOLE_POSIX
|
||||||
threadMutexLock(&CONSOLE.execMutex);
|
threadMutexLock(&CONSOLE.execMutex);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Toggle console
|
char_t execBuffer[CONSOLE_EXEC_BUFFER_MAX][CONSOLE_LINE_MAX];
|
||||||
if(inputPressed(INPUT_ACTION_CONSOLE)) {
|
|
||||||
consoleVarSetBool("console", !consoleVarGetBool("console", false));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Anything to exec?
|
|
||||||
if(CONSOLE.execBufferCount == 0) {
|
|
||||||
#ifdef DUSK_CONSOLE_POSIX
|
|
||||||
threadMutexUnlock(&CONSOLE.execMutex);
|
|
||||||
#endif
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy the exec buffer, this allows exec command to work
|
|
||||||
consolecmdexec_t execBuffer[CONSOLE_EXEC_BUFFER_MAX];
|
|
||||||
uint32_t execBufferCount = CONSOLE.execBufferCount;
|
uint32_t execBufferCount = CONSOLE.execBufferCount;
|
||||||
memoryCopy(
|
memoryCopy(execBuffer, CONSOLE.execBuffer, sizeof(execBuffer));
|
||||||
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;
|
CONSOLE.execBufferCount = 0;
|
||||||
|
|
||||||
#ifdef DUSK_CONSOLE_POSIX
|
#ifdef DUSK_CONSOLE_POSIX
|
||||||
threadMutexUnlock(&CONSOLE.execMutex);
|
threadMutexUnlock(&CONSOLE.execMutex);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Exec pending buffer.
|
|
||||||
for(uint32_t i = 0; i < execBufferCount; i++) {
|
for(uint32_t i = 0; i < execBufferCount; i++) {
|
||||||
consolecmdexec_t *exec = &execBuffer[i];
|
jerry_value_t result = 0;
|
||||||
assertNotNull(exec->cmd, "Command execution has no command.");
|
errorret_t err = scriptManagerExec(execBuffer[i], &result);
|
||||||
exec->cmd->function(exec);
|
if(err.code != ERROR_OK) {
|
||||||
|
consolePrint("Error: %s", err.state->message);
|
||||||
|
errorCatch(err);
|
||||||
|
} else if(!jerry_value_is_undefined(result)) {
|
||||||
|
jerry_value_t strVal = jerry_value_to_string(result);
|
||||||
|
char_t buf[CONSOLE_LINE_MAX];
|
||||||
|
jerry_size_t len = jerry_string_to_buffer(
|
||||||
|
strVal, JERRY_ENCODING_UTF8, (jerry_char_t*)buf, sizeof(buf) - 1
|
||||||
|
);
|
||||||
|
buf[len] = '\0';
|
||||||
|
jerry_value_free(strVal);
|
||||||
|
consolePrint("%s", buf);
|
||||||
|
}
|
||||||
|
if(result != 0) jerry_value_free(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
errorret_t consoleDraw() {
|
errorret_t consoleDraw(void) {
|
||||||
if(!consoleVarGetBool("console", false)) {
|
if(!CONSOLE.visible) errorOk();
|
||||||
errorOk();
|
|
||||||
}
|
|
||||||
|
|
||||||
for(uint32_t i = 0; i < CONSOLE_HISTORY_MAX; i++) {
|
for(uint32_t i = 0; i < CONSOLE_HISTORY_MAX; i++) {
|
||||||
errorChain(textDraw(
|
errorChain(textDraw(
|
||||||
@@ -454,29 +164,23 @@ void consoleDispose(void) {
|
|||||||
|
|
||||||
if(rc == 0) continue;
|
if(rc == 0) continue;
|
||||||
if(rc < 0) {
|
if(rc < 0) {
|
||||||
if(errno == EINTR) continue; // Interrupted by signal, retry
|
if(errno == EINTR) continue;
|
||||||
assertUnreachable("poll() failed with unexpected error.");
|
assertUnreachable("poll() failed with unexpected error.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for errors or input
|
|
||||||
if(pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) break;
|
if(pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) break;
|
||||||
if(!(pfd.revents & POLLIN)) {
|
if(!(pfd.revents & POLLIN)) {
|
||||||
pfd.revents = 0;
|
pfd.revents = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read a line from stdin
|
|
||||||
if(!fgets(line, CONSOLE_LINE_MAX, stdin)) {
|
if(!fgets(line, CONSOLE_LINE_MAX, stdin)) {
|
||||||
if(feof(stdin)) break;
|
if(feof(stdin)) break;
|
||||||
clearerr(stdin);
|
clearerr(stdin);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Did we read a full line or did it get truncated?
|
|
||||||
size_t len = strlen(line);
|
size_t len = strlen(line);
|
||||||
int32_t fullLine = len > 0 && line[len - 1] == '\n';
|
|
||||||
|
|
||||||
// Strip trailing newline/CR
|
|
||||||
while(len && (line[len - 1] == '\n' || line[len - 1] == '\r')) {
|
while(len && (line[len - 1] == '\n' || line[len - 1] == '\r')) {
|
||||||
line[--len] = '\0';
|
line[--len] = '\0';
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-110
@@ -1,14 +1,14 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2025 Dominic Masters
|
* Copyright (c) 2026 Dominic Masters
|
||||||
*
|
*
|
||||||
* This software is released under the MIT License.
|
* This software is released under the MIT License.
|
||||||
* https://opensource.org/licenses/MIT
|
* https://opensource.org/licenses/MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "consolevar.h"
|
#include "consoledefs.h"
|
||||||
#include "consolecmd.h"
|
|
||||||
#include "error/error.h"
|
#include "error/error.h"
|
||||||
|
#include "dusk.h"
|
||||||
|
|
||||||
#ifdef DUSK_CONSOLE_POSIX
|
#ifdef DUSK_CONSOLE_POSIX
|
||||||
#include "thread/thread.h"
|
#include "thread/thread.h"
|
||||||
@@ -17,37 +17,14 @@
|
|||||||
#define CONSOLE_POSIX_POLL_RATE 75
|
#define CONSOLE_POSIX_POLL_RATE 75
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
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 {
|
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];
|
char_t line[CONSOLE_HISTORY_MAX][CONSOLE_LINE_MAX];
|
||||||
|
bool_t visible;
|
||||||
|
|
||||||
consolecmdexec_t execBuffer[CONSOLE_EXEC_BUFFER_MAX];
|
char_t execBuffer[CONSOLE_EXEC_BUFFER_MAX][CONSOLE_LINE_MAX];
|
||||||
uint32_t execBufferCount;
|
uint32_t execBufferCount;
|
||||||
|
|
||||||
consolecmd_t *cmdGet;
|
|
||||||
consolecmd_t *cmdSet;
|
|
||||||
|
|
||||||
#ifdef DUSK_CONSOLE_POSIX
|
#ifdef DUSK_CONSOLE_POSIX
|
||||||
char_t inputBuffer[CONSOLE_LINE_MAX];
|
|
||||||
thread_t thread;
|
thread_t thread;
|
||||||
threadmutex_t execMutex;
|
threadmutex_t execMutex;
|
||||||
threadmutex_t printMutex;
|
threadmutex_t printMutex;
|
||||||
@@ -59,104 +36,33 @@ extern console_t CONSOLE;
|
|||||||
/**
|
/**
|
||||||
* Initializes the console.
|
* Initializes the console.
|
||||||
*/
|
*/
|
||||||
void consoleInit();
|
void consoleInit(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers a console command.
|
* Prints a message to the console history.
|
||||||
*
|
*
|
||||||
* @param name The name of the command.
|
* @param message The message to print (printf-style).
|
||||||
* @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);
|
void consolePrint(const char_t *message, ...);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers a console variable.
|
* Queues a JS string for execution on the main thread. Thread-safe.
|
||||||
*
|
*
|
||||||
* @param name The name of the variable.
|
* @param line The JS source line to execute.
|
||||||
* @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
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a console variable by name.
|
|
||||||
*
|
|
||||||
* @param name The name of the variable.
|
|
||||||
* @return The variable, or NULL if not found.
|
|
||||||
*/
|
|
||||||
consolevar_t * consoleVarGet(const char_t *name);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the value of a console variable as an int32_t.
|
|
||||||
*
|
|
||||||
* @param name The name of the variable.
|
|
||||||
* @param initial The default value to return if the variable is not found or
|
|
||||||
* invalid.
|
|
||||||
* @return The value of the variable, or default if not found or invalid.
|
|
||||||
*/
|
|
||||||
int32_t consoleVarGetInt(const char_t *name, const int32_t initial);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the value of a console variable as a bool_t.
|
|
||||||
*
|
|
||||||
* @param name The name of the variable.
|
|
||||||
* @param initial The default value to return if the variable is not found or
|
|
||||||
* invalid.
|
|
||||||
* @return The value of the variable, or default if not found or invalid.
|
|
||||||
*/
|
|
||||||
bool_t consoleVarGetBool(const char_t *name, const bool_t initial);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the value of a console variable as an int32_t.
|
|
||||||
*
|
|
||||||
* @param name The name of the variable.
|
|
||||||
* @param value The new value of the variable.
|
|
||||||
*/
|
|
||||||
void consoleVarSetInt(const char_t *name, const int32_t value);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the value of a console variable as a bool_t.
|
|
||||||
*
|
|
||||||
* @param name The name of the variable.
|
|
||||||
* @param value The new value of the variable.
|
|
||||||
*/
|
|
||||||
void consoleVarSetBool(const char_t *name, const bool_t value);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prints a message to the console.
|
|
||||||
*
|
|
||||||
* @param message The message to print.
|
|
||||||
*/
|
|
||||||
void consolePrint(
|
|
||||||
const char_t *message,
|
|
||||||
...
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executes a console command. This method is thread safe and can be called from
|
|
||||||
* any thread.
|
|
||||||
*
|
|
||||||
* @param line The line to execute.
|
|
||||||
*/
|
*/
|
||||||
void consoleExec(const char_t *line);
|
void consoleExec(const char_t *line);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Processes the console's pending commands.
|
* Processes pending queued script lines. Call once per frame from main thread.
|
||||||
*/
|
*/
|
||||||
void consoleUpdate();
|
void consoleUpdate(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders the console to the screen. This is in UI space.
|
* Renders the console history to the screen (UI space).
|
||||||
*
|
*
|
||||||
* @return The error return value.
|
* @return The error return value.
|
||||||
*/
|
*/
|
||||||
errorret_t consoleDraw();
|
errorret_t consoleDraw(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disposes of the console.
|
* Disposes of the console.
|
||||||
@@ -165,7 +71,7 @@ void consoleDispose(void);
|
|||||||
|
|
||||||
#ifdef DUSK_CONSOLE_POSIX
|
#ifdef DUSK_CONSOLE_POSIX
|
||||||
/**
|
/**
|
||||||
* Input thread handler for posix input.
|
* Input thread handler for POSIX stdin.
|
||||||
*
|
*
|
||||||
* @param thread The thread that is running.
|
* @param thread The thread that is running.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -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,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2025 Dominic Masters
|
* Copyright (c) 2026 Dominic Masters
|
||||||
*
|
*
|
||||||
* This software is released under the MIT License.
|
* This software is released under the MIT License.
|
||||||
* https://opensource.org/licenses/MIT
|
* https://opensource.org/licenses/MIT
|
||||||
@@ -7,16 +7,6 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define CONSOLE_CMD_NAME_MAX 16
|
#define CONSOLE_LINE_MAX 512
|
||||||
#define CONSOLE_CMD_ARGC_MAX 16
|
|
||||||
|
|
||||||
#define CONSOLE_COMMANDS_MAX 32
|
|
||||||
#define CONSOLE_VARIABLES_MAX 64
|
|
||||||
#define CONSOLE_LINE_MAX 128
|
|
||||||
#define CONSOLE_HISTORY_MAX 16
|
#define CONSOLE_HISTORY_MAX 16
|
||||||
#define CONSOLE_EXEC_BUFFER_MAX 32
|
#define CONSOLE_EXEC_BUFFER_MAX 32
|
||||||
#define CONSOLE_ALIAS_MAX 32
|
|
||||||
|
|
||||||
#define CONSOLE_VAR_NAME_MAX 32
|
|
||||||
#define CONSOLE_VAR_VALUE_MAX 32
|
|
||||||
#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);
|
|
||||||
+191
-76
@@ -57,16 +57,7 @@ errorret_t sceneRender(void) {
|
|||||||
|
|
||||||
mat4 view, proj, model;
|
mat4 view, proj, model;
|
||||||
|
|
||||||
if(camCount > 0) {
|
// For each camera
|
||||||
entityid_t meshEnts[ENTITY_COUNT_MAX];
|
|
||||||
componentid_t meshComps[ENTITY_COUNT_MAX];
|
|
||||||
entityid_t meshCount = componentGetEntitiesWithComponent(
|
|
||||||
COMPONENT_TYPE_MESH, meshEnts, meshComps
|
|
||||||
);
|
|
||||||
|
|
||||||
if(meshCount > 0) {
|
|
||||||
errorChain(shaderBind(&SHADER_UNLIT));
|
|
||||||
|
|
||||||
for(entityid_t camIndex = 0; camIndex < camCount; camIndex++) {
|
for(entityid_t camIndex = 0; camIndex < camCount; camIndex++) {
|
||||||
entityid_t camEnt = camEnts[camIndex];
|
entityid_t camEnt = camEnts[camIndex];
|
||||||
componentid_t camComp = camComps[camIndex];
|
componentid_t camComp = camComps[camIndex];
|
||||||
@@ -79,88 +70,212 @@ errorret_t sceneRender(void) {
|
|||||||
entityCameraGetProjection(camEnt, camComp, proj);
|
entityCameraGetProjection(camEnt, camComp, proj);
|
||||||
entityPositionGetTransform(camEnt, camPos, view);
|
entityPositionGetTransform(camEnt, camPos, view);
|
||||||
|
|
||||||
for(entityid_t meshIndex = 0; meshIndex < meshCount; meshIndex++) {
|
// For each entity
|
||||||
entityid_t meshEnt = meshEnts[meshIndex];
|
for(entityid_t entityId = 0; entityId < ENTITY_COUNT_MAX; entityId++) {
|
||||||
componentid_t meshComp = meshComps[meshIndex];
|
// Does this entity have a material?
|
||||||
mesh_t *mesh = entityMeshGetMesh(meshEnt, meshComp);
|
componentid_t matComp = entityGetComponent(
|
||||||
if(mesh == NULL) continue;
|
entityId, COMPONENT_TYPE_MATERIAL
|
||||||
|
);
|
||||||
|
if(matComp != 0xFF) {
|
||||||
|
// Yes, get the mesh
|
||||||
|
componentid_t meshComp = entityGetComponent(
|
||||||
|
entityId, COMPONENT_TYPE_MESH
|
||||||
|
);
|
||||||
|
|
||||||
|
if(meshComp == 0xFF) {
|
||||||
|
logError("Entity with material component without mesh component found\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Yes, get the material and shader.
|
||||||
|
shadermaterial_t *material = entityMaterialGetShaderMaterial(
|
||||||
|
entityId, matComp
|
||||||
|
);
|
||||||
|
shader_t *shader = entityMaterialGetShader(entityId, matComp);
|
||||||
|
if(shader == NULL) {
|
||||||
|
logError("Entity with material component without shader found\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the mesh
|
||||||
|
mesh_t *mesh = entityMeshGetMesh(entityId, meshComp);
|
||||||
|
if(mesh == NULL) {
|
||||||
|
logError("Entity with material component without mesh found\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the transform.
|
||||||
componentid_t meshPos = entityGetComponent(
|
componentid_t meshPos = entityGetComponent(
|
||||||
meshEnt, COMPONENT_TYPE_POSITION
|
entityId, COMPONENT_TYPE_POSITION
|
||||||
);
|
);
|
||||||
if(meshPos == 0xFF) {
|
if(meshPos == 0xFF) {
|
||||||
logError("Mesh entity without entity position found\n");
|
glm_mat4_identity(model);
|
||||||
continue;
|
} else {
|
||||||
|
entityPositionGetTransform(entityId, meshPos, model);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentid_t meshMat = entityGetComponent(
|
// Render the mesh.
|
||||||
meshEnt, COMPONENT_TYPE_MATERIAL
|
|
||||||
);
|
|
||||||
if(meshMat == 0xFF) {
|
|
||||||
logError("Mesh entity without material component found\n");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
shadermaterial_t *material = entityMaterialGetShaderMaterial(
|
|
||||||
meshEnt, meshMat
|
|
||||||
);
|
|
||||||
shader_t *shader = entityMaterialGetShader(meshEnt, meshMat);
|
|
||||||
if(shader == NULL) {
|
|
||||||
logError("Mesh entity with material component without shader found\n");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
entityPositionGetTransform(meshEnt, meshPos, model);
|
|
||||||
|
|
||||||
errorChain(shaderBind(shader));
|
errorChain(shaderBind(shader));
|
||||||
errorChain(shaderSetMatrix(shader, SHADER_UNLIT_PROJECTION, proj));
|
errorChain(shaderSetMatrix(shader, SHADER_UNLIT_PROJECTION, proj));
|
||||||
errorChain(shaderSetMatrix(shader, SHADER_UNLIT_VIEW, view));
|
errorChain(shaderSetMatrix(shader, SHADER_UNLIT_VIEW, view));
|
||||||
errorChain(shaderSetMatrix(shader, SHADER_UNLIT_MODEL, model));
|
errorChain(shaderSetMatrix(shader, SHADER_UNLIT_MODEL, model));
|
||||||
errorChain(shaderSetMaterial(shader, material));
|
errorChain(shaderSetMaterial(shader, material));
|
||||||
errorChain(meshDraw(mesh, 0, -1));
|
errorChain(meshDraw(mesh, 0, -1));
|
||||||
}
|
continue;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glm_ortho(
|
// No, in future there may be other renderable types.
|
||||||
0.0f, SCREEN.width,
|
}
|
||||||
SCREEN.height, 0.0f,
|
}
|
||||||
0.1f, 100.0f,
|
|
||||||
proj
|
|
||||||
);
|
|
||||||
glm_lookat(
|
|
||||||
(vec3){ 0.0f, 0.0f, 1.0f },
|
|
||||||
(vec3){ 0.0f, 0.0f, 0.0f },
|
|
||||||
(vec3){ 0.0f, 1.0f, 0.0f },
|
|
||||||
view
|
|
||||||
);
|
|
||||||
glm_mat4_identity(model);
|
|
||||||
|
|
||||||
errorChain(shaderBind(&SHADER_UNLIT));
|
|
||||||
errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_PROJECTION, proj));
|
|
||||||
errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_VIEW, view));
|
|
||||||
errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_MODEL, model));
|
|
||||||
errorChain(consoleDraw());
|
|
||||||
|
|
||||||
// FPS
|
|
||||||
char_t fpsText[32];
|
|
||||||
|
|
||||||
dusktimeepoch_t now = timeGetEpoch();
|
|
||||||
double_t delta = now.time - LAST.time;
|
|
||||||
LAST = now;
|
|
||||||
double_t fps = delta > 0 ? 1.0 / delta : 0.0;
|
|
||||||
snprintf(fpsText, sizeof(fpsText), "FPS: %.2f", fps);
|
|
||||||
|
|
||||||
errorChain(spriteBatchFlush());
|
|
||||||
errorChain(textDraw(
|
|
||||||
0, 0,
|
|
||||||
fpsText, COLOR_WHITE,
|
|
||||||
&FONT_TILESET_DEFAULT, &FONT_TEXTURE_DEFAULT
|
|
||||||
));
|
|
||||||
errorChain(spriteBatchFlush());
|
|
||||||
|
|
||||||
errorOk();
|
errorOk();
|
||||||
|
|
||||||
|
// if(camCount > 0) {
|
||||||
|
// // For each entity
|
||||||
|
// for(entityid_t entityId = 0; entityId < ENTITY_COUNT_MAX; entityId++) {
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
// entityid_t meshEnts[ENTITY_COUNT_MAX];
|
||||||
|
// componentid_t meshComps[ENTITY_COUNT_MAX];
|
||||||
|
// entityid_t meshCount = componentGetEntitiesWithComponent(
|
||||||
|
// COMPONENT_TYPE_MESH, meshEnts, meshComps
|
||||||
|
// );
|
||||||
|
|
||||||
|
// if(meshCount > 0) {
|
||||||
|
// errorChain(shaderBind(&SHADER_UNLIT));
|
||||||
|
|
||||||
|
// for(entityid_t camIndex = 0; camIndex < camCount; camIndex++) {
|
||||||
|
// entityid_t camEnt = camEnts[camIndex];
|
||||||
|
// componentid_t camComp = camComps[camIndex];
|
||||||
|
// componentid_t camPos = entityGetComponent(camEnt, COMPONENT_TYPE_POSITION);
|
||||||
|
// if(camPos == 0xFF) {
|
||||||
|
// logError("Camera entity without entity position found\n");
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// entityCameraGetProjection(camEnt, camComp, proj);
|
||||||
|
// entityPositionGetTransform(camEnt, camPos, view);
|
||||||
|
|
||||||
|
// for(entityid_t meshIndex = 0; meshIndex < meshCount; meshIndex++) {
|
||||||
|
// entityid_t meshEnt = meshEnts[meshIndex];
|
||||||
|
// componentid_t meshComp = meshComps[meshIndex];
|
||||||
|
// mesh_t *mesh = entityMeshGetMesh(meshEnt, meshComp);
|
||||||
|
// if(mesh == NULL) continue;
|
||||||
|
|
||||||
|
// componentid_t meshPos = entityGetComponent(
|
||||||
|
// meshEnt, COMPONENT_TYPE_POSITION
|
||||||
|
// );
|
||||||
|
// if(meshPos == 0xFF) {
|
||||||
|
// logError("Mesh entity without entity position found\n");
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// componentid_t meshMat = entityGetComponent(
|
||||||
|
// meshEnt, COMPONENT_TYPE_MATERIAL
|
||||||
|
// );
|
||||||
|
// if(meshMat == 0xFF) {
|
||||||
|
// logError("Mesh entity without material component found\n");
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// shadermaterial_t *material = entityMaterialGetShaderMaterial(
|
||||||
|
// meshEnt, meshMat
|
||||||
|
// );
|
||||||
|
// shader_t *shader = entityMaterialGetShader(meshEnt, meshMat);
|
||||||
|
// if(shader == NULL) {
|
||||||
|
// logError("Mesh entity with material component without shader found\n");
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// entityPositionGetTransform(meshEnt, meshPos, model);
|
||||||
|
|
||||||
|
// errorChain(shaderBind(shader));
|
||||||
|
// errorChain(shaderSetMatrix(shader, SHADER_UNLIT_PROJECTION, proj));
|
||||||
|
// errorChain(shaderSetMatrix(shader, SHADER_UNLIT_VIEW, view));
|
||||||
|
// errorChain(shaderSetMatrix(shader, SHADER_UNLIT_MODEL, model));
|
||||||
|
// errorChain(shaderSetMaterial(shader, material));
|
||||||
|
// errorChain(meshDraw(mesh, 0, -1));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// glm_ortho(
|
||||||
|
// 0.0f, SCREEN.width,
|
||||||
|
// SCREEN.height, 0.0f,
|
||||||
|
// 0.1f, 100.0f,
|
||||||
|
// proj
|
||||||
|
// );
|
||||||
|
// glm_lookat(
|
||||||
|
// (vec3){ 0.0f, 0.0f, 1.0f },
|
||||||
|
// (vec3){ 0.0f, 0.0f, 0.0f },
|
||||||
|
// (vec3){ 0.0f, 1.0f, 0.0f },
|
||||||
|
// view
|
||||||
|
// );
|
||||||
|
// glm_mat4_identity(model);
|
||||||
|
|
||||||
|
// errorChain(shaderBind(&SHADER_UNLIT));
|
||||||
|
// errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_PROJECTION, proj));
|
||||||
|
// errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_VIEW, view));
|
||||||
|
// errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_MODEL, model));
|
||||||
|
|
||||||
|
// {
|
||||||
|
// entityid_t sprEnts[ENTITY_COUNT_MAX];
|
||||||
|
// componentid_t sprComps[ENTITY_COUNT_MAX];
|
||||||
|
// entityid_t sprCount = componentGetEntitiesWithComponent(
|
||||||
|
// COMPONENT_TYPE_SPRITE, sprEnts, sprComps
|
||||||
|
// );
|
||||||
|
// for(entityid_t si = 0; si < sprCount; si++) {
|
||||||
|
// entitysprite_t *spr = entitySpriteGet(sprEnts[si], sprComps[si]);
|
||||||
|
// vec3 pos = { 0.0f, 0.0f, 0.0f };
|
||||||
|
// componentid_t posComp = entityGetComponent(
|
||||||
|
// sprEnts[si], COMPONENT_TYPE_POSITION
|
||||||
|
// );
|
||||||
|
// if(posComp != 0xFF) {
|
||||||
|
// entityPositionGetPosition(sprEnts[si], posComp, pos);
|
||||||
|
// }
|
||||||
|
// errorChain(shaderSetTexture(
|
||||||
|
// &SHADER_UNLIT, SHADER_UNLIT_TEXTURE, spr->texture
|
||||||
|
// ));
|
||||||
|
// #if !MESH_ENABLE_COLOR
|
||||||
|
// errorChain(shaderSetColor(
|
||||||
|
// &SHADER_UNLIT, SHADER_UNLIT_COLOR, spr->color
|
||||||
|
// ));
|
||||||
|
// #endif
|
||||||
|
// errorChain(spriteBatchPush(
|
||||||
|
// pos[0], pos[1],
|
||||||
|
// pos[0] + spr->width, pos[1] + spr->height,
|
||||||
|
// #if MESH_ENABLE_COLOR
|
||||||
|
// spr->color,
|
||||||
|
// #endif
|
||||||
|
// spr->uv[0], spr->uv[1],
|
||||||
|
// spr->uv[2], spr->uv[3]
|
||||||
|
// ));
|
||||||
|
// errorChain(spriteBatchFlush());
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// errorChain(consoleDraw());
|
||||||
|
|
||||||
|
// // FPS
|
||||||
|
// char_t fpsText[32];
|
||||||
|
|
||||||
|
// dusktimeepoch_t now = timeGetEpoch();
|
||||||
|
// double_t delta = now.time - LAST.time;
|
||||||
|
// LAST = now;
|
||||||
|
// double_t fps = delta > 0 ? 1.0 / delta : 0.0;
|
||||||
|
// snprintf(fpsText, sizeof(fpsText), "FPS: %.2f", fps);
|
||||||
|
|
||||||
|
// errorChain(spriteBatchFlush());
|
||||||
|
// errorChain(textDraw(
|
||||||
|
// 0, 0,
|
||||||
|
// fpsText, COLOR_WHITE,
|
||||||
|
// &FONT_TILESET_DEFAULT, &FONT_TEXTURE_DEFAULT
|
||||||
|
// ));
|
||||||
|
// errorChain(spriteBatchFlush());
|
||||||
|
|
||||||
|
// errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
errorret_t sceneSetImmediate(const char_t *scene) {
|
errorret_t sceneSetImmediate(const char_t *scene) {
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ moduleBaseFunction(moduleConsolePrint) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
moduleBaseFunction(moduleConsoleGetVisible) {
|
moduleBaseFunction(moduleConsoleGetVisible) {
|
||||||
return jerry_boolean(consoleVarGetBool("console", false));
|
return jerry_boolean(CONSOLE.visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
moduleBaseFunction(moduleConsoleSetVisible) {
|
moduleBaseFunction(moduleConsoleSetVisible) {
|
||||||
@@ -47,7 +47,7 @@ moduleBaseFunction(moduleConsoleSetVisible) {
|
|||||||
if(!jerry_value_is_boolean(args[0])) {
|
if(!jerry_value_is_boolean(args[0])) {
|
||||||
return moduleBaseThrow("Console.visible: expected boolean");
|
return moduleBaseThrow("Console.visible: expected boolean");
|
||||||
}
|
}
|
||||||
consoleVarSetBool("console", jerry_value_is_true(args[0]));
|
CONSOLE.visible = jerry_value_is_true(args[0]);
|
||||||
return jerry_undefined();
|
return jerry_undefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2026 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "script/module/modulebase.h"
|
||||||
|
#include "script/scriptproto.h"
|
||||||
|
#include "engine/engine.h"
|
||||||
|
|
||||||
|
static scriptproto_t MODULE_ENGINE_PROTO;
|
||||||
|
|
||||||
|
moduleBaseFunction(moduleEngineExit) {
|
||||||
|
ENGINE.running = false;
|
||||||
|
return jerry_undefined();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void moduleEngine(void) {
|
||||||
|
scriptProtoInit(
|
||||||
|
&MODULE_ENGINE_PROTO, "Engine",
|
||||||
|
sizeof(uint8_t), NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
scriptProtoDefineStaticFunc(
|
||||||
|
&MODULE_ENGINE_PROTO, "exit", moduleEngineExit
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -80,6 +80,43 @@ static jerry_value_t moduleEntityGetComponent(
|
|||||||
#include "entity/componentlist.h"
|
#include "entity/componentlist.h"
|
||||||
#undef X
|
#undef X
|
||||||
|
|
||||||
|
moduleBaseFunction(moduleEntityToString) {
|
||||||
|
entityscript_t *inst = (entityscript_t*)scriptProtoGetValue(
|
||||||
|
&MODULE_ENTITY_PROTO, callInfo->this_value
|
||||||
|
);
|
||||||
|
if(!inst) return jerry_string_sz("Entity(?)");
|
||||||
|
|
||||||
|
char_t components[128];
|
||||||
|
size_t clen = 0;
|
||||||
|
bool_t first = true;
|
||||||
|
|
||||||
|
for(componenttype_t t = 1; t < COMPONENT_TYPE_COUNT; t++) {
|
||||||
|
if(entityGetComponent(inst->id, t) == 0xFF) continue;
|
||||||
|
if(!first) {
|
||||||
|
stringCopy(components + clen, ", ", sizeof(components) - clen);
|
||||||
|
clen += 2;
|
||||||
|
}
|
||||||
|
const char_t *name = COMPONENT_DEFINITIONS[t].enumName;
|
||||||
|
stringCopy(components + clen, name, sizeof(components) - clen);
|
||||||
|
clen += strlen(name);
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
char_t buf[256];
|
||||||
|
if(first) {
|
||||||
|
stringFormat(
|
||||||
|
buf, sizeof(buf),
|
||||||
|
"{ \"id\": %d, \"components\": [] }", inst->id
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
stringFormat(
|
||||||
|
buf, sizeof(buf),
|
||||||
|
"{ \"id\": %d, \"components\": [ %s ] }", inst->id, components
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return jerry_string_sz(buf);
|
||||||
|
}
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
moduleBaseFunction(moduleEntityConstructor) {
|
moduleBaseFunction(moduleEntityConstructor) {
|
||||||
entityscript_t *inst = (entityscript_t*)memoryAllocate(
|
entityscript_t *inst = (entityscript_t*)memoryAllocate(
|
||||||
@@ -130,6 +167,8 @@ static void moduleEntity(void) {
|
|||||||
moduleEntityConstructor
|
moduleEntityConstructor
|
||||||
);
|
);
|
||||||
|
|
||||||
|
scriptProtoDefineToString(&MODULE_ENTITY_PROTO, moduleEntityToString);
|
||||||
|
|
||||||
// Entity Methods
|
// Entity Methods
|
||||||
scriptProtoDefineFunc(
|
scriptProtoDefineFunc(
|
||||||
&MODULE_ENTITY_PROTO, "add", moduleEntityAddComponent
|
&MODULE_ENTITY_PROTO, "add", moduleEntityAddComponent
|
||||||
|
|||||||
@@ -156,6 +156,22 @@ moduleBaseFunction(moduleMatStaticLookAt) {
|
|||||||
return scriptProtoCreateValue(&MODULE_MAT4_PROTO, r);
|
return scriptProtoCreateValue(&MODULE_MAT4_PROTO, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
moduleBaseFunction(moduleMatToString) {
|
||||||
|
float_t (*m)[4] = (float_t (*)[4])moduleMatGet(callInfo);
|
||||||
|
if(!m) return jerry_string_sz("Mat4(?)");
|
||||||
|
char_t buf[256];
|
||||||
|
stringFormat(
|
||||||
|
buf, sizeof(buf),
|
||||||
|
"Mat4([%g,%g,%g,%g], [%g,%g,%g,%g],"
|
||||||
|
" [%g,%g,%g,%g], [%g,%g,%g,%g])",
|
||||||
|
m[0][0], m[0][1], m[0][2], m[0][3],
|
||||||
|
m[1][0], m[1][1], m[1][2], m[1][3],
|
||||||
|
m[2][0], m[2][1], m[2][2], m[2][3],
|
||||||
|
m[3][0], m[3][1], m[3][2], m[3][3]
|
||||||
|
);
|
||||||
|
return jerry_string_sz(buf);
|
||||||
|
}
|
||||||
|
|
||||||
static inline jerry_value_t moduleMat4Push(float (*m)[4]) {
|
static inline jerry_value_t moduleMat4Push(float (*m)[4]) {
|
||||||
return scriptProtoCreateValue(&MODULE_MAT4_PROTO, m);
|
return scriptProtoCreateValue(&MODULE_MAT4_PROTO, m);
|
||||||
}
|
}
|
||||||
@@ -174,6 +190,8 @@ static void moduleMat4(void) {
|
|||||||
&MODULE_MAT4_PROTO, "Mat4", sizeof(mat4), moduleMatConstructor
|
&MODULE_MAT4_PROTO, "Mat4", sizeof(mat4), moduleMatConstructor
|
||||||
);
|
);
|
||||||
|
|
||||||
|
scriptProtoDefineToString(&MODULE_MAT4_PROTO, moduleMatToString);
|
||||||
|
|
||||||
scriptProtoDefineFunc(
|
scriptProtoDefineFunc(
|
||||||
&MODULE_MAT4_PROTO, "mul", moduleMatMul
|
&MODULE_MAT4_PROTO, "mul", moduleMatMul
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -142,6 +142,14 @@ moduleBaseFunction(moduleVec2Distance) {
|
|||||||
return jerry_number(glm_vec2_distance(a, b));
|
return jerry_number(glm_vec2_distance(a, b));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
moduleBaseFunction(moduleVec2ToString) {
|
||||||
|
float_t *v = moduleVec2Get(callInfo);
|
||||||
|
if(!v) return jerry_string_sz("Vec2(?, ?)");
|
||||||
|
char_t buf[64];
|
||||||
|
stringFormat(buf, sizeof(buf), "Vec2(%g, %g)", v[0], v[1]);
|
||||||
|
return jerry_string_sz(buf);
|
||||||
|
}
|
||||||
|
|
||||||
static inline jerry_value_t moduleVec2Push(const float_t *v) {
|
static inline jerry_value_t moduleVec2Push(const float_t *v) {
|
||||||
return scriptProtoCreateValue(&MODULE_VEC2_PROTO, v);
|
return scriptProtoCreateValue(&MODULE_VEC2_PROTO, v);
|
||||||
}
|
}
|
||||||
@@ -166,6 +174,8 @@ static void moduleVec2(void) {
|
|||||||
&MODULE_VEC2_PROTO, "y", moduleVec2GetY, moduleVec2SetY
|
&MODULE_VEC2_PROTO, "y", moduleVec2GetY, moduleVec2SetY
|
||||||
);
|
);
|
||||||
|
|
||||||
|
scriptProtoDefineToString(&MODULE_VEC2_PROTO, moduleVec2ToString);
|
||||||
|
|
||||||
scriptProtoDefineFunc(&MODULE_VEC2_PROTO, "dot", moduleVec2Dot);
|
scriptProtoDefineFunc(&MODULE_VEC2_PROTO, "dot", moduleVec2Dot);
|
||||||
scriptProtoDefineFunc(&MODULE_VEC2_PROTO, "length", moduleVec2Length);
|
scriptProtoDefineFunc(&MODULE_VEC2_PROTO, "length", moduleVec2Length);
|
||||||
scriptProtoDefineFunc(&MODULE_VEC2_PROTO, "lengthSq", moduleVec2LengthSq);
|
scriptProtoDefineFunc(&MODULE_VEC2_PROTO, "lengthSq", moduleVec2LengthSq);
|
||||||
|
|||||||
@@ -165,6 +165,14 @@ moduleBaseFunction(moduleVec3Distance) {
|
|||||||
return jerry_number(glm_vec3_distance(a, b));
|
return jerry_number(glm_vec3_distance(a, b));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
moduleBaseFunction(moduleVec3ToString) {
|
||||||
|
float_t *v = moduleVec3Get(callInfo);
|
||||||
|
if(!v) return jerry_string_sz("Vec3(?, ?, ?)");
|
||||||
|
char_t buf[80];
|
||||||
|
stringFormat(buf, sizeof(buf), "Vec3(%g, %g, %g)", v[0], v[1], v[2]);
|
||||||
|
return jerry_string_sz(buf);
|
||||||
|
}
|
||||||
|
|
||||||
static inline jerry_value_t moduleVec3Push(const float_t *v) {
|
static inline jerry_value_t moduleVec3Push(const float_t *v) {
|
||||||
return scriptProtoCreateValue(&MODULE_VEC3_PROTO, v);
|
return scriptProtoCreateValue(&MODULE_VEC3_PROTO, v);
|
||||||
}
|
}
|
||||||
@@ -193,6 +201,8 @@ static void moduleVec3(void) {
|
|||||||
&MODULE_VEC3_PROTO, "z", moduleVec3GetZ, moduleVec3SetZ
|
&MODULE_VEC3_PROTO, "z", moduleVec3GetZ, moduleVec3SetZ
|
||||||
);
|
);
|
||||||
|
|
||||||
|
scriptProtoDefineToString(&MODULE_VEC3_PROTO, moduleVec3ToString);
|
||||||
|
|
||||||
scriptProtoDefineFunc(&MODULE_VEC3_PROTO, "dot", moduleVec3Dot);
|
scriptProtoDefineFunc(&MODULE_VEC3_PROTO, "dot", moduleVec3Dot);
|
||||||
scriptProtoDefineFunc(&MODULE_VEC3_PROTO, "cross", moduleVec3Cross);
|
scriptProtoDefineFunc(&MODULE_VEC3_PROTO, "cross", moduleVec3Cross);
|
||||||
scriptProtoDefineFunc(&MODULE_VEC3_PROTO, "length", moduleVec3Length);
|
scriptProtoDefineFunc(&MODULE_VEC3_PROTO, "length", moduleVec3Length);
|
||||||
|
|||||||
@@ -74,6 +74,17 @@ moduleBaseFunction(moduleVec3RefSetZ) {
|
|||||||
return jerry_undefined();
|
return jerry_undefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
moduleBaseFunction(moduleVec3RefToString) {
|
||||||
|
vec3ref_t *ref = moduleVec3RefGet(callInfo);
|
||||||
|
if(!ref) return jerry_string_sz("Vec3(?, ?, ?)");
|
||||||
|
char_t buf[80];
|
||||||
|
stringFormat(
|
||||||
|
buf, sizeof(buf),
|
||||||
|
"Vec3(%g, %g, %g)", ref->data[0], ref->data[1], ref->data[2]
|
||||||
|
);
|
||||||
|
return jerry_string_sz(buf);
|
||||||
|
}
|
||||||
|
|
||||||
static inline jerry_value_t moduleVec3RefPush(
|
static inline jerry_value_t moduleVec3RefPush(
|
||||||
float_t *data, void (*onChange)(void *), void *ctx
|
float_t *data, void (*onChange)(void *), void *ctx
|
||||||
) {
|
) {
|
||||||
@@ -98,6 +109,8 @@ static void moduleVec3Ref(void) {
|
|||||||
scriptProtoInit(
|
scriptProtoInit(
|
||||||
&MODULE_VEC3_REF_PROTO, NULL, sizeof(vec3ref_t), NULL
|
&MODULE_VEC3_REF_PROTO, NULL, sizeof(vec3ref_t), NULL
|
||||||
);
|
);
|
||||||
|
scriptProtoDefineToString(&MODULE_VEC3_REF_PROTO, moduleVec3RefToString);
|
||||||
|
|
||||||
scriptProtoDefineProp(
|
scriptProtoDefineProp(
|
||||||
&MODULE_VEC3_REF_PROTO, "x",
|
&MODULE_VEC3_REF_PROTO, "x",
|
||||||
moduleVec3RefGetX, moduleVec3RefSetX
|
moduleVec3RefGetX, moduleVec3RefSetX
|
||||||
|
|||||||
@@ -199,6 +199,17 @@ moduleBaseFunction(moduleVec4Lerp) {
|
|||||||
return scriptProtoCreateValue(&MODULE_VEC4_PROTO, r);
|
return scriptProtoCreateValue(&MODULE_VEC4_PROTO, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
moduleBaseFunction(moduleVec4ToString) {
|
||||||
|
float_t *v = moduleVec4Get(callInfo);
|
||||||
|
if(!v) return jerry_string_sz("Vec4(?, ?, ?, ?)");
|
||||||
|
char_t buf[96];
|
||||||
|
stringFormat(
|
||||||
|
buf, sizeof(buf),
|
||||||
|
"Vec4(%g, %g, %g, %g)", v[0], v[1], v[2], v[3]
|
||||||
|
);
|
||||||
|
return jerry_string_sz(buf);
|
||||||
|
}
|
||||||
|
|
||||||
static inline jerry_value_t moduleVec4Push(const float_t *v) {
|
static inline jerry_value_t moduleVec4Push(const float_t *v) {
|
||||||
return scriptProtoCreateValue(&MODULE_VEC4_PROTO, v);
|
return scriptProtoCreateValue(&MODULE_VEC4_PROTO, v);
|
||||||
}
|
}
|
||||||
@@ -243,6 +254,8 @@ static void moduleVec4(void) {
|
|||||||
&MODULE_VEC4_PROTO, "v1", moduleVec4GetV1, moduleVec4SetV1
|
&MODULE_VEC4_PROTO, "v1", moduleVec4GetV1, moduleVec4SetV1
|
||||||
);
|
);
|
||||||
|
|
||||||
|
scriptProtoDefineToString(&MODULE_VEC4_PROTO, moduleVec4ToString);
|
||||||
|
|
||||||
scriptProtoDefineFunc(&MODULE_VEC4_PROTO, "dot", moduleVec4Dot);
|
scriptProtoDefineFunc(&MODULE_VEC4_PROTO, "dot", moduleVec4Dot);
|
||||||
scriptProtoDefineFunc(&MODULE_VEC4_PROTO, "length", moduleVec4Length);
|
scriptProtoDefineFunc(&MODULE_VEC4_PROTO, "length", moduleVec4Length);
|
||||||
scriptProtoDefineFunc(&MODULE_VEC4_PROTO, "lengthSq", moduleVec4LengthSq);
|
scriptProtoDefineFunc(&MODULE_VEC4_PROTO, "lengthSq", moduleVec4LengthSq);
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "script/module/display/modulescreen.h"
|
#include "script/module/display/modulescreen.h"
|
||||||
#include "script/module/scene/modulescene.h"
|
#include "script/module/scene/modulescene.h"
|
||||||
#include "script/module/console/moduleconsole.h"
|
#include "script/module/console/moduleconsole.h"
|
||||||
|
#include "script/module/engine/moduleengine.h"
|
||||||
|
|
||||||
static void moduleRegister(void) {
|
static void moduleRegister(void) {
|
||||||
moduleInclude();
|
moduleInclude();
|
||||||
@@ -28,4 +29,5 @@ static void moduleRegister(void) {
|
|||||||
moduleScreen();
|
moduleScreen();
|
||||||
moduleScene();
|
moduleScene();
|
||||||
moduleConsole();
|
moduleConsole();
|
||||||
|
moduleEngine();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ errorret_t scriptManagerInit(void) {
|
|||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
errorret_t scriptManagerExec(const char_t *script) {
|
errorret_t scriptManagerExec(const char_t *script, jerry_value_t *resultOut) {
|
||||||
assertNotNull(script, "Script cannot be NULL");
|
assertNotNull(script, "Script cannot be NULL");
|
||||||
|
|
||||||
jerry_value_t result = jerry_eval(
|
jerry_value_t result = jerry_eval(
|
||||||
@@ -62,7 +62,11 @@ errorret_t scriptManagerExec(const char_t *script) {
|
|||||||
errorThrow("Failed to execute script: %s", buf);
|
errorThrow("Failed to execute script: %s", buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(resultOut != NULL) {
|
||||||
|
*resultOut = result;
|
||||||
|
} else {
|
||||||
jerry_value_free(result);
|
jerry_value_free(result);
|
||||||
|
}
|
||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,9 +37,12 @@ errorret_t scriptManagerInit(void);
|
|||||||
* Execute a JS string in the active script context.
|
* Execute a JS string in the active script context.
|
||||||
*
|
*
|
||||||
* @param script The JS source to execute.
|
* @param script The JS source to execute.
|
||||||
|
* @param result Optional out-parameter for the script's return value.
|
||||||
|
* Caller must call jerry_value_free() on it when done.
|
||||||
|
* Pass NULL to discard the return value.
|
||||||
* @return The error return value.
|
* @return The error return value.
|
||||||
*/
|
*/
|
||||||
errorret_t scriptManagerExec(const char_t *script);
|
errorret_t scriptManagerExec(const char_t *script, jerry_value_t *result);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute a JS file in the active script context.
|
* Execute a JS file in the active script context.
|
||||||
|
|||||||
@@ -9,5 +9,5 @@
|
|||||||
#include "script/scriptmanager.h"
|
#include "script/scriptmanager.h"
|
||||||
|
|
||||||
void modulePlatformVita(void) {
|
void modulePlatformVita(void) {
|
||||||
scriptManagerExec("VITA = true\n");
|
scriptManagerExec("VITA = true\n", NULL);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user