No script
This commit is contained in:
@@ -32,15 +32,6 @@ if(NOT yyjson_FOUND)
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NOT jerryscript_FOUND)
|
|
||||||
find_package(jerryscript REQUIRED)
|
|
||||||
target_link_libraries(${DUSK_LIBRARY_TARGET_NAME} PUBLIC
|
|
||||||
jerryscript::core
|
|
||||||
jerryscript::ext
|
|
||||||
jerryscript::port
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Includes
|
# Includes
|
||||||
target_include_directories(${DUSK_LIBRARY_TARGET_NAME}
|
target_include_directories(${DUSK_LIBRARY_TARGET_NAME}
|
||||||
PUBLIC
|
PUBLIC
|
||||||
@@ -71,7 +62,6 @@ add_subdirectory(input)
|
|||||||
add_subdirectory(locale)
|
add_subdirectory(locale)
|
||||||
add_subdirectory(physics)
|
add_subdirectory(physics)
|
||||||
add_subdirectory(scene)
|
add_subdirectory(scene)
|
||||||
add_subdirectory(script)
|
|
||||||
add_subdirectory(system)
|
add_subdirectory(system)
|
||||||
add_subdirectory(time)
|
add_subdirectory(time)
|
||||||
add_subdirectory(ui)
|
add_subdirectory(ui)
|
||||||
|
|||||||
@@ -8,5 +8,4 @@
|
|||||||
# Subdirs
|
# Subdirs
|
||||||
add_subdirectory(display)
|
add_subdirectory(display)
|
||||||
add_subdirectory(locale)
|
add_subdirectory(locale)
|
||||||
add_subdirectory(script)
|
|
||||||
add_subdirectory(json)
|
add_subdirectory(json)
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
# Copyright (c) 2026 Dominic Masters
|
|
||||||
#
|
|
||||||
# This software is released under the MIT License.
|
|
||||||
# https://opensource.org/licenses/MIT
|
|
||||||
|
|
||||||
# Sources
|
|
||||||
target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
|
||||||
PUBLIC
|
|
||||||
assetscriptloader.c
|
|
||||||
)
|
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2026 Dominic Masters
|
|
||||||
*
|
|
||||||
* This software is released under the MIT License.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "assetscriptloader.h"
|
|
||||||
#include "assert/assert.h"
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <zip.h>
|
|
||||||
|
|
||||||
errorret_t assetScriptLoader(assetfile_t *file) {
|
|
||||||
assertNotNull(file, "Asset file cannot be NULL");
|
|
||||||
assertNull(file->zipFile, "Asset file zip handle must be NULL before open");
|
|
||||||
assertNotNull(file->output, "Asset file output cannot be NULL");
|
|
||||||
|
|
||||||
assetscript_t *script = (assetscript_t *)file->output;
|
|
||||||
|
|
||||||
errorChain(assetFileOpen(file));
|
|
||||||
|
|
||||||
// Accumulate full source into a dynamically grown buffer.
|
|
||||||
size_t srcLen = 0;
|
|
||||||
size_t capacity = ASSET_SCRIPT_CHUNK_SIZE;
|
|
||||||
char_t *src = (char_t *)malloc(capacity + 1);
|
|
||||||
if(!src) {
|
|
||||||
assetFileClose(file);
|
|
||||||
errorThrow("Out of memory reading script: %s", file->filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
while(1) {
|
|
||||||
if(srcLen + ASSET_SCRIPT_CHUNK_SIZE > capacity) {
|
|
||||||
capacity = srcLen + ASSET_SCRIPT_CHUNK_SIZE;
|
|
||||||
char_t *tmp = (char_t *)realloc(src, capacity + 1);
|
|
||||||
if(!tmp) {
|
|
||||||
free(src);
|
|
||||||
assetFileClose(file);
|
|
||||||
errorThrow("Out of memory reading script: %s", file->filename);
|
|
||||||
}
|
|
||||||
src = tmp;
|
|
||||||
}
|
|
||||||
zip_int64_t n = zip_fread(
|
|
||||||
file->zipFile, src + srcLen, ASSET_SCRIPT_CHUNK_SIZE
|
|
||||||
);
|
|
||||||
if(n <= 0) break;
|
|
||||||
srcLen += (size_t)n;
|
|
||||||
}
|
|
||||||
src[srcLen] = '\0';
|
|
||||||
|
|
||||||
errorret_t closeRet = assetFileClose(file);
|
|
||||||
|
|
||||||
jerry_value_t result = jerry_eval(
|
|
||||||
(const jerry_char_t *)src,
|
|
||||||
srcLen,
|
|
||||||
JERRY_PARSE_NO_OPTS
|
|
||||||
);
|
|
||||||
free(src);
|
|
||||||
|
|
||||||
if(jerry_value_is_exception(result)) {
|
|
||||||
jerry_value_t errVal = jerry_exception_value(result, false);
|
|
||||||
jerry_value_t errStr = jerry_value_to_string(errVal);
|
|
||||||
char_t buf[256];
|
|
||||||
jerry_size_t len = jerry_string_to_buffer(
|
|
||||||
errStr, JERRY_ENCODING_UTF8, (jerry_char_t *)buf, sizeof(buf) - 1
|
|
||||||
);
|
|
||||||
buf[len] = '\0';
|
|
||||||
jerry_value_free(errStr);
|
|
||||||
jerry_value_free(errVal);
|
|
||||||
jerry_value_free(result);
|
|
||||||
errorThrow("Script error in '%s': %s", file->filename, buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(script->resultOut != NULL) {
|
|
||||||
*(script->resultOut) = result;
|
|
||||||
} else {
|
|
||||||
jerry_value_free(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
return closeRet;
|
|
||||||
}
|
|
||||||
|
|
||||||
errorret_t assetScriptLoad(
|
|
||||||
const char_t *path,
|
|
||||||
jerry_value_t *resultOut
|
|
||||||
) {
|
|
||||||
assertNotNull(path, "Script path cannot be NULL");
|
|
||||||
|
|
||||||
assetscript_t scriptData;
|
|
||||||
scriptData.resultOut = resultOut;
|
|
||||||
|
|
||||||
return assetLoad(path, assetScriptLoader, NULL, &scriptData);
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2026 Dominic Masters
|
|
||||||
*
|
|
||||||
* This software is released under the MIT License.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include "asset/asset.h"
|
|
||||||
|
|
||||||
#define ASSET_SCRIPT_CHUNK_SIZE 1024
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
jerry_value_t *resultOut;
|
|
||||||
} assetscript_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handler for script assets. Reads the full source, evaluates it with
|
|
||||||
* JerryScript, and optionally stores the result.
|
|
||||||
*
|
|
||||||
* @param file Asset file to load the script from.
|
|
||||||
* @return Any error that occurs during loading.
|
|
||||||
*/
|
|
||||||
errorret_t assetScriptLoader(assetfile_t *file);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads a script from the specified path.
|
|
||||||
*
|
|
||||||
* @param path Path to the script asset.
|
|
||||||
* @param resultOut Optional out-parameter for the script return value.
|
|
||||||
* Caller must call jerry_value_free() if non-NULL.
|
|
||||||
* Pass NULL to discard the return value.
|
|
||||||
* @return Any error that occurs during loading.
|
|
||||||
*/
|
|
||||||
errorret_t assetScriptLoad(
|
|
||||||
const char_t *path,
|
|
||||||
jerry_value_t *resultOut
|
|
||||||
);
|
|
||||||
+1
-109
@@ -12,7 +12,6 @@
|
|||||||
#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 "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"
|
||||||
@@ -23,10 +22,7 @@ void consoleInit(void) {
|
|||||||
memoryZero(&CONSOLE, sizeof(console_t));
|
memoryZero(&CONSOLE, sizeof(console_t));
|
||||||
|
|
||||||
#ifdef DUSK_CONSOLE_POSIX
|
#ifdef DUSK_CONSOLE_POSIX
|
||||||
threadInit(&CONSOLE.thread, consoleInputThread);
|
|
||||||
threadMutexInit(&CONSOLE.execMutex);
|
|
||||||
threadMutexInit(&CONSOLE.printMutex);
|
threadMutexInit(&CONSOLE.printMutex);
|
||||||
threadStartRequest(&CONSOLE.thread);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,30 +52,6 @@ void consolePrint(const char_t *message, ...) {
|
|||||||
logDebug("%s\n", buffer);
|
logDebug("%s\n", buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void consoleExec(const char_t *line) {
|
|
||||||
assertNotNull(line, "line must not be NULL");
|
|
||||||
|
|
||||||
#ifdef DUSK_CONSOLE_POSIX
|
|
||||||
threadMutexLock(&CONSOLE.execMutex);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
assertTrue(
|
|
||||||
CONSOLE.execBufferCount < CONSOLE_EXEC_BUFFER_MAX,
|
|
||||||
"Console exec buffer is full"
|
|
||||||
);
|
|
||||||
|
|
||||||
stringCopy(
|
|
||||||
CONSOLE.execBuffer[CONSOLE.execBufferCount],
|
|
||||||
line,
|
|
||||||
CONSOLE_LINE_MAX
|
|
||||||
);
|
|
||||||
CONSOLE.execBufferCount++;
|
|
||||||
|
|
||||||
#ifdef DUSK_CONSOLE_POSIX
|
|
||||||
threadMutexUnlock(&CONSOLE.execMutex);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void consoleUpdate(void) {
|
void consoleUpdate(void) {
|
||||||
#ifdef DUSK_TIME_DYNAMIC
|
#ifdef DUSK_TIME_DYNAMIC
|
||||||
if(TIME.dynamicUpdate) return;
|
if(TIME.dynamicUpdate) return;
|
||||||
@@ -88,40 +60,6 @@ void consoleUpdate(void) {
|
|||||||
if(inputPressed(INPUT_ACTION_CONSOLE)) {
|
if(inputPressed(INPUT_ACTION_CONSOLE)) {
|
||||||
CONSOLE.visible = !CONSOLE.visible;
|
CONSOLE.visible = !CONSOLE.visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(CONSOLE.execBufferCount == 0) return;
|
|
||||||
|
|
||||||
#ifdef DUSK_CONSOLE_POSIX
|
|
||||||
threadMutexLock(&CONSOLE.execMutex);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
char_t execBuffer[CONSOLE_EXEC_BUFFER_MAX][CONSOLE_LINE_MAX];
|
|
||||||
uint32_t execBufferCount = CONSOLE.execBufferCount;
|
|
||||||
memoryCopy(execBuffer, CONSOLE.execBuffer, sizeof(execBuffer));
|
|
||||||
CONSOLE.execBufferCount = 0;
|
|
||||||
|
|
||||||
#ifdef DUSK_CONSOLE_POSIX
|
|
||||||
threadMutexUnlock(&CONSOLE.execMutex);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for(uint32_t i = 0; i < execBufferCount; i++) {
|
|
||||||
jerry_value_t result = 0;
|
|
||||||
errorret_t err = scriptManagerExec(execBuffer[i], &result);
|
|
||||||
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(void) {
|
errorret_t consoleDraw(void) {
|
||||||
@@ -140,52 +78,6 @@ errorret_t consoleDraw(void) {
|
|||||||
|
|
||||||
void consoleDispose(void) {
|
void consoleDispose(void) {
|
||||||
#ifdef DUSK_CONSOLE_POSIX
|
#ifdef DUSK_CONSOLE_POSIX
|
||||||
threadStop(&CONSOLE.thread);
|
|
||||||
threadMutexDispose(&CONSOLE.execMutex);
|
|
||||||
threadMutexDispose(&CONSOLE.printMutex);
|
threadMutexDispose(&CONSOLE.printMutex);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DUSK_CONSOLE_POSIX
|
|
||||||
void consoleInputThread(thread_t *thread) {
|
|
||||||
assertNotNull(thread, "Thread cannot be NULL.");
|
|
||||||
|
|
||||||
char_t line[CONSOLE_LINE_MAX];
|
|
||||||
|
|
||||||
struct pollfd pfd = {
|
|
||||||
.fd = STDIN_FILENO,
|
|
||||||
.events = POLLIN
|
|
||||||
};
|
|
||||||
|
|
||||||
while(!threadShouldStop(thread) && ENGINE.running) {
|
|
||||||
int32_t rc = poll(&pfd, 1, CONSOLE_POSIX_POLL_RATE);
|
|
||||||
|
|
||||||
if(rc == 0) continue;
|
|
||||||
if(rc < 0) {
|
|
||||||
if(errno == EINTR) continue;
|
|
||||||
assertUnreachable("poll() failed with unexpected error.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) break;
|
|
||||||
if(!(pfd.revents & POLLIN)) {
|
|
||||||
pfd.revents = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!fgets(line, CONSOLE_LINE_MAX, stdin)) {
|
|
||||||
if(feof(stdin)) break;
|
|
||||||
clearerr(stdin);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t len = strlen(line);
|
|
||||||
while(len && (line[len - 1] == '\n' || line[len - 1] == '\r')) {
|
|
||||||
line[--len] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
if(len > 0) consoleExec(line);
|
|
||||||
|
|
||||||
pfd.revents = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -21,12 +21,7 @@ typedef struct {
|
|||||||
char_t line[CONSOLE_HISTORY_MAX][CONSOLE_LINE_MAX];
|
char_t line[CONSOLE_HISTORY_MAX][CONSOLE_LINE_MAX];
|
||||||
bool_t visible;
|
bool_t visible;
|
||||||
|
|
||||||
char_t execBuffer[CONSOLE_EXEC_BUFFER_MAX][CONSOLE_LINE_MAX];
|
|
||||||
uint32_t execBufferCount;
|
|
||||||
|
|
||||||
#ifdef DUSK_CONSOLE_POSIX
|
#ifdef DUSK_CONSOLE_POSIX
|
||||||
thread_t thread;
|
|
||||||
threadmutex_t execMutex;
|
|
||||||
threadmutex_t printMutex;
|
threadmutex_t printMutex;
|
||||||
#endif
|
#endif
|
||||||
} console_t;
|
} console_t;
|
||||||
@@ -45,13 +40,6 @@ void consoleInit(void);
|
|||||||
*/
|
*/
|
||||||
void consolePrint(const char_t *message, ...);
|
void consolePrint(const char_t *message, ...);
|
||||||
|
|
||||||
/**
|
|
||||||
* Queues a JS string for execution on the main thread. Thread-safe.
|
|
||||||
*
|
|
||||||
* @param line The JS source line to execute.
|
|
||||||
*/
|
|
||||||
void consoleExec(const char_t *line);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Processes pending queued script lines. Call once per frame from main thread.
|
* Processes pending queued script lines. Call once per frame from main thread.
|
||||||
*/
|
*/
|
||||||
@@ -67,13 +55,4 @@ errorret_t consoleDraw(void);
|
|||||||
/**
|
/**
|
||||||
* Disposes of the console.
|
* Disposes of the console.
|
||||||
*/
|
*/
|
||||||
void consoleDispose(void);
|
void consoleDispose(void);
|
||||||
|
|
||||||
#ifdef DUSK_CONSOLE_POSIX
|
|
||||||
/**
|
|
||||||
* Input thread handler for POSIX stdin.
|
|
||||||
*
|
|
||||||
* @param thread The thread that is running.
|
|
||||||
*/
|
|
||||||
void consoleInputThread(thread_t *thread);
|
|
||||||
#endif
|
|
||||||
+13
-104
@@ -6,102 +6,13 @@
|
|||||||
#include "cutscene.h"
|
#include "cutscene.h"
|
||||||
#include "assert/assert.h"
|
#include "assert/assert.h"
|
||||||
#include "util/memory.h"
|
#include "util/memory.h"
|
||||||
#include "script/module/modulebase.h"
|
|
||||||
#include "script/module/cutscene/modulecutscene.h"
|
|
||||||
#include "console/console.h"
|
#include "console/console.h"
|
||||||
#include "time/time.h"
|
#include "time/time.h"
|
||||||
|
|
||||||
cutscene_t CUTSCENE;
|
cutscene_t CUTSCENE;
|
||||||
|
|
||||||
static errorret_t cutsceneCallMethod(const char_t *method) {
|
|
||||||
if(CUTSCENE.scriptRef == CUTSCENE_SCRIPT_REF_NONE) errorOk();
|
|
||||||
|
|
||||||
jerry_value_t key = jerry_string_sz(method);
|
|
||||||
jerry_value_t fn = jerry_object_get(CUTSCENE.scriptRef, key);
|
|
||||||
jerry_value_free(key);
|
|
||||||
|
|
||||||
if(!jerry_value_is_function(fn)) {
|
|
||||||
jerry_value_free(fn);
|
|
||||||
errorOk();
|
|
||||||
}
|
|
||||||
|
|
||||||
jerry_value_t result = jerry_call(fn, CUTSCENE.scriptRef, NULL, 0);
|
|
||||||
jerry_value_free(fn);
|
|
||||||
|
|
||||||
if(jerry_value_is_exception(result)) {
|
|
||||||
cutsceneevent_t *event = &CUTSCENE.events[CUTSCENE.eventCurrent];
|
|
||||||
char_t errMsg[512];
|
|
||||||
moduleBaseExceptionMessage(result, errMsg, sizeof(errMsg));
|
|
||||||
jerry_value_free(result);
|
|
||||||
errorThrow(
|
|
||||||
"Cutscene event '%s' %s failed: %s",
|
|
||||||
event->script.script, method, errMsg
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
jerry_value_free(result);
|
|
||||||
errorOk();
|
|
||||||
}
|
|
||||||
|
|
||||||
static errorret_t cutsceneEventStart(void) {
|
|
||||||
cutsceneevent_t *event = &CUTSCENE.events[CUTSCENE.eventCurrent];
|
|
||||||
|
|
||||||
if(event->type == CUTSCENE_EVENT_TYPE_NATIVE) {
|
|
||||||
if(event->native.onStart) errorChain(event->native.onStart());
|
|
||||||
} else if(event->type == CUTSCENE_EVENT_TYPE_SCRIPT) {
|
|
||||||
jerry_value_t eventClass = CUTSCENE_SCRIPT_REF_NONE;
|
|
||||||
errorChain(scriptManagerExecFile(event->script.script, &eventClass));
|
|
||||||
|
|
||||||
if(!jerry_value_is_function(eventClass)) {
|
|
||||||
if(eventClass != CUTSCENE_SCRIPT_REF_NONE) jerry_value_free(eventClass);
|
|
||||||
errorThrow(
|
|
||||||
"Cutscene event '%s' must export a constructor function",
|
|
||||||
event->script.script
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
jerry_value_t eventObj = jerry_construct(eventClass, NULL, 0);
|
|
||||||
jerry_value_free(eventClass);
|
|
||||||
|
|
||||||
if(jerry_value_is_exception(eventObj)) {
|
|
||||||
char_t errMsg[512];
|
|
||||||
moduleBaseExceptionMessage(eventObj, errMsg, sizeof(errMsg));
|
|
||||||
jerry_value_free(eventObj);
|
|
||||||
errorThrow(
|
|
||||||
"Cutscene event '%s' constructor threw: %s",
|
|
||||||
event->script.script, errMsg
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
CUTSCENE.scriptRef = eventObj;
|
|
||||||
errorChain(cutsceneCallMethod("onStart"));
|
|
||||||
}
|
|
||||||
|
|
||||||
errorOk();
|
|
||||||
}
|
|
||||||
|
|
||||||
static errorret_t cutsceneEventEnd(void) {
|
|
||||||
cutsceneevent_t *event = &CUTSCENE.events[CUTSCENE.eventCurrent];
|
|
||||||
|
|
||||||
if(event->type == CUTSCENE_EVENT_TYPE_NATIVE) {
|
|
||||||
if(event->native.onEnd) errorChain(event->native.onEnd());
|
|
||||||
} else if(event->type == CUTSCENE_EVENT_TYPE_SCRIPT) {
|
|
||||||
errorret_t err = cutsceneCallMethod("onEnd");
|
|
||||||
if(CUTSCENE.scriptRef != CUTSCENE_SCRIPT_REF_NONE) {
|
|
||||||
jerry_value_free(CUTSCENE.scriptRef);
|
|
||||||
CUTSCENE.scriptRef = CUTSCENE_SCRIPT_REF_NONE;
|
|
||||||
}
|
|
||||||
errorChain(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
errorOk();
|
|
||||||
}
|
|
||||||
|
|
||||||
errorret_t cutsceneInit(void) {
|
errorret_t cutsceneInit(void) {
|
||||||
memoryZero(&CUTSCENE, sizeof(cutscene_t));
|
memoryZero(&CUTSCENE, sizeof(cutscene_t));
|
||||||
CUTSCENE.scriptRef = CUTSCENE_SCRIPT_REF_NONE;
|
|
||||||
CUTSCENE.activeRef = CUTSCENE_SCRIPT_REF_NONE;
|
|
||||||
consolePrint("Cutscene init");
|
|
||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,18 +23,10 @@ errorret_t cutsceneUpdate(void) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
errorChain(moduleCutsceneUpdate());
|
|
||||||
|
|
||||||
if(!CUTSCENE.active) errorOk();
|
if(!CUTSCENE.active) errorOk();
|
||||||
|
|
||||||
cutsceneevent_t *event = &CUTSCENE.events[CUTSCENE.eventCurrent];
|
cutsceneevent_t *event = &CUTSCENE.events[CUTSCENE.eventCurrent];
|
||||||
|
if(event->onUpdate) errorChain(event->onUpdate());
|
||||||
if(event->type == CUTSCENE_EVENT_TYPE_NATIVE) {
|
|
||||||
if(event->native.onUpdate) errorChain(event->native.onUpdate());
|
|
||||||
} else if(event->type == CUTSCENE_EVENT_TYPE_SCRIPT) {
|
|
||||||
errorChain(cutsceneCallMethod("onUpdate"));
|
|
||||||
}
|
|
||||||
|
|
||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,23 +50,26 @@ errorret_t cutscenePlay(
|
|||||||
CUTSCENE.eventCurrent = 0;
|
CUTSCENE.eventCurrent = 0;
|
||||||
CUTSCENE.active = true;
|
CUTSCENE.active = true;
|
||||||
|
|
||||||
errorChain(cutsceneEventStart());
|
cutsceneevent_t *firstEvent = &CUTSCENE.events[0];
|
||||||
consolePrint("Cutscene play");
|
if(firstEvent->onStart) errorChain(firstEvent->onStart());
|
||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
errorret_t cutsceneAdvance(void) {
|
errorret_t cutsceneAdvance(void) {
|
||||||
if(!CUTSCENE.active) errorOk();
|
if(!CUTSCENE.active) errorOk();
|
||||||
|
|
||||||
errorChain(cutsceneEventEnd());
|
cutsceneevent_t *currentEvent = &CUTSCENE.events[CUTSCENE.eventCurrent];
|
||||||
|
if(currentEvent->onEnd) errorChain(currentEvent->onEnd());
|
||||||
CUTSCENE.eventCurrent++;
|
CUTSCENE.eventCurrent++;
|
||||||
|
|
||||||
if(CUTSCENE.eventCurrent >= CUTSCENE.eventCount) {
|
if(CUTSCENE.eventCurrent >= CUTSCENE.eventCount) {
|
||||||
|
if(CUTSCENE.onStop) errorChain(CUTSCENE.onStop());
|
||||||
CUTSCENE.active = false;
|
CUTSCENE.active = false;
|
||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
errorChain(cutsceneEventStart());
|
cutsceneevent_t *nextEvent = &CUTSCENE.events[CUTSCENE.eventCurrent];
|
||||||
|
if(nextEvent->onStart) errorChain(nextEvent->onStart());
|
||||||
consolePrint("Cutscene advance");
|
consolePrint("Cutscene advance");
|
||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
@@ -171,9 +77,12 @@ errorret_t cutsceneAdvance(void) {
|
|||||||
errorret_t cutsceneStop(void) {
|
errorret_t cutsceneStop(void) {
|
||||||
if(!CUTSCENE.active) errorOk();
|
if(!CUTSCENE.active) errorOk();
|
||||||
|
|
||||||
errorChain(cutsceneEventEnd());
|
cutsceneevent_t *currentEvent = &CUTSCENE.events[CUTSCENE.eventCurrent];
|
||||||
|
if(currentEvent->onEnd) errorChain(currentEvent->onEnd());
|
||||||
|
|
||||||
|
if(CUTSCENE.onStop) errorChain(CUTSCENE.onStop());
|
||||||
|
|
||||||
CUTSCENE.active = false;
|
CUTSCENE.active = false;
|
||||||
consolePrint("Cutscene stop");
|
|
||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,42 +4,23 @@
|
|||||||
// https://opensource.org/licenses/MIT
|
// https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "script/scriptmanager.h"
|
|
||||||
#include "error/error.h"
|
#include "error/error.h"
|
||||||
|
|
||||||
#define CUTSCENE_EVENT_COUNT_MAX 16
|
#define CUTSCENE_EVENT_COUNT_MAX 16
|
||||||
#define CUTSCENE_SCRIPT_REF_NONE ((jerry_value_t)0)
|
#define CUTSCENE_SCRIPT_REF_NONE ((jerry_value_t)0)
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
CUTSCENE_EVENT_TYPE_NULL,
|
|
||||||
CUTSCENE_EVENT_TYPE_NATIVE,
|
|
||||||
CUTSCENE_EVENT_TYPE_SCRIPT,
|
|
||||||
CUTSCENE_EVENT_TYPE_COUNT
|
|
||||||
} cutsceneeventtype_t;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
cutsceneeventtype_t type;
|
errorret_t (*onStart)(void);
|
||||||
|
errorret_t (*onEnd)(void);
|
||||||
union {
|
errorret_t (*onUpdate)(void);
|
||||||
struct {
|
|
||||||
errorret_t (*onStart)(void);
|
|
||||||
errorret_t (*onEnd)(void);
|
|
||||||
errorret_t (*onUpdate)(void);
|
|
||||||
} native;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
const char_t *script;
|
|
||||||
} script;
|
|
||||||
};
|
|
||||||
} cutsceneevent_t;
|
} cutsceneevent_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
cutsceneevent_t events[CUTSCENE_EVENT_COUNT_MAX];
|
cutsceneevent_t events[CUTSCENE_EVENT_COUNT_MAX];
|
||||||
uint8_t eventCount;
|
uint8_t eventCount;
|
||||||
uint8_t eventCurrent;
|
uint8_t eventCurrent;
|
||||||
|
errorret_t (*onStop)(void);
|
||||||
bool_t active;
|
bool_t active;
|
||||||
jerry_value_t scriptRef;
|
|
||||||
jerry_value_t activeRef;
|
|
||||||
} cutscene_t;
|
} cutscene_t;
|
||||||
|
|
||||||
extern cutscene_t CUTSCENE;
|
extern cutscene_t CUTSCENE;
|
||||||
|
|||||||
@@ -23,7 +23,6 @@
|
|||||||
#include <cglm/cglm.h>
|
#include <cglm/cglm.h>
|
||||||
#include <cglm/types.h>
|
#include <cglm/types.h>
|
||||||
#include <cglm/vec2.h>
|
#include <cglm/vec2.h>
|
||||||
#include <jerryscript.h>
|
|
||||||
|
|
||||||
#include "duskplatform.h"
|
#include "duskplatform.h"
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
#include "asset/asset.h"
|
#include "asset/asset.h"
|
||||||
#include "ui/ui.h"
|
#include "ui/ui.h"
|
||||||
#include "ui/uitextbox.h"
|
#include "ui/uitextbox.h"
|
||||||
#include "script/scriptmanager.h"
|
|
||||||
#include "assert/assert.h"
|
#include "assert/assert.h"
|
||||||
#include "entity/entitymanager.h"
|
#include "entity/entitymanager.h"
|
||||||
#include "entity/component/physics/entityphysics.h"
|
#include "entity/component/physics/entityphysics.h"
|
||||||
@@ -53,7 +52,6 @@ errorret_t engineInit(const int32_t argc, const char_t **argv) {
|
|||||||
errorChain(assetInit());
|
errorChain(assetInit());
|
||||||
// errorChain(saveInit());
|
// errorChain(saveInit());
|
||||||
errorChain(localeManagerInit());
|
errorChain(localeManagerInit());
|
||||||
errorChain(scriptManagerInit());
|
|
||||||
errorChain(displayInit());
|
errorChain(displayInit());
|
||||||
errorChain(uiInit());
|
errorChain(uiInit());
|
||||||
errorChain(uiTextboxInit());
|
errorChain(uiTextboxInit());
|
||||||
@@ -67,7 +65,7 @@ errorret_t engineInit(const int32_t argc, const char_t **argv) {
|
|||||||
|
|
||||||
/* Run the init script. */
|
/* Run the init script. */
|
||||||
consolePrint("Engine initialized");
|
consolePrint("Engine initialized");
|
||||||
errorChain(scriptManagerExecFile("init.js", NULL));
|
// errorChain(scriptManagerExecFile("init.js", NULL));
|
||||||
|
|
||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,6 @@
|
|||||||
#include "util/memory.h"
|
#include "util/memory.h"
|
||||||
#include "util/string.h"
|
#include "util/string.h"
|
||||||
#include "console/console.h"
|
#include "console/console.h"
|
||||||
#include "script/module/overworld/modulemap.h"
|
|
||||||
|
|
||||||
map_t MAP;
|
map_t MAP;
|
||||||
|
|
||||||
@@ -29,7 +28,6 @@ chunkindex_t mapChunkRelToIndex(
|
|||||||
|
|
||||||
void mapInit(void) {
|
void mapInit(void) {
|
||||||
memoryZero(&MAP, sizeof(map_t));
|
memoryZero(&MAP, sizeof(map_t));
|
||||||
MAP.scriptRef = MAP_SCRIPT_REF_NONE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
errorret_t mapLoad(const char_t *handle) {
|
errorret_t mapLoad(const char_t *handle) {
|
||||||
@@ -39,31 +37,11 @@ errorret_t mapLoad(const char_t *handle) {
|
|||||||
if(mapIsLoaded()) mapDispose();
|
if(mapIsLoaded()) mapDispose();
|
||||||
|
|
||||||
memoryZero(&MAP, sizeof(map_t));
|
memoryZero(&MAP, sizeof(map_t));
|
||||||
MAP.scriptRef = MAP_SCRIPT_REF_NONE;
|
|
||||||
stringCopy(MAP.handle, handle, MAP_HANDLE_MAX);
|
stringCopy(MAP.handle, handle, MAP_HANDLE_MAX);
|
||||||
|
|
||||||
char_t path[ASSET_FILE_NAME_MAX];
|
char_t path[ASSET_FILE_NAME_MAX];
|
||||||
stringFormat(path, sizeof(path), "maps/%s/init.js", handle);
|
stringFormat(path, sizeof(path), "maps/%s/init.js", handle);
|
||||||
|
|
||||||
jerry_value_t mapClass = MAP_SCRIPT_REF_NONE;
|
|
||||||
errorChain(scriptManagerExecFile(path, &mapClass));
|
|
||||||
|
|
||||||
if(!jerry_value_is_function(mapClass)) {
|
|
||||||
if(mapClass != MAP_SCRIPT_REF_NONE) jerry_value_free(mapClass);
|
|
||||||
errorThrow("Map '%s' must export a constructor function", handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
jerry_value_t mapObj = jerry_construct(mapClass, NULL, 0);
|
|
||||||
jerry_value_free(mapClass);
|
|
||||||
|
|
||||||
if(jerry_value_is_exception(mapObj)) {
|
|
||||||
char_t errMsg[512];
|
|
||||||
moduleBaseExceptionMessage(mapObj, errMsg, sizeof(errMsg));
|
|
||||||
jerry_value_free(mapObj);
|
|
||||||
errorThrow("Map '%s' constructor threw: %s", handle, errMsg);
|
|
||||||
}
|
|
||||||
|
|
||||||
MAP.scriptRef = mapObj;
|
|
||||||
consolePrint("Map loaded: %s", handle);
|
consolePrint("Map loaded: %s", handle);
|
||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
@@ -160,16 +138,11 @@ mapchunk_t *mapGetChunkAt(chunkpos_t pos) {
|
|||||||
|
|
||||||
errorret_t mapUpdate(void) {
|
errorret_t mapUpdate(void) {
|
||||||
if(!MAP.loaded) errorOk();
|
if(!MAP.loaded) errorOk();
|
||||||
errorChain(moduleMapCall("update"));
|
|
||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
void mapDispose(void) {
|
void mapDispose(void) {
|
||||||
consolePrint("Map disposing: %s", MAP.handle);
|
consolePrint("Map disposing: %s", MAP.handle);
|
||||||
if(MAP.scriptRef != MAP_SCRIPT_REF_NONE) {
|
|
||||||
moduleMapCall("dispose");
|
|
||||||
moduleMapReset();
|
|
||||||
}
|
|
||||||
if(!MAP.loaded) return;
|
if(!MAP.loaded) return;
|
||||||
for(chunkindex_t i = 0; i < MAP_CHUNKS_COUNT; i++) {
|
for(chunkindex_t i = 0; i < MAP_CHUNKS_COUNT; i++) {
|
||||||
mapChunkUnload(&MAP.chunks[i]);
|
mapChunkUnload(&MAP.chunks[i]);
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "mapchunk.h"
|
#include "mapchunk.h"
|
||||||
#include "error/error.h"
|
#include "error/error.h"
|
||||||
#include "script/scriptmanager.h"
|
|
||||||
|
|
||||||
#define MAP_NAME_MAX 64
|
#define MAP_NAME_MAX 64
|
||||||
#define MAP_HANDLE_MAX 32
|
#define MAP_HANDLE_MAX 32
|
||||||
@@ -27,12 +26,8 @@ typedef struct {
|
|||||||
mapchunk_t *chunkOrder[MAP_CHUNKS_COUNT];
|
mapchunk_t *chunkOrder[MAP_CHUNKS_COUNT];
|
||||||
chunkpos_t chunkPosition;
|
chunkpos_t chunkPosition;
|
||||||
bool_t loaded;
|
bool_t loaded;
|
||||||
jerry_value_t scriptRef;
|
|
||||||
} map_t;
|
} map_t;
|
||||||
|
|
||||||
/** Sentinel value meaning no map script is loaded. */
|
|
||||||
#define MAP_SCRIPT_REF_NONE ((jerry_value_t)0)
|
|
||||||
|
|
||||||
extern map_t MAP;
|
extern map_t MAP;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -12,11 +12,9 @@
|
|||||||
#include "util/string.h"
|
#include "util/string.h"
|
||||||
#include "asset/asset.h"
|
#include "asset/asset.h"
|
||||||
#include "console/console.h"
|
#include "console/console.h"
|
||||||
#include "script/module/overworld/modulemapchunk.h"
|
|
||||||
|
|
||||||
errorret_t mapChunkLoad(mapchunk_t *chunk) {
|
errorret_t mapChunkLoad(mapchunk_t *chunk) {
|
||||||
chunk->entityCount = 0;
|
chunk->entityCount = 0;
|
||||||
chunk->scriptRef = MAP_CHUNK_SCRIPT_REF_NONE;
|
|
||||||
memoryZero(chunk->entities, sizeof(chunk->entities));
|
memoryZero(chunk->entities, sizeof(chunk->entities));
|
||||||
|
|
||||||
if(MAP.handle[0] == '\0') errorOk();
|
if(MAP.handle[0] == '\0') errorOk();
|
||||||
@@ -33,31 +31,6 @@ errorret_t mapChunkLoad(mapchunk_t *chunk) {
|
|||||||
|
|
||||||
if(!assetFileExists(path)) errorOk();
|
if(!assetFileExists(path)) errorOk();
|
||||||
|
|
||||||
jerry_value_t chunkClass = MAP_CHUNK_SCRIPT_REF_NONE;
|
|
||||||
errorChain(scriptManagerExecFile(path, &chunkClass));
|
|
||||||
|
|
||||||
if(!jerry_value_is_function(chunkClass)) {
|
|
||||||
if(chunkClass != MAP_CHUNK_SCRIPT_REF_NONE) jerry_value_free(chunkClass);
|
|
||||||
errorThrow("Chunk script '%s' must export a constructor", path);
|
|
||||||
}
|
|
||||||
|
|
||||||
jerry_value_t args[3] = {
|
|
||||||
jerry_number((double)chunk->position.x),
|
|
||||||
jerry_number((double)chunk->position.y),
|
|
||||||
jerry_number((double)chunk->position.z),
|
|
||||||
};
|
|
||||||
jerry_value_t chunkObj = jerry_construct(chunkClass, args, 3);
|
|
||||||
jerry_value_free(chunkClass);
|
|
||||||
jerry_value_free(args[0]);
|
|
||||||
jerry_value_free(args[1]);
|
|
||||||
jerry_value_free(args[2]);
|
|
||||||
|
|
||||||
if(jerry_value_is_exception(chunkObj)) {
|
|
||||||
jerry_value_free(chunkObj);
|
|
||||||
errorThrow("Chunk script '%s' constructor threw", path);
|
|
||||||
}
|
|
||||||
|
|
||||||
chunk->scriptRef = chunkObj;
|
|
||||||
consolePrint(
|
consolePrint(
|
||||||
"Chunk loaded: %s [%d,%d,%d]",
|
"Chunk loaded: %s [%d,%d,%d]",
|
||||||
path,
|
path,
|
||||||
@@ -75,19 +48,6 @@ void mapChunkUnload(mapchunk_t *chunk) {
|
|||||||
(int)chunk->position.y,
|
(int)chunk->position.y,
|
||||||
(int)chunk->position.z
|
(int)chunk->position.z
|
||||||
);
|
);
|
||||||
if(chunk->scriptRef != MAP_CHUNK_SCRIPT_REF_NONE) {
|
|
||||||
jerry_value_t key = jerry_string_sz("dispose");
|
|
||||||
jerry_value_t fn = jerry_object_get(chunk->scriptRef, key);
|
|
||||||
jerry_value_free(key);
|
|
||||||
|
|
||||||
if(jerry_value_is_function(fn)) {
|
|
||||||
jerry_value_t result = jerry_call(fn, chunk->scriptRef, NULL, 0);
|
|
||||||
jerry_value_free(result);
|
|
||||||
}
|
|
||||||
jerry_value_free(fn);
|
|
||||||
jerry_value_free(chunk->scriptRef);
|
|
||||||
chunk->scriptRef = MAP_CHUNK_SCRIPT_REF_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(uint8_t i = 0; i < chunk->entityCount; i++) {
|
for(uint8_t i = 0; i < chunk->entityCount; i++) {
|
||||||
entityDispose(chunk->entities[i]);
|
entityDispose(chunk->entities[i]);
|
||||||
|
|||||||
@@ -9,18 +9,13 @@
|
|||||||
#include "maptypes.h"
|
#include "maptypes.h"
|
||||||
#include "entity/entitybase.h"
|
#include "entity/entitybase.h"
|
||||||
#include "error/error.h"
|
#include "error/error.h"
|
||||||
#include "script/scriptmanager.h"
|
|
||||||
|
|
||||||
#define MAP_CHUNK_ENTITY_COUNT_MAX 64
|
#define MAP_CHUNK_ENTITY_COUNT_MAX 64
|
||||||
|
|
||||||
/** Sentinel value meaning no chunk script is loaded. */
|
|
||||||
#define MAP_CHUNK_SCRIPT_REF_NONE ((jerry_value_t)0)
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
chunkpos_t position;
|
chunkpos_t position;
|
||||||
entityid_t entities[MAP_CHUNK_ENTITY_COUNT_MAX];
|
entityid_t entities[MAP_CHUNK_ENTITY_COUNT_MAX];
|
||||||
uint8_t entityCount;
|
uint8_t entityCount;
|
||||||
jerry_value_t scriptRef;
|
|
||||||
} mapchunk_t;
|
} mapchunk_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+7
-69
@@ -16,16 +16,12 @@
|
|||||||
#include "display/screen/screen.h"
|
#include "display/screen/screen.h"
|
||||||
#include "console/console.h"
|
#include "console/console.h"
|
||||||
#include "util/string.h"
|
#include "util/string.h"
|
||||||
#include "script/scriptmanager.h"
|
|
||||||
#include "script/module/scene/modulescene.h"
|
|
||||||
#include "script/module/cutscene/modulecutscene.h"
|
|
||||||
#include "ui/ui.h"
|
#include "ui/ui.h"
|
||||||
|
|
||||||
scene_t SCENE;
|
scene_t SCENE;
|
||||||
|
|
||||||
errorret_t sceneInit(void) {
|
errorret_t sceneInit(void) {
|
||||||
memoryZero(&SCENE, sizeof(scene_t));
|
memoryZero(&SCENE, sizeof(scene_t));
|
||||||
SCENE.scriptRef = SCENE_SCRIPT_REF_NONE;
|
|
||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,14 +32,6 @@ errorret_t sceneUpdate(void) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(stringCompare(SCENE.sceneNext, SCENE.sceneCurrent) != 0) {
|
|
||||||
errorChain(sceneSetImmediate(SCENE.sceneNext));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(SCENE.sceneActive) {
|
|
||||||
errorChain(moduleSceneCall("update"));
|
|
||||||
}
|
|
||||||
|
|
||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,64 +158,14 @@ errorret_t sceneRender(void) {
|
|||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
errorret_t sceneSetImmediate(const char_t *scene) {
|
// void sceneSet(const char_t *scene) {
|
||||||
if(scene != SCENE.sceneNext) {
|
// stringCopy(
|
||||||
stringCopy(
|
// SCENE.sceneNext,
|
||||||
SCENE.sceneNext,
|
// scene == NULL ? "" : scene,
|
||||||
scene == NULL ? "" : scene,
|
// ASSET_FILE_NAME_MAX
|
||||||
ASSET_FILE_NAME_MAX
|
// );
|
||||||
);
|
// }
|
||||||
}
|
|
||||||
|
|
||||||
if(SCENE.sceneActive) {
|
|
||||||
errorChain(moduleSceneCall("dispose"));
|
|
||||||
SCENE.sceneActive = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleCutsceneReset();
|
|
||||||
moduleSceneReset();
|
|
||||||
|
|
||||||
stringCopy(
|
|
||||||
SCENE.sceneCurrent,
|
|
||||||
scene == NULL ? "" : scene,
|
|
||||||
ASSET_FILE_NAME_MAX
|
|
||||||
);
|
|
||||||
|
|
||||||
if(scene != NULL) {
|
|
||||||
jerry_value_t sceneClass = SCENE_SCRIPT_REF_NONE;
|
|
||||||
errorChain(scriptManagerExecFile(scene, &sceneClass));
|
|
||||||
|
|
||||||
if(!jerry_value_is_function(sceneClass)) {
|
|
||||||
if(sceneClass != SCENE_SCRIPT_REF_NONE) jerry_value_free(sceneClass);
|
|
||||||
errorThrow("Scene '%s' must export a constructor function", scene);
|
|
||||||
}
|
|
||||||
|
|
||||||
jerry_value_t sceneObj = jerry_construct(sceneClass, NULL, 0);
|
|
||||||
jerry_value_free(sceneClass);
|
|
||||||
|
|
||||||
if(jerry_value_is_exception(sceneObj)) {
|
|
||||||
char_t errMsg[512];
|
|
||||||
moduleBaseExceptionMessage(sceneObj, errMsg, sizeof(errMsg));
|
|
||||||
jerry_value_free(sceneObj);
|
|
||||||
errorThrow("Scene '%s' constructor threw: %s", scene, errMsg);
|
|
||||||
}
|
|
||||||
|
|
||||||
SCENE.scriptRef = sceneObj;
|
|
||||||
SCENE.sceneActive = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
errorOk();
|
|
||||||
}
|
|
||||||
|
|
||||||
void sceneSet(const char_t *scene) {
|
|
||||||
stringCopy(
|
|
||||||
SCENE.sceneNext,
|
|
||||||
scene == NULL ? "" : scene,
|
|
||||||
ASSET_FILE_NAME_MAX
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
errorret_t sceneDispose(void) {
|
errorret_t sceneDispose(void) {
|
||||||
errorChain(moduleSceneCall("dispose"));
|
|
||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-16
@@ -6,22 +6,16 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "script/scriptmanager.h"
|
|
||||||
#include "asset/assetfile.h"
|
#include "asset/assetfile.h"
|
||||||
|
|
||||||
#define SCENE_EVENT_UPDATE_MAX 16
|
#define SCENE_EVENT_UPDATE_MAX 16
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
bool_t sceneActive;
|
void *nothing;
|
||||||
jerry_value_t scriptRef;
|
|
||||||
char_t sceneCurrent[ASSET_FILE_NAME_MAX];
|
|
||||||
char_t sceneNext[ASSET_FILE_NAME_MAX];
|
|
||||||
} scene_t;
|
} scene_t;
|
||||||
|
|
||||||
extern scene_t SCENE;
|
extern scene_t SCENE;
|
||||||
|
|
||||||
/** Sentinel value meaning no scene script is loaded. */
|
|
||||||
#define SCENE_SCRIPT_REF_NONE ((jerry_value_t)0)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the scene manager.
|
* Initializes the scene manager.
|
||||||
@@ -44,20 +38,12 @@ errorret_t sceneUpdate(void);
|
|||||||
*/
|
*/
|
||||||
errorret_t sceneRender(void);
|
errorret_t sceneRender(void);
|
||||||
|
|
||||||
/**
|
|
||||||
* Immediately switches scenes, disposing the current one first.
|
|
||||||
*
|
|
||||||
* @param scene Scene to switch to (asset file path).
|
|
||||||
* @return Any error state that happened.
|
|
||||||
*/
|
|
||||||
errorret_t sceneSetImmediate(const char_t *scene);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Requests a scene change on the next safe opportunity.
|
* Requests a scene change on the next safe opportunity.
|
||||||
*
|
*
|
||||||
* @param scene Which scene to set.
|
* @param scene Which scene to set.
|
||||||
*/
|
*/
|
||||||
void sceneSet(const char_t *scene);
|
// void sceneSet(const char_t *scene);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disposes of the current scene.
|
* Disposes of the current scene.
|
||||||
|
|||||||
@@ -1,13 +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
|
|
||||||
scriptmanager.c
|
|
||||||
scriptproto.c
|
|
||||||
)
|
|
||||||
|
|
||||||
# Subdirectories
|
|
||||||
@@ -1,371 +0,0 @@
|
|||||||
// 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/module/event/moduleEvent.h"
|
|
||||||
#include "script/scriptproto.h"
|
|
||||||
#include "animation/animation.h"
|
|
||||||
#include "util/memory.h"
|
|
||||||
|
|
||||||
static scriptproto_t MODULE_ANIMATION_PROP_PROTO;
|
|
||||||
static scriptproto_t MODULE_ANIMATION_PROTO;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
float_t value;
|
|
||||||
} jsAnimationProperty_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
animation_t anim;
|
|
||||||
jerry_value_t onStartCallback;
|
|
||||||
jerry_value_t onCompleteCallback;
|
|
||||||
} jsAnimation_t;
|
|
||||||
|
|
||||||
static inline jsAnimation_t *moduleAnimationGetWrapper(
|
|
||||||
const jerry_call_info_t *callInfo
|
|
||||||
) {
|
|
||||||
return (jsAnimation_t *)scriptProtoGetValue(
|
|
||||||
&MODULE_ANIMATION_PROTO, callInfo->this_value
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline animation_t *moduleAnimationGet(
|
|
||||||
const jerry_call_info_t *callInfo
|
|
||||||
) {
|
|
||||||
return (animation_t *)moduleAnimationGetWrapper(callInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void jsAnimationPropertyFree(void *ptr, jerry_object_native_info_t *info) {
|
|
||||||
(void)info;
|
|
||||||
memoryFree(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void jsAnimationOnStartBridge(void *params, void *user) {
|
|
||||||
(void)params;
|
|
||||||
jsAnimation_t *janim = (jsAnimation_t *)user;
|
|
||||||
if(!janim->onStartCallback) return;
|
|
||||||
jerry_value_t ret = jerry_call(janim->onStartCallback, jerry_undefined(), NULL, 0);
|
|
||||||
jerry_value_free(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void jsAnimationOnCompleteBridge(void *params, void *user) {
|
|
||||||
(void)params;
|
|
||||||
jsAnimation_t *janim = (jsAnimation_t *)user;
|
|
||||||
if(!janim->onCompleteCallback) return;
|
|
||||||
jerry_value_t ret = jerry_call(janim->onCompleteCallback, jerry_undefined(), NULL, 0);
|
|
||||||
jerry_value_free(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void jsAnimationFree(void *ptr, jerry_object_native_info_t *info) {
|
|
||||||
(void)info;
|
|
||||||
jsAnimation_t *janim = (jsAnimation_t *)ptr;
|
|
||||||
if(janim->onStartCallback) {
|
|
||||||
eventUnsubscribe(&janim->anim.onStart, jsAnimationOnStartBridge, janim);
|
|
||||||
jerry_value_free(janim->onStartCallback);
|
|
||||||
}
|
|
||||||
if(janim->onCompleteCallback) {
|
|
||||||
eventUnsubscribe(
|
|
||||||
&janim->anim.onComplete, jsAnimationOnCompleteBridge, janim
|
|
||||||
);
|
|
||||||
jerry_value_free(janim->onCompleteCallback);
|
|
||||||
}
|
|
||||||
memoryFree(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fires onReach callbacks for keyframes crossed between prevTime and newTime.
|
|
||||||
// Reads _keyframes from propObj; calls each callback with propObj as this.
|
|
||||||
static jerry_value_t moduleAnimationFireKeyframes(
|
|
||||||
const jerry_value_t propObj,
|
|
||||||
float_t prevTime,
|
|
||||||
float_t newTime
|
|
||||||
) {
|
|
||||||
jerry_value_t kfArr = moduleBaseGetProp(propObj, "_keyframes");
|
|
||||||
|
|
||||||
if(!jerry_value_is_array(kfArr)) {
|
|
||||||
jerry_value_free(kfArr);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
jerry_length_t len = jerry_array_length(kfArr);
|
|
||||||
for(jerry_length_t i = 0; i < len; i++) {
|
|
||||||
jerry_value_t kfObj = jerry_object_get_index(kfArr, i);
|
|
||||||
|
|
||||||
jerry_value_t tVal = moduleBaseGetProp(kfObj, "time");
|
|
||||||
float_t kfTime = moduleBaseValueFloat(tVal);
|
|
||||||
jerry_value_free(tVal);
|
|
||||||
|
|
||||||
if(prevTime < kfTime && newTime >= kfTime) {
|
|
||||||
jerry_value_t cb = moduleBaseGetProp(kfObj, "onReach");
|
|
||||||
|
|
||||||
if(jerry_value_is_function(cb)) {
|
|
||||||
jerry_value_t r = jerry_call(cb, propObj, NULL, 0);
|
|
||||||
jerry_value_free(cb);
|
|
||||||
if(jerry_value_is_exception(r)) {
|
|
||||||
jerry_value_free(kfObj);
|
|
||||||
jerry_value_free(kfArr);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
jerry_value_free(r);
|
|
||||||
} else {
|
|
||||||
jerry_value_free(cb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
jerry_value_free(kfObj);
|
|
||||||
}
|
|
||||||
|
|
||||||
jerry_value_free(kfArr);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleAnimationPropGetValue) {
|
|
||||||
jsAnimationProperty_t *jsprop = (jsAnimationProperty_t *)scriptProtoGetValue(
|
|
||||||
&MODULE_ANIMATION_PROP_PROTO, callInfo->this_value
|
|
||||||
);
|
|
||||||
if(!jsprop) return moduleBaseThrow("Invalid AnimationProperty instance");
|
|
||||||
return jerry_number((double)jsprop->value);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleAnimationConstructor) {
|
|
||||||
jsAnimation_t *janim = (jsAnimation_t *)memoryAllocate(sizeof(jsAnimation_t));
|
|
||||||
animationInit(&janim->anim);
|
|
||||||
janim->onStartCallback = 0;
|
|
||||||
janim->onCompleteCallback = 0;
|
|
||||||
|
|
||||||
if(argc > 0 && jerry_value_is_boolean(args[argc - 1])) {
|
|
||||||
if(jerry_value_is_true(args[argc - 1])) {
|
|
||||||
janim->anim.flags |= ANIMATION_FLAG_LOOP_ENABLED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
jerry_object_set_native_ptr(callInfo->this_value, &MODULE_ANIMATION_PROTO.info, janim);
|
|
||||||
|
|
||||||
jerry_value_t propsArr = jerry_array(0);
|
|
||||||
|
|
||||||
if(argc > 0 && jerry_value_is_array(args[0])) {
|
|
||||||
jerry_length_t numProps = jerry_array_length(args[0]);
|
|
||||||
for(jerry_length_t p = 0; p < numProps; p++) {
|
|
||||||
jerry_value_t kfArr = jerry_object_get_index(args[0], p);
|
|
||||||
if(!jerry_value_is_array(kfArr)) {
|
|
||||||
jerry_value_free(kfArr);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
jsAnimationProperty_t *jsprop = (jsAnimationProperty_t *)memoryAllocate(
|
|
||||||
sizeof(jsAnimationProperty_t)
|
|
||||||
);
|
|
||||||
jsprop->value = 0.0f;
|
|
||||||
|
|
||||||
animationproperty_t *prop = animationAddProperty(&janim->anim, &jsprop->value);
|
|
||||||
|
|
||||||
jerry_length_t kfLen = jerry_array_length(kfArr);
|
|
||||||
for(jerry_length_t i = 0; i < kfLen; i++) {
|
|
||||||
jerry_value_t kf = jerry_object_get_index(kfArr, i);
|
|
||||||
|
|
||||||
jerry_value_t tVal = moduleBaseGetProp(kf, "time");
|
|
||||||
float_t t = moduleBaseValueFloat(tVal);
|
|
||||||
jerry_value_free(tVal);
|
|
||||||
|
|
||||||
jerry_value_t vVal = moduleBaseGetProp(kf, "value");
|
|
||||||
float_t v = moduleBaseValueFloat(vVal);
|
|
||||||
jerry_value_free(vVal);
|
|
||||||
|
|
||||||
jerry_value_t eVal = moduleBaseGetProp(kf, "easing");
|
|
||||||
easingtype_t e = moduleReadEasing(eVal);
|
|
||||||
jerry_value_free(eVal);
|
|
||||||
|
|
||||||
jerry_value_free(kf);
|
|
||||||
animationPropertyAddKeyframe(prop, t, v, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the JS AnimationProperty object manually so &jsprop->value stays
|
|
||||||
// stable as the C animation target (scriptProtoCreateValue would memcpy).
|
|
||||||
jerry_value_t propObj = jerry_object();
|
|
||||||
jerry_object_set_native_ptr(propObj, &MODULE_ANIMATION_PROP_PROTO.info, jsprop);
|
|
||||||
jerry_object_set_proto(propObj, MODULE_ANIMATION_PROP_PROTO.prototype);
|
|
||||||
|
|
||||||
jerry_value_t kfStoreKey = jerry_string_sz("_keyframes");
|
|
||||||
jerry_object_set(propObj, kfStoreKey, kfArr);
|
|
||||||
jerry_value_free(kfStoreKey);
|
|
||||||
jerry_value_free(kfArr);
|
|
||||||
|
|
||||||
jerry_object_set_index(propsArr, (uint32_t)p, propObj);
|
|
||||||
jerry_value_free(propObj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
jerry_value_t propsKey = jerry_string_sz("properties");
|
|
||||||
jerry_object_set(callInfo->this_value, propsKey, propsArr);
|
|
||||||
jerry_value_free(propsKey);
|
|
||||||
jerry_value_free(propsArr);
|
|
||||||
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleAnimationUpdate) {
|
|
||||||
jsAnimation_t *janim = moduleAnimationGetWrapper(callInfo);
|
|
||||||
if(!janim) return moduleBaseThrow("Invalid Animation instance");
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireNumber(0);
|
|
||||||
|
|
||||||
float_t prevTime = janim->anim.time;
|
|
||||||
animationUpdate(&janim->anim, moduleBaseArgFloat(0));
|
|
||||||
|
|
||||||
jerry_value_t propsArr = moduleBaseGetProp(callInfo->this_value, "properties");
|
|
||||||
if(jerry_value_is_array(propsArr)) {
|
|
||||||
jerry_length_t len = jerry_array_length(propsArr);
|
|
||||||
for(jerry_length_t p = 0; p < len; p++) {
|
|
||||||
jerry_value_t propObj = jerry_object_get_index(propsArr, p);
|
|
||||||
jerry_value_t result = moduleAnimationFireKeyframes(
|
|
||||||
propObj, prevTime, janim->anim.time
|
|
||||||
);
|
|
||||||
jerry_value_free(propObj);
|
|
||||||
if(jerry_value_is_exception(result)) {
|
|
||||||
jerry_value_free(propsArr);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
jerry_value_free(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
jerry_value_free(propsArr);
|
|
||||||
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleAnimationReset) {
|
|
||||||
animation_t *anim = moduleAnimationGet(callInfo);
|
|
||||||
if(!anim) return moduleBaseThrow("Invalid Animation instance");
|
|
||||||
animationReset(anim);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleAnimationGetComplete) {
|
|
||||||
animation_t *anim = moduleAnimationGet(callInfo);
|
|
||||||
return anim ? jerry_boolean(animationIsFinished(anim)) : jerry_boolean(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleAnimationGetLoop) {
|
|
||||||
animation_t *anim = moduleAnimationGet(callInfo);
|
|
||||||
return anim ? jerry_boolean(animationIsLooping(anim)) : jerry_boolean(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleAnimationSetLoop) {
|
|
||||||
animation_t *anim = moduleAnimationGet(callInfo);
|
|
||||||
if(!anim) return moduleBaseThrow("Invalid Animation instance");
|
|
||||||
moduleBaseRequireArgs(1);
|
|
||||||
if(moduleBaseArgBool(0)) {
|
|
||||||
anim->flags |= ANIMATION_FLAG_LOOP_ENABLED;
|
|
||||||
} else {
|
|
||||||
anim->flags &= ~ANIMATION_FLAG_LOOP_ENABLED;
|
|
||||||
}
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleAnimationGetTime) {
|
|
||||||
animation_t *anim = moduleAnimationGet(callInfo);
|
|
||||||
return anim ? jerry_number((double)anim->time) : jerry_number(0.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleAnimationGetDuration) {
|
|
||||||
animation_t *anim = moduleAnimationGet(callInfo);
|
|
||||||
return anim
|
|
||||||
? jerry_number((double)animationGetDuration(anim))
|
|
||||||
: jerry_number(0.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleAnimationGetOnStart) {
|
|
||||||
jsAnimation_t *janim = moduleAnimationGetWrapper(callInfo);
|
|
||||||
if(!janim || !janim->onStartCallback) return jerry_null();
|
|
||||||
return jerry_value_copy(janim->onStartCallback);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleAnimationSetOnStart) {
|
|
||||||
jsAnimation_t *janim = moduleAnimationGetWrapper(callInfo);
|
|
||||||
if(!janim) return moduleBaseThrow("Invalid Animation instance");
|
|
||||||
|
|
||||||
if(janim->onStartCallback) {
|
|
||||||
eventUnsubscribe(&janim->anim.onStart, jsAnimationOnStartBridge, janim);
|
|
||||||
jerry_value_free(janim->onStartCallback);
|
|
||||||
janim->onStartCallback = 0;
|
|
||||||
}
|
|
||||||
if(argc >= 1 && jerry_value_is_function(args[0])) {
|
|
||||||
janim->onStartCallback = jerry_value_copy(args[0]);
|
|
||||||
eventSubscribe(&janim->anim.onStart, jsAnimationOnStartBridge, janim);
|
|
||||||
}
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleAnimationGetOnComplete) {
|
|
||||||
jsAnimation_t *janim = moduleAnimationGetWrapper(callInfo);
|
|
||||||
if(!janim || !janim->onCompleteCallback) return jerry_null();
|
|
||||||
return jerry_value_copy(janim->onCompleteCallback);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleAnimationSetOnComplete) {
|
|
||||||
jsAnimation_t *janim = moduleAnimationGetWrapper(callInfo);
|
|
||||||
if(!janim) return moduleBaseThrow("Invalid Animation instance");
|
|
||||||
|
|
||||||
if(janim->onCompleteCallback) {
|
|
||||||
eventUnsubscribe(
|
|
||||||
&janim->anim.onComplete, jsAnimationOnCompleteBridge, janim
|
|
||||||
);
|
|
||||||
jerry_value_free(janim->onCompleteCallback);
|
|
||||||
janim->onCompleteCallback = 0;
|
|
||||||
}
|
|
||||||
if(argc >= 1 && jerry_value_is_function(args[0])) {
|
|
||||||
janim->onCompleteCallback = jerry_value_copy(args[0]);
|
|
||||||
eventSubscribe(&janim->anim.onComplete, jsAnimationOnCompleteBridge, janim);
|
|
||||||
}
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void moduleAnimation(void) {
|
|
||||||
scriptProtoInit(
|
|
||||||
&MODULE_ANIMATION_PROP_PROTO, NULL, sizeof(jsAnimationProperty_t), NULL
|
|
||||||
);
|
|
||||||
MODULE_ANIMATION_PROP_PROTO.info.free_cb = jsAnimationPropertyFree;
|
|
||||||
scriptProtoDefineProp(
|
|
||||||
&MODULE_ANIMATION_PROP_PROTO, "value",
|
|
||||||
moduleAnimationPropGetValue, NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
scriptProtoInit(
|
|
||||||
&MODULE_ANIMATION_PROTO,
|
|
||||||
"Animation",
|
|
||||||
sizeof(jsAnimation_t),
|
|
||||||
moduleAnimationConstructor
|
|
||||||
);
|
|
||||||
MODULE_ANIMATION_PROTO.info.free_cb = jsAnimationFree;
|
|
||||||
|
|
||||||
scriptProtoDefineFunc(
|
|
||||||
&MODULE_ANIMATION_PROTO, "update", moduleAnimationUpdate
|
|
||||||
);
|
|
||||||
scriptProtoDefineFunc(
|
|
||||||
&MODULE_ANIMATION_PROTO, "reset", moduleAnimationReset
|
|
||||||
);
|
|
||||||
scriptProtoDefineProp(
|
|
||||||
&MODULE_ANIMATION_PROTO, "complete",
|
|
||||||
moduleAnimationGetComplete, NULL
|
|
||||||
);
|
|
||||||
scriptProtoDefineProp(
|
|
||||||
&MODULE_ANIMATION_PROTO, "loop",
|
|
||||||
moduleAnimationGetLoop, moduleAnimationSetLoop
|
|
||||||
);
|
|
||||||
scriptProtoDefineProp(
|
|
||||||
&MODULE_ANIMATION_PROTO, "time",
|
|
||||||
moduleAnimationGetTime, NULL
|
|
||||||
);
|
|
||||||
scriptProtoDefineProp(
|
|
||||||
&MODULE_ANIMATION_PROTO, "duration",
|
|
||||||
moduleAnimationGetDuration, NULL
|
|
||||||
);
|
|
||||||
scriptProtoDefineProp(
|
|
||||||
&MODULE_ANIMATION_PROTO, "onStart",
|
|
||||||
moduleAnimationGetOnStart, moduleAnimationSetOnStart
|
|
||||||
);
|
|
||||||
scriptProtoDefineProp(
|
|
||||||
&MODULE_ANIMATION_PROTO, "onComplete",
|
|
||||||
moduleAnimationGetOnComplete, moduleAnimationSetOnComplete
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
// 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 "animation/easing.h"
|
|
||||||
|
|
||||||
static scriptproto_t MODULE_EASING_PROTO;
|
|
||||||
|
|
||||||
// Generate one handler per easing curve.
|
|
||||||
#define EASING_MODULE_TABLE \
|
|
||||||
X(Linear, "linear", EASING_LINEAR, easingLinear) \
|
|
||||||
X(InSine, "inSine", EASING_IN_SINE, easingInSine) \
|
|
||||||
X(OutSine, "outSine", EASING_OUT_SINE, easingOutSine) \
|
|
||||||
X(InOutSine, "inOutSine", EASING_IN_OUT_SINE, easingInOutSine) \
|
|
||||||
X(InQuad, "inQuad", EASING_IN_QUAD, easingInQuad) \
|
|
||||||
X(OutQuad, "outQuad", EASING_OUT_QUAD, easingOutQuad) \
|
|
||||||
X(InOutQuad, "inOutQuad", EASING_IN_OUT_QUAD, easingInOutQuad) \
|
|
||||||
X(InCubic, "inCubic", EASING_IN_CUBIC, easingInCubic) \
|
|
||||||
X(OutCubic, "outCubic", EASING_OUT_CUBIC, easingOutCubic) \
|
|
||||||
X(InOutCubic, "inOutCubic", EASING_IN_OUT_CUBIC, easingInOutCubic) \
|
|
||||||
X(InQuart, "inQuart", EASING_IN_QUART, easingInQuart) \
|
|
||||||
X(OutQuart, "outQuart", EASING_OUT_QUART, easingOutQuart) \
|
|
||||||
X(InOutQuart, "inOutQuart", EASING_IN_OUT_QUART, easingInOutQuart) \
|
|
||||||
X(InBack, "inBack", EASING_IN_BACK, easingInBack) \
|
|
||||||
X(OutBack, "outBack", EASING_OUT_BACK, easingOutBack) \
|
|
||||||
X(InOutBack, "inOutBack", EASING_IN_OUT_BACK, easingInOutBack)
|
|
||||||
|
|
||||||
#define X(CName, jsName, type, fn) \
|
|
||||||
moduleBaseFunction(moduleEasing##CName) { \
|
|
||||||
if(argc < 1 || !jerry_value_is_number(args[0])) { \
|
|
||||||
return moduleBaseThrow("Expected number t"); \
|
|
||||||
} \
|
|
||||||
float_t t = (float_t)jerry_value_as_number(args[0]); \
|
|
||||||
return jerry_number((double)fn(t)); \
|
|
||||||
}
|
|
||||||
EASING_MODULE_TABLE
|
|
||||||
#undef X
|
|
||||||
|
|
||||||
// Adds a callable easing function with a .type property to the Easing object.
|
|
||||||
static void moduleEasingRegister(
|
|
||||||
const char_t *jsName,
|
|
||||||
uint8_t type,
|
|
||||||
jerry_external_handler_t fn
|
|
||||||
) {
|
|
||||||
jerry_value_t fnVal = jerry_function_external(fn);
|
|
||||||
|
|
||||||
jerry_value_t typeKey = jerry_string_sz("type");
|
|
||||||
jerry_value_t typeVal = jerry_number((double)type);
|
|
||||||
jerry_object_set(fnVal, typeKey, typeVal);
|
|
||||||
jerry_value_free(typeKey);
|
|
||||||
jerry_value_free(typeVal);
|
|
||||||
|
|
||||||
jerry_value_t nameKey = jerry_string_sz(jsName);
|
|
||||||
jerry_object_set(MODULE_EASING_PROTO.prototype, nameKey, fnVal);
|
|
||||||
jerry_value_free(nameKey);
|
|
||||||
jerry_value_free(fnVal);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void moduleEasing(void) {
|
|
||||||
scriptProtoInit(&MODULE_EASING_PROTO, "Easing", sizeof(uint8_t), NULL);
|
|
||||||
|
|
||||||
#define X(CName, jsName, type, fn) \
|
|
||||||
moduleEasingRegister(jsName, type, moduleEasing##CName);
|
|
||||||
EASING_MODULE_TABLE
|
|
||||||
#undef X
|
|
||||||
}
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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 "console/console.h"
|
|
||||||
|
|
||||||
static scriptproto_t MODULE_CONSOLE_PROTO;
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleConsolePrint) {
|
|
||||||
char_t buf[512];
|
|
||||||
char_t msg[4096];
|
|
||||||
size_t msgLen = 0;
|
|
||||||
|
|
||||||
for(jerry_length_t i = 0; i < argc; ++i) {
|
|
||||||
jerry_value_t strVal = jerry_value_to_string(args[i]);
|
|
||||||
moduleBaseToString(strVal, buf, sizeof(buf));
|
|
||||||
jerry_value_free(strVal);
|
|
||||||
|
|
||||||
size_t partLen = strlen(buf);
|
|
||||||
if(msgLen + partLen + 1 < sizeof(msg)) {
|
|
||||||
stringCopy(msg + msgLen, buf, sizeof(msg) - msgLen);
|
|
||||||
msgLen += partLen;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(i + 1 < argc && msgLen + 1 < sizeof(msg)) {
|
|
||||||
msg[msgLen++] = '\t';
|
|
||||||
msg[msgLen] = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
consolePrint("%s", msg);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleConsoleGetVisible) {
|
|
||||||
return jerry_boolean(CONSOLE.visible);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleConsoleSetVisible) {
|
|
||||||
moduleBaseRequireArgs(1);
|
|
||||||
CONSOLE.visible = moduleBaseArgBool(0);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void moduleConsole(void) {
|
|
||||||
scriptProtoInit(
|
|
||||||
&MODULE_CONSOLE_PROTO, "Console",
|
|
||||||
sizeof(uint8_t), NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
scriptProtoDefineStaticFunc(
|
|
||||||
&MODULE_CONSOLE_PROTO, "print", moduleConsolePrint
|
|
||||||
);
|
|
||||||
scriptProtoDefineStaticProp(
|
|
||||||
&MODULE_CONSOLE_PROTO, "visible",
|
|
||||||
moduleConsoleGetVisible, moduleConsoleSetVisible
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,198 +0,0 @@
|
|||||||
// 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 "cutscene/cutscene.h"
|
|
||||||
#include "error/error.h"
|
|
||||||
|
|
||||||
static scriptproto_t MODULE_CUTSCENE_PROTO;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Disposes the active JS cutscene without firing the then callback.
|
|
||||||
* Safe to call when no cutscene is active.
|
|
||||||
*/
|
|
||||||
static void moduleCutsceneReset(void) {
|
|
||||||
if(CUTSCENE.activeRef == CUTSCENE_SCRIPT_REF_NONE) return;
|
|
||||||
|
|
||||||
jerry_value_t key = jerry_string_sz("dispose");
|
|
||||||
jerry_value_t fn = jerry_object_get(CUTSCENE.activeRef, key);
|
|
||||||
jerry_value_free(key);
|
|
||||||
|
|
||||||
if(jerry_value_is_function(fn)) {
|
|
||||||
jerry_value_t result = jerry_call(fn, CUTSCENE.activeRef, NULL, 0);
|
|
||||||
jerry_value_free(fn);
|
|
||||||
jerry_value_free(result);
|
|
||||||
} else {
|
|
||||||
jerry_value_free(fn);
|
|
||||||
}
|
|
||||||
|
|
||||||
jerry_value_free(CUTSCENE.activeRef);
|
|
||||||
CUTSCENE.activeRef = CUTSCENE_SCRIPT_REF_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ticks the active JS cutscene. Called from cutsceneUpdate().
|
|
||||||
*
|
|
||||||
* @return Any error state that happened.
|
|
||||||
*/
|
|
||||||
static errorret_t moduleCutsceneUpdate(void) {
|
|
||||||
if(CUTSCENE.activeRef == CUTSCENE_SCRIPT_REF_NONE) errorOk();
|
|
||||||
|
|
||||||
jerry_value_t key = jerry_string_sz("update");
|
|
||||||
jerry_value_t fn = jerry_object_get(CUTSCENE.activeRef, key);
|
|
||||||
jerry_value_free(key);
|
|
||||||
|
|
||||||
if(!jerry_value_is_function(fn)) {
|
|
||||||
jerry_value_free(fn);
|
|
||||||
errorOk();
|
|
||||||
}
|
|
||||||
|
|
||||||
jerry_value_t result = jerry_call(fn, CUTSCENE.activeRef, NULL, 0);
|
|
||||||
jerry_value_free(fn);
|
|
||||||
|
|
||||||
if(jerry_value_is_exception(result)) {
|
|
||||||
char_t errMsg[512];
|
|
||||||
moduleBaseExceptionMessage(result, errMsg, sizeof(errMsg));
|
|
||||||
jerry_value_free(result);
|
|
||||||
errorThrow("Cutscene update failed: %s", errMsg);
|
|
||||||
}
|
|
||||||
|
|
||||||
jerry_value_free(result);
|
|
||||||
errorOk();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleCutsceneDefaultConstructor) {
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleCutsceneDefaultUpdate) {
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleCutsceneDefaultDispose) {
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* cutscene.then(callback)
|
|
||||||
*
|
|
||||||
* Sets the completion callback fired when Cutscene.finish() is called.
|
|
||||||
* Only one callback may be set; calling then() again replaces it.
|
|
||||||
* Returns the instance for optional chaining.
|
|
||||||
*/
|
|
||||||
moduleBaseFunction(moduleCutsceneThen) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireFunction(0);
|
|
||||||
jerry_value_t key = jerry_string_sz("_onFinished");
|
|
||||||
jerry_object_set(callInfo->this_value, key, args[0]);
|
|
||||||
jerry_value_free(key);
|
|
||||||
|
|
||||||
return jerry_value_copy(callInfo->this_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cutscene.play(instance)
|
|
||||||
*
|
|
||||||
* Registers a cutscene instance with the engine and begins calling its
|
|
||||||
* update() each tick. Stops any currently active cutscene first.
|
|
||||||
* Returns the instance to allow chaining .then() directly.
|
|
||||||
*/
|
|
||||||
moduleBaseFunction(moduleCutscenePlay) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireObject(0);
|
|
||||||
if(CUTSCENE.activeRef != CUTSCENE_SCRIPT_REF_NONE) {
|
|
||||||
moduleCutsceneReset();
|
|
||||||
}
|
|
||||||
|
|
||||||
CUTSCENE.activeRef = jerry_value_copy(args[0]);
|
|
||||||
return jerry_value_copy(args[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cutscene.finish()
|
|
||||||
*
|
|
||||||
* Marks the active cutscene as complete: calls dispose(), clears the
|
|
||||||
* active ref, then fires the then() callback if one was set.
|
|
||||||
* Intended to be called from within the cutscene's own update().
|
|
||||||
*/
|
|
||||||
moduleBaseFunction(moduleCutsceneFinish) {
|
|
||||||
if(CUTSCENE.activeRef == CUTSCENE_SCRIPT_REF_NONE) {
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
jerry_value_t cbKey = jerry_string_sz("_onFinished");
|
|
||||||
jerry_value_t callback = jerry_object_get(CUTSCENE.activeRef, cbKey);
|
|
||||||
jerry_value_free(cbKey);
|
|
||||||
|
|
||||||
jerry_value_t dispKey = jerry_string_sz("dispose");
|
|
||||||
jerry_value_t dispFn = jerry_object_get(CUTSCENE.activeRef, dispKey);
|
|
||||||
jerry_value_free(dispKey);
|
|
||||||
|
|
||||||
if(jerry_value_is_function(dispFn)) {
|
|
||||||
jerry_value_t r = jerry_call(dispFn, CUTSCENE.activeRef, NULL, 0);
|
|
||||||
jerry_value_free(dispFn);
|
|
||||||
if(jerry_value_is_exception(r)) {
|
|
||||||
jerry_value_free(callback);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
jerry_value_free(r);
|
|
||||||
} else {
|
|
||||||
jerry_value_free(dispFn);
|
|
||||||
}
|
|
||||||
|
|
||||||
jerry_value_free(CUTSCENE.activeRef);
|
|
||||||
CUTSCENE.activeRef = CUTSCENE_SCRIPT_REF_NONE;
|
|
||||||
|
|
||||||
if(jerry_value_is_function(callback)) {
|
|
||||||
jerry_value_t r = jerry_call(callback, jerry_undefined(), NULL, 0);
|
|
||||||
jerry_value_free(callback);
|
|
||||||
if(jerry_value_is_exception(r)) return r;
|
|
||||||
jerry_value_free(r);
|
|
||||||
} else {
|
|
||||||
jerry_value_free(callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cutscene.stop()
|
|
||||||
*
|
|
||||||
* Immediately disposes the active cutscene without firing the then
|
|
||||||
* callback. No-op when no cutscene is active.
|
|
||||||
*/
|
|
||||||
moduleBaseFunction(moduleCutsceneStop) {
|
|
||||||
moduleCutsceneReset();
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void moduleCutscene(void) {
|
|
||||||
scriptProtoInit(
|
|
||||||
&MODULE_CUTSCENE_PROTO,
|
|
||||||
"Cutscene",
|
|
||||||
sizeof(uint8_t),
|
|
||||||
moduleCutsceneDefaultConstructor
|
|
||||||
);
|
|
||||||
|
|
||||||
scriptProtoDefineFunc(
|
|
||||||
&MODULE_CUTSCENE_PROTO, "update", moduleCutsceneDefaultUpdate
|
|
||||||
);
|
|
||||||
scriptProtoDefineFunc(
|
|
||||||
&MODULE_CUTSCENE_PROTO, "dispose", moduleCutsceneDefaultDispose
|
|
||||||
);
|
|
||||||
scriptProtoDefineFunc(
|
|
||||||
&MODULE_CUTSCENE_PROTO, "then", moduleCutsceneThen
|
|
||||||
);
|
|
||||||
|
|
||||||
scriptProtoDefineStaticFunc(
|
|
||||||
&MODULE_CUTSCENE_PROTO, "play", moduleCutscenePlay
|
|
||||||
);
|
|
||||||
scriptProtoDefineStaticFunc(
|
|
||||||
&MODULE_CUTSCENE_PROTO, "finish", moduleCutsceneFinish
|
|
||||||
);
|
|
||||||
scriptProtoDefineStaticFunc(
|
|
||||||
&MODULE_CUTSCENE_PROTO, "stop", moduleCutsceneStop
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,136 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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 "display/color.h"
|
|
||||||
#include "time/time.h"
|
|
||||||
#include "script/scriptproto.h"
|
|
||||||
|
|
||||||
static scriptproto_t MODULE_COLOR_PROTO;
|
|
||||||
|
|
||||||
static inline color_t * moduleColorGet(
|
|
||||||
const jerry_call_info_t *callInfo
|
|
||||||
) {
|
|
||||||
return (color_t*)scriptProtoGetValue(
|
|
||||||
&MODULE_COLOR_PROTO, callInfo->this_value
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleColorGetR) {
|
|
||||||
moduleBaseGetOrReturn(color_t, c, moduleColorGet);
|
|
||||||
return jerry_number(c->r);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleColorGetG) {
|
|
||||||
moduleBaseGetOrReturn(color_t, c, moduleColorGet);
|
|
||||||
return jerry_number(c->g);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleColorGetB) {
|
|
||||||
moduleBaseGetOrReturn(color_t, c, moduleColorGet);
|
|
||||||
return jerry_number(c->b);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleColorGetA) {
|
|
||||||
moduleBaseGetOrReturn(color_t, c, moduleColorGet);
|
|
||||||
return jerry_number(c->a);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleColorSetR) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireNumber(0);
|
|
||||||
moduleBaseGetOrReturn(color_t, c, moduleColorGet);
|
|
||||||
c->r = (colorchannel8_t)moduleBaseArgInt(0);
|
|
||||||
return args[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleColorSetG) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireNumber(0);
|
|
||||||
moduleBaseGetOrReturn(color_t, c, moduleColorGet);
|
|
||||||
c->g = (colorchannel8_t)moduleBaseArgInt(0);
|
|
||||||
return args[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleColorSetB) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireNumber(0);
|
|
||||||
moduleBaseGetOrReturn(color_t, c, moduleColorGet);
|
|
||||||
c->b = (colorchannel8_t)moduleBaseArgInt(0);
|
|
||||||
return args[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleColorSetA) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireNumber(0);
|
|
||||||
moduleBaseGetOrReturn(color_t, c, moduleColorGet);
|
|
||||||
c->a = (colorchannel8_t)moduleBaseArgInt(0);
|
|
||||||
return args[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleColorToString) {
|
|
||||||
moduleBaseGetOrReturn(color_t, c, moduleColorGet);
|
|
||||||
char_t buf[64];
|
|
||||||
stringFormat(
|
|
||||||
buf, sizeof(buf),
|
|
||||||
"{ \"r\": %d, \"g\": %d, \"b\": %d, \"a\": %d }",
|
|
||||||
(int32_t)c->r, (int32_t)c->g,
|
|
||||||
(int32_t)c->b, (int32_t)c->a
|
|
||||||
);
|
|
||||||
return jerry_string_sz(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
static jerry_value_t moduleColorMakeObject(color_t color) {
|
|
||||||
return scriptProtoCreateValue(&MODULE_COLOR_PROTO, &color);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleColorConstructor) {
|
|
||||||
if(argc > 0 && !jerry_value_is_number(args[0])) return moduleBaseThrow("Color: r must be a number");
|
|
||||||
if(argc > 1 && !jerry_value_is_number(args[1])) return moduleBaseThrow("Color: g must be a number");
|
|
||||||
if(argc > 2 && !jerry_value_is_number(args[2])) return moduleBaseThrow("Color: b must be a number");
|
|
||||||
if(argc > 3 && !jerry_value_is_number(args[3])) return moduleBaseThrow("Color: a must be a number");
|
|
||||||
color_t c;
|
|
||||||
c.r = (colorchannel8_t)moduleBaseOptInt(0, 255);
|
|
||||||
c.g = (colorchannel8_t)moduleBaseOptInt(1, 255);
|
|
||||||
c.b = (colorchannel8_t)moduleBaseOptInt(2, 255);
|
|
||||||
c.a = (colorchannel8_t)moduleBaseOptInt(3, 255);
|
|
||||||
return moduleColorMakeObject(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleColorRainbow) {
|
|
||||||
float_t t = moduleBaseOptFloat(0, TIME.time * 4.0f);
|
|
||||||
if(argc >= 2 && jerry_value_is_number(args[1])) t *= moduleBaseArgFloat(1);
|
|
||||||
|
|
||||||
color_t c;
|
|
||||||
c.r = (colorchannel8_t)((sinf(t) + 1.0f) * 0.5f * 255.0f);
|
|
||||||
c.g = (colorchannel8_t)((sinf(t + 2.0f) + 1.0f) * 0.5f * 255.0f);
|
|
||||||
c.b = (colorchannel8_t)((sinf(t + 4.0f) + 1.0f) * 0.5f * 255.0f);
|
|
||||||
c.a = 255;
|
|
||||||
return moduleColorMakeObject(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void moduleColor(void) {
|
|
||||||
scriptProtoInit(
|
|
||||||
&MODULE_COLOR_PROTO, "Color", sizeof(color_t), moduleColorConstructor
|
|
||||||
);
|
|
||||||
|
|
||||||
scriptProtoDefineProp(
|
|
||||||
&MODULE_COLOR_PROTO, "r", moduleColorGetR, moduleColorSetR
|
|
||||||
);
|
|
||||||
scriptProtoDefineProp(
|
|
||||||
&MODULE_COLOR_PROTO, "g", moduleColorGetG, moduleColorSetG
|
|
||||||
);
|
|
||||||
scriptProtoDefineProp(
|
|
||||||
&MODULE_COLOR_PROTO, "b", moduleColorGetB, moduleColorSetB
|
|
||||||
);
|
|
||||||
scriptProtoDefineProp(
|
|
||||||
&MODULE_COLOR_PROTO, "a", moduleColorGetA, moduleColorSetA
|
|
||||||
);
|
|
||||||
|
|
||||||
scriptProtoDefineStaticFunc(
|
|
||||||
&MODULE_COLOR_PROTO, "rainbow", moduleColorRainbow
|
|
||||||
);
|
|
||||||
scriptProtoDefineToString(&MODULE_COLOR_PROTO, moduleColorToString);
|
|
||||||
moduleBaseEval(COLOR_SCRIPT);
|
|
||||||
}
|
|
||||||
@@ -1,420 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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 "script/module/math/modulevec3ref.h"
|
|
||||||
#include "display/mesh/mesh.h"
|
|
||||||
#include "display/mesh/cube.h"
|
|
||||||
#include "display/mesh/quad.h"
|
|
||||||
#include "display/mesh/sphere.h"
|
|
||||||
#include "display/mesh/plane.h"
|
|
||||||
#include "display/mesh/capsule.h"
|
|
||||||
#include "display/mesh/triprism.h"
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
mesh_t mesh;
|
|
||||||
meshvertex_t *vertices;
|
|
||||||
int32_t vertexCount;
|
|
||||||
bool_t initialized;
|
|
||||||
} meshscript_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
meshvertex_t *vertex;
|
|
||||||
} meshvertexscript_t;
|
|
||||||
|
|
||||||
static scriptproto_t MODULE_MESH_PROTO;
|
|
||||||
static scriptproto_t MODULE_MESH_VERTEX_PROTO;
|
|
||||||
|
|
||||||
static inline meshscript_t * moduleMeshGet(
|
|
||||||
const jerry_call_info_t *callInfo
|
|
||||||
) {
|
|
||||||
return (meshscript_t*)scriptProtoGetValue(
|
|
||||||
&MODULE_MESH_PROTO, callInfo->this_value
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline meshscript_t * moduleMeshFrom(const jerry_value_t val) {
|
|
||||||
return (meshscript_t*)scriptProtoGetValue(&MODULE_MESH_PROTO, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void moduleMeshFreeData(
|
|
||||||
void *ptr,
|
|
||||||
jerry_object_native_info_t *info
|
|
||||||
) {
|
|
||||||
(void)info;
|
|
||||||
meshscript_t *ms = (meshscript_t*)ptr;
|
|
||||||
if(ms->initialized) (void)meshDispose(&ms->mesh);
|
|
||||||
if(ms->vertices) memoryFree(ms->vertices);
|
|
||||||
memoryFree(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Creates a new JS Mesh object from an already-filled heap-allocated meshscript_t.
|
|
||||||
static jerry_value_t moduleMeshWrapNew(meshscript_t *ms) {
|
|
||||||
jerry_value_t obj = jerry_object();
|
|
||||||
jerry_object_set_native_ptr(obj, &MODULE_MESH_PROTO.info, ms);
|
|
||||||
jerry_object_set_proto(obj, MODULE_MESH_PROTO.prototype);
|
|
||||||
|
|
||||||
jerry_value_t arr = jerry_array((jerry_length_t)ms->vertexCount);
|
|
||||||
for(int32_t i = 0; i < ms->vertexCount; i++) {
|
|
||||||
meshvertexscript_t mv = { .vertex = &ms->vertices[i] };
|
|
||||||
jerry_value_t vobj = scriptProtoCreateValue(&MODULE_MESH_VERTEX_PROTO, &mv);
|
|
||||||
jerry_value_t res = jerry_object_set_index(arr, (uint32_t)i, vobj);
|
|
||||||
jerry_value_free(res);
|
|
||||||
jerry_value_free(vobj);
|
|
||||||
}
|
|
||||||
jerry_value_t key = jerry_string_sz("_verts");
|
|
||||||
jerry_object_set(obj, key, arr);
|
|
||||||
jerry_value_free(key);
|
|
||||||
jerry_value_free(arr);
|
|
||||||
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allocates a meshscript_t for the given vertex count and buffers it.
|
|
||||||
// Caller is responsible for populating ms->vertices before calling meshInit.
|
|
||||||
static meshscript_t * moduleMeshAlloc(const int32_t vertexCount) {
|
|
||||||
meshscript_t *ms = (meshscript_t*)memoryAllocate(sizeof(meshscript_t));
|
|
||||||
memoryZero(ms, sizeof(meshscript_t));
|
|
||||||
ms->vertices = (meshvertex_t*)memoryAllocate(
|
|
||||||
(size_t)vertexCount * sizeof(meshvertex_t)
|
|
||||||
);
|
|
||||||
memoryZero(ms->vertices, (size_t)vertexCount * sizeof(meshvertex_t));
|
|
||||||
ms->vertexCount = vertexCount;
|
|
||||||
return ms;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finalizes a meshscript_t: uploads to GPU and wraps in a JS object.
|
|
||||||
static jerry_value_t moduleMeshFinalize(
|
|
||||||
meshscript_t *ms,
|
|
||||||
const meshprimitivetype_t type
|
|
||||||
) {
|
|
||||||
(void)meshInit(&ms->mesh, type, ms->vertexCount, ms->vertices);
|
|
||||||
ms->initialized = true;
|
|
||||||
return moduleMeshWrapNew(ms);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---- MeshVertex ----
|
|
||||||
|
|
||||||
static inline meshvertexscript_t * moduleMeshVertexGet(
|
|
||||||
const jerry_call_info_t *callInfo
|
|
||||||
) {
|
|
||||||
return (meshvertexscript_t*)scriptProtoGetValue(
|
|
||||||
&MODULE_MESH_VERTEX_PROTO, callInfo->this_value
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleMeshVertexGetPosition) {
|
|
||||||
moduleBaseGetOrReturn(meshvertexscript_t, mv, moduleMeshVertexGet);
|
|
||||||
return moduleVec3RefPush(mv->vertex->pos, NULL, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleMeshVertexSetPosition) {
|
|
||||||
moduleBaseRequireArgs(1);
|
|
||||||
moduleBaseGetOrReturn(meshvertexscript_t, mv, moduleMeshVertexGet);
|
|
||||||
vec3 v;
|
|
||||||
if(!moduleVec3AnyCheck(args[0], v)) return moduleBaseThrow("Expected Vec3");
|
|
||||||
glm_vec3_copy(v, mv->vertex->pos);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---- Mesh instance ----
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleMeshConstructor) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireNumber(0);
|
|
||||||
|
|
||||||
int32_t vertexCount = moduleBaseArgInt(0);
|
|
||||||
if(vertexCount <= 0) return moduleBaseThrow("Vertex count must be > 0");
|
|
||||||
|
|
||||||
meshscript_t *ms = moduleMeshAlloc(vertexCount);
|
|
||||||
jerry_object_set_native_ptr(
|
|
||||||
callInfo->this_value, &MODULE_MESH_PROTO.info, ms
|
|
||||||
);
|
|
||||||
|
|
||||||
jerry_value_t arr = jerry_array((jerry_length_t)vertexCount);
|
|
||||||
for(int32_t i = 0; i < vertexCount; i++) {
|
|
||||||
meshvertexscript_t mv = { .vertex = &ms->vertices[i] };
|
|
||||||
jerry_value_t vobj = scriptProtoCreateValue(&MODULE_MESH_VERTEX_PROTO, &mv);
|
|
||||||
jerry_value_t res = jerry_object_set_index(arr, (uint32_t)i, vobj);
|
|
||||||
jerry_value_free(res);
|
|
||||||
jerry_value_free(vobj);
|
|
||||||
}
|
|
||||||
jerry_value_t key = jerry_string_sz("_verts");
|
|
||||||
jerry_object_set(callInfo->this_value, key, arr);
|
|
||||||
jerry_value_free(key);
|
|
||||||
jerry_value_free(arr);
|
|
||||||
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleMeshGetVertices) {
|
|
||||||
jerry_value_t key = jerry_string_sz("_verts");
|
|
||||||
jerry_value_t arr = jerry_object_get(callInfo->this_value, key);
|
|
||||||
jerry_value_free(key);
|
|
||||||
return arr;
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleMeshGetVertexCount) {
|
|
||||||
moduleBaseGetOrReturn(meshscript_t, ms, moduleMeshGet);
|
|
||||||
return jerry_number((double)ms->vertexCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleMeshFlush) {
|
|
||||||
moduleBaseGetOrReturn(meshscript_t, ms, moduleMeshGet);
|
|
||||||
if(!ms->initialized) {
|
|
||||||
(void)meshInit(
|
|
||||||
&ms->mesh,
|
|
||||||
MESH_PRIMITIVE_TYPE_TRIANGLES,
|
|
||||||
ms->vertexCount,
|
|
||||||
ms->vertices
|
|
||||||
);
|
|
||||||
ms->initialized = true;
|
|
||||||
} else {
|
|
||||||
(void)meshFlush(&ms->mesh, 0, -1);
|
|
||||||
}
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleMeshDispose) {
|
|
||||||
moduleBaseGetOrReturn(meshscript_t, ms, moduleMeshGet);
|
|
||||||
if(ms->initialized) {
|
|
||||||
(void)meshDispose(&ms->mesh);
|
|
||||||
ms->initialized = false;
|
|
||||||
}
|
|
||||||
if(ms->vertices) {
|
|
||||||
memoryFree(ms->vertices);
|
|
||||||
ms->vertices = NULL;
|
|
||||||
}
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleMeshToString) {
|
|
||||||
meshscript_t *ms = moduleMeshGet(callInfo);
|
|
||||||
if(!ms) return jerry_string_sz("Mesh(?)");
|
|
||||||
char_t buf[64];
|
|
||||||
stringFormat(buf, sizeof(buf), "Mesh(%d)", ms->vertexCount);
|
|
||||||
return jerry_string_sz(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---- Static defaults (engine-owned, not GC'd) ----
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleMeshDefaultCube) {
|
|
||||||
return moduleBaseWrapPointer(&CUBE_MESH_SIMPLE);
|
|
||||||
}
|
|
||||||
moduleBaseFunction(moduleMeshDefaultQuad) {
|
|
||||||
return moduleBaseWrapPointer(&QUAD_MESH_SIMPLE);
|
|
||||||
}
|
|
||||||
moduleBaseFunction(moduleMeshDefaultSphere) {
|
|
||||||
return moduleBaseWrapPointer(&SPHERE_MESH_SIMPLE);
|
|
||||||
}
|
|
||||||
moduleBaseFunction(moduleMeshDefaultPlane) {
|
|
||||||
return moduleBaseWrapPointer(&PLANE_MESH_SIMPLE);
|
|
||||||
}
|
|
||||||
moduleBaseFunction(moduleMeshDefaultCapsule) {
|
|
||||||
return moduleBaseWrapPointer(&CAPSULE_MESH_SIMPLE);
|
|
||||||
}
|
|
||||||
moduleBaseFunction(moduleMeshDefaultTriPrism) {
|
|
||||||
return moduleBaseWrapPointer(&TRIPRISM_MESH_SIMPLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---- Static factory methods ----
|
|
||||||
|
|
||||||
// Mesh.createCube(min?, max?) — defaults to (-0.5,-0.5,-0.5)..(0.5,0.5,0.5)
|
|
||||||
moduleBaseFunction(moduleMeshCreateCube) {
|
|
||||||
vec3 min = { -0.5f, -0.5f, -0.5f };
|
|
||||||
vec3 max = { 0.5f, 0.5f, 0.5f };
|
|
||||||
if(argc >= 2) {
|
|
||||||
if(!moduleVec3AnyCheck(args[0], min)) {
|
|
||||||
return moduleBaseThrow("Mesh.createCube: expected Vec3 min");
|
|
||||||
}
|
|
||||||
if(!moduleVec3AnyCheck(args[1], max)) {
|
|
||||||
return moduleBaseThrow("Mesh.createCube: expected Vec3 max");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
meshscript_t *ms = moduleMeshAlloc(CUBE_VERTEX_COUNT);
|
|
||||||
cubeBuffer(
|
|
||||||
ms->vertices, min, max
|
|
||||||
#if MESH_ENABLE_COLOR
|
|
||||||
, COLOR_WHITE_4B
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
return moduleMeshFinalize(ms, CUBE_PRIMITIVE_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mesh.createQuad(minX, minY, maxX, maxY) — 2D XY quad, u0-u1=0-1 v0-v1=0-1
|
|
||||||
moduleBaseFunction(moduleMeshCreateQuad) {
|
|
||||||
float_t minX = -0.5f, minY = -0.5f, maxX = 0.5f, maxY = 0.5f;
|
|
||||||
if(argc >= 4) {
|
|
||||||
if(!jerry_value_is_number(args[0]) || !jerry_value_is_number(args[1]) ||
|
|
||||||
!jerry_value_is_number(args[2]) || !jerry_value_is_number(args[3])) {
|
|
||||||
return moduleBaseThrow("Mesh.createQuad: expected (minX, minY, maxX, maxY)");
|
|
||||||
}
|
|
||||||
minX = moduleBaseArgFloat(0);
|
|
||||||
minY = moduleBaseArgFloat(1);
|
|
||||||
maxX = moduleBaseArgFloat(2);
|
|
||||||
maxY = moduleBaseArgFloat(3);
|
|
||||||
}
|
|
||||||
meshscript_t *ms = moduleMeshAlloc(QUAD_VERTEX_COUNT);
|
|
||||||
quadBuffer(
|
|
||||||
ms->vertices,
|
|
||||||
minX, minY, maxX, maxY,
|
|
||||||
0.0f, 0.0f, 1.0f, 1.0f
|
|
||||||
#if MESH_ENABLE_COLOR
|
|
||||||
, COLOR_WHITE_4B
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
return moduleMeshFinalize(ms, QUAD_PRIMITIVE_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mesh.createSphere(radius?, stacks?, sectors?)
|
|
||||||
moduleBaseFunction(moduleMeshCreateSphere) {
|
|
||||||
float_t radius = moduleBaseOptFloat(0, 0.5f);
|
|
||||||
int32_t stacks = moduleBaseOptInt(1, SPHERE_STACKS);
|
|
||||||
int32_t sectors = moduleBaseOptInt(2, SPHERE_SECTORS);
|
|
||||||
int32_t vertexCount = stacks * sectors * 6;
|
|
||||||
vec3 center = { 0.0f, 0.0f, 0.0f };
|
|
||||||
meshscript_t *ms = moduleMeshAlloc(vertexCount);
|
|
||||||
sphereBuffer(
|
|
||||||
ms->vertices, center, radius, stacks, sectors
|
|
||||||
#if MESH_ENABLE_COLOR
|
|
||||||
, COLOR_WHITE_4B
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
return moduleMeshFinalize(ms, SPHERE_PRIMITIVE_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mesh.createPlane(width?, height?) — XZ-aligned, centered at origin
|
|
||||||
moduleBaseFunction(moduleMeshCreatePlane) {
|
|
||||||
float_t width = moduleBaseOptFloat(0, 1.0f);
|
|
||||||
float_t height = moduleBaseOptFloat(1, 1.0f);
|
|
||||||
vec3 min = { -width * 0.5f, 0.0f, -height * 0.5f };
|
|
||||||
vec3 max = { width * 0.5f, 0.0f, height * 0.5f };
|
|
||||||
vec2 uvMin = { 0.0f, 0.0f };
|
|
||||||
vec2 uvMax = { 1.0f, 1.0f };
|
|
||||||
meshscript_t *ms = moduleMeshAlloc(PLANE_VERTEX_COUNT);
|
|
||||||
planeBuffer(
|
|
||||||
ms->vertices, PLANE_AXIS_XZ, min, max
|
|
||||||
#if MESH_ENABLE_COLOR
|
|
||||||
, COLOR_WHITE_4B
|
|
||||||
#endif
|
|
||||||
, uvMin, uvMax
|
|
||||||
);
|
|
||||||
return moduleMeshFinalize(ms, PLANE_PRIMITIVE_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mesh.createCapsule(radius?, halfHeight?, capRings?, sectors?)
|
|
||||||
moduleBaseFunction(moduleMeshCreateCapsule) {
|
|
||||||
float_t radius = moduleBaseOptFloat(0, 0.5f);
|
|
||||||
float_t halfHeight = moduleBaseOptFloat(1, 0.5f);
|
|
||||||
int32_t capRings = moduleBaseOptInt(2, CAPSULE_CAP_RINGS);
|
|
||||||
int32_t sectors = moduleBaseOptInt(3, CAPSULE_SECTORS);
|
|
||||||
int32_t vertexCount = (2 * capRings + 1) * sectors * 6;
|
|
||||||
vec3 center = { 0.0f, 0.0f, 0.0f };
|
|
||||||
meshscript_t *ms = moduleMeshAlloc(vertexCount);
|
|
||||||
capsuleBuffer(
|
|
||||||
ms->vertices, center, radius, halfHeight, capRings, sectors
|
|
||||||
#if MESH_ENABLE_COLOR
|
|
||||||
, COLOR_WHITE_4B
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
return moduleMeshFinalize(ms, CAPSULE_PRIMITIVE_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mesh.createTriPrism(x0, y0, x1, y1, x2, y2, minZ, maxZ)
|
|
||||||
moduleBaseFunction(moduleMeshCreateTriPrism) {
|
|
||||||
moduleBaseRequireArgs(8);
|
|
||||||
float_t x0 = moduleBaseArgFloat(0);
|
|
||||||
float_t y0 = moduleBaseArgFloat(1);
|
|
||||||
float_t x1 = moduleBaseArgFloat(2);
|
|
||||||
float_t y1 = moduleBaseArgFloat(3);
|
|
||||||
float_t x2 = moduleBaseArgFloat(4);
|
|
||||||
float_t y2 = moduleBaseArgFloat(5);
|
|
||||||
float_t minZ = moduleBaseArgFloat(6);
|
|
||||||
float_t maxZ = moduleBaseArgFloat(7);
|
|
||||||
meshscript_t *ms = moduleMeshAlloc(TRIPRISM_VERTEX_COUNT);
|
|
||||||
triPrismBuffer(
|
|
||||||
ms->vertices, x0, y0, x1, y1, x2, y2, minZ, maxZ
|
|
||||||
#if MESH_ENABLE_COLOR
|
|
||||||
, COLOR_WHITE_4B
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
return moduleMeshFinalize(ms, TRIPRISM_PRIMITIVE_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---- Registration ----
|
|
||||||
|
|
||||||
static void moduleMesh(void) {
|
|
||||||
// MeshVertex - internal type, no global constructor
|
|
||||||
scriptProtoInit(
|
|
||||||
&MODULE_MESH_VERTEX_PROTO, NULL,
|
|
||||||
sizeof(meshvertexscript_t), NULL
|
|
||||||
);
|
|
||||||
scriptProtoDefineProp(
|
|
||||||
&MODULE_MESH_VERTEX_PROTO, "position",
|
|
||||||
moduleMeshVertexGetPosition, moduleMeshVertexSetPosition
|
|
||||||
);
|
|
||||||
|
|
||||||
// Mesh - global constructor: new Mesh(vertexCount)
|
|
||||||
scriptProtoInit(
|
|
||||||
&MODULE_MESH_PROTO, "Mesh",
|
|
||||||
sizeof(meshscript_t), moduleMeshConstructor
|
|
||||||
);
|
|
||||||
MODULE_MESH_PROTO.info.free_cb = moduleMeshFreeData;
|
|
||||||
|
|
||||||
scriptProtoDefineToString(&MODULE_MESH_PROTO, moduleMeshToString);
|
|
||||||
scriptProtoDefineProp(
|
|
||||||
&MODULE_MESH_PROTO, "vertices",
|
|
||||||
moduleMeshGetVertices, NULL
|
|
||||||
);
|
|
||||||
scriptProtoDefineProp(
|
|
||||||
&MODULE_MESH_PROTO, "vertexCount",
|
|
||||||
moduleMeshGetVertexCount, NULL
|
|
||||||
);
|
|
||||||
scriptProtoDefineFunc(&MODULE_MESH_PROTO, "flush", moduleMeshFlush);
|
|
||||||
scriptProtoDefineFunc(&MODULE_MESH_PROTO, "dispose", moduleMeshDispose);
|
|
||||||
|
|
||||||
// Static default mesh references
|
|
||||||
scriptProtoDefineStaticProp(
|
|
||||||
&MODULE_MESH_PROTO, "DEFAULT_CUBE", moduleMeshDefaultCube, NULL
|
|
||||||
);
|
|
||||||
scriptProtoDefineStaticProp(
|
|
||||||
&MODULE_MESH_PROTO, "DEFAULT_QUAD", moduleMeshDefaultQuad, NULL
|
|
||||||
);
|
|
||||||
scriptProtoDefineStaticProp(
|
|
||||||
&MODULE_MESH_PROTO, "DEFAULT_SPHERE", moduleMeshDefaultSphere, NULL
|
|
||||||
);
|
|
||||||
scriptProtoDefineStaticProp(
|
|
||||||
&MODULE_MESH_PROTO, "DEFAULT_PLANE", moduleMeshDefaultPlane, NULL
|
|
||||||
);
|
|
||||||
scriptProtoDefineStaticProp(
|
|
||||||
&MODULE_MESH_PROTO, "DEFAULT_CAPSULE", moduleMeshDefaultCapsule, NULL
|
|
||||||
);
|
|
||||||
scriptProtoDefineStaticProp(
|
|
||||||
&MODULE_MESH_PROTO, "DEFAULT_TRIPRISM", moduleMeshDefaultTriPrism, NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
// Static factory methods
|
|
||||||
scriptProtoDefineStaticFunc(
|
|
||||||
&MODULE_MESH_PROTO, "createCube", moduleMeshCreateCube
|
|
||||||
);
|
|
||||||
scriptProtoDefineStaticFunc(
|
|
||||||
&MODULE_MESH_PROTO, "createQuad", moduleMeshCreateQuad
|
|
||||||
);
|
|
||||||
scriptProtoDefineStaticFunc(
|
|
||||||
&MODULE_MESH_PROTO, "createSphere", moduleMeshCreateSphere
|
|
||||||
);
|
|
||||||
scriptProtoDefineStaticFunc(
|
|
||||||
&MODULE_MESH_PROTO, "createPlane", moduleMeshCreatePlane
|
|
||||||
);
|
|
||||||
scriptProtoDefineStaticFunc(
|
|
||||||
&MODULE_MESH_PROTO, "createCapsule", moduleMeshCreateCapsule
|
|
||||||
);
|
|
||||||
scriptProtoDefineStaticFunc(
|
|
||||||
&MODULE_MESH_PROTO, "createTriPrism", moduleMeshCreateTriPrism
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2026 Dominic Masters
|
|
||||||
*
|
|
||||||
* This software is released under the MIT License.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include "script/module/display/modulecolor.h"
|
|
||||||
#include "display/screen/screen.h"
|
|
||||||
|
|
||||||
static scriptproto_t MODULE_SCREEN_PROTO;
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleScreenGetWidth) {
|
|
||||||
return jerry_number(SCREEN.width);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleScreenGetHeight) {
|
|
||||||
return jerry_number(SCREEN.height);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleScreenGetAspect) {
|
|
||||||
return jerry_number(SCREEN.aspect);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleScreenGetBackground) {
|
|
||||||
return moduleColorMakeObject(SCREEN.background);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleScreenSetBackground) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireObject(0);
|
|
||||||
color_t *color = (color_t*)scriptProtoGetValue(&MODULE_COLOR_PROTO, args[0]);
|
|
||||||
if(!color) return moduleBaseThrow("Background must be a valid color object");
|
|
||||||
memoryCopy(&SCREEN.background, color, sizeof(color_t));
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleScreenToString) {
|
|
||||||
char_t buf[128];
|
|
||||||
stringFormat(
|
|
||||||
buf, sizeof(buf),
|
|
||||||
"{ \"width\": %d, \"height\": %d, \"aspect\": %.2f }",
|
|
||||||
SCREEN.width, SCREEN.height, SCREEN.aspect
|
|
||||||
);
|
|
||||||
return jerry_string_sz(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void moduleScreen(void) {
|
|
||||||
scriptProtoInit(
|
|
||||||
&MODULE_SCREEN_PROTO, "Screen", sizeof(screen_t), NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
scriptProtoDefineProp(
|
|
||||||
&MODULE_SCREEN_PROTO, "width", moduleScreenGetWidth, NULL
|
|
||||||
);
|
|
||||||
scriptProtoDefineProp(
|
|
||||||
&MODULE_SCREEN_PROTO, "height", moduleScreenGetHeight, NULL
|
|
||||||
);
|
|
||||||
scriptProtoDefineProp(
|
|
||||||
&MODULE_SCREEN_PROTO, "aspect", moduleScreenGetAspect, NULL
|
|
||||||
);
|
|
||||||
scriptProtoDefineProp(
|
|
||||||
&MODULE_SCREEN_PROTO, "background",
|
|
||||||
moduleScreenGetBackground, moduleScreenSetBackground
|
|
||||||
);
|
|
||||||
|
|
||||||
scriptProtoDefineToString(&MODULE_SCREEN_PROTO, moduleScreenToString);
|
|
||||||
}
|
|
||||||
@@ -1,127 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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 "script/module/display/modulecolor.h"
|
|
||||||
#include "script/module/math/modulevec2.h"
|
|
||||||
#include "script/module/math/modulevec3.h"
|
|
||||||
#include "display/spritebatch/spritebatch.h"
|
|
||||||
|
|
||||||
static scriptproto_t MODULE_SPRITEBATCH_PROTO;
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleSpriteBatchGetSpriteCount) {
|
|
||||||
return jerry_number(SPRITEBATCH.spriteCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleSpriteBatchPush) {
|
|
||||||
#if MESH_ENABLE_COLOR
|
|
||||||
moduleBaseRequireArgs(9);
|
|
||||||
#else
|
|
||||||
moduleBaseRequireArgs(8);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
moduleBaseRequireNumber(0);
|
|
||||||
moduleBaseRequireNumber(1);
|
|
||||||
moduleBaseRequireNumber(2);
|
|
||||||
moduleBaseRequireNumber(3);
|
|
||||||
|
|
||||||
#if MESH_ENABLE_COLOR
|
|
||||||
color_t *col = (color_t *)scriptProtoGetValue(&MODULE_COLOR_PROTO, args[4]);
|
|
||||||
if(!col) return moduleBaseThrow("color must be a Color object");
|
|
||||||
moduleBaseRequireNumber(5);
|
|
||||||
moduleBaseRequireNumber(6);
|
|
||||||
moduleBaseRequireNumber(7);
|
|
||||||
moduleBaseRequireNumber(8);
|
|
||||||
spriteBatchPush(
|
|
||||||
moduleBaseArgFloat(0), moduleBaseArgFloat(1),
|
|
||||||
moduleBaseArgFloat(2), moduleBaseArgFloat(3),
|
|
||||||
*col,
|
|
||||||
moduleBaseArgFloat(5), moduleBaseArgFloat(6),
|
|
||||||
moduleBaseArgFloat(7), moduleBaseArgFloat(8)
|
|
||||||
);
|
|
||||||
#else
|
|
||||||
moduleBaseRequireNumber(4);
|
|
||||||
moduleBaseRequireNumber(5);
|
|
||||||
moduleBaseRequireNumber(6);
|
|
||||||
moduleBaseRequireNumber(7);
|
|
||||||
spriteBatchPush(
|
|
||||||
moduleBaseArgFloat(0), moduleBaseArgFloat(1),
|
|
||||||
moduleBaseArgFloat(2), moduleBaseArgFloat(3),
|
|
||||||
moduleBaseArgFloat(4), moduleBaseArgFloat(5),
|
|
||||||
moduleBaseArgFloat(6), moduleBaseArgFloat(7)
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleSpriteBatchPush3D) {
|
|
||||||
#if MESH_ENABLE_COLOR
|
|
||||||
moduleBaseRequireArgs(5);
|
|
||||||
#else
|
|
||||||
moduleBaseRequireArgs(4);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
float_t *min = moduleVec3From(args[0]);
|
|
||||||
if(!min) return moduleBaseThrow("min must be a Vec3");
|
|
||||||
float_t *max = moduleVec3From(args[1]);
|
|
||||||
if(!max) return moduleBaseThrow("max must be a Vec3");
|
|
||||||
|
|
||||||
#if MESH_ENABLE_COLOR
|
|
||||||
color_t *col = (color_t *)scriptProtoGetValue(&MODULE_COLOR_PROTO, args[2]);
|
|
||||||
if(!col) return moduleBaseThrow("color must be a Color object");
|
|
||||||
float_t *uvMin = moduleVec2From(args[3]);
|
|
||||||
if(!uvMin) return moduleBaseThrow("uvMin must be a Vec2");
|
|
||||||
float_t *uvMax = moduleVec2From(args[4]);
|
|
||||||
if(!uvMax) return moduleBaseThrow("uvMax must be a Vec2");
|
|
||||||
spriteBatchPush3D(min, max, *col, uvMin, uvMax);
|
|
||||||
#else
|
|
||||||
float_t *uvMin = moduleVec2From(args[2]);
|
|
||||||
if(!uvMin) return moduleBaseThrow("uvMin must be a Vec2");
|
|
||||||
float_t *uvMax = moduleVec2From(args[3]);
|
|
||||||
if(!uvMax) return moduleBaseThrow("uvMax must be a Vec2");
|
|
||||||
spriteBatchPush3D(min, max, uvMin, uvMax);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleSpriteBatchClear) {
|
|
||||||
spriteBatchClear();
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleSpriteBatchFlush) {
|
|
||||||
spriteBatchFlush();
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void moduleSpriteBatch(void) {
|
|
||||||
scriptProtoInit(
|
|
||||||
&MODULE_SPRITEBATCH_PROTO, "SpriteBatch", sizeof(uint8_t), NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
scriptProtoDefineStaticProp(
|
|
||||||
&MODULE_SPRITEBATCH_PROTO, "spriteCount",
|
|
||||||
moduleSpriteBatchGetSpriteCount, NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
scriptProtoDefineStaticFunc(
|
|
||||||
&MODULE_SPRITEBATCH_PROTO, "push", moduleSpriteBatchPush
|
|
||||||
);
|
|
||||||
scriptProtoDefineStaticFunc(
|
|
||||||
&MODULE_SPRITEBATCH_PROTO, "push3D", moduleSpriteBatchPush3D
|
|
||||||
);
|
|
||||||
scriptProtoDefineStaticFunc(
|
|
||||||
&MODULE_SPRITEBATCH_PROTO, "clear", moduleSpriteBatchClear
|
|
||||||
);
|
|
||||||
scriptProtoDefineStaticFunc(
|
|
||||||
&MODULE_SPRITEBATCH_PROTO, "flush", moduleSpriteBatchFlush
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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 "script/module/display/modulecolor.h"
|
|
||||||
#include "display/text/text.h"
|
|
||||||
|
|
||||||
static scriptproto_t MODULE_TEXT_PROTO;
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleTextDraw) {
|
|
||||||
moduleBaseRequireArgs(3); moduleBaseRequireNumber(0); moduleBaseRequireNumber(1);
|
|
||||||
moduleBaseRequireString(2);
|
|
||||||
|
|
||||||
float_t x = moduleBaseArgFloat(0);
|
|
||||||
float_t y = moduleBaseArgFloat(1);
|
|
||||||
|
|
||||||
char_t text[1024];
|
|
||||||
moduleBaseToString(args[2], text, sizeof(text));
|
|
||||||
|
|
||||||
color_t col = COLOR_WHITE;
|
|
||||||
if(argc >= 4) {
|
|
||||||
color_t *c = (color_t *)scriptProtoGetValue(&MODULE_COLOR_PROTO, args[3]);
|
|
||||||
if(c) col = *c;
|
|
||||||
}
|
|
||||||
|
|
||||||
errorret_t err = textDraw(
|
|
||||||
x, y, text, col, &FONT_DEFAULT
|
|
||||||
);
|
|
||||||
if(err.code != ERROR_OK) {
|
|
||||||
errorCatch(errorPrint(err));
|
|
||||||
return moduleBaseThrow("Text draw failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleTextMeasure) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireString(0);
|
|
||||||
|
|
||||||
char_t text[1024];
|
|
||||||
moduleBaseToString(args[0], text, sizeof(text));
|
|
||||||
|
|
||||||
int32_t w, h;
|
|
||||||
textMeasure(text, &FONT_DEFAULT, &w, &h);
|
|
||||||
|
|
||||||
jerry_value_t obj = jerry_object();
|
|
||||||
jerry_value_t wKey = jerry_string_sz("width");
|
|
||||||
jerry_value_t hKey = jerry_string_sz("height");
|
|
||||||
jerry_value_t wVal = jerry_number(w);
|
|
||||||
jerry_value_t hVal = jerry_number(h);
|
|
||||||
jerry_object_set(obj, wKey, wVal);
|
|
||||||
jerry_object_set(obj, hKey, hVal);
|
|
||||||
jerry_value_free(wKey);
|
|
||||||
jerry_value_free(hKey);
|
|
||||||
jerry_value_free(wVal);
|
|
||||||
jerry_value_free(hVal);
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void moduleText(void) {
|
|
||||||
scriptProtoInit(&MODULE_TEXT_PROTO, "Text", sizeof(uint8_t), NULL);
|
|
||||||
scriptProtoDefineStaticFunc(&MODULE_TEXT_PROTO, "draw", moduleTextDraw);
|
|
||||||
scriptProtoDefineStaticFunc(&MODULE_TEXT_PROTO, "measure", moduleTextMeasure);
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,182 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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 "entity/entity.h"
|
|
||||||
#include "entity/component/display/entitycamera.h"
|
|
||||||
#include "moduleentityposition.h"
|
|
||||||
|
|
||||||
static scriptproto_t MODULE_ENTITY_CAMERA_PROTO;
|
|
||||||
|
|
||||||
static entitycamera_t * moduleEntityCameraGet(
|
|
||||||
const jerry_call_info_t *callInfo
|
|
||||||
) {
|
|
||||||
componenthandle_t *h = scriptProtoGetValue(
|
|
||||||
&MODULE_ENTITY_CAMERA_PROTO, callInfo->this_value
|
|
||||||
);
|
|
||||||
if(!h) return NULL;
|
|
||||||
return (entitycamera_t*)componentGetData(h->eid, h->cid, COMPONENT_TYPE_CAMERA);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---- Getters ----
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityCameraGetZNear) {
|
|
||||||
moduleBaseGetOrReturn(entitycamera_t, cam, moduleEntityCameraGet);
|
|
||||||
return jerry_number(cam->nearClip);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityCameraGetZFar) {
|
|
||||||
moduleBaseGetOrReturn(entitycamera_t, cam, moduleEntityCameraGet);
|
|
||||||
return jerry_number(cam->farClip);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityCameraGetFov) {
|
|
||||||
moduleBaseGetOrReturn(entitycamera_t, cam, moduleEntityCameraGet);
|
|
||||||
if(
|
|
||||||
cam->projType != ENTITY_CAMERA_PROJECTION_TYPE_PERSPECTIVE &&
|
|
||||||
cam->projType != ENTITY_CAMERA_PROJECTION_TYPE_PERSPECTIVE_FLIPPED
|
|
||||||
) return jerry_undefined();
|
|
||||||
return jerry_number(cam->perspective.fov);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityCameraGetProjectionType) {
|
|
||||||
moduleBaseGetOrReturn(entitycamera_t, cam, moduleEntityCameraGet);
|
|
||||||
return jerry_number(cam->projType);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityCameraGetOrthoTop) {
|
|
||||||
moduleBaseGetOrReturn(entitycamera_t, cam, moduleEntityCameraGet);
|
|
||||||
if(cam->projType != ENTITY_CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC) return jerry_undefined();
|
|
||||||
return jerry_number(cam->orthographic.top);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityCameraGetOrthoBottom) {
|
|
||||||
moduleBaseGetOrReturn(entitycamera_t, cam, moduleEntityCameraGet);
|
|
||||||
if(cam->projType != ENTITY_CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC) return jerry_undefined();
|
|
||||||
return jerry_number(cam->orthographic.bottom);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityCameraGetOrthoLeft) {
|
|
||||||
moduleBaseGetOrReturn(entitycamera_t, cam, moduleEntityCameraGet);
|
|
||||||
if(cam->projType != ENTITY_CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC) return jerry_undefined();
|
|
||||||
return jerry_number(cam->orthographic.left);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityCameraGetOrthoRight) {
|
|
||||||
moduleBaseGetOrReturn(entitycamera_t, cam, moduleEntityCameraGet);
|
|
||||||
if(cam->projType != ENTITY_CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC) return jerry_undefined();
|
|
||||||
return jerry_number(cam->orthographic.right);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---- Setters ----
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityCameraSetZNear) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireNumber(0);
|
|
||||||
moduleBaseGetOrReturn(entitycamera_t, cam, moduleEntityCameraGet);
|
|
||||||
cam->nearClip = moduleBaseArgFloat(0);
|
|
||||||
return args[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityCameraSetZFar) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireNumber(0);
|
|
||||||
moduleBaseGetOrReturn(entitycamera_t, cam, moduleEntityCameraGet);
|
|
||||||
cam->farClip = moduleBaseArgFloat(0);
|
|
||||||
return args[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityCameraSetFov) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireNumber(0);
|
|
||||||
moduleBaseGetOrReturn(entitycamera_t, cam, moduleEntityCameraGet);
|
|
||||||
if(
|
|
||||||
cam->projType != ENTITY_CAMERA_PROJECTION_TYPE_PERSPECTIVE &&
|
|
||||||
cam->projType != ENTITY_CAMERA_PROJECTION_TYPE_PERSPECTIVE_FLIPPED
|
|
||||||
) return jerry_undefined();
|
|
||||||
cam->perspective.fov = moduleBaseArgFloat(0);
|
|
||||||
return args[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityCameraSetProjectionType) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireNumber(0);
|
|
||||||
moduleBaseGetOrReturn(entitycamera_t, cam, moduleEntityCameraGet);
|
|
||||||
int32_t t = moduleBaseArgInt(0);
|
|
||||||
if(
|
|
||||||
t < ENTITY_CAMERA_PROJECTION_TYPE_PERSPECTIVE ||
|
|
||||||
t > ENTITY_CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC
|
|
||||||
) return moduleBaseThrow("Invalid projection type");
|
|
||||||
cam->projType = (entitycameraprojectiontype_t)t;
|
|
||||||
return args[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityCameraSetOrthoTop) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireNumber(0);
|
|
||||||
moduleBaseGetOrReturn(entitycamera_t, cam, moduleEntityCameraGet);
|
|
||||||
if(cam->projType != ENTITY_CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC) return jerry_undefined();
|
|
||||||
cam->orthographic.top = moduleBaseArgFloat(0);
|
|
||||||
return args[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityCameraSetOrthoBottom) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireNumber(0);
|
|
||||||
moduleBaseGetOrReturn(entitycamera_t, cam, moduleEntityCameraGet);
|
|
||||||
if(cam->projType != ENTITY_CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC) return jerry_undefined();
|
|
||||||
cam->orthographic.bottom = moduleBaseArgFloat(0);
|
|
||||||
return args[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityCameraSetOrthoLeft) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireNumber(0);
|
|
||||||
moduleBaseGetOrReturn(entitycamera_t, cam, moduleEntityCameraGet);
|
|
||||||
if(cam->projType != ENTITY_CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC) return jerry_undefined();
|
|
||||||
cam->orthographic.left = moduleBaseArgFloat(0);
|
|
||||||
return args[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityCameraSetOrthoRight) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireNumber(0);
|
|
||||||
moduleBaseGetOrReturn(entitycamera_t, cam, moduleEntityCameraGet);
|
|
||||||
if(cam->projType != ENTITY_CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC) return jerry_undefined();
|
|
||||||
cam->orthographic.right = moduleBaseArgFloat(0);
|
|
||||||
return args[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityCameraAdd) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireNumber(0);
|
|
||||||
entityid_t id = (entityid_t)moduleBaseArgInt(0);
|
|
||||||
componentid_t comp = entityAddComponent(id, COMPONENT_TYPE_CAMERA);
|
|
||||||
componenthandle_t h = { .eid = id, .cid = comp };
|
|
||||||
return scriptProtoCreateValue(&MODULE_ENTITY_CAMERA_PROTO, &h);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void moduleEntityCAMERA(void) {
|
|
||||||
scriptProtoInit(
|
|
||||||
&MODULE_ENTITY_CAMERA_PROTO, NULL, sizeof(componenthandle_t), NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
scriptProtoDefineProp(&MODULE_ENTITY_CAMERA_PROTO, "zNear",
|
|
||||||
moduleEntityCameraGetZNear, moduleEntityCameraSetZNear);
|
|
||||||
scriptProtoDefineProp(&MODULE_ENTITY_CAMERA_PROTO, "zFar",
|
|
||||||
moduleEntityCameraGetZFar, moduleEntityCameraSetZFar);
|
|
||||||
scriptProtoDefineProp(&MODULE_ENTITY_CAMERA_PROTO, "fov",
|
|
||||||
moduleEntityCameraGetFov, moduleEntityCameraSetFov);
|
|
||||||
scriptProtoDefineProp(&MODULE_ENTITY_CAMERA_PROTO, "projectionType",
|
|
||||||
moduleEntityCameraGetProjectionType, moduleEntityCameraSetProjectionType);
|
|
||||||
scriptProtoDefineProp(&MODULE_ENTITY_CAMERA_PROTO, "orthoTop",
|
|
||||||
moduleEntityCameraGetOrthoTop, moduleEntityCameraSetOrthoTop);
|
|
||||||
scriptProtoDefineProp(&MODULE_ENTITY_CAMERA_PROTO, "orthoBottom",
|
|
||||||
moduleEntityCameraGetOrthoBottom, moduleEntityCameraSetOrthoBottom);
|
|
||||||
scriptProtoDefineProp(&MODULE_ENTITY_CAMERA_PROTO, "orthoLeft",
|
|
||||||
moduleEntityCameraGetOrthoLeft, moduleEntityCameraSetOrthoLeft);
|
|
||||||
scriptProtoDefineProp(&MODULE_ENTITY_CAMERA_PROTO, "orthoRight",
|
|
||||||
moduleEntityCameraGetOrthoRight, moduleEntityCameraSetOrthoRight);
|
|
||||||
|
|
||||||
moduleBaseSetInt("CAMERA_TYPE_ORTHOGRAPHIC",
|
|
||||||
ENTITY_CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC);
|
|
||||||
moduleBaseSetInt("CAMERA_TYPE_PERSPECTIVE",
|
|
||||||
ENTITY_CAMERA_PROJECTION_TYPE_PERSPECTIVE);
|
|
||||||
}
|
|
||||||
@@ -1,146 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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/module/math/modulevec3ref.h"
|
|
||||||
#include "script/scriptproto.h"
|
|
||||||
#include "entity/entity.h"
|
|
||||||
#include "entity/component/physics/entityphysics.h"
|
|
||||||
#include "moduleentityposition.h"
|
|
||||||
|
|
||||||
static scriptproto_t MODULE_ENTITY_PHYSICS_PROTO;
|
|
||||||
|
|
||||||
static entityphysics_t * moduleEntityPhysicsGet(
|
|
||||||
const jerry_call_info_t *callInfo
|
|
||||||
) {
|
|
||||||
componenthandle_t *h = scriptProtoGetValue(
|
|
||||||
&MODULE_ENTITY_PHYSICS_PROTO, callInfo->this_value
|
|
||||||
);
|
|
||||||
if(!h) return NULL;
|
|
||||||
return entityPhysicsGet(h->eid, h->cid);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityPhysicsGetVelocity) {
|
|
||||||
moduleBaseGetOrReturn(entityphysics_t, phys, moduleEntityPhysicsGet);
|
|
||||||
return moduleVec3RefPush(phys->velocity, NULL, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityPhysicsSetVelocity) {
|
|
||||||
moduleBaseRequireArgs(1);
|
|
||||||
moduleBaseGetOrReturn(entityphysics_t, phys, moduleEntityPhysicsGet);
|
|
||||||
vec3 v;
|
|
||||||
if(!moduleVec3AnyCheck(args[0], v)) return moduleBaseThrow("Expected Vec3");
|
|
||||||
glm_vec3_copy(v, phys->velocity);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityPhysicsGetOnGround) {
|
|
||||||
moduleBaseGetOrReturn(entityphysics_t, phys, moduleEntityPhysicsGet);
|
|
||||||
return jerry_boolean(phys->onGround);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityPhysicsGetBodyType) {
|
|
||||||
moduleBaseGetOrReturn(entityphysics_t, phys, moduleEntityPhysicsGet);
|
|
||||||
return jerry_number(phys->type);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityPhysicsSetBodyType) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireNumber(0);
|
|
||||||
moduleBaseGetOrReturn(entityphysics_t, phys, moduleEntityPhysicsGet);
|
|
||||||
phys->type = (physicsbodytype_t)moduleBaseArgInt(0);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityPhysicsApplyImpulse) {
|
|
||||||
moduleBaseRequireArgs(1);
|
|
||||||
moduleBaseGetOrReturn(entityphysics_t, phys, moduleEntityPhysicsGet);
|
|
||||||
if(phys->type == PHYSICS_BODY_STATIC) return jerry_undefined();
|
|
||||||
vec3 impulse;
|
|
||||||
if(!moduleVec3Check(args[0], impulse)) return moduleBaseThrow("Expected Vec3 impulse");
|
|
||||||
glm_vec3_add(phys->velocity, impulse, phys->velocity);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityPhysicsSetShapeCube) {
|
|
||||||
moduleBaseRequireArgs(1);
|
|
||||||
moduleBaseGetOrReturn(entityphysics_t, phys, moduleEntityPhysicsGet);
|
|
||||||
vec3 half;
|
|
||||||
if(!moduleVec3Check(args[0], half)) return moduleBaseThrow("Expected Vec3 halfExtents");
|
|
||||||
phys->shape.type = PHYSICS_SHAPE_CUBE;
|
|
||||||
glm_vec3_copy(half, phys->shape.data.cube.halfExtents);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityPhysicsSetShapeSphere) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireNumber(0);
|
|
||||||
moduleBaseGetOrReturn(entityphysics_t, phys, moduleEntityPhysicsGet);
|
|
||||||
phys->shape.type = PHYSICS_SHAPE_SPHERE;
|
|
||||||
phys->shape.data.sphere.radius = moduleBaseArgFloat(0);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityPhysicsSetShapeCapsule) {
|
|
||||||
moduleBaseRequireArgs(2); moduleBaseRequireNumber(0); moduleBaseRequireNumber(1);
|
|
||||||
moduleBaseGetOrReturn(entityphysics_t, phys, moduleEntityPhysicsGet);
|
|
||||||
phys->shape.type = PHYSICS_SHAPE_CAPSULE;
|
|
||||||
phys->shape.data.capsule.radius = moduleBaseArgFloat(0);
|
|
||||||
phys->shape.data.capsule.halfHeight = moduleBaseArgFloat(1);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityPhysicsSetShapePlane) {
|
|
||||||
moduleBaseRequireArgs(2); moduleBaseRequireNumber(1);
|
|
||||||
moduleBaseGetOrReturn(entityphysics_t, phys, moduleEntityPhysicsGet);
|
|
||||||
vec3 normal;
|
|
||||||
if(!moduleVec3Check(args[0], normal)) return moduleBaseThrow("Expected Vec3 normal");
|
|
||||||
phys->shape.type = PHYSICS_SHAPE_PLANE;
|
|
||||||
glm_vec3_copy(normal, phys->shape.data.plane.normal);
|
|
||||||
phys->shape.data.plane.distance = moduleBaseArgFloat(1);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityPhysicsAdd) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireNumber(0);
|
|
||||||
entityid_t id = (entityid_t)moduleBaseArgInt(0);
|
|
||||||
componentid_t comp = entityAddComponent(id, COMPONENT_TYPE_PHYSICS);
|
|
||||||
componenthandle_t h = { .eid = id, .cid = comp };
|
|
||||||
return scriptProtoCreateValue(&MODULE_ENTITY_PHYSICS_PROTO, &h);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void moduleEntityPHYSICS(void) {
|
|
||||||
scriptProtoInit(
|
|
||||||
&MODULE_ENTITY_PHYSICS_PROTO, NULL, sizeof(componenthandle_t), NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
scriptProtoDefineProp(&MODULE_ENTITY_PHYSICS_PROTO, "velocity",
|
|
||||||
moduleEntityPhysicsGetVelocity, moduleEntityPhysicsSetVelocity);
|
|
||||||
scriptProtoDefineProp(&MODULE_ENTITY_PHYSICS_PROTO, "onGround",
|
|
||||||
moduleEntityPhysicsGetOnGround, NULL);
|
|
||||||
scriptProtoDefineProp(&MODULE_ENTITY_PHYSICS_PROTO, "bodyType",
|
|
||||||
moduleEntityPhysicsGetBodyType, moduleEntityPhysicsSetBodyType);
|
|
||||||
|
|
||||||
scriptProtoDefineFunc(&MODULE_ENTITY_PHYSICS_PROTO, "applyImpulse",
|
|
||||||
moduleEntityPhysicsApplyImpulse);
|
|
||||||
scriptProtoDefineFunc(&MODULE_ENTITY_PHYSICS_PROTO, "setShapeCube",
|
|
||||||
moduleEntityPhysicsSetShapeCube);
|
|
||||||
scriptProtoDefineFunc(&MODULE_ENTITY_PHYSICS_PROTO, "setShapeSphere",
|
|
||||||
moduleEntityPhysicsSetShapeSphere);
|
|
||||||
scriptProtoDefineFunc(&MODULE_ENTITY_PHYSICS_PROTO, "setShapeCapsule",
|
|
||||||
moduleEntityPhysicsSetShapeCapsule);
|
|
||||||
scriptProtoDefineFunc(&MODULE_ENTITY_PHYSICS_PROTO, "setShapePlane",
|
|
||||||
moduleEntityPhysicsSetShapePlane);
|
|
||||||
|
|
||||||
moduleBaseSetInt("PHYSICS_BODY_STATIC", PHYSICS_BODY_STATIC);
|
|
||||||
moduleBaseSetInt("PHYSICS_BODY_DYNAMIC", PHYSICS_BODY_DYNAMIC);
|
|
||||||
moduleBaseSetInt("PHYSICS_BODY_KINEMATIC", PHYSICS_BODY_KINEMATIC);
|
|
||||||
|
|
||||||
moduleBaseSetInt("PHYSICS_SHAPE_CUBE", PHYSICS_SHAPE_CUBE);
|
|
||||||
moduleBaseSetInt("PHYSICS_SHAPE_SPHERE", PHYSICS_SHAPE_SPHERE);
|
|
||||||
moduleBaseSetInt("PHYSICS_SHAPE_CAPSULE", PHYSICS_SHAPE_CAPSULE);
|
|
||||||
moduleBaseSetInt("PHYSICS_SHAPE_PLANE", PHYSICS_SHAPE_PLANE);
|
|
||||||
}
|
|
||||||
@@ -1,138 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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/module/math/modulevec3ref.h"
|
|
||||||
#include "script/scriptproto.h"
|
|
||||||
#include "entity/entity.h"
|
|
||||||
#include "entity/component/display/entityposition.h"
|
|
||||||
|
|
||||||
#ifndef COMPONENT_HANDLE_DEFINED
|
|
||||||
#define COMPONENT_HANDLE_DEFINED
|
|
||||||
typedef struct {
|
|
||||||
entityid_t eid;
|
|
||||||
componentid_t cid;
|
|
||||||
} componenthandle_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static scriptproto_t MODULE_ENTITY_POSITION_PROTO;
|
|
||||||
|
|
||||||
static entityposition_t * moduleEntityPositionGet(
|
|
||||||
const jerry_call_info_t *callInfo
|
|
||||||
) {
|
|
||||||
componenthandle_t *h = scriptProtoGetValue(
|
|
||||||
&MODULE_ENTITY_POSITION_PROTO, callInfo->this_value
|
|
||||||
);
|
|
||||||
if(!h) return NULL;
|
|
||||||
return entityPositionGet(h->eid, h->cid);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityPositionGetPosition) {
|
|
||||||
moduleBaseGetOrReturn(entityposition_t, pos, moduleEntityPositionGet);
|
|
||||||
return moduleVec3RefPush(pos->position, (void(*)(void*))entityPositionRebuild, pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityPositionSetPosition) {
|
|
||||||
moduleBaseRequireArgs(1);
|
|
||||||
moduleBaseGetOrReturn(entityposition_t, pos, moduleEntityPositionGet);
|
|
||||||
vec3 v;
|
|
||||||
if(!moduleVec3AnyCheck(args[0], v)) return moduleBaseThrow("Expected Vec3");
|
|
||||||
glm_vec3_copy(v, pos->position);
|
|
||||||
entityPositionRebuild(pos);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityPositionGetRotation) {
|
|
||||||
moduleBaseGetOrReturn(entityposition_t, pos, moduleEntityPositionGet);
|
|
||||||
return moduleVec3RefPush(pos->rotation, (void(*)(void*))entityPositionRebuild, pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityPositionSetRotation) {
|
|
||||||
moduleBaseRequireArgs(1);
|
|
||||||
moduleBaseGetOrReturn(entityposition_t, pos, moduleEntityPositionGet);
|
|
||||||
vec3 v;
|
|
||||||
if(!moduleVec3AnyCheck(args[0], v)) return moduleBaseThrow("Expected Vec3");
|
|
||||||
glm_vec3_copy(v, pos->rotation);
|
|
||||||
entityPositionRebuild(pos);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityPositionGetScale) {
|
|
||||||
moduleBaseGetOrReturn(entityposition_t, pos, moduleEntityPositionGet);
|
|
||||||
return moduleVec3RefPush(pos->scale, (void(*)(void*))entityPositionRebuild, pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityPositionSetScale) {
|
|
||||||
moduleBaseRequireArgs(1);
|
|
||||||
moduleBaseGetOrReturn(entityposition_t, pos, moduleEntityPositionGet);
|
|
||||||
vec3 v;
|
|
||||||
if(!moduleVec3AnyCheck(args[0], v)) return moduleBaseThrow("Expected Vec3");
|
|
||||||
glm_vec3_copy(v, pos->scale);
|
|
||||||
entityPositionRebuild(pos);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityPositionLookAt) {
|
|
||||||
moduleBaseRequireArgs(1);
|
|
||||||
moduleBaseGetOrReturn(entityposition_t, pos, moduleEntityPositionGet);
|
|
||||||
vec3 target;
|
|
||||||
if(!moduleVec3AnyCheck(args[0], target)) return moduleBaseThrow("Expected Vec3 target");
|
|
||||||
vec3 up = { 0.0f, 1.0f, 0.0f };
|
|
||||||
if(argc >= 2 && !moduleVec3AnyCheck(args[1], up)) return moduleBaseThrow("Expected Vec3 up");
|
|
||||||
componenthandle_t *h = scriptProtoGetValue(
|
|
||||||
&MODULE_ENTITY_POSITION_PROTO, callInfo->this_value
|
|
||||||
);
|
|
||||||
entityPositionLookAt(h->eid, h->cid, target, up, pos->position);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityPositionGetParent) {
|
|
||||||
moduleBaseGetOrReturn(entityposition_t, pos, moduleEntityPositionGet);
|
|
||||||
if(pos->parentEntityId == ENTITY_ID_INVALID) return jerry_null();
|
|
||||||
componenthandle_t ph = { .eid = pos->parentEntityId, .cid = pos->parentComponentId };
|
|
||||||
return scriptProtoCreateValue(&MODULE_ENTITY_POSITION_PROTO, &ph);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityPositionSetParentProp) {
|
|
||||||
componenthandle_t *h = scriptProtoGetValue(
|
|
||||||
&MODULE_ENTITY_POSITION_PROTO, callInfo->this_value
|
|
||||||
);
|
|
||||||
if(!h) return jerry_undefined();
|
|
||||||
if(argc < 1 || jerry_value_is_null(args[0]) || jerry_value_is_undefined(args[0])) {
|
|
||||||
entityPositionSetParent(h->eid, h->cid, ENTITY_ID_INVALID, COMPONENT_ID_INVALID);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
componenthandle_t *ph = scriptProtoGetValue(&MODULE_ENTITY_POSITION_PROTO, args[0]);
|
|
||||||
if(!ph) return moduleBaseThrow("Expected EntityPosition");
|
|
||||||
entityPositionSetParent(h->eid, h->cid, ph->eid, ph->cid);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityPositionAdd) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireNumber(0);
|
|
||||||
entityid_t id = (entityid_t)moduleBaseArgInt(0);
|
|
||||||
componentid_t comp = entityAddComponent(id, COMPONENT_TYPE_POSITION);
|
|
||||||
componenthandle_t h = { .eid = id, .cid = comp };
|
|
||||||
return scriptProtoCreateValue(&MODULE_ENTITY_POSITION_PROTO, &h);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void moduleEntityPOSITION(void) {
|
|
||||||
scriptProtoInit(
|
|
||||||
&MODULE_ENTITY_POSITION_PROTO, NULL, sizeof(componenthandle_t), NULL
|
|
||||||
);
|
|
||||||
scriptProtoDefineProp(&MODULE_ENTITY_POSITION_PROTO, "position",
|
|
||||||
moduleEntityPositionGetPosition, moduleEntityPositionSetPosition);
|
|
||||||
scriptProtoDefineProp(&MODULE_ENTITY_POSITION_PROTO, "rotation",
|
|
||||||
moduleEntityPositionGetRotation, moduleEntityPositionSetRotation);
|
|
||||||
scriptProtoDefineProp(&MODULE_ENTITY_POSITION_PROTO, "scale",
|
|
||||||
moduleEntityPositionGetScale, moduleEntityPositionSetScale);
|
|
||||||
scriptProtoDefineProp(&MODULE_ENTITY_POSITION_PROTO, "parent",
|
|
||||||
moduleEntityPositionGetParent, moduleEntityPositionSetParentProp);
|
|
||||||
scriptProtoDefineFunc(&MODULE_ENTITY_POSITION_PROTO, "lookAt",
|
|
||||||
moduleEntityPositionLookAt);
|
|
||||||
}
|
|
||||||
@@ -1,201 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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/module/display/modulemesh.h"
|
|
||||||
#include "script/module/display/modulecolor.h"
|
|
||||||
#include "script/scriptproto.h"
|
|
||||||
#include "entity/entity.h"
|
|
||||||
#include "entity/component/display/entityrenderable.h"
|
|
||||||
#include "moduleentityposition.h"
|
|
||||||
|
|
||||||
static scriptproto_t MODULE_ENTITY_RENDERABLE_PROTO;
|
|
||||||
|
|
||||||
static entityrenderable_t * moduleEntityRenderableGet(
|
|
||||||
const jerry_call_info_t *callInfo
|
|
||||||
) {
|
|
||||||
componenthandle_t *h = scriptProtoGetValue(
|
|
||||||
&MODULE_ENTITY_RENDERABLE_PROTO, callInfo->this_value
|
|
||||||
);
|
|
||||||
if(!h) return NULL;
|
|
||||||
return (entityrenderable_t*)componentGetData(
|
|
||||||
h->eid, h->cid, COMPONENT_TYPE_RENDERABLE
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityRenderableGetType) {
|
|
||||||
moduleBaseGetOrReturn(entityrenderable_t, r, moduleEntityRenderableGet);
|
|
||||||
return jerry_number(r->type);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityRenderableSetType) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireNumber(0);
|
|
||||||
moduleBaseGetOrReturn(entityrenderable_t, r, moduleEntityRenderableGet);
|
|
||||||
r->type = (entityrenderabletype_t)moduleBaseArgInt(0);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityRenderableGetMesh) {
|
|
||||||
moduleBaseGetOrReturn(entityrenderable_t, r, moduleEntityRenderableGet);
|
|
||||||
if(!r->mesh) return jerry_undefined();
|
|
||||||
return moduleBaseWrapPointer(r->mesh);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityRenderableSetMesh) {
|
|
||||||
moduleBaseRequireArgs(1);
|
|
||||||
moduleBaseGetOrReturn(entityrenderable_t, r, moduleEntityRenderableGet);
|
|
||||||
meshscript_t *ms = moduleMeshFrom(args[0]);
|
|
||||||
if(ms) { r->mesh = &ms->mesh; return jerry_undefined(); }
|
|
||||||
mesh_t *raw = (mesh_t*)moduleBaseUnwrapPointer(args[0]);
|
|
||||||
if(raw) { r->mesh = raw; return jerry_undefined(); }
|
|
||||||
return moduleBaseThrow("Expected a Mesh object or mesh constant");
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityRenderableGetColor) {
|
|
||||||
moduleBaseGetOrReturn(entityrenderable_t, r, moduleEntityRenderableGet);
|
|
||||||
return moduleColorMakeObject(r->material.unlit.color);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityRenderableSetColor) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireObject(0);
|
|
||||||
color_t *color = (color_t*)scriptProtoGetValue(&MODULE_COLOR_PROTO, args[0]);
|
|
||||||
if(!color) return moduleBaseThrow("Renderable.color: expected valid color object");
|
|
||||||
moduleBaseGetOrReturn(entityrenderable_t, r, moduleEntityRenderableGet);
|
|
||||||
memoryCopy(&r->material.unlit.color, color, sizeof(color_t));
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityRenderableSpriteBatchAdd) {
|
|
||||||
moduleBaseRequireArgs(1);
|
|
||||||
componenthandle_t *h = scriptProtoGetValue(
|
|
||||||
&MODULE_ENTITY_RENDERABLE_PROTO, callInfo->this_value
|
|
||||||
);
|
|
||||||
if(!h) return jerry_undefined();
|
|
||||||
|
|
||||||
spritebatchsprite_t sprite;
|
|
||||||
glm_vec3_zero(sprite.min);
|
|
||||||
glm_vec3_zero(sprite.max);
|
|
||||||
glm_vec2_zero(sprite.uvMin);
|
|
||||||
glm_vec2_zero(sprite.uvMax);
|
|
||||||
sprite.texture = NULL;
|
|
||||||
#if MESH_ENABLE_COLOR
|
|
||||||
sprite.color = COLOR_WHITE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
jerry_value_t obj = args[0];
|
|
||||||
#define getVecField(name, dst, n) do { \
|
|
||||||
jerry_value_t _v = jerry_object_get_sz(obj, name); \
|
|
||||||
if(!jerry_value_is_undefined(_v)) moduleVec##n##AnyCheck(_v, dst); \
|
|
||||||
jerry_value_free(_v); \
|
|
||||||
} while(0)
|
|
||||||
getVecField("min", sprite.min, 3);
|
|
||||||
getVecField("max", sprite.max, 3);
|
|
||||||
getVecField("uvMin", sprite.uvMin, 2);
|
|
||||||
getVecField("uvMax", sprite.uvMax, 2);
|
|
||||||
#undef getVecField
|
|
||||||
|
|
||||||
entityRenderableSpriteBatchAdd(h->eid, h->cid, &sprite);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityRenderableSpriteBatchClear) {
|
|
||||||
componenthandle_t *h = scriptProtoGetValue(
|
|
||||||
&MODULE_ENTITY_RENDERABLE_PROTO, callInfo->this_value
|
|
||||||
);
|
|
||||||
if(!h) return jerry_undefined();
|
|
||||||
entityRenderableSpriteBatchClear(h->eid, h->cid);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void jsRenderCallbackFree(void *user) {
|
|
||||||
jerry_value_t *cb = (jerry_value_t *)user;
|
|
||||||
jerry_value_free(*cb);
|
|
||||||
memoryFree(cb);
|
|
||||||
}
|
|
||||||
|
|
||||||
static errorret_t jsRenderCallbackBridge(
|
|
||||||
const entityid_t entityId,
|
|
||||||
const componentid_t componentId,
|
|
||||||
const mat4 view,
|
|
||||||
const mat4 proj,
|
|
||||||
const mat4 model,
|
|
||||||
void *user
|
|
||||||
) {
|
|
||||||
(void)entityId; (void)componentId;
|
|
||||||
(void)view; (void)proj; (void)model;
|
|
||||||
jerry_value_t *cb = (jerry_value_t *)user;
|
|
||||||
jerry_value_t ret = jerry_call(*cb, jerry_undefined(), NULL, 0);
|
|
||||||
if(jerry_value_is_exception(ret)) {
|
|
||||||
jerry_value_free(ret);
|
|
||||||
errorThrow("Renderable callback threw a JS exception");
|
|
||||||
}
|
|
||||||
jerry_value_free(ret);
|
|
||||||
errorOk();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityRenderableSetCallback) {
|
|
||||||
componenthandle_t *h = scriptProtoGetValue(
|
|
||||||
&MODULE_ENTITY_RENDERABLE_PROTO, callInfo->this_value
|
|
||||||
);
|
|
||||||
if(!h) return jerry_undefined();
|
|
||||||
|
|
||||||
entityrenderable_t *r = (entityrenderable_t *)componentGetData(
|
|
||||||
h->eid, h->cid, COMPONENT_TYPE_RENDERABLE
|
|
||||||
);
|
|
||||||
|
|
||||||
if(
|
|
||||||
r->type == ENTITY_RENDERABLE_TYPE_CALLBACK &&
|
|
||||||
r->userFree &&
|
|
||||||
r->user
|
|
||||||
) {
|
|
||||||
r->userFree(r->user);
|
|
||||||
r->user = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(argc >= 1 && jerry_value_is_function(args[0])) {
|
|
||||||
jerry_value_t *cb = (jerry_value_t *)memoryAllocate(sizeof(jerry_value_t));
|
|
||||||
*cb = jerry_value_copy(args[0]);
|
|
||||||
r->type = ENTITY_RENDERABLE_TYPE_CALLBACK;
|
|
||||||
r->callback = jsRenderCallbackBridge;
|
|
||||||
r->userFree = jsRenderCallbackFree;
|
|
||||||
r->user = cb;
|
|
||||||
} else {
|
|
||||||
r->type = ENTITY_RENDERABLE_TYPE_CALLBACK;
|
|
||||||
r->callback = NULL;
|
|
||||||
r->userFree = NULL;
|
|
||||||
r->user = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void moduleEntityRENDERABLE(void) {
|
|
||||||
scriptProtoInit(
|
|
||||||
&MODULE_ENTITY_RENDERABLE_PROTO, NULL, sizeof(componenthandle_t), NULL
|
|
||||||
);
|
|
||||||
scriptProtoDefineProp(&MODULE_ENTITY_RENDERABLE_PROTO, "type",
|
|
||||||
moduleEntityRenderableGetType, moduleEntityRenderableSetType);
|
|
||||||
scriptProtoDefineProp(&MODULE_ENTITY_RENDERABLE_PROTO, "mesh",
|
|
||||||
moduleEntityRenderableGetMesh, moduleEntityRenderableSetMesh);
|
|
||||||
scriptProtoDefineProp(&MODULE_ENTITY_RENDERABLE_PROTO, "color",
|
|
||||||
moduleEntityRenderableGetColor, moduleEntityRenderableSetColor);
|
|
||||||
scriptProtoDefineFunc(&MODULE_ENTITY_RENDERABLE_PROTO, "addSprite",
|
|
||||||
moduleEntityRenderableSpriteBatchAdd);
|
|
||||||
scriptProtoDefineFunc(&MODULE_ENTITY_RENDERABLE_PROTO, "clearSprites",
|
|
||||||
moduleEntityRenderableSpriteBatchClear);
|
|
||||||
|
|
||||||
scriptProtoDefineFunc(&MODULE_ENTITY_RENDERABLE_PROTO, "setCallback",
|
|
||||||
moduleEntityRenderableSetCallback);
|
|
||||||
|
|
||||||
moduleBaseSetInt("ENTITY_RENDERABLE_TYPE_MATERIAL",
|
|
||||||
ENTITY_RENDERABLE_TYPE_MATERIAL);
|
|
||||||
moduleBaseSetInt("ENTITY_RENDERABLE_TYPE_SPRITEBATCH",
|
|
||||||
ENTITY_RENDERABLE_TYPE_SPRITEBATCH);
|
|
||||||
moduleBaseSetInt("ENTITY_RENDERABLE_TYPE_CALLBACK",
|
|
||||||
ENTITY_RENDERABLE_TYPE_CALLBACK);
|
|
||||||
}
|
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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/module/math/modulevec3.h"
|
|
||||||
#include "script/scriptproto.h"
|
|
||||||
#include "entity/entity.h"
|
|
||||||
#include "entity/component/trigger/entitytrigger.h"
|
|
||||||
#include "moduleentityposition.h"
|
|
||||||
|
|
||||||
static scriptproto_t MODULE_ENTITY_TRIGGER_PROTO;
|
|
||||||
|
|
||||||
static entitytrigger_t * moduleEntityTriggerGet(
|
|
||||||
const jerry_call_info_t *callInfo
|
|
||||||
) {
|
|
||||||
componenthandle_t *h = scriptProtoGetValue(
|
|
||||||
&MODULE_ENTITY_TRIGGER_PROTO, callInfo->this_value
|
|
||||||
);
|
|
||||||
if(!h) return NULL;
|
|
||||||
return entityTriggerGet(h->eid, h->cid);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityTriggerGetMin) {
|
|
||||||
moduleBaseGetOrReturn(entitytrigger_t, t, moduleEntityTriggerGet);
|
|
||||||
return moduleVec3Push(t->min);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityTriggerSetMin) {
|
|
||||||
moduleBaseRequireArgs(1);
|
|
||||||
moduleBaseGetOrReturn(entitytrigger_t, t, moduleEntityTriggerGet);
|
|
||||||
vec3 v;
|
|
||||||
if(!moduleVec3AnyCheck(args[0], v)) return moduleBaseThrow("Expected Vec3");
|
|
||||||
glm_vec3_copy(v, t->min);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityTriggerGetMax) {
|
|
||||||
moduleBaseGetOrReturn(entitytrigger_t, t, moduleEntityTriggerGet);
|
|
||||||
return moduleVec3Push(t->max);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityTriggerSetMax) {
|
|
||||||
moduleBaseRequireArgs(1);
|
|
||||||
moduleBaseGetOrReturn(entitytrigger_t, t, moduleEntityTriggerGet);
|
|
||||||
vec3 v;
|
|
||||||
if(!moduleVec3AnyCheck(args[0], v)) return moduleBaseThrow("Expected Vec3");
|
|
||||||
glm_vec3_copy(v, t->max);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityTriggerSetBounds) {
|
|
||||||
moduleBaseRequireArgs(2);
|
|
||||||
componenthandle_t *h = scriptProtoGetValue(
|
|
||||||
&MODULE_ENTITY_TRIGGER_PROTO, callInfo->this_value
|
|
||||||
);
|
|
||||||
if(!h) return jerry_undefined();
|
|
||||||
vec3 mn, mx;
|
|
||||||
if(!moduleVec3AnyCheck(args[0], mn)) return moduleBaseThrow("Expected Vec3 min");
|
|
||||||
if(!moduleVec3AnyCheck(args[1], mx)) return moduleBaseThrow("Expected Vec3 max");
|
|
||||||
entityTriggerSetBounds(h->eid, h->cid, mn, mx);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityTriggerContains) {
|
|
||||||
moduleBaseRequireArgs(1);
|
|
||||||
componenthandle_t *h = scriptProtoGetValue(
|
|
||||||
&MODULE_ENTITY_TRIGGER_PROTO, callInfo->this_value
|
|
||||||
);
|
|
||||||
if(!h) return jerry_boolean(false);
|
|
||||||
vec3 point;
|
|
||||||
if(!moduleVec3AnyCheck(args[0], point)) return moduleBaseThrow("Expected Vec3");
|
|
||||||
return jerry_boolean(entityTriggerContains(h->eid, h->cid, point));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void moduleEntityTRIGGER(void) {
|
|
||||||
scriptProtoInit(
|
|
||||||
&MODULE_ENTITY_TRIGGER_PROTO, NULL, sizeof(componenthandle_t), NULL
|
|
||||||
);
|
|
||||||
scriptProtoDefineProp(&MODULE_ENTITY_TRIGGER_PROTO, "min",
|
|
||||||
moduleEntityTriggerGetMin, moduleEntityTriggerSetMin);
|
|
||||||
scriptProtoDefineProp(&MODULE_ENTITY_TRIGGER_PROTO, "max",
|
|
||||||
moduleEntityTriggerGetMax, moduleEntityTriggerSetMax);
|
|
||||||
scriptProtoDefineFunc(&MODULE_ENTITY_TRIGGER_PROTO, "setBounds",
|
|
||||||
moduleEntityTriggerSetBounds);
|
|
||||||
scriptProtoDefineFunc(&MODULE_ENTITY_TRIGGER_PROTO, "contains",
|
|
||||||
moduleEntityTriggerContains);
|
|
||||||
}
|
|
||||||
@@ -1,196 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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 "entity/entity.h"
|
|
||||||
#include "entity/entitymanager.h"
|
|
||||||
|
|
||||||
#include "component/moduleentityposition.h"
|
|
||||||
#include "component/moduleentitycamera.h"
|
|
||||||
#include "component/moduleentityrenderable.h"
|
|
||||||
#include "component/moduleentityphysics.h"
|
|
||||||
#include "component/moduleentitytrigger.h"
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
entityid_t id;
|
|
||||||
} entityscript_t;
|
|
||||||
|
|
||||||
static scriptproto_t MODULE_ENTITY_PROTO;
|
|
||||||
|
|
||||||
static inline entityscript_t * moduleEntityGet(
|
|
||||||
const jerry_call_info_t *callInfo
|
|
||||||
) {
|
|
||||||
return (entityscript_t*)scriptProtoGetValue(
|
|
||||||
&MODULE_ENTITY_PROTO, callInfo->this_value
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Getters
|
|
||||||
moduleBaseFunction(moduleEntityGetId) {
|
|
||||||
moduleBaseGetOrReturn(entityscript_t, inst, moduleEntityGet);
|
|
||||||
return jerry_number(inst->id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Getter defined for each component type
|
|
||||||
static jerry_value_t moduleEntityGetComponent(
|
|
||||||
const jerry_call_info_t *callInfo,
|
|
||||||
const jerry_value_t args[],
|
|
||||||
const jerry_length_t argc,
|
|
||||||
const componenttype_t type,
|
|
||||||
scriptproto_t *proto
|
|
||||||
) {
|
|
||||||
assertNotNull(callInfo, "Call info must not be null");
|
|
||||||
assertTrue(argc >= 0, "Argc must be non-negative");
|
|
||||||
assertTrue(
|
|
||||||
type > COMPONENT_TYPE_NULL && type < COMPONENT_TYPE_COUNT,
|
|
||||||
"Invalid component type"
|
|
||||||
);
|
|
||||||
|
|
||||||
entityid_t entityId;
|
|
||||||
componentid_t compId;
|
|
||||||
|
|
||||||
entityscript_t *inst = moduleEntityGet(callInfo);
|
|
||||||
if(!inst) return jerry_undefined();
|
|
||||||
entityId = inst->id;
|
|
||||||
|
|
||||||
// Find the component ID of the requested type.
|
|
||||||
compId = entityGetComponent(entityId, type);
|
|
||||||
if(compId == COMPONENT_ID_INVALID) {
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
componenthandle_t h = { .eid = entityId, .cid = compId };
|
|
||||||
return scriptProtoCreateValue(proto, &h);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define X(enumName, type, field, init, dispose) \
|
|
||||||
moduleBaseFunction(moduleEntityGet##enumName) { \
|
|
||||||
return moduleEntityGetComponent( \
|
|
||||||
callInfo, \
|
|
||||||
args, \
|
|
||||||
argc, \
|
|
||||||
COMPONENT_TYPE_##enumName, \
|
|
||||||
&MODULE_ENTITY_##enumName##_PROTO \
|
|
||||||
); \
|
|
||||||
}
|
|
||||||
#include "entity/componentlist.h"
|
|
||||||
#undef X
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityToString) {
|
|
||||||
entityscript_t *inst = moduleEntityGet(callInfo);
|
|
||||||
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) == COMPONENT_ID_INVALID) 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
|
|
||||||
moduleBaseFunction(moduleEntityConstructor) {
|
|
||||||
entityscript_t *inst = (entityscript_t*)memoryAllocate(
|
|
||||||
sizeof(entityscript_t)
|
|
||||||
);
|
|
||||||
inst->id = entityManagerAdd();
|
|
||||||
jerry_object_set_native_ptr(
|
|
||||||
callInfo->this_value, &MODULE_ENTITY_PROTO.info, inst
|
|
||||||
);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityAddComponent) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireNumber(0);
|
|
||||||
componenttype_t type = (componenttype_t)moduleBaseArgInt(0);
|
|
||||||
if(type <= COMPONENT_TYPE_NULL || type >= COMPONENT_TYPE_COUNT) {
|
|
||||||
return moduleBaseThrow("Entity.add: invalid component type");
|
|
||||||
}
|
|
||||||
|
|
||||||
entityscript_t *inst = moduleEntityGet(callInfo);
|
|
||||||
if(!inst) return moduleBaseThrow("Entity.add: invalid entity");
|
|
||||||
|
|
||||||
componentid_t id = entityAddComponent(inst->id, type);
|
|
||||||
componenthandle_t h = { .eid = inst->id, .cid = id };
|
|
||||||
switch(type) {
|
|
||||||
#define X(enumName, stype, field, init, dispose) \
|
|
||||||
case COMPONENT_TYPE_##enumName: \
|
|
||||||
return scriptProtoCreateValue(&MODULE_ENTITY_##enumName##_PROTO, &h);
|
|
||||||
#include "entity/componentlist.h"
|
|
||||||
#undef X
|
|
||||||
default: return jerry_number(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleEntityDisposeMethod) {
|
|
||||||
moduleBaseGetOrReturn(entityscript_t, inst, moduleEntityGet);
|
|
||||||
entityDispose(inst->id);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void moduleEntity(void) {
|
|
||||||
// Init the entity prototype
|
|
||||||
scriptProtoInit(
|
|
||||||
&MODULE_ENTITY_PROTO,
|
|
||||||
"Entity",
|
|
||||||
sizeof(entityscript_t),
|
|
||||||
moduleEntityConstructor
|
|
||||||
);
|
|
||||||
|
|
||||||
scriptProtoDefineToString(&MODULE_ENTITY_PROTO, moduleEntityToString);
|
|
||||||
|
|
||||||
// Entity Methods
|
|
||||||
scriptProtoDefineFunc(
|
|
||||||
&MODULE_ENTITY_PROTO, "add", moduleEntityAddComponent
|
|
||||||
);
|
|
||||||
scriptProtoDefineFunc(
|
|
||||||
&MODULE_ENTITY_PROTO, "dispose", moduleEntityDisposeMethod
|
|
||||||
);
|
|
||||||
|
|
||||||
// Entity props
|
|
||||||
scriptProtoDefineProp(
|
|
||||||
&MODULE_ENTITY_PROTO, "id", moduleEntityGetId, NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
// Init component type modules.
|
|
||||||
#define X(enumName, type, field, iMethod, dMethod) \
|
|
||||||
moduleEntity##enumName(); \
|
|
||||||
scriptProtoDefineProp( \
|
|
||||||
&MODULE_ENTITY_PROTO, \
|
|
||||||
COMPONENT_DEFINITIONS[COMPONENT_TYPE_##enumName].name, \
|
|
||||||
moduleEntityGet##enumName, \
|
|
||||||
NULL \
|
|
||||||
); \
|
|
||||||
moduleBaseSetInt(#enumName, COMPONENT_TYPE_##enumName);
|
|
||||||
#include "entity/componentlist.h"
|
|
||||||
#undef X
|
|
||||||
}
|
|
||||||
@@ -1,103 +0,0 @@
|
|||||||
// 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 "event/event.h"
|
|
||||||
#include "assert/assert.h"
|
|
||||||
#include "animation/easing.h"
|
|
||||||
|
|
||||||
#define MODULE_EVENT_POOL_MAX 32
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
jerry_value_t callback; // owned copy; slot is free when event == NULL
|
|
||||||
event_t *event;
|
|
||||||
} jsEventSub_t;
|
|
||||||
|
|
||||||
static jsEventSub_t MODULE_EVENT_POOL[MODULE_EVENT_POOL_MAX];
|
|
||||||
|
|
||||||
static void moduleEventBridge(void *params, void *user) {
|
|
||||||
(void)params;
|
|
||||||
jsEventSub_t *sub = (jsEventSub_t *)user;
|
|
||||||
jerry_value_t ret = jerry_call(sub->callback, jerry_undefined(), NULL, 0);
|
|
||||||
jerry_value_free(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool_t moduleEventCallbackEquals(
|
|
||||||
const jerry_value_t a,
|
|
||||||
const jerry_value_t b
|
|
||||||
) {
|
|
||||||
jerry_value_t result = jerry_binary_op(JERRY_BIN_OP_STRICT_EQUAL, a, b);
|
|
||||||
bool_t eq = jerry_value_is_true(result);
|
|
||||||
jerry_value_free(result);
|
|
||||||
return eq;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void moduleEventJsSubscribe(event_t *event, jerry_value_t callback) {
|
|
||||||
assertNotNull(event, "event must not be NULL");
|
|
||||||
|
|
||||||
for(uint8_t i = 0; i < MODULE_EVENT_POOL_MAX; i++) {
|
|
||||||
if(MODULE_EVENT_POOL[i].event != event) continue;
|
|
||||||
if(moduleEventCallbackEquals(MODULE_EVENT_POOL[i].callback, callback)) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(uint8_t i = 0; i < MODULE_EVENT_POOL_MAX; i++) {
|
|
||||||
if(MODULE_EVENT_POOL[i].event != NULL) continue;
|
|
||||||
MODULE_EVENT_POOL[i].callback = jerry_value_copy(callback);
|
|
||||||
MODULE_EVENT_POOL[i].event = event;
|
|
||||||
eventSubscribe(event, moduleEventBridge, &MODULE_EVENT_POOL[i]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
assertUnreachable("MODULE_EVENT_POOL_MAX exceeded");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void moduleEventJsUnsubscribe(event_t *event, jerry_value_t callback) {
|
|
||||||
assertNotNull(event, "event must not be NULL");
|
|
||||||
|
|
||||||
for(uint8_t i = 0; i < MODULE_EVENT_POOL_MAX; i++) {
|
|
||||||
if(MODULE_EVENT_POOL[i].event != event) continue;
|
|
||||||
if(!moduleEventCallbackEquals(MODULE_EVENT_POOL[i].callback, callback)) continue;
|
|
||||||
|
|
||||||
eventUnsubscribe(event, moduleEventBridge, &MODULE_EVENT_POOL[i]);
|
|
||||||
jerry_value_free(MODULE_EVENT_POOL[i].callback);
|
|
||||||
MODULE_EVENT_POOL[i].callback = 0;
|
|
||||||
MODULE_EVENT_POOL[i].event = NULL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Swap a pool-based event callback slot. Unsubscribes and frees the previous
|
|
||||||
* function (if any), then subscribes fn if it is callable. Pass
|
|
||||||
* jerry_undefined() as fn to clear without setting a new callback.
|
|
||||||
*/
|
|
||||||
static inline void moduleEventSetCallback(
|
|
||||||
jerry_value_t *slot, event_t *event, jerry_value_t fn
|
|
||||||
) {
|
|
||||||
if(*slot) {
|
|
||||||
moduleEventJsUnsubscribe(event, *slot);
|
|
||||||
jerry_value_free(*slot);
|
|
||||||
*slot = 0;
|
|
||||||
}
|
|
||||||
if(jerry_value_is_function(fn)) {
|
|
||||||
*slot = jerry_value_copy(fn);
|
|
||||||
moduleEventJsSubscribe(event, fn);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read an easing type from a JS value. Accepts either a raw number (easing
|
|
||||||
* enum) or an easing function object with a .type property. Returns
|
|
||||||
* EASING_LINEAR for any other input.
|
|
||||||
*/
|
|
||||||
static inline easingtype_t moduleReadEasing(jerry_value_t val) {
|
|
||||||
if(jerry_value_is_number(val)) return (easingtype_t)moduleBaseValueInt(val);
|
|
||||||
jerry_value_t typeVal = moduleBaseGetProp(val, "type");
|
|
||||||
easingtype_t type = jerry_value_is_number(typeVal)
|
|
||||||
? (easingtype_t)moduleBaseValueInt(typeVal) : EASING_LINEAR;
|
|
||||||
jerry_value_free(typeVal);
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
@@ -1,211 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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 "script/module/math/modulevec2.h"
|
|
||||||
#include "script/module/event/moduleEvent.h"
|
|
||||||
#include "input/input.h"
|
|
||||||
|
|
||||||
static scriptproto_t MODULE_INPUT_PROTO;
|
|
||||||
|
|
||||||
// Static Methods
|
|
||||||
moduleBaseFunction(moduleInputBind) {
|
|
||||||
moduleBaseRequireArgs(2); moduleBaseRequireString(0); moduleBaseRequireNumber(1);
|
|
||||||
|
|
||||||
char_t strBtn[128];
|
|
||||||
moduleBaseToString(args[0], strBtn, sizeof(strBtn));
|
|
||||||
if(strBtn[0] == '\0') {
|
|
||||||
return moduleBaseThrow("Input.bind: button name cannot be empty");
|
|
||||||
}
|
|
||||||
|
|
||||||
const inputaction_t action = (inputaction_t)moduleBaseArgInt(1);
|
|
||||||
if(action <= INPUT_ACTION_NULL || action >= INPUT_ACTION_COUNT) {
|
|
||||||
return moduleBaseThrow("Input.bind: invalid action");
|
|
||||||
}
|
|
||||||
|
|
||||||
inputbutton_t btn = inputButtonGetByName(strBtn);
|
|
||||||
if(btn.type == INPUT_BUTTON_TYPE_NONE) {
|
|
||||||
return moduleBaseThrow("Input.bind: invalid button name");
|
|
||||||
}
|
|
||||||
|
|
||||||
inputBind(btn, action);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleInputIsDown) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireNumber(0);
|
|
||||||
const inputaction_t action = (inputaction_t)moduleBaseArgInt(0);
|
|
||||||
if(action <= INPUT_ACTION_NULL || action >= INPUT_ACTION_COUNT) {
|
|
||||||
return moduleBaseThrow("Input.isDown: invalid action");
|
|
||||||
}
|
|
||||||
return jerry_boolean(inputIsDown(action));
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleInputPressed) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireNumber(0);
|
|
||||||
const inputaction_t action = (inputaction_t)moduleBaseArgInt(0);
|
|
||||||
if(action <= INPUT_ACTION_NULL || action >= INPUT_ACTION_COUNT) {
|
|
||||||
return moduleBaseThrow("Input.pressed: invalid action");
|
|
||||||
}
|
|
||||||
return jerry_boolean(inputPressed(action));
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleInputReleased) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireNumber(0);
|
|
||||||
const inputaction_t action = (inputaction_t)moduleBaseArgInt(0);
|
|
||||||
if(action <= INPUT_ACTION_NULL || action >= INPUT_ACTION_COUNT) {
|
|
||||||
return moduleBaseThrow("Input.released: invalid action");
|
|
||||||
}
|
|
||||||
return jerry_boolean(inputReleased(action));
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleInputGetValue) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireNumber(0);
|
|
||||||
const inputaction_t action = (inputaction_t)moduleBaseArgInt(0);
|
|
||||||
if(action <= INPUT_ACTION_NULL || action >= INPUT_ACTION_COUNT) {
|
|
||||||
return moduleBaseThrow("Input.getValue: invalid action");
|
|
||||||
}
|
|
||||||
return jerry_number(inputGetCurrentValue(action));
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleInputAxis) {
|
|
||||||
moduleBaseRequireArgs(2); moduleBaseRequireNumber(0); moduleBaseRequireNumber(1);
|
|
||||||
const inputaction_t neg = (inputaction_t)moduleBaseArgInt(0);
|
|
||||||
const inputaction_t pos = (inputaction_t)moduleBaseArgInt(1);
|
|
||||||
if(neg <= INPUT_ACTION_NULL || neg >= INPUT_ACTION_COUNT) {
|
|
||||||
return moduleBaseThrow("Input.axis: invalid negative action");
|
|
||||||
}
|
|
||||||
if(pos <= INPUT_ACTION_NULL || pos >= INPUT_ACTION_COUNT) {
|
|
||||||
return moduleBaseThrow("Input.axis: invalid positive action");
|
|
||||||
}
|
|
||||||
return jerry_number(inputAxis(neg, pos));
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleInputAxis2D) {
|
|
||||||
moduleBaseRequireArgs(4);
|
|
||||||
moduleBaseRequireNumber(0); moduleBaseRequireNumber(1);
|
|
||||||
moduleBaseRequireNumber(2); moduleBaseRequireNumber(3);
|
|
||||||
const inputaction_t negX = (inputaction_t)moduleBaseArgInt(0);
|
|
||||||
const inputaction_t posX = (inputaction_t)moduleBaseArgInt(1);
|
|
||||||
const inputaction_t negY = (inputaction_t)moduleBaseArgInt(2);
|
|
||||||
const inputaction_t posY = (inputaction_t)moduleBaseArgInt(3);
|
|
||||||
if(negX <= INPUT_ACTION_NULL || negX >= INPUT_ACTION_COUNT) {
|
|
||||||
return moduleBaseThrow("Input.axis2D: invalid negX action");
|
|
||||||
}
|
|
||||||
if(posX <= INPUT_ACTION_NULL || posX >= INPUT_ACTION_COUNT) {
|
|
||||||
return moduleBaseThrow("Input.axis2D: invalid posX action");
|
|
||||||
}
|
|
||||||
if(negY <= INPUT_ACTION_NULL || negY >= INPUT_ACTION_COUNT) {
|
|
||||||
return moduleBaseThrow("Input.axis2D: invalid negY action");
|
|
||||||
}
|
|
||||||
if(posY <= INPUT_ACTION_NULL || posY >= INPUT_ACTION_COUNT) {
|
|
||||||
return moduleBaseThrow("Input.axis2D: invalid posY action");
|
|
||||||
}
|
|
||||||
vec2 result;
|
|
||||||
inputAxis2D(negX, posX, negY, posY, result);
|
|
||||||
return moduleVec2Push(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleInputOnPressed) {
|
|
||||||
moduleBaseRequireArgs(2); moduleBaseRequireNumber(0); moduleBaseRequireFunction(1);
|
|
||||||
const inputaction_t action = (inputaction_t)moduleBaseArgInt(0);
|
|
||||||
if(action <= INPUT_ACTION_NULL || action >= INPUT_ACTION_COUNT) {
|
|
||||||
return moduleBaseThrow("Input.onPressed: invalid action");
|
|
||||||
}
|
|
||||||
moduleEventJsSubscribe(&INPUT.actions[action].onPressed, args[1]);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleInputOffPressed) {
|
|
||||||
moduleBaseRequireArgs(2); moduleBaseRequireNumber(0); moduleBaseRequireFunction(1);
|
|
||||||
const inputaction_t action = (inputaction_t)moduleBaseArgInt(0);
|
|
||||||
if(action <= INPUT_ACTION_NULL || action >= INPUT_ACTION_COUNT) {
|
|
||||||
return moduleBaseThrow("Input.offPressed: invalid action");
|
|
||||||
}
|
|
||||||
moduleEventJsUnsubscribe(&INPUT.actions[action].onPressed, args[1]);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleInputOnReleased) {
|
|
||||||
moduleBaseRequireArgs(2); moduleBaseRequireNumber(0); moduleBaseRequireFunction(1);
|
|
||||||
const inputaction_t action = (inputaction_t)moduleBaseArgInt(0);
|
|
||||||
if(action <= INPUT_ACTION_NULL || action >= INPUT_ACTION_COUNT) {
|
|
||||||
return moduleBaseThrow("Input.onReleased: invalid action");
|
|
||||||
}
|
|
||||||
moduleEventJsSubscribe(&INPUT.actions[action].onReleased, args[1]);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleInputOffReleased) {
|
|
||||||
moduleBaseRequireArgs(2); moduleBaseRequireNumber(0); moduleBaseRequireFunction(1);
|
|
||||||
const inputaction_t action = (inputaction_t)moduleBaseArgInt(0);
|
|
||||||
if(action <= INPUT_ACTION_NULL || action >= INPUT_ACTION_COUNT) {
|
|
||||||
return moduleBaseThrow("Input.offReleased: invalid action");
|
|
||||||
}
|
|
||||||
moduleEventJsUnsubscribe(&INPUT.actions[action].onReleased, args[1]);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void moduleInput(void) {
|
|
||||||
moduleBaseEval(INPUT_ACTION_SCRIPT);
|
|
||||||
|
|
||||||
moduleBaseEval(
|
|
||||||
""
|
|
||||||
#ifdef DUSK_INPUT_KEYBOARD
|
|
||||||
"var INPUT_KEYBOARD = true;\n"
|
|
||||||
#endif
|
|
||||||
#ifdef DUSK_INPUT_GAMEPAD
|
|
||||||
"var INPUT_GAMEPAD = true;\n"
|
|
||||||
#endif
|
|
||||||
#ifdef DUSK_INPUT_POINTER
|
|
||||||
"var INPUT_POINTER = true;\n"
|
|
||||||
#endif
|
|
||||||
#ifdef DUSK_INPUT_TOUCH
|
|
||||||
"var INPUT_TOUCH = true;\n"
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
|
|
||||||
scriptProtoInit(
|
|
||||||
&MODULE_INPUT_PROTO, "Input", sizeof(uint8_t), NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
scriptProtoDefineStaticFunc(
|
|
||||||
&MODULE_INPUT_PROTO, "bind", moduleInputBind
|
|
||||||
);
|
|
||||||
scriptProtoDefineStaticFunc(
|
|
||||||
&MODULE_INPUT_PROTO, "isDown", moduleInputIsDown
|
|
||||||
);
|
|
||||||
scriptProtoDefineStaticFunc(
|
|
||||||
&MODULE_INPUT_PROTO, "pressed", moduleInputPressed
|
|
||||||
);
|
|
||||||
scriptProtoDefineStaticFunc(
|
|
||||||
&MODULE_INPUT_PROTO, "released", moduleInputReleased
|
|
||||||
);
|
|
||||||
scriptProtoDefineStaticFunc(
|
|
||||||
&MODULE_INPUT_PROTO, "getValue", moduleInputGetValue
|
|
||||||
);
|
|
||||||
scriptProtoDefineStaticFunc(
|
|
||||||
&MODULE_INPUT_PROTO, "axis", moduleInputAxis
|
|
||||||
);
|
|
||||||
scriptProtoDefineStaticFunc(
|
|
||||||
&MODULE_INPUT_PROTO, "axis2D", moduleInputAxis2D
|
|
||||||
);
|
|
||||||
scriptProtoDefineStaticFunc(
|
|
||||||
&MODULE_INPUT_PROTO, "onPressed", moduleInputOnPressed
|
|
||||||
);
|
|
||||||
scriptProtoDefineStaticFunc(
|
|
||||||
&MODULE_INPUT_PROTO, "offPressed", moduleInputOffPressed
|
|
||||||
);
|
|
||||||
scriptProtoDefineStaticFunc(
|
|
||||||
&MODULE_INPUT_PROTO, "onReleased", moduleInputOnReleased
|
|
||||||
);
|
|
||||||
scriptProtoDefineStaticFunc(
|
|
||||||
&MODULE_INPUT_PROTO, "offReleased", moduleInputOffReleased
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,109 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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 "item/inventory.h"
|
|
||||||
#include "item/backpack.h"
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
inventory_t *inventory;
|
|
||||||
} inventoryscript_t;
|
|
||||||
|
|
||||||
static scriptproto_t MODULE_INVENTORY_PROTO;
|
|
||||||
|
|
||||||
static inline inventory_t * moduleInventoryGet(
|
|
||||||
const jerry_call_info_t *callInfo
|
|
||||||
) {
|
|
||||||
inventoryscript_t *h = (inventoryscript_t*)scriptProtoGetValue(
|
|
||||||
&MODULE_INVENTORY_PROTO, callInfo->this_value
|
|
||||||
);
|
|
||||||
return h ? h->inventory : NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleInventoryAdd) {
|
|
||||||
moduleBaseRequireArgs(2); moduleBaseRequireNumber(0); moduleBaseRequireNumber(1);
|
|
||||||
moduleBaseGetOrReturn(inventory_t, inv, moduleInventoryGet);
|
|
||||||
inventoryAdd(inv, (itemid_t)moduleBaseArgInt(0), (uint8_t)moduleBaseArgInt(1));
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleInventoryRemove) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireNumber(0);
|
|
||||||
moduleBaseGetOrReturn(inventory_t, inv, moduleInventoryGet);
|
|
||||||
inventoryRemove(inv, (itemid_t)moduleBaseArgInt(0));
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleInventorySet) {
|
|
||||||
moduleBaseRequireArgs(2); moduleBaseRequireNumber(0); moduleBaseRequireNumber(1);
|
|
||||||
moduleBaseGetOrReturn(inventory_t, inv, moduleInventoryGet);
|
|
||||||
inventorySet(inv, (itemid_t)moduleBaseArgInt(0), (uint8_t)moduleBaseArgInt(1));
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleInventoryCount) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireNumber(0);
|
|
||||||
moduleBaseGetOrReturn(inventory_t, inv, moduleInventoryGet);
|
|
||||||
return jerry_number((double)inventoryGetCount(inv, (itemid_t)moduleBaseArgInt(0)));
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleInventoryHas) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireNumber(0);
|
|
||||||
moduleBaseGetOrReturn(inventory_t, inv, moduleInventoryGet);
|
|
||||||
return jerry_boolean(inventoryItemExists(inv, (itemid_t)moduleBaseArgInt(0)));
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleInventoryIsItemFull) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireNumber(0);
|
|
||||||
moduleBaseGetOrReturn(inventory_t, inv, moduleInventoryGet);
|
|
||||||
return jerry_boolean(inventoryItemFull(inv, (itemid_t)moduleBaseArgInt(0)));
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleInventorySort) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireNumber(0);
|
|
||||||
moduleBaseGetOrReturn(inventory_t, inv, moduleInventoryGet);
|
|
||||||
inventorySort(
|
|
||||||
inv,
|
|
||||||
(inventorysort_t)moduleBaseArgInt(0),
|
|
||||||
(argc >= 2 && jerry_value_is_true(args[1]))
|
|
||||||
);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleInventoryGetFull) {
|
|
||||||
moduleBaseGetOrReturn(inventory_t, inv, moduleInventoryGet);
|
|
||||||
return jerry_boolean(inventoryIsFull(inv));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void moduleItem(void) {
|
|
||||||
moduleBaseEval(ITEM_SCRIPT);
|
|
||||||
moduleBaseSetInt("INVENTORY_SORT_BY_ID", INVENTORY_SORT_BY_ID);
|
|
||||||
moduleBaseSetInt("INVENTORY_SORT_BY_TYPE", INVENTORY_SORT_BY_TYPE);
|
|
||||||
|
|
||||||
scriptProtoInit(
|
|
||||||
&MODULE_INVENTORY_PROTO, NULL,
|
|
||||||
sizeof(inventoryscript_t), NULL
|
|
||||||
);
|
|
||||||
scriptProtoDefineProp(
|
|
||||||
&MODULE_INVENTORY_PROTO, "full",
|
|
||||||
moduleInventoryGetFull, NULL
|
|
||||||
);
|
|
||||||
scriptProtoDefineFunc(&MODULE_INVENTORY_PROTO, "add", moduleInventoryAdd);
|
|
||||||
scriptProtoDefineFunc(&MODULE_INVENTORY_PROTO, "remove", moduleInventoryRemove);
|
|
||||||
scriptProtoDefineFunc(&MODULE_INVENTORY_PROTO, "set", moduleInventorySet);
|
|
||||||
scriptProtoDefineFunc(&MODULE_INVENTORY_PROTO, "count", moduleInventoryCount);
|
|
||||||
scriptProtoDefineFunc(&MODULE_INVENTORY_PROTO, "has", moduleInventoryHas);
|
|
||||||
scriptProtoDefineFunc(&MODULE_INVENTORY_PROTO, "isItemFull", moduleInventoryIsItemFull);
|
|
||||||
scriptProtoDefineFunc(&MODULE_INVENTORY_PROTO, "sort", moduleInventorySort);
|
|
||||||
|
|
||||||
inventoryscript_t h = { .inventory = &BACKPACK };
|
|
||||||
jerry_value_t backpackObj = scriptProtoCreateValue(&MODULE_INVENTORY_PROTO, &h);
|
|
||||||
moduleBaseSetValue("Backpack", backpackObj);
|
|
||||||
jerry_value_free(backpackObj);
|
|
||||||
}
|
|
||||||
@@ -1,226 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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 "cglm/cglm.h"
|
|
||||||
#include "modulevec3.h"
|
|
||||||
#include "modulevec4.h"
|
|
||||||
|
|
||||||
static scriptproto_t MODULE_MAT4_PROTO;
|
|
||||||
|
|
||||||
static inline void * moduleMatGet(const jerry_call_info_t *callInfo) {
|
|
||||||
return scriptProtoGetValue(&MODULE_MAT4_PROTO, callInfo->this_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleMatConstructor) {
|
|
||||||
float_t (*ptr)[4] = (float_t (*)[4])memoryAllocate(sizeof(mat4));
|
|
||||||
glm_mat4_identity(ptr);
|
|
||||||
jerry_object_set_native_ptr(
|
|
||||||
callInfo->this_value, &MODULE_MAT4_PROTO.info, ptr
|
|
||||||
);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleMatMul) {
|
|
||||||
moduleBaseRequireArgs(1);
|
|
||||||
float_t (*a)[4] = (float_t (*)[4])moduleMatGet(callInfo);
|
|
||||||
if(!a) return moduleBaseThrow("Mat4.mul: invalid this");
|
|
||||||
float_t (*b)[4] = (float_t (*)[4])scriptProtoGetValue(
|
|
||||||
&MODULE_MAT4_PROTO, args[0]
|
|
||||||
);
|
|
||||||
if(!b) return moduleBaseThrow("Mat4.mul: argument must be a Mat4");
|
|
||||||
mat4 r;
|
|
||||||
glm_mat4_mul(a, b, r);
|
|
||||||
return scriptProtoCreateValue(&MODULE_MAT4_PROTO, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleMatTranspose) {
|
|
||||||
float_t (*m)[4] = (float_t (*)[4])moduleMatGet(callInfo);
|
|
||||||
if(!m) return moduleBaseThrow("Mat4.transpose: invalid this");
|
|
||||||
mat4 r;
|
|
||||||
glm_mat4_transpose_to(m, r);
|
|
||||||
return scriptProtoCreateValue(&MODULE_MAT4_PROTO, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleMatInverse) {
|
|
||||||
float_t (*m)[4] = (float_t (*)[4])moduleMatGet(callInfo);
|
|
||||||
if(!m) return moduleBaseThrow("Mat4.inverse: invalid this");
|
|
||||||
mat4 r;
|
|
||||||
glm_mat4_inv(m, r);
|
|
||||||
return scriptProtoCreateValue(&MODULE_MAT4_PROTO, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleMatDeterminant) {
|
|
||||||
float_t (*m)[4] = (float_t (*)[4])moduleMatGet(callInfo);
|
|
||||||
if(!m) return moduleBaseThrow("Mat4.determinant: invalid this");
|
|
||||||
return jerry_number(glm_mat4_det(m));
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleMatMulVec3) {
|
|
||||||
moduleBaseRequireArgs(1);
|
|
||||||
float_t (*m)[4] = (float_t (*)[4])moduleMatGet(callInfo);
|
|
||||||
if(!m) return moduleBaseThrow("Mat4.mulVec3: invalid this");
|
|
||||||
vec3 vin;
|
|
||||||
if(!moduleVec3Check(args[0], vin)) {
|
|
||||||
return moduleBaseThrow("Mat4.mulVec3: argument must be a Vec3");
|
|
||||||
}
|
|
||||||
float_t w = moduleBaseOptFloat(1, 1.0f);
|
|
||||||
vec3 vout;
|
|
||||||
glm_mat4_mulv3(m, vin, w, vout);
|
|
||||||
return moduleVec3Push(vout);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleMatMulVec4) {
|
|
||||||
moduleBaseRequireArgs(1);
|
|
||||||
float_t (*m)[4] = (float_t (*)[4])moduleMatGet(callInfo);
|
|
||||||
if(!m) return moduleBaseThrow("Mat4.mulVec4: invalid this");
|
|
||||||
vec4 vin;
|
|
||||||
if(!moduleVec4Check(args[0], vin)) {
|
|
||||||
return moduleBaseThrow("Mat4.mulVec4: argument must be a Vec4");
|
|
||||||
}
|
|
||||||
vec4 vout;
|
|
||||||
glm_mat4_mulv(m, vin, vout);
|
|
||||||
return moduleVec4Push(vout);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleMatTranslate) {
|
|
||||||
moduleBaseRequireArgs(1);
|
|
||||||
float_t (*m)[4] = (float_t (*)[4])moduleMatGet(callInfo);
|
|
||||||
if(!m) return moduleBaseThrow("Mat4.translate: invalid this");
|
|
||||||
vec3 tv;
|
|
||||||
if(!moduleVec3Check(args[0], tv)) {
|
|
||||||
return moduleBaseThrow("Mat4.translate: argument must be a Vec3");
|
|
||||||
}
|
|
||||||
mat4 r;
|
|
||||||
glm_mat4_copy(m, r);
|
|
||||||
glm_translate(r, tv);
|
|
||||||
return scriptProtoCreateValue(&MODULE_MAT4_PROTO, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleMatScale) {
|
|
||||||
moduleBaseRequireArgs(1);
|
|
||||||
float_t (*m)[4] = (float_t (*)[4])moduleMatGet(callInfo);
|
|
||||||
if(!m) return moduleBaseThrow("Mat4.scale: invalid this");
|
|
||||||
vec3 sv;
|
|
||||||
if(!moduleVec3Check(args[0], sv)) {
|
|
||||||
return moduleBaseThrow("Mat4.scale: argument must be a Vec3");
|
|
||||||
}
|
|
||||||
mat4 r;
|
|
||||||
glm_mat4_copy(m, r);
|
|
||||||
glm_scale(r, sv);
|
|
||||||
return scriptProtoCreateValue(&MODULE_MAT4_PROTO, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleMatStaticIdentity) {
|
|
||||||
mat4 r;
|
|
||||||
glm_mat4_identity(r);
|
|
||||||
return scriptProtoCreateValue(&MODULE_MAT4_PROTO, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleMatStaticPerspective) {
|
|
||||||
moduleBaseRequireArgs(4);
|
|
||||||
moduleBaseRequireNumber(0); moduleBaseRequireNumber(1);
|
|
||||||
moduleBaseRequireNumber(2); moduleBaseRequireNumber(3);
|
|
||||||
mat4 r;
|
|
||||||
glm_perspective(
|
|
||||||
moduleBaseArgFloat(0), moduleBaseArgFloat(1),
|
|
||||||
moduleBaseArgFloat(2), moduleBaseArgFloat(3),
|
|
||||||
r
|
|
||||||
);
|
|
||||||
return scriptProtoCreateValue(&MODULE_MAT4_PROTO, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleMatStaticLookAt) {
|
|
||||||
moduleBaseRequireArgs(3);
|
|
||||||
vec3 eye, center, up;
|
|
||||||
if(!moduleVec3Check(args[0], eye)) {
|
|
||||||
return moduleBaseThrow("Mat4.lookAt: eye must be a Vec3");
|
|
||||||
}
|
|
||||||
if(!moduleVec3Check(args[1], center)) {
|
|
||||||
return moduleBaseThrow("Mat4.lookAt: center must be a Vec3");
|
|
||||||
}
|
|
||||||
if(!moduleVec3Check(args[2], up)) {
|
|
||||||
return moduleBaseThrow("Mat4.lookAt: up must be a Vec3");
|
|
||||||
}
|
|
||||||
mat4 r;
|
|
||||||
glm_lookat(eye, center, up, 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]) {
|
|
||||||
return scriptProtoCreateValue(&MODULE_MAT4_PROTO, m);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool_t moduleMat4Check(jerry_value_t val, float (*out)[4]) {
|
|
||||||
float_t (*m)[4] = (float_t (*)[4])scriptProtoGetValue(
|
|
||||||
&MODULE_MAT4_PROTO, val
|
|
||||||
);
|
|
||||||
if(!m) return false;
|
|
||||||
glm_mat4_copy(m, out);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void moduleMat4(void) {
|
|
||||||
scriptProtoInit(
|
|
||||||
&MODULE_MAT4_PROTO, "Mat4", sizeof(mat4), moduleMatConstructor
|
|
||||||
);
|
|
||||||
|
|
||||||
scriptProtoDefineToString(&MODULE_MAT4_PROTO, moduleMatToString);
|
|
||||||
|
|
||||||
scriptProtoDefineFunc(
|
|
||||||
&MODULE_MAT4_PROTO, "mul", moduleMatMul
|
|
||||||
);
|
|
||||||
scriptProtoDefineFunc(
|
|
||||||
&MODULE_MAT4_PROTO, "transpose", moduleMatTranspose
|
|
||||||
);
|
|
||||||
scriptProtoDefineFunc(
|
|
||||||
&MODULE_MAT4_PROTO, "inverse", moduleMatInverse
|
|
||||||
);
|
|
||||||
scriptProtoDefineFunc(
|
|
||||||
&MODULE_MAT4_PROTO, "determinant", moduleMatDeterminant
|
|
||||||
);
|
|
||||||
scriptProtoDefineFunc(
|
|
||||||
&MODULE_MAT4_PROTO, "mulVec3", moduleMatMulVec3
|
|
||||||
);
|
|
||||||
scriptProtoDefineFunc(
|
|
||||||
&MODULE_MAT4_PROTO, "mulVec4", moduleMatMulVec4
|
|
||||||
);
|
|
||||||
scriptProtoDefineFunc(
|
|
||||||
&MODULE_MAT4_PROTO, "translate", moduleMatTranslate
|
|
||||||
);
|
|
||||||
scriptProtoDefineFunc(
|
|
||||||
&MODULE_MAT4_PROTO, "scale", moduleMatScale
|
|
||||||
);
|
|
||||||
|
|
||||||
scriptProtoDefineStaticFunc(
|
|
||||||
&MODULE_MAT4_PROTO, "identity", moduleMatStaticIdentity
|
|
||||||
);
|
|
||||||
scriptProtoDefineStaticFunc(
|
|
||||||
&MODULE_MAT4_PROTO, "perspective", moduleMatStaticPerspective
|
|
||||||
);
|
|
||||||
scriptProtoDefineStaticFunc(
|
|
||||||
&MODULE_MAT4_PROTO, "lookAt", moduleMatStaticLookAt
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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 "modulevec2.h"
|
|
||||||
#include "modulevec3.h"
|
|
||||||
#include "modulevec3ref.h"
|
|
||||||
#include "modulevec4.h"
|
|
||||||
#include "modulemat4.h"
|
|
||||||
|
|
||||||
static void moduleMath(void) {
|
|
||||||
moduleVec2();
|
|
||||||
moduleVec3();
|
|
||||||
moduleVec3Ref();
|
|
||||||
moduleVec4();
|
|
||||||
moduleMat4();
|
|
||||||
}
|
|
||||||
@@ -1,193 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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 "cglm/cglm.h"
|
|
||||||
|
|
||||||
static scriptproto_t MODULE_VEC2_PROTO;
|
|
||||||
|
|
||||||
static inline float_t * moduleVec2Get(const jerry_call_info_t *callInfo) {
|
|
||||||
return (float_t *)scriptProtoGetValue(
|
|
||||||
&MODULE_VEC2_PROTO, callInfo->this_value
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline float_t * moduleVec2From(jerry_value_t val) {
|
|
||||||
return (float_t *)scriptProtoGetValue(&MODULE_VEC2_PROTO, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec2Constructor) {
|
|
||||||
float_t *ptr = (float_t *)memoryAllocate(sizeof(vec2));
|
|
||||||
ptr[0] = moduleBaseOptFloat(0, 0.0f);
|
|
||||||
ptr[1] = moduleBaseOptFloat(1, 0.0f);
|
|
||||||
jerry_object_set_native_ptr(
|
|
||||||
callInfo->this_value, &MODULE_VEC2_PROTO.info, ptr
|
|
||||||
);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec2GetX) {
|
|
||||||
moduleBaseGetOrReturn(float_t, v, moduleVec2Get);
|
|
||||||
return jerry_number(v[0]);
|
|
||||||
}
|
|
||||||
moduleBaseFunction(moduleVec2SetX) {
|
|
||||||
moduleBaseRequireArgs(1);
|
|
||||||
moduleBaseGetOrReturn(float_t, v, moduleVec2Get);
|
|
||||||
v[0] = moduleBaseArgFloat(0);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec2GetY) {
|
|
||||||
moduleBaseGetOrReturn(float_t, v, moduleVec2Get);
|
|
||||||
return jerry_number(v[1]);
|
|
||||||
}
|
|
||||||
moduleBaseFunction(moduleVec2SetY) {
|
|
||||||
moduleBaseRequireArgs(1);
|
|
||||||
moduleBaseGetOrReturn(float_t, v, moduleVec2Get);
|
|
||||||
v[1] = moduleBaseArgFloat(0);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec2Dot) {
|
|
||||||
moduleBaseRequireArgs(1);
|
|
||||||
float_t *a = moduleVec2Get(callInfo);
|
|
||||||
if(!a) return moduleBaseThrow("Vec2.dot: invalid this");
|
|
||||||
float_t *b = moduleVec2From(args[0]);
|
|
||||||
if(!b) return moduleBaseThrow("Vec2.dot: argument must be a Vec2");
|
|
||||||
return jerry_number(glm_vec2_dot(a, b));
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec2Length) {
|
|
||||||
float_t *v = moduleVec2Get(callInfo);
|
|
||||||
if(!v) return moduleBaseThrow("Vec2.length: invalid this");
|
|
||||||
return jerry_number(glm_vec2_norm(v));
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec2LengthSq) {
|
|
||||||
float_t *v = moduleVec2Get(callInfo);
|
|
||||||
if(!v) return moduleBaseThrow("Vec2.lengthSq: invalid this");
|
|
||||||
return jerry_number(glm_vec2_norm2(v));
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec2Normalize) {
|
|
||||||
float_t *v = moduleVec2Get(callInfo);
|
|
||||||
if(!v) return moduleBaseThrow("Vec2.normalize: invalid this");
|
|
||||||
vec2 r;
|
|
||||||
glm_vec2_normalize_to(v, r);
|
|
||||||
return scriptProtoCreateValue(&MODULE_VEC2_PROTO, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec2Negate) {
|
|
||||||
float_t *v = moduleVec2Get(callInfo);
|
|
||||||
if(!v) return moduleBaseThrow("Vec2.negate: invalid this");
|
|
||||||
vec2 r;
|
|
||||||
glm_vec2_negate_to(v, r);
|
|
||||||
return scriptProtoCreateValue(&MODULE_VEC2_PROTO, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec2Add) {
|
|
||||||
moduleBaseRequireArgs(1);
|
|
||||||
float_t *a = moduleVec2Get(callInfo);
|
|
||||||
if(!a) return moduleBaseThrow("Vec2.add: invalid this");
|
|
||||||
float_t *b = moduleVec2From(args[0]);
|
|
||||||
if(!b) return moduleBaseThrow("Vec2.add: argument must be a Vec2");
|
|
||||||
vec2 r;
|
|
||||||
glm_vec2_add(a, b, r);
|
|
||||||
return scriptProtoCreateValue(&MODULE_VEC2_PROTO, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec2Sub) {
|
|
||||||
moduleBaseRequireArgs(1);
|
|
||||||
float_t *a = moduleVec2Get(callInfo);
|
|
||||||
if(!a) return moduleBaseThrow("Vec2.sub: invalid this");
|
|
||||||
float_t *b = moduleVec2From(args[0]);
|
|
||||||
if(!b) return moduleBaseThrow("Vec2.sub: argument must be a Vec2");
|
|
||||||
vec2 r;
|
|
||||||
glm_vec2_sub(a, b, r);
|
|
||||||
return scriptProtoCreateValue(&MODULE_VEC2_PROTO, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec2Scale) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireNumber(0);
|
|
||||||
float_t *v = moduleVec2Get(callInfo);
|
|
||||||
if(!v) return moduleBaseThrow("Vec2.scale: invalid this");
|
|
||||||
vec2 r;
|
|
||||||
glm_vec2_scale(v, moduleBaseArgFloat(0), r);
|
|
||||||
return scriptProtoCreateValue(&MODULE_VEC2_PROTO, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec2Lerp) {
|
|
||||||
moduleBaseRequireArgs(2); moduleBaseRequireNumber(1);
|
|
||||||
float_t *a = moduleVec2Get(callInfo);
|
|
||||||
if(!a) return moduleBaseThrow("Vec2.lerp: invalid this");
|
|
||||||
float_t *b = moduleVec2From(args[0]);
|
|
||||||
if(!b) return moduleBaseThrow("Vec2.lerp: first argument must be a Vec2");
|
|
||||||
vec2 r;
|
|
||||||
glm_vec2_lerp(a, b, moduleBaseArgFloat(1), r);
|
|
||||||
return scriptProtoCreateValue(&MODULE_VEC2_PROTO, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec2Distance) {
|
|
||||||
moduleBaseRequireArgs(1);
|
|
||||||
float_t *a = moduleVec2Get(callInfo);
|
|
||||||
if(!a) return moduleBaseThrow("Vec2.distance: invalid this");
|
|
||||||
float_t *b = moduleVec2From(args[0]);
|
|
||||||
if(!b) return moduleBaseThrow("Vec2.distance: argument must be a Vec2");
|
|
||||||
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) {
|
|
||||||
return scriptProtoCreateValue(&MODULE_VEC2_PROTO, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool_t moduleVec2Check(jerry_value_t val, float_t *out) {
|
|
||||||
float_t *v = moduleVec2From(val);
|
|
||||||
if(!v) return false;
|
|
||||||
out[0] = v[0];
|
|
||||||
out[1] = v[1];
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool_t moduleVec2AnyCheck(jerry_value_t val, float_t *out) {
|
|
||||||
return moduleVec2Check(val, out);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void moduleVec2(void) {
|
|
||||||
scriptProtoInit(
|
|
||||||
&MODULE_VEC2_PROTO, "Vec2", sizeof(vec2), moduleVec2Constructor
|
|
||||||
);
|
|
||||||
|
|
||||||
scriptProtoDefineProp(
|
|
||||||
&MODULE_VEC2_PROTO, "x", moduleVec2GetX, moduleVec2SetX
|
|
||||||
);
|
|
||||||
scriptProtoDefineProp(
|
|
||||||
&MODULE_VEC2_PROTO, "y", moduleVec2GetY, moduleVec2SetY
|
|
||||||
);
|
|
||||||
|
|
||||||
scriptProtoDefineToString(&MODULE_VEC2_PROTO, moduleVec2ToString);
|
|
||||||
|
|
||||||
scriptProtoDefineFunc(&MODULE_VEC2_PROTO, "dot", moduleVec2Dot);
|
|
||||||
scriptProtoDefineFunc(&MODULE_VEC2_PROTO, "length", moduleVec2Length);
|
|
||||||
scriptProtoDefineFunc(&MODULE_VEC2_PROTO, "lengthSq", moduleVec2LengthSq);
|
|
||||||
scriptProtoDefineFunc(&MODULE_VEC2_PROTO, "normalize", moduleVec2Normalize);
|
|
||||||
scriptProtoDefineFunc(&MODULE_VEC2_PROTO, "negate", moduleVec2Negate);
|
|
||||||
scriptProtoDefineFunc(&MODULE_VEC2_PROTO, "add", moduleVec2Add);
|
|
||||||
scriptProtoDefineFunc(&MODULE_VEC2_PROTO, "sub", moduleVec2Sub);
|
|
||||||
scriptProtoDefineFunc(&MODULE_VEC2_PROTO, "scale", moduleVec2Scale);
|
|
||||||
scriptProtoDefineFunc(&MODULE_VEC2_PROTO, "lerp", moduleVec2Lerp);
|
|
||||||
scriptProtoDefineFunc(&MODULE_VEC2_PROTO, "distance", moduleVec2Distance);
|
|
||||||
}
|
|
||||||
@@ -1,217 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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 "cglm/cglm.h"
|
|
||||||
|
|
||||||
static scriptproto_t MODULE_VEC3_PROTO;
|
|
||||||
|
|
||||||
static inline float_t * moduleVec3Get(const jerry_call_info_t *callInfo) {
|
|
||||||
return (float_t *)scriptProtoGetValue(
|
|
||||||
&MODULE_VEC3_PROTO, callInfo->this_value
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline float_t * moduleVec3From(jerry_value_t val) {
|
|
||||||
return (float_t *)scriptProtoGetValue(&MODULE_VEC3_PROTO, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec3Constructor) {
|
|
||||||
float_t *ptr = (float_t *)memoryAllocate(sizeof(vec3));
|
|
||||||
ptr[0] = moduleBaseOptFloat(0, 0.0f);
|
|
||||||
ptr[1] = moduleBaseOptFloat(1, 0.0f);
|
|
||||||
ptr[2] = moduleBaseOptFloat(2, 0.0f);
|
|
||||||
jerry_object_set_native_ptr(
|
|
||||||
callInfo->this_value, &MODULE_VEC3_PROTO.info, ptr
|
|
||||||
);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec3GetX) {
|
|
||||||
moduleBaseGetOrReturn(float_t, v, moduleVec3Get);
|
|
||||||
return jerry_number(v[0]);
|
|
||||||
}
|
|
||||||
moduleBaseFunction(moduleVec3SetX) {
|
|
||||||
moduleBaseRequireArgs(1);
|
|
||||||
moduleBaseGetOrReturn(float_t, v, moduleVec3Get);
|
|
||||||
v[0] = moduleBaseArgFloat(0);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec3GetY) {
|
|
||||||
moduleBaseGetOrReturn(float_t, v, moduleVec3Get);
|
|
||||||
return jerry_number(v[1]);
|
|
||||||
}
|
|
||||||
moduleBaseFunction(moduleVec3SetY) {
|
|
||||||
moduleBaseRequireArgs(1);
|
|
||||||
moduleBaseGetOrReturn(float_t, v, moduleVec3Get);
|
|
||||||
v[1] = moduleBaseArgFloat(0);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec3GetZ) {
|
|
||||||
moduleBaseGetOrReturn(float_t, v, moduleVec3Get);
|
|
||||||
return jerry_number(v[2]);
|
|
||||||
}
|
|
||||||
moduleBaseFunction(moduleVec3SetZ) {
|
|
||||||
moduleBaseRequireArgs(1);
|
|
||||||
moduleBaseGetOrReturn(float_t, v, moduleVec3Get);
|
|
||||||
v[2] = moduleBaseArgFloat(0);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec3Dot) {
|
|
||||||
moduleBaseRequireArgs(1);
|
|
||||||
float_t *a = moduleVec3Get(callInfo);
|
|
||||||
if(!a) return moduleBaseThrow("Vec3.dot: invalid this");
|
|
||||||
float_t *b = moduleVec3From(args[0]);
|
|
||||||
if(!b) return moduleBaseThrow("Vec3.dot: argument must be a Vec3");
|
|
||||||
return jerry_number(glm_vec3_dot(a, b));
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec3Cross) {
|
|
||||||
moduleBaseRequireArgs(1);
|
|
||||||
float_t *a = moduleVec3Get(callInfo);
|
|
||||||
if(!a) return moduleBaseThrow("Vec3.cross: invalid this");
|
|
||||||
float_t *b = moduleVec3From(args[0]);
|
|
||||||
if(!b) return moduleBaseThrow("Vec3.cross: argument must be a Vec3");
|
|
||||||
vec3 r;
|
|
||||||
glm_vec3_cross(a, b, r);
|
|
||||||
return scriptProtoCreateValue(&MODULE_VEC3_PROTO, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec3Length) {
|
|
||||||
float_t *v = moduleVec3Get(callInfo);
|
|
||||||
if(!v) return moduleBaseThrow("Vec3.length: invalid this");
|
|
||||||
return jerry_number(glm_vec3_norm(v));
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec3LengthSq) {
|
|
||||||
float_t *v = moduleVec3Get(callInfo);
|
|
||||||
if(!v) return moduleBaseThrow("Vec3.lengthSq: invalid this");
|
|
||||||
return jerry_number(glm_vec3_norm2(v));
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec3Normalize) {
|
|
||||||
float_t *v = moduleVec3Get(callInfo);
|
|
||||||
if(!v) return moduleBaseThrow("Vec3.normalize: invalid this");
|
|
||||||
vec3 r;
|
|
||||||
glm_vec3_normalize_to(v, r);
|
|
||||||
return scriptProtoCreateValue(&MODULE_VEC3_PROTO, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec3Negate) {
|
|
||||||
float_t *v = moduleVec3Get(callInfo);
|
|
||||||
if(!v) return moduleBaseThrow("Vec3.negate: invalid this");
|
|
||||||
vec3 r;
|
|
||||||
glm_vec3_negate_to(v, r);
|
|
||||||
return scriptProtoCreateValue(&MODULE_VEC3_PROTO, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec3Add) {
|
|
||||||
moduleBaseRequireArgs(1);
|
|
||||||
float_t *a = moduleVec3Get(callInfo);
|
|
||||||
if(!a) return moduleBaseThrow("Vec3.add: invalid this");
|
|
||||||
float_t *b = moduleVec3From(args[0]);
|
|
||||||
if(!b) return moduleBaseThrow("Vec3.add: argument must be a Vec3");
|
|
||||||
vec3 r;
|
|
||||||
glm_vec3_add(a, b, r);
|
|
||||||
return scriptProtoCreateValue(&MODULE_VEC3_PROTO, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec3Sub) {
|
|
||||||
moduleBaseRequireArgs(1);
|
|
||||||
float_t *a = moduleVec3Get(callInfo);
|
|
||||||
if(!a) return moduleBaseThrow("Vec3.sub: invalid this");
|
|
||||||
float_t *b = moduleVec3From(args[0]);
|
|
||||||
if(!b) return moduleBaseThrow("Vec3.sub: argument must be a Vec3");
|
|
||||||
vec3 r;
|
|
||||||
glm_vec3_sub(a, b, r);
|
|
||||||
return scriptProtoCreateValue(&MODULE_VEC3_PROTO, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec3Scale) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireNumber(0);
|
|
||||||
float_t *v = moduleVec3Get(callInfo);
|
|
||||||
if(!v) return moduleBaseThrow("Vec3.scale: invalid this");
|
|
||||||
vec3 r;
|
|
||||||
glm_vec3_scale(v, moduleBaseArgFloat(0), r);
|
|
||||||
return scriptProtoCreateValue(&MODULE_VEC3_PROTO, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec3Lerp) {
|
|
||||||
moduleBaseRequireArgs(2); moduleBaseRequireNumber(1);
|
|
||||||
float_t *a = moduleVec3Get(callInfo);
|
|
||||||
if(!a) return moduleBaseThrow("Vec3.lerp: invalid this");
|
|
||||||
float_t *b = moduleVec3From(args[0]);
|
|
||||||
if(!b) return moduleBaseThrow("Vec3.lerp: first argument must be a Vec3");
|
|
||||||
vec3 r;
|
|
||||||
glm_vec3_lerp(a, b, moduleBaseArgFloat(1), r);
|
|
||||||
return scriptProtoCreateValue(&MODULE_VEC3_PROTO, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec3Distance) {
|
|
||||||
moduleBaseRequireArgs(1);
|
|
||||||
float_t *a = moduleVec3Get(callInfo);
|
|
||||||
if(!a) return moduleBaseThrow("Vec3.distance: invalid this");
|
|
||||||
float_t *b = moduleVec3From(args[0]);
|
|
||||||
if(!b) return moduleBaseThrow("Vec3.distance: argument must be a Vec3");
|
|
||||||
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) {
|
|
||||||
return scriptProtoCreateValue(&MODULE_VEC3_PROTO, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool_t moduleVec3Check(jerry_value_t val, float_t *out) {
|
|
||||||
float_t *v = moduleVec3From(val);
|
|
||||||
if(!v) return false;
|
|
||||||
out[0] = v[0];
|
|
||||||
out[1] = v[1];
|
|
||||||
out[2] = v[2];
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void moduleVec3(void) {
|
|
||||||
scriptProtoInit(
|
|
||||||
&MODULE_VEC3_PROTO, "Vec3", sizeof(vec3), moduleVec3Constructor
|
|
||||||
);
|
|
||||||
|
|
||||||
scriptProtoDefineProp(
|
|
||||||
&MODULE_VEC3_PROTO, "x", moduleVec3GetX, moduleVec3SetX
|
|
||||||
);
|
|
||||||
scriptProtoDefineProp(
|
|
||||||
&MODULE_VEC3_PROTO, "y", moduleVec3GetY, moduleVec3SetY
|
|
||||||
);
|
|
||||||
scriptProtoDefineProp(
|
|
||||||
&MODULE_VEC3_PROTO, "z", moduleVec3GetZ, moduleVec3SetZ
|
|
||||||
);
|
|
||||||
|
|
||||||
scriptProtoDefineToString(&MODULE_VEC3_PROTO, moduleVec3ToString);
|
|
||||||
|
|
||||||
scriptProtoDefineFunc(&MODULE_VEC3_PROTO, "dot", moduleVec3Dot);
|
|
||||||
scriptProtoDefineFunc(&MODULE_VEC3_PROTO, "cross", moduleVec3Cross);
|
|
||||||
scriptProtoDefineFunc(&MODULE_VEC3_PROTO, "length", moduleVec3Length);
|
|
||||||
scriptProtoDefineFunc(&MODULE_VEC3_PROTO, "lengthSq", moduleVec3LengthSq);
|
|
||||||
scriptProtoDefineFunc(&MODULE_VEC3_PROTO, "normalize", moduleVec3Normalize);
|
|
||||||
scriptProtoDefineFunc(&MODULE_VEC3_PROTO, "negate", moduleVec3Negate);
|
|
||||||
scriptProtoDefineFunc(&MODULE_VEC3_PROTO, "add", moduleVec3Add);
|
|
||||||
scriptProtoDefineFunc(&MODULE_VEC3_PROTO, "sub", moduleVec3Sub);
|
|
||||||
scriptProtoDefineFunc(&MODULE_VEC3_PROTO, "scale", moduleVec3Scale);
|
|
||||||
scriptProtoDefineFunc(&MODULE_VEC3_PROTO, "lerp", moduleVec3Lerp);
|
|
||||||
scriptProtoDefineFunc(&MODULE_VEC3_PROTO, "distance", moduleVec3Distance);
|
|
||||||
}
|
|
||||||
@@ -1,123 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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 "cglm/cglm.h"
|
|
||||||
#include "modulevec3.h"
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
float_t *data;
|
|
||||||
void (*onChange)(void *ctx);
|
|
||||||
void *ctx;
|
|
||||||
} vec3ref_t;
|
|
||||||
|
|
||||||
static scriptproto_t MODULE_VEC3_REF_PROTO;
|
|
||||||
|
|
||||||
static inline vec3ref_t * moduleVec3RefGet(
|
|
||||||
const jerry_call_info_t *callInfo
|
|
||||||
) {
|
|
||||||
return (vec3ref_t*)scriptProtoGetValue(
|
|
||||||
&MODULE_VEC3_REF_PROTO, callInfo->this_value
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline vec3ref_t * moduleVec3RefFrom(jerry_value_t val) {
|
|
||||||
return (vec3ref_t*)scriptProtoGetValue(&MODULE_VEC3_REF_PROTO, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void moduleVec3RefNotify(vec3ref_t *ref) {
|
|
||||||
if(ref->onChange) ref->onChange(ref->ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec3RefGetX) {
|
|
||||||
moduleBaseGetOrReturn(vec3ref_t, ref, moduleVec3RefGet);
|
|
||||||
return jerry_number(ref->data[0]);
|
|
||||||
}
|
|
||||||
moduleBaseFunction(moduleVec3RefSetX) {
|
|
||||||
moduleBaseRequireArgs(1);
|
|
||||||
moduleBaseGetOrReturn(vec3ref_t, ref, moduleVec3RefGet);
|
|
||||||
ref->data[0] = moduleBaseArgFloat(0);
|
|
||||||
moduleVec3RefNotify(ref);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec3RefGetY) {
|
|
||||||
moduleBaseGetOrReturn(vec3ref_t, ref, moduleVec3RefGet);
|
|
||||||
return jerry_number(ref->data[1]);
|
|
||||||
}
|
|
||||||
moduleBaseFunction(moduleVec3RefSetY) {
|
|
||||||
moduleBaseRequireArgs(1);
|
|
||||||
moduleBaseGetOrReturn(vec3ref_t, ref, moduleVec3RefGet);
|
|
||||||
ref->data[1] = moduleBaseArgFloat(0);
|
|
||||||
moduleVec3RefNotify(ref);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec3RefGetZ) {
|
|
||||||
moduleBaseGetOrReturn(vec3ref_t, ref, moduleVec3RefGet);
|
|
||||||
return jerry_number(ref->data[2]);
|
|
||||||
}
|
|
||||||
moduleBaseFunction(moduleVec3RefSetZ) {
|
|
||||||
moduleBaseRequireArgs(1);
|
|
||||||
moduleBaseGetOrReturn(vec3ref_t, ref, moduleVec3RefGet);
|
|
||||||
ref->data[2] = moduleBaseArgFloat(0);
|
|
||||||
moduleVec3RefNotify(ref);
|
|
||||||
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(
|
|
||||||
float_t *data, void (*onChange)(void *), void *ctx
|
|
||||||
) {
|
|
||||||
vec3ref_t ref = { .data = data, .onChange = onChange, .ctx = ctx };
|
|
||||||
return scriptProtoCreateValue(&MODULE_VEC3_REF_PROTO, &ref);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool_t moduleVec3RefCheck(jerry_value_t val, float_t *out) {
|
|
||||||
vec3ref_t *ref = moduleVec3RefFrom(val);
|
|
||||||
if(!ref) return false;
|
|
||||||
out[0] = ref->data[0];
|
|
||||||
out[1] = ref->data[1];
|
|
||||||
out[2] = ref->data[2];
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool_t moduleVec3AnyCheck(jerry_value_t val, float_t *out) {
|
|
||||||
return moduleVec3Check(val, out) || moduleVec3RefCheck(val, out);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void moduleVec3Ref(void) {
|
|
||||||
scriptProtoInit(
|
|
||||||
&MODULE_VEC3_REF_PROTO, NULL, sizeof(vec3ref_t), NULL
|
|
||||||
);
|
|
||||||
scriptProtoDefineToString(&MODULE_VEC3_REF_PROTO, moduleVec3RefToString);
|
|
||||||
|
|
||||||
scriptProtoDefineProp(
|
|
||||||
&MODULE_VEC3_REF_PROTO, "x",
|
|
||||||
moduleVec3RefGetX, moduleVec3RefSetX
|
|
||||||
);
|
|
||||||
scriptProtoDefineProp(
|
|
||||||
&MODULE_VEC3_REF_PROTO, "y",
|
|
||||||
moduleVec3RefGetY, moduleVec3RefSetY
|
|
||||||
);
|
|
||||||
scriptProtoDefineProp(
|
|
||||||
&MODULE_VEC3_REF_PROTO, "z",
|
|
||||||
moduleVec3RefGetZ, moduleVec3RefSetZ
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,248 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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 "cglm/cglm.h"
|
|
||||||
|
|
||||||
static scriptproto_t MODULE_VEC4_PROTO;
|
|
||||||
|
|
||||||
static inline float_t * moduleVec4Get(const jerry_call_info_t *callInfo) {
|
|
||||||
return (float_t *)scriptProtoGetValue(
|
|
||||||
&MODULE_VEC4_PROTO, callInfo->this_value
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline float_t * moduleVec4From(jerry_value_t val) {
|
|
||||||
return (float_t *)scriptProtoGetValue(&MODULE_VEC4_PROTO, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec4Constructor) {
|
|
||||||
float_t *ptr = (float_t *)memoryAllocate(sizeof(vec4));
|
|
||||||
ptr[0] = moduleBaseOptFloat(0, 0.0f);
|
|
||||||
ptr[1] = moduleBaseOptFloat(1, 0.0f);
|
|
||||||
ptr[2] = moduleBaseOptFloat(2, 0.0f);
|
|
||||||
ptr[3] = moduleBaseOptFloat(3, 0.0f);
|
|
||||||
jerry_object_set_native_ptr(
|
|
||||||
callInfo->this_value, &MODULE_VEC4_PROTO.info, ptr
|
|
||||||
);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
// x/y/z/w
|
|
||||||
moduleBaseFunction(moduleVec4GetX) {
|
|
||||||
moduleBaseGetOrReturn(float_t, v, moduleVec4Get); return jerry_number(v[0]);
|
|
||||||
}
|
|
||||||
moduleBaseFunction(moduleVec4SetX) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseGetOrReturn(float_t, v, moduleVec4Get);
|
|
||||||
v[0] = moduleBaseArgFloat(0); return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec4GetY) {
|
|
||||||
moduleBaseGetOrReturn(float_t, v, moduleVec4Get); return jerry_number(v[1]);
|
|
||||||
}
|
|
||||||
moduleBaseFunction(moduleVec4SetY) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseGetOrReturn(float_t, v, moduleVec4Get);
|
|
||||||
v[1] = moduleBaseArgFloat(0); return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec4GetZ) {
|
|
||||||
moduleBaseGetOrReturn(float_t, v, moduleVec4Get); return jerry_number(v[2]);
|
|
||||||
}
|
|
||||||
moduleBaseFunction(moduleVec4SetZ) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseGetOrReturn(float_t, v, moduleVec4Get);
|
|
||||||
v[2] = moduleBaseArgFloat(0); return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec4GetW) {
|
|
||||||
moduleBaseGetOrReturn(float_t, v, moduleVec4Get); return jerry_number(v[3]);
|
|
||||||
}
|
|
||||||
moduleBaseFunction(moduleVec4SetW) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseGetOrReturn(float_t, v, moduleVec4Get);
|
|
||||||
v[3] = moduleBaseArgFloat(0); return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
// u0/v0/u1/v1 aliases for UV coordinates
|
|
||||||
moduleBaseFunction(moduleVec4GetU0) {
|
|
||||||
moduleBaseGetOrReturn(float_t, v, moduleVec4Get); return jerry_number(v[0]);
|
|
||||||
}
|
|
||||||
moduleBaseFunction(moduleVec4SetU0) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseGetOrReturn(float_t, v, moduleVec4Get);
|
|
||||||
v[0] = moduleBaseArgFloat(0); return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec4GetV0) {
|
|
||||||
moduleBaseGetOrReturn(float_t, v, moduleVec4Get); return jerry_number(v[1]);
|
|
||||||
}
|
|
||||||
moduleBaseFunction(moduleVec4SetV0) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseGetOrReturn(float_t, v, moduleVec4Get);
|
|
||||||
v[1] = moduleBaseArgFloat(0); return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec4GetU1) {
|
|
||||||
moduleBaseGetOrReturn(float_t, v, moduleVec4Get); return jerry_number(v[2]);
|
|
||||||
}
|
|
||||||
moduleBaseFunction(moduleVec4SetU1) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseGetOrReturn(float_t, v, moduleVec4Get);
|
|
||||||
v[2] = moduleBaseArgFloat(0); return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec4GetV1) {
|
|
||||||
moduleBaseGetOrReturn(float_t, v, moduleVec4Get); return jerry_number(v[3]);
|
|
||||||
}
|
|
||||||
moduleBaseFunction(moduleVec4SetV1) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseGetOrReturn(float_t, v, moduleVec4Get);
|
|
||||||
v[3] = moduleBaseArgFloat(0); return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec4Dot) {
|
|
||||||
moduleBaseRequireArgs(1);
|
|
||||||
float_t *a = moduleVec4Get(callInfo);
|
|
||||||
if(!a) return moduleBaseThrow("Vec4.dot: invalid this");
|
|
||||||
float_t *b = moduleVec4From(args[0]);
|
|
||||||
if(!b) return moduleBaseThrow("Vec4.dot: argument must be a Vec4");
|
|
||||||
return jerry_number(glm_vec4_dot(a, b));
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec4Length) {
|
|
||||||
float_t *v = moduleVec4Get(callInfo);
|
|
||||||
if(!v) return moduleBaseThrow("Vec4.length: invalid this");
|
|
||||||
return jerry_number(glm_vec4_norm(v));
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec4LengthSq) {
|
|
||||||
float_t *v = moduleVec4Get(callInfo);
|
|
||||||
if(!v) return moduleBaseThrow("Vec4.lengthSq: invalid this");
|
|
||||||
return jerry_number(glm_vec4_norm2(v));
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec4Normalize) {
|
|
||||||
float_t *v = moduleVec4Get(callInfo);
|
|
||||||
if(!v) return moduleBaseThrow("Vec4.normalize: invalid this");
|
|
||||||
vec4 r;
|
|
||||||
glm_vec4_normalize_to(v, r);
|
|
||||||
return scriptProtoCreateValue(&MODULE_VEC4_PROTO, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec4Negate) {
|
|
||||||
float_t *v = moduleVec4Get(callInfo);
|
|
||||||
if(!v) return moduleBaseThrow("Vec4.negate: invalid this");
|
|
||||||
vec4 r;
|
|
||||||
glm_vec4_negate_to(v, r);
|
|
||||||
return scriptProtoCreateValue(&MODULE_VEC4_PROTO, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec4Add) {
|
|
||||||
moduleBaseRequireArgs(1);
|
|
||||||
float_t *a = moduleVec4Get(callInfo);
|
|
||||||
if(!a) return moduleBaseThrow("Vec4.add: invalid this");
|
|
||||||
float_t *b = moduleVec4From(args[0]);
|
|
||||||
if(!b) return moduleBaseThrow("Vec4.add: argument must be a Vec4");
|
|
||||||
vec4 r;
|
|
||||||
glm_vec4_add(a, b, r);
|
|
||||||
return scriptProtoCreateValue(&MODULE_VEC4_PROTO, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec4Sub) {
|
|
||||||
moduleBaseRequireArgs(1);
|
|
||||||
float_t *a = moduleVec4Get(callInfo);
|
|
||||||
if(!a) return moduleBaseThrow("Vec4.sub: invalid this");
|
|
||||||
float_t *b = moduleVec4From(args[0]);
|
|
||||||
if(!b) return moduleBaseThrow("Vec4.sub: argument must be a Vec4");
|
|
||||||
vec4 r;
|
|
||||||
glm_vec4_sub(a, b, r);
|
|
||||||
return scriptProtoCreateValue(&MODULE_VEC4_PROTO, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec4Scale) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireNumber(0);
|
|
||||||
float_t *v = moduleVec4Get(callInfo);
|
|
||||||
if(!v) return moduleBaseThrow("Vec4.scale: invalid this");
|
|
||||||
vec4 r;
|
|
||||||
glm_vec4_scale(v, moduleBaseArgFloat(0), r);
|
|
||||||
return scriptProtoCreateValue(&MODULE_VEC4_PROTO, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleVec4Lerp) {
|
|
||||||
moduleBaseRequireArgs(2); moduleBaseRequireNumber(1);
|
|
||||||
float_t *a = moduleVec4Get(callInfo);
|
|
||||||
if(!a) return moduleBaseThrow("Vec4.lerp: invalid this");
|
|
||||||
float_t *b = moduleVec4From(args[0]);
|
|
||||||
if(!b) return moduleBaseThrow("Vec4.lerp: first argument must be a Vec4");
|
|
||||||
vec4 r;
|
|
||||||
glm_vec4_lerp(a, b, moduleBaseArgFloat(1), 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) {
|
|
||||||
return scriptProtoCreateValue(&MODULE_VEC4_PROTO, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool_t moduleVec4Check(jerry_value_t val, float_t *out) {
|
|
||||||
float_t *v = moduleVec4From(val);
|
|
||||||
if(!v) return false;
|
|
||||||
out[0] = v[0];
|
|
||||||
out[1] = v[1];
|
|
||||||
out[2] = v[2];
|
|
||||||
out[3] = v[3];
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void moduleVec4(void) {
|
|
||||||
scriptProtoInit(
|
|
||||||
&MODULE_VEC4_PROTO, "Vec4", sizeof(vec4), moduleVec4Constructor
|
|
||||||
);
|
|
||||||
|
|
||||||
scriptProtoDefineProp(
|
|
||||||
&MODULE_VEC4_PROTO, "x", moduleVec4GetX, moduleVec4SetX
|
|
||||||
);
|
|
||||||
scriptProtoDefineProp(
|
|
||||||
&MODULE_VEC4_PROTO, "y", moduleVec4GetY, moduleVec4SetY
|
|
||||||
);
|
|
||||||
scriptProtoDefineProp(
|
|
||||||
&MODULE_VEC4_PROTO, "z", moduleVec4GetZ, moduleVec4SetZ
|
|
||||||
);
|
|
||||||
scriptProtoDefineProp(
|
|
||||||
&MODULE_VEC4_PROTO, "w", moduleVec4GetW, moduleVec4SetW
|
|
||||||
);
|
|
||||||
scriptProtoDefineProp(
|
|
||||||
&MODULE_VEC4_PROTO, "u0", moduleVec4GetU0, moduleVec4SetU0
|
|
||||||
);
|
|
||||||
scriptProtoDefineProp(
|
|
||||||
&MODULE_VEC4_PROTO, "v0", moduleVec4GetV0, moduleVec4SetV0
|
|
||||||
);
|
|
||||||
scriptProtoDefineProp(
|
|
||||||
&MODULE_VEC4_PROTO, "u1", moduleVec4GetU1, moduleVec4SetU1
|
|
||||||
);
|
|
||||||
scriptProtoDefineProp(
|
|
||||||
&MODULE_VEC4_PROTO, "v1", moduleVec4GetV1, moduleVec4SetV1
|
|
||||||
);
|
|
||||||
|
|
||||||
scriptProtoDefineToString(&MODULE_VEC4_PROTO, moduleVec4ToString);
|
|
||||||
|
|
||||||
scriptProtoDefineFunc(&MODULE_VEC4_PROTO, "dot", moduleVec4Dot);
|
|
||||||
scriptProtoDefineFunc(&MODULE_VEC4_PROTO, "length", moduleVec4Length);
|
|
||||||
scriptProtoDefineFunc(&MODULE_VEC4_PROTO, "lengthSq", moduleVec4LengthSq);
|
|
||||||
scriptProtoDefineFunc(&MODULE_VEC4_PROTO, "normalize", moduleVec4Normalize);
|
|
||||||
scriptProtoDefineFunc(&MODULE_VEC4_PROTO, "negate", moduleVec4Negate);
|
|
||||||
scriptProtoDefineFunc(&MODULE_VEC4_PROTO, "add", moduleVec4Add);
|
|
||||||
scriptProtoDefineFunc(&MODULE_VEC4_PROTO, "sub", moduleVec4Sub);
|
|
||||||
scriptProtoDefineFunc(&MODULE_VEC4_PROTO, "scale", moduleVec4Scale);
|
|
||||||
scriptProtoDefineFunc(&MODULE_VEC4_PROTO, "lerp", moduleVec4Lerp);
|
|
||||||
}
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2026 Dominic Masters
|
|
||||||
*
|
|
||||||
* This software is released under the MIT License.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include "script/module/script/moduleinclude.h"
|
|
||||||
#include "script/module/math/modulemath.h"
|
|
||||||
#include "script/module/entity/moduleentity.h"
|
|
||||||
#include "script/module/input/moduleinput.h"
|
|
||||||
#include "script/module/moduleplatform.h"
|
|
||||||
#include "script/module/time/moduletime.h"
|
|
||||||
#include "script/module/display/modulecolor.h"
|
|
||||||
#include "script/module/display/modulemesh.h"
|
|
||||||
#include "script/module/display/modulescreen.h"
|
|
||||||
#include "script/module/display/modulespritebatch.h"
|
|
||||||
#include "script/module/display/moduletext.h"
|
|
||||||
#include "script/module/animation/moduleeasing.h"
|
|
||||||
#include "script/module/animation/moduleanimation.h"
|
|
||||||
#include "script/module/scene/modulescene.h"
|
|
||||||
#include "script/module/cutscene/modulecutscene.h"
|
|
||||||
#include "script/module/console/moduleconsole.h"
|
|
||||||
#include "script/module/engine/moduleengine.h"
|
|
||||||
#include "script/module/item/moduleitem.h"
|
|
||||||
#include "script/module/story/modulestory.h"
|
|
||||||
#include "script/module/event/moduleEvent.h"
|
|
||||||
#include "script/module/ui/moduletextbox.h"
|
|
||||||
#include "script/module/ui/modulefullbox.h"
|
|
||||||
#include "script/module/save/modulesave.h"
|
|
||||||
#include "script/module/overworld/modulemap.h"
|
|
||||||
|
|
||||||
static void moduleRegister(void) {
|
|
||||||
moduleInclude();
|
|
||||||
moduleMath();
|
|
||||||
moduleMesh();
|
|
||||||
moduleEntity();
|
|
||||||
moduleInput();
|
|
||||||
modulePlatform();
|
|
||||||
moduleTime();
|
|
||||||
moduleColor();
|
|
||||||
moduleScreen();
|
|
||||||
moduleSpriteBatch();
|
|
||||||
moduleText();
|
|
||||||
moduleEasing();
|
|
||||||
moduleAnimation();
|
|
||||||
moduleScene();
|
|
||||||
moduleCutscene();
|
|
||||||
moduleConsole();
|
|
||||||
moduleEngine();
|
|
||||||
moduleItem();
|
|
||||||
moduleStory();
|
|
||||||
moduleTextbox();
|
|
||||||
moduleFullbox();
|
|
||||||
moduleSave();
|
|
||||||
moduleMap();
|
|
||||||
}
|
|
||||||
@@ -1,513 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2026 Dominic Masters
|
|
||||||
*
|
|
||||||
* This software is released under the MIT License.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include "script/scriptmanager.h"
|
|
||||||
#include "assert/assert.h"
|
|
||||||
#include "util/string.h"
|
|
||||||
#include "util/memory.h"
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Define a function for a module in JavaScript.
|
|
||||||
*
|
|
||||||
* @param name Name of the method (in C, not JS)
|
|
||||||
* @return A C function with that name, containing the standard JS sig.
|
|
||||||
*/
|
|
||||||
#define moduleBaseFunction(name) \
|
|
||||||
static jerry_value_t name( \
|
|
||||||
const jerry_call_info_t *callInfo, \
|
|
||||||
const jerry_value_t args[], \
|
|
||||||
const jerry_length_t argc)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Define a standard JS prototype for a module.
|
|
||||||
* This creates the INFO struct, and a prototype reference value.
|
|
||||||
*
|
|
||||||
* Values are;
|
|
||||||
* {NAME}_INFO and {NAME_PROTOTYPE}
|
|
||||||
*
|
|
||||||
* @param name Name of the module.
|
|
||||||
* @return See above.
|
|
||||||
*/
|
|
||||||
#define moduleBaseProtoDefine(name) \
|
|
||||||
static const jerry_object_native_info_t name##_INFO = { \
|
|
||||||
.free_cb = moduleBaseFreeProto, \
|
|
||||||
.number_of_references = 0, \
|
|
||||||
.offset_of_references = 0 \
|
|
||||||
}; \
|
|
||||||
static jerry_value_t name##_PROTOTYPE = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the pointer to what is otherwise a prototype in the JerryScript code.
|
|
||||||
* This, for example, allows you to define a pointer in C and have it be a
|
|
||||||
* prototype for objects in JavaScript.
|
|
||||||
*
|
|
||||||
* @param object The JavaScript object to get the native pointer from.
|
|
||||||
* @param info The native info "prototype" struct used to get the pointer.
|
|
||||||
* @return The pointer to the proto (or NULL).
|
|
||||||
*/
|
|
||||||
static void* moduleBaseGetProto(
|
|
||||||
const jerry_value_t object,
|
|
||||||
const jerry_object_native_info_t *info
|
|
||||||
) {
|
|
||||||
assertNotNull(info, "Native info must not be null");
|
|
||||||
if(!jerry_value_is_object(object)) return NULL;
|
|
||||||
|
|
||||||
return (void*)jerry_object_get_native_ptr(object, info);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create an object based on a C value.
|
|
||||||
*
|
|
||||||
* @param input The pointer to the value to create a JS object for.
|
|
||||||
* @param size The size of the data provided in input.
|
|
||||||
* @param info The native info "prototype" struct used to create the object.
|
|
||||||
* @return A JS object wrapping the provided C value.
|
|
||||||
*/
|
|
||||||
static jerry_value_t moduleBaseCreateProto(
|
|
||||||
void *input,
|
|
||||||
const size_t size,
|
|
||||||
const jerry_object_native_info_t *info,
|
|
||||||
const jerry_value_t prototype
|
|
||||||
) {
|
|
||||||
assertNotNull(input, "Input pointer must not be null");
|
|
||||||
assertTrue(size > 0, "Struct size must be greater than 0");
|
|
||||||
assertNotNull(info, "Native info must not be null");
|
|
||||||
|
|
||||||
void *ptr = memoryAllocate(size);
|
|
||||||
memoryCopy(ptr, input, size);
|
|
||||||
jerry_value_t proto = jerry_object();
|
|
||||||
jerry_object_set_native_ptr(proto, info, ptr);
|
|
||||||
jerry_object_set_proto(proto, prototype);
|
|
||||||
return proto;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Standard JerryScript free callback.
|
|
||||||
*
|
|
||||||
* @param ptr The pointer to free.
|
|
||||||
* @param info The native info struct associated with the pointer.
|
|
||||||
*/
|
|
||||||
static void moduleBaseFreeProto(void *ptr, jerry_object_native_info_t *info) {
|
|
||||||
assertNotNull(ptr, "Pointer must not be null");
|
|
||||||
assertNotNull(info, "Native info must not be null");
|
|
||||||
memoryFree(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Quickly defines a property on a prototype with a getter and setter.
|
|
||||||
*/
|
|
||||||
static void moduleBaseProtoDefineProp(
|
|
||||||
const jerry_value_t prototype,
|
|
||||||
const char_t *name,
|
|
||||||
jerry_external_handler_t getter,
|
|
||||||
jerry_external_handler_t setter
|
|
||||||
) {
|
|
||||||
assertTrue(prototype != 0, "Prototype must not be null");
|
|
||||||
assertNotNull(name, "Property name must not be null");
|
|
||||||
assertNotNull(getter, "Getter must not be null");
|
|
||||||
|
|
||||||
jerry_property_descriptor_t desc;
|
|
||||||
memset(&desc, 0, sizeof(desc));
|
|
||||||
desc.flags = (uint16_t)(
|
|
||||||
JERRY_PROP_IS_GET_DEFINED |
|
|
||||||
JERRY_PROP_IS_ENUMERABLE_DEFINED | JERRY_PROP_IS_ENUMERABLE |
|
|
||||||
JERRY_PROP_IS_CONFIGURABLE_DEFINED | JERRY_PROP_IS_CONFIGURABLE
|
|
||||||
);
|
|
||||||
|
|
||||||
desc.getter = jerry_function_external(getter);
|
|
||||||
|
|
||||||
if(setter != NULL) {
|
|
||||||
desc.flags |= JERRY_PROP_IS_SET_DEFINED;
|
|
||||||
desc.setter = jerry_function_external(setter);
|
|
||||||
}
|
|
||||||
|
|
||||||
jerry_value_t key = jerry_string_sz(name);
|
|
||||||
jerry_value_t result = jerry_object_define_own_prop(prototype, key, &desc);
|
|
||||||
jerry_value_free(result);
|
|
||||||
jerry_value_free(key);
|
|
||||||
jerry_value_free(desc.getter);
|
|
||||||
if(setter != NULL) jerry_value_free(desc.setter);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register a global function for a module.
|
|
||||||
*
|
|
||||||
* @param name The name of the function as seen in JavaScript.
|
|
||||||
* @param fn The C handler function for the method.
|
|
||||||
*/
|
|
||||||
static void moduleBaseFunctionRegister(
|
|
||||||
const char_t *name,
|
|
||||||
jerry_external_handler_t fn
|
|
||||||
) {
|
|
||||||
assertNotNull(name, "Function name must not be null");
|
|
||||||
assertNotNull(fn, "Function handler must not be null");
|
|
||||||
|
|
||||||
jerry_value_t global = jerry_current_realm();
|
|
||||||
jerry_value_t key = jerry_string_sz(name);
|
|
||||||
jerry_value_t func = jerry_function_external(fn);
|
|
||||||
jerry_object_set(global, key, func);
|
|
||||||
jerry_value_free(func);
|
|
||||||
jerry_value_free(key);
|
|
||||||
jerry_value_free(global);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Evaluates a script in the global scope.
|
|
||||||
*
|
|
||||||
* @param script The script to evaluate.
|
|
||||||
*/
|
|
||||||
static void moduleBaseEval(const char_t *script) {
|
|
||||||
assertNotNull(script, "Script must not be null");
|
|
||||||
|
|
||||||
jerry_value_t result = jerry_eval(
|
|
||||||
(const jerry_char_t *)script,
|
|
||||||
strlen(script),
|
|
||||||
JERRY_PARSE_NO_OPTS
|
|
||||||
);
|
|
||||||
jerry_value_free(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Throw a type error from a module function.
|
|
||||||
*
|
|
||||||
* @param message The error message to throw.
|
|
||||||
* @return A JerryScript error value.
|
|
||||||
*/
|
|
||||||
static jerry_value_t moduleBaseThrow(const char_t *message) {
|
|
||||||
assertStrLenMin(message, 1, "Error message must not be empty");
|
|
||||||
return jerry_throw_sz(JERRY_ERROR_TYPE, message);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts a C errorret_t into a JS exception, forwarding the error message
|
|
||||||
* so that try/catch in JS sees the real error text. Clears the C error state.
|
|
||||||
*
|
|
||||||
* @param err The errorret_t returned by a failing C function.
|
|
||||||
* @return A JerryScript error value carrying the C error message.
|
|
||||||
*/
|
|
||||||
static jerry_value_t moduleBaseThrowError(const errorret_t err) {
|
|
||||||
assertNotNull(err.state, "Error state must not be NULL");
|
|
||||||
assertNotNull(err.state->message, "Error message must not be NULL");
|
|
||||||
jerry_value_t jsErr = jerry_throw_sz(JERRY_ERROR_TYPE, err.state->message);
|
|
||||||
errorCatch(err);
|
|
||||||
return jsErr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set a global string constant.
|
|
||||||
*/
|
|
||||||
static void moduleBaseSetString(const char_t *name, const char_t *value) {
|
|
||||||
jerry_value_t global = jerry_current_realm();
|
|
||||||
jerry_value_t key = jerry_string_sz(name);
|
|
||||||
jerry_value_t val = jerry_string_sz(value);
|
|
||||||
jerry_object_set(global, key, val);
|
|
||||||
jerry_value_free(val);
|
|
||||||
jerry_value_free(key);
|
|
||||||
jerry_value_free(global);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Defines a global object with the provided name and prototype.
|
|
||||||
*
|
|
||||||
* @param name The name of the global object to create.
|
|
||||||
* @param prototype The prototype to set on the global object.
|
|
||||||
*/
|
|
||||||
static void moduleBaseCreateGlobalObject(
|
|
||||||
const char_t *name, jerry_value_t prototype
|
|
||||||
) {
|
|
||||||
jerry_value_t global = jerry_current_realm();
|
|
||||||
jerry_value_t key = jerry_string_sz(name);
|
|
||||||
jerry_object_set(global, key, prototype);
|
|
||||||
jerry_value_free(key);
|
|
||||||
jerry_value_free(global);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Assert an argument is a number; return type error if not.
|
|
||||||
*/
|
|
||||||
#define moduleBaseRequireNumber(i) do { \
|
|
||||||
if(!jerry_value_is_number(args[(i)])) { \
|
|
||||||
return moduleBaseThrow("Expected number argument"); \
|
|
||||||
} \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Assert an argument is a string; return type error if not.
|
|
||||||
*/
|
|
||||||
#define moduleBaseRequireString(i) do { \
|
|
||||||
if(!jerry_value_is_string(args[(i)])) { \
|
|
||||||
return moduleBaseThrow("Expected string argument"); \
|
|
||||||
} \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Assert an argument is a function; return type error if not.
|
|
||||||
*/
|
|
||||||
#define moduleBaseRequireFunction(i) do { \
|
|
||||||
if(!jerry_value_is_function(args[(i)])) { \
|
|
||||||
return moduleBaseThrow("Expected function argument"); \
|
|
||||||
} \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Assert an argument is an object; return type error if not.
|
|
||||||
*/
|
|
||||||
#define moduleBaseRequireObject(i) do { \
|
|
||||||
if(!jerry_value_is_object(args[(i)])) { \
|
|
||||||
return moduleBaseThrow("Expected object argument"); \
|
|
||||||
} \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Require at least N arguments; throw a TypeError if fewer were provided.
|
|
||||||
*
|
|
||||||
* Example: moduleBaseRequireArgs(2);
|
|
||||||
*/
|
|
||||||
#define moduleBaseRequireArgs(n) do { \
|
|
||||||
if(argc < (jerry_length_t)(n)) { \
|
|
||||||
return moduleBaseThrow("Expected at least " #n " argument(s)"); \
|
|
||||||
} \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Declare a typed pointer from a getter and immediately return undefined if it
|
|
||||||
* is NULL. The named variable is available for the rest of the function.
|
|
||||||
*
|
|
||||||
* Example:
|
|
||||||
* moduleBaseGetOrReturn(entitycamera_t, cam, moduleEntityCameraGet);
|
|
||||||
* return jerry_number(cam->nearClip);
|
|
||||||
*/
|
|
||||||
#define moduleBaseGetOrReturn(type, var, getter) \
|
|
||||||
type *var = (getter)(callInfo); \
|
|
||||||
if(!(var)) return jerry_undefined()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cast argument i to float_t. Call after validating the arg is a number.
|
|
||||||
*/
|
|
||||||
#define moduleBaseArgFloat(i) ((float_t)jerry_value_as_number(args[(i)]))
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cast argument i to int32_t. Call after validating the arg is a number.
|
|
||||||
*/
|
|
||||||
#define moduleBaseArgInt(i) ((int32_t)jerry_value_as_number(args[(i)]))
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read argument i as a boolean (true/false).
|
|
||||||
*/
|
|
||||||
#define moduleBaseArgBool(i) (jerry_value_is_true(args[(i)]))
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read optional argument i as float_t. Returns def if the argument is missing
|
|
||||||
* or not a number.
|
|
||||||
*/
|
|
||||||
#define moduleBaseOptFloat(i, def) \
|
|
||||||
((jerry_length_t)(i) < argc && jerry_value_is_number(args[(i)]) \
|
|
||||||
? (float_t)jerry_value_as_number(args[(i)]) : (def))
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read optional argument i as int32_t. Returns def if the argument is missing
|
|
||||||
* or not a number.
|
|
||||||
*/
|
|
||||||
#define moduleBaseOptInt(i, def) \
|
|
||||||
((jerry_length_t)(i) < argc && jerry_value_is_number(args[(i)]) \
|
|
||||||
? (int32_t)jerry_value_as_number(args[(i)]) : (def))
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set a global numeric constant.
|
|
||||||
*/
|
|
||||||
static inline void moduleBaseSetNumber(const char_t *name, double value) {
|
|
||||||
jerry_value_t global = jerry_current_realm();
|
|
||||||
jerry_value_t key = jerry_string_sz(name);
|
|
||||||
jerry_value_t val = jerry_number(value);
|
|
||||||
jerry_object_set(global, key, val);
|
|
||||||
jerry_value_free(val);
|
|
||||||
jerry_value_free(key);
|
|
||||||
jerry_value_free(global);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set a global integer constant.
|
|
||||||
*/
|
|
||||||
static inline void moduleBaseSetInt(const char_t *name, int32_t value) {
|
|
||||||
moduleBaseSetNumber(name, (double)value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set a global JS value. Caller retains ownership of the value and must free
|
|
||||||
* it independently.
|
|
||||||
*/
|
|
||||||
static inline void moduleBaseSetValue(const char_t *name, jerry_value_t value) {
|
|
||||||
jerry_value_t global = jerry_current_realm();
|
|
||||||
jerry_value_t key = jerry_string_sz(name);
|
|
||||||
jerry_object_set(global, key, value);
|
|
||||||
jerry_value_free(key);
|
|
||||||
jerry_value_free(global);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrap an engine-owned C pointer as a JS object (no GC free callback).
|
|
||||||
* Used for global singletons like INPUT_EVENT_PRESSED, SHADER_UNLIT, etc.
|
|
||||||
*/
|
|
||||||
static inline jerry_value_t moduleBaseWrapPointer(void *ptr) {
|
|
||||||
jerry_value_t obj = jerry_object();
|
|
||||||
jerry_object_set_native_ptr(obj, &JS_PTR_NATIVE_INFO, ptr);
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set a named global to a wrapped engine-owned C pointer.
|
|
||||||
* Combines moduleBaseWrapPointer and moduleBaseSetValue in one call.
|
|
||||||
*/
|
|
||||||
static inline void moduleBaseSetWrappedPointer(const char_t *name, void *ptr) {
|
|
||||||
jerry_value_t val = moduleBaseWrapPointer(ptr);
|
|
||||||
moduleBaseSetValue(name, val);
|
|
||||||
jerry_value_free(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unwrap a C pointer from a JS object created by moduleBaseWrapPointer.
|
|
||||||
* Returns NULL if the object does not carry a matching native pointer.
|
|
||||||
*/
|
|
||||||
static inline void *moduleBaseUnwrapPointer(jerry_value_t val) {
|
|
||||||
if(!jerry_value_is_object(val)) return NULL;
|
|
||||||
return jerry_object_get_native_ptr(val, &JS_PTR_NATIVE_INFO);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy a JerryScript string value into a C buffer (null-terminated).
|
|
||||||
*
|
|
||||||
* @param val Jerry string value.
|
|
||||||
* @param buf Output buffer.
|
|
||||||
* @param buflen Buffer capacity including the null terminator.
|
|
||||||
*/
|
|
||||||
static inline void moduleBaseToString(
|
|
||||||
jerry_value_t val,
|
|
||||||
char_t *buf,
|
|
||||||
jerry_size_t buflen
|
|
||||||
) {
|
|
||||||
jerry_size_t len = jerry_string_to_buffer(
|
|
||||||
val, JERRY_ENCODING_UTF8, (jerry_char_t *)buf, buflen - 1
|
|
||||||
);
|
|
||||||
buf[len] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Define a named property on a JS object with getter and optional setter.
|
|
||||||
*
|
|
||||||
* @param obj Target object (e.g. a prototype).
|
|
||||||
* @param name Property name.
|
|
||||||
* @param getter C getter handler.
|
|
||||||
* @param setter C setter handler, or NULL for read-only property.
|
|
||||||
*/
|
|
||||||
static inline void moduleBaseDefineProperty(
|
|
||||||
jerry_value_t obj,
|
|
||||||
const char_t *name,
|
|
||||||
jerry_external_handler_t getter,
|
|
||||||
jerry_external_handler_t setter
|
|
||||||
) {
|
|
||||||
jerry_property_descriptor_t desc;
|
|
||||||
memset(&desc, 0, sizeof(desc));
|
|
||||||
desc.flags = (uint16_t)(
|
|
||||||
JERRY_PROP_IS_GET_DEFINED |
|
|
||||||
JERRY_PROP_IS_ENUMERABLE_DEFINED | JERRY_PROP_IS_ENUMERABLE |
|
|
||||||
JERRY_PROP_IS_CONFIGURABLE_DEFINED | JERRY_PROP_IS_CONFIGURABLE
|
|
||||||
);
|
|
||||||
desc.getter = jerry_function_external(getter);
|
|
||||||
if(setter != NULL) {
|
|
||||||
desc.flags |= JERRY_PROP_IS_SET_DEFINED;
|
|
||||||
desc.setter = jerry_function_external(setter);
|
|
||||||
}
|
|
||||||
jerry_value_t key = jerry_string_sz(name);
|
|
||||||
jerry_value_t result = jerry_object_define_own_prop(obj, key, &desc);
|
|
||||||
jerry_value_free(result);
|
|
||||||
jerry_value_free(key);
|
|
||||||
jerry_value_free(desc.getter);
|
|
||||||
if(setter != NULL) jerry_value_free(desc.setter);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set a named method (C function) on a JS object.
|
|
||||||
*
|
|
||||||
* @param obj Target object (e.g. a prototype).
|
|
||||||
* @param name Method name.
|
|
||||||
* @param fn C handler function.
|
|
||||||
*/
|
|
||||||
static inline void moduleBaseDefineMethod(
|
|
||||||
jerry_value_t obj,
|
|
||||||
const char_t *name,
|
|
||||||
jerry_external_handler_t fn
|
|
||||||
) {
|
|
||||||
jerry_value_t key = jerry_string_sz(name);
|
|
||||||
jerry_value_t func = jerry_function_external(fn);
|
|
||||||
jerry_object_set(obj, key, func);
|
|
||||||
jerry_value_free(func);
|
|
||||||
jerry_value_free(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Format an error message from a JerryScript exception value.
|
|
||||||
* Caller must ensure buf is large enough.
|
|
||||||
*/
|
|
||||||
static inline void moduleBaseExceptionMessage(
|
|
||||||
jerry_value_t exception,
|
|
||||||
char_t *buf,
|
|
||||||
size_t buflen
|
|
||||||
) {
|
|
||||||
jerry_value_t errVal = jerry_exception_value(exception, false);
|
|
||||||
jerry_value_t errStr = jerry_value_to_string(errVal);
|
|
||||||
jerry_size_t len = jerry_string_to_buffer(
|
|
||||||
errStr, JERRY_ENCODING_UTF8, (jerry_char_t *)buf, (jerry_size_t)(buflen - 1)
|
|
||||||
);
|
|
||||||
buf[len] = '\0';
|
|
||||||
jerry_value_free(errStr);
|
|
||||||
jerry_value_free(errVal);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Define a named global function.
|
|
||||||
*
|
|
||||||
* @param name The name of the function as seen in JavaScript.
|
|
||||||
* @param fn The C handler function for the method.
|
|
||||||
*/
|
|
||||||
static inline void moduleBaseDefineGlobalMethod(
|
|
||||||
const char_t *name,
|
|
||||||
jerry_external_handler_t fn
|
|
||||||
) {
|
|
||||||
jerry_value_t global = jerry_current_realm();
|
|
||||||
moduleBaseDefineMethod(global, name, fn);
|
|
||||||
jerry_value_free(global);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a named property from a JS object. Caller must free the returned value.
|
|
||||||
*/
|
|
||||||
static inline jerry_value_t moduleBaseGetProp(
|
|
||||||
jerry_value_t obj, const char_t *name
|
|
||||||
) {
|
|
||||||
jerry_value_t key = jerry_string_sz(name);
|
|
||||||
jerry_value_t val = jerry_object_get(obj, key);
|
|
||||||
jerry_value_free(key);
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cast a JS value to float_t. Use for non-args[] values (e.g. object
|
|
||||||
* properties). For args[], prefer moduleBaseArgFloat.
|
|
||||||
*/
|
|
||||||
static inline float_t moduleBaseValueFloat(jerry_value_t val) {
|
|
||||||
return (float_t)jerry_value_as_number(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cast a JS value to int32_t. Use for non-args[] values (e.g. object
|
|
||||||
* properties). For args[], prefer moduleBaseArgInt.
|
|
||||||
*/
|
|
||||||
static inline int32_t moduleBaseValueInt(jerry_value_t val) {
|
|
||||||
return (int32_t)jerry_value_as_number(val);
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2025 Dominic Masters
|
|
||||||
*
|
|
||||||
* This software is released under the MIT License.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include "script/module/modulebase.h"
|
|
||||||
#include "script/module/moduleplatformplatform.h"
|
|
||||||
|
|
||||||
#ifndef DUSK_TARGET_SYSTEM
|
|
||||||
#error "DUSK_TARGET_SYSTEM must be defined"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define MODULE_PLATFORM_VALUE "var PLATFORM = '" DUSK_TARGET_SYSTEM "';\n"
|
|
||||||
|
|
||||||
static void modulePlatform(void) {
|
|
||||||
moduleBaseEval(MODULE_PLATFORM_VALUE);
|
|
||||||
|
|
||||||
#ifdef modulePlatformPlatform
|
|
||||||
modulePlatformPlatform();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
@@ -1,137 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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 "overworld/map.h"
|
|
||||||
#include "modulemapchunk.h"
|
|
||||||
|
|
||||||
static scriptproto_t MODULE_MAP_PROTO;
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleMapDefaultUpdate) {
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleMapDefaultDispose) {
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleMapDefaultConstructor) {
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleMapLoad) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireString(0);
|
|
||||||
|
|
||||||
char_t handle[MAP_HANDLE_MAX];
|
|
||||||
moduleBaseToString(args[0], handle, sizeof(handle));
|
|
||||||
if(handle[0] == '\0') return moduleBaseThrow("Map.load: handle cannot be empty");
|
|
||||||
|
|
||||||
errorret_t err = mapLoad(handle);
|
|
||||||
if(err.code != ERROR_OK) return moduleBaseThrow("Map.load: failed to load map");
|
|
||||||
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleMapIsLoaded) {
|
|
||||||
return jerry_boolean(mapIsLoaded());
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleMapDispose) {
|
|
||||||
mapDispose();
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleMapSetChunkSize) {
|
|
||||||
moduleBaseRequireArgs(3);
|
|
||||||
moduleBaseRequireNumber(0); moduleBaseRequireNumber(1); moduleBaseRequireNumber(2);
|
|
||||||
|
|
||||||
MAP.chunkTileWidth = (uint16_t)moduleBaseArgInt(0);
|
|
||||||
MAP.chunkTileHeight = (uint16_t)moduleBaseArgInt(1);
|
|
||||||
MAP.chunkTileDepth = (uint16_t)moduleBaseArgInt(2);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleMapSetPosition) {
|
|
||||||
moduleBaseRequireArgs(3);
|
|
||||||
moduleBaseRequireNumber(0); moduleBaseRequireNumber(1); moduleBaseRequireNumber(2);
|
|
||||||
|
|
||||||
tilepos_t pos = {
|
|
||||||
.x = (tileunit_t)moduleBaseArgInt(0),
|
|
||||||
.y = (tileunit_t)moduleBaseArgInt(1),
|
|
||||||
.z = (tileunit_t)moduleBaseArgInt(2),
|
|
||||||
};
|
|
||||||
errorret_t err = mapPositionSet(pos);
|
|
||||||
if(err.code != ERROR_OK) return moduleBaseThrow("Map.setPosition: failed");
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void moduleMapReset(void) {
|
|
||||||
if(MAP.scriptRef != MAP_SCRIPT_REF_NONE) {
|
|
||||||
jerry_value_free(MAP.scriptRef);
|
|
||||||
MAP.scriptRef = MAP_SCRIPT_REF_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
jerry_value_t global = jerry_current_realm();
|
|
||||||
jerry_value_t key = jerry_string_sz("module");
|
|
||||||
jerry_value_t undef = jerry_undefined();
|
|
||||||
jerry_object_set(global, key, undef);
|
|
||||||
jerry_value_free(undef);
|
|
||||||
jerry_value_free(key);
|
|
||||||
jerry_value_free(global);
|
|
||||||
}
|
|
||||||
|
|
||||||
static errorret_t moduleMapCall(const char_t *method) {
|
|
||||||
assertStrLenMin(method, 1, "Method name cannot be empty");
|
|
||||||
|
|
||||||
if(MAP.scriptRef == MAP_SCRIPT_REF_NONE) errorOk();
|
|
||||||
|
|
||||||
jerry_value_t key = jerry_string_sz(method);
|
|
||||||
jerry_value_t fn = jerry_object_get(MAP.scriptRef, key);
|
|
||||||
jerry_value_free(key);
|
|
||||||
|
|
||||||
if(!jerry_value_is_function(fn)) {
|
|
||||||
jerry_value_free(fn);
|
|
||||||
errorOk();
|
|
||||||
}
|
|
||||||
|
|
||||||
jerry_value_t result = jerry_call(fn, MAP.scriptRef, NULL, 0);
|
|
||||||
jerry_value_free(fn);
|
|
||||||
|
|
||||||
if(jerry_value_is_exception(result)) {
|
|
||||||
char_t errMsg[512];
|
|
||||||
moduleBaseExceptionMessage(result, errMsg, sizeof(errMsg));
|
|
||||||
jerry_value_free(result);
|
|
||||||
errorThrow("Map:%s failed: %s", method, errMsg);
|
|
||||||
}
|
|
||||||
|
|
||||||
jerry_value_free(result);
|
|
||||||
errorOk();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void moduleMap(void) {
|
|
||||||
moduleMapChunk();
|
|
||||||
|
|
||||||
scriptProtoInit(
|
|
||||||
&MODULE_MAP_PROTO,
|
|
||||||
"Map",
|
|
||||||
sizeof(uint8_t),
|
|
||||||
moduleMapDefaultConstructor
|
|
||||||
);
|
|
||||||
|
|
||||||
scriptProtoDefineFunc(&MODULE_MAP_PROTO, "update", moduleMapDefaultUpdate);
|
|
||||||
scriptProtoDefineFunc(&MODULE_MAP_PROTO, "dispose", moduleMapDefaultDispose);
|
|
||||||
|
|
||||||
scriptProtoDefineStaticFunc(&MODULE_MAP_PROTO, "load", moduleMapLoad);
|
|
||||||
scriptProtoDefineStaticFunc(&MODULE_MAP_PROTO, "dispose", moduleMapDispose);
|
|
||||||
scriptProtoDefineStaticFunc(&MODULE_MAP_PROTO, "setChunkSize", moduleMapSetChunkSize);
|
|
||||||
scriptProtoDefineStaticFunc(&MODULE_MAP_PROTO, "setPosition", moduleMapSetPosition);
|
|
||||||
scriptProtoDefineStaticProp(
|
|
||||||
&MODULE_MAP_PROTO, "isLoaded", moduleMapIsLoaded, NULL
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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 "overworld/mapchunk.h"
|
|
||||||
|
|
||||||
static scriptproto_t MODULE_MAP_CHUNK_PROTO;
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleMapChunkDefaultConstructor) {
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleMapChunkDefaultDispose) {
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void moduleMapChunk(void) {
|
|
||||||
scriptProtoInit(
|
|
||||||
&MODULE_MAP_CHUNK_PROTO,
|
|
||||||
"MapChunk",
|
|
||||||
sizeof(uint8_t),
|
|
||||||
moduleMapChunkDefaultConstructor
|
|
||||||
);
|
|
||||||
|
|
||||||
scriptProtoDefineFunc(
|
|
||||||
&MODULE_MAP_CHUNK_PROTO, "dispose", moduleMapChunkDefaultDispose
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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 "script/module/save/modulesaveslot.h"
|
|
||||||
#include "save/save.h"
|
|
||||||
|
|
||||||
static scriptproto_t MODULE_SAVE_PROTO;
|
|
||||||
|
|
||||||
// Static Properties
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleSaveGetCount) {
|
|
||||||
return jerry_number((double)SAVE_FILE_COUNT_MAX);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Static Methods
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleSaveLoad) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireNumber(0);
|
|
||||||
const uint8_t slot = (uint8_t)moduleBaseArgInt(0);
|
|
||||||
if(slot >= SAVE_FILE_COUNT_MAX) return moduleBaseThrow("Save.load: slot out of range");
|
|
||||||
errorret_t err = saveLoad(slot);
|
|
||||||
if(err.code != ERROR_OK) return moduleBaseThrowError(err);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleSaveWrite) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireNumber(0);
|
|
||||||
const uint8_t slot = (uint8_t)moduleBaseArgInt(0);
|
|
||||||
if(slot >= SAVE_FILE_COUNT_MAX) return moduleBaseThrow("Save.write: slot out of range");
|
|
||||||
errorret_t err = saveWrite(slot);
|
|
||||||
if(err.code != ERROR_OK) return moduleBaseThrowError(err);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleSaveDelete) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireNumber(0);
|
|
||||||
const uint8_t slot = (uint8_t)moduleBaseArgInt(0);
|
|
||||||
if(slot >= SAVE_FILE_COUNT_MAX) return moduleBaseThrow("Save.delete: slot out of range");
|
|
||||||
errorret_t err = saveDelete(slot);
|
|
||||||
if(err.code != ERROR_OK) return moduleBaseThrowError(err);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleSaveExists) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireNumber(0);
|
|
||||||
const uint8_t slot = (uint8_t)moduleBaseArgInt(0);
|
|
||||||
if(slot >= SAVE_FILE_COUNT_MAX) return moduleBaseThrow("Save.exists: slot out of range");
|
|
||||||
return jerry_boolean(saveExists(slot));
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleSaveGet) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireNumber(0);
|
|
||||||
const uint8_t slot = (uint8_t)moduleBaseArgInt(0);
|
|
||||||
if(slot >= SAVE_FILE_COUNT_MAX) return moduleBaseThrow("Save.get: slot out of range");
|
|
||||||
return moduleSaveSlotCreate(slot);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void moduleSave(void) {
|
|
||||||
moduleSaveSlot();
|
|
||||||
|
|
||||||
scriptProtoInit(&MODULE_SAVE_PROTO, "Save", sizeof(uint8_t), NULL);
|
|
||||||
|
|
||||||
scriptProtoDefineStaticProp(&MODULE_SAVE_PROTO, "count",
|
|
||||||
moduleSaveGetCount, NULL
|
|
||||||
);
|
|
||||||
scriptProtoDefineStaticFunc(&MODULE_SAVE_PROTO, "load", moduleSaveLoad);
|
|
||||||
scriptProtoDefineStaticFunc(&MODULE_SAVE_PROTO, "write", moduleSaveWrite);
|
|
||||||
scriptProtoDefineStaticFunc(&MODULE_SAVE_PROTO, "delete", moduleSaveDelete);
|
|
||||||
scriptProtoDefineStaticFunc(&MODULE_SAVE_PROTO, "exists", moduleSaveExists);
|
|
||||||
scriptProtoDefineStaticFunc(&MODULE_SAVE_PROTO, "get", moduleSaveGet);
|
|
||||||
}
|
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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 "save/save.h"
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint8_t slot;
|
|
||||||
} saveslotscript_t;
|
|
||||||
|
|
||||||
static scriptproto_t MODULE_SAVE_SLOT_PROTO;
|
|
||||||
|
|
||||||
static inline saveslotscript_t * moduleSaveSlotGet(
|
|
||||||
const jerry_call_info_t *callInfo
|
|
||||||
) {
|
|
||||||
return (saveslotscript_t *)scriptProtoGetValue(
|
|
||||||
&MODULE_SAVE_SLOT_PROTO, callInfo->this_value
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Properties
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleSaveSlotGetSlot) {
|
|
||||||
moduleBaseGetOrReturn(saveslotscript_t, s, moduleSaveSlotGet);
|
|
||||||
return jerry_number((double)s->slot);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleSaveSlotGetExists) {
|
|
||||||
moduleBaseGetOrReturn(saveslotscript_t, s, moduleSaveSlotGet);
|
|
||||||
return jerry_boolean(saveExists(s->slot));
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleSaveSlotGetVersion) {
|
|
||||||
moduleBaseGetOrReturn(saveslotscript_t, s, moduleSaveSlotGet);
|
|
||||||
return jerry_number((double)saveGet(s->slot)->version);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Methods
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleSaveSlotLoad) {
|
|
||||||
moduleBaseGetOrReturn(saveslotscript_t, s, moduleSaveSlotGet);
|
|
||||||
errorret_t err = saveLoad(s->slot);
|
|
||||||
if(err.code != ERROR_OK) return moduleBaseThrowError(err);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleSaveSlotWrite) {
|
|
||||||
moduleBaseGetOrReturn(saveslotscript_t, s, moduleSaveSlotGet);
|
|
||||||
errorret_t err = saveWrite(s->slot);
|
|
||||||
if(err.code != ERROR_OK) return moduleBaseThrowError(err);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleSaveSlotDelete) {
|
|
||||||
moduleBaseGetOrReturn(saveslotscript_t, s, moduleSaveSlotGet);
|
|
||||||
errorret_t err = saveDelete(s->slot);
|
|
||||||
if(err.code != ERROR_OK) return moduleBaseThrowError(err);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
jerry_value_t moduleSaveSlotCreate(const uint8_t slot) {
|
|
||||||
saveslotscript_t s = { .slot = slot };
|
|
||||||
return scriptProtoCreateValue(&MODULE_SAVE_SLOT_PROTO, &s);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void moduleSaveSlot(void) {
|
|
||||||
scriptProtoInit(&MODULE_SAVE_SLOT_PROTO, "SaveSlot", sizeof(saveslotscript_t), NULL);
|
|
||||||
|
|
||||||
scriptProtoDefineProp(&MODULE_SAVE_SLOT_PROTO, "slot",
|
|
||||||
moduleSaveSlotGetSlot, NULL
|
|
||||||
);
|
|
||||||
scriptProtoDefineProp(&MODULE_SAVE_SLOT_PROTO, "exists",
|
|
||||||
moduleSaveSlotGetExists, NULL
|
|
||||||
);
|
|
||||||
scriptProtoDefineProp(&MODULE_SAVE_SLOT_PROTO, "version",
|
|
||||||
moduleSaveSlotGetVersion, NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
scriptProtoDefineFunc(&MODULE_SAVE_SLOT_PROTO, "load", moduleSaveSlotLoad);
|
|
||||||
scriptProtoDefineFunc(&MODULE_SAVE_SLOT_PROTO, "write", moduleSaveSlotWrite);
|
|
||||||
scriptProtoDefineFunc(&MODULE_SAVE_SLOT_PROTO, "delete", moduleSaveSlotDelete);
|
|
||||||
}
|
|
||||||
@@ -1,109 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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 "scene/scene.h"
|
|
||||||
|
|
||||||
static scriptproto_t MODULE_SCENE_PROTO;
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleSceneDefaultUpdate) {
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleSceneDefaultDispose) {
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleSceneDefaultConstructor) {
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleSceneSet) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireString(0);
|
|
||||||
|
|
||||||
char_t name[ASSET_FILE_NAME_MAX];
|
|
||||||
moduleBaseToString(args[0], name, sizeof(name));
|
|
||||||
if(name[0] == '\0') return moduleBaseThrow("Scene.set: name cannot be empty");
|
|
||||||
|
|
||||||
sceneSet(name);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleSceneGetCurrent) {
|
|
||||||
if(SCENE.sceneCurrent[0] == '\0') return jerry_undefined();
|
|
||||||
return jerry_string_sz(SCENE.sceneCurrent);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void moduleSceneReset(void) {
|
|
||||||
if(SCENE.scriptRef != SCENE_SCRIPT_REF_NONE) {
|
|
||||||
jerry_value_free(SCENE.scriptRef);
|
|
||||||
SCENE.scriptRef = SCENE_SCRIPT_REF_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Drop the 'module' global reference to the scene class so JerryScript's
|
|
||||||
// GC can collect it and all associated closures.
|
|
||||||
jerry_value_t global = jerry_current_realm();
|
|
||||||
jerry_value_t key = jerry_string_sz("module");
|
|
||||||
jerry_value_t undef = jerry_undefined();
|
|
||||||
jerry_object_set(global, key, undef);
|
|
||||||
jerry_value_free(undef);
|
|
||||||
jerry_value_free(key);
|
|
||||||
jerry_value_free(global);
|
|
||||||
}
|
|
||||||
|
|
||||||
static errorret_t moduleSceneCall(const char_t *method) {
|
|
||||||
assertStrLenMin(method, 1, "Method name cannot be empty");
|
|
||||||
|
|
||||||
if(SCENE.scriptRef == SCENE_SCRIPT_REF_NONE) {
|
|
||||||
errorThrow("No active scene script to call method on");
|
|
||||||
}
|
|
||||||
|
|
||||||
jerry_value_t key = jerry_string_sz(method);
|
|
||||||
jerry_value_t fn = jerry_object_get(SCENE.scriptRef, key);
|
|
||||||
jerry_value_free(key);
|
|
||||||
|
|
||||||
if(!jerry_value_is_function(fn)) {
|
|
||||||
jerry_value_free(fn);
|
|
||||||
errorThrow("Scene method '%s' not found", method);
|
|
||||||
}
|
|
||||||
|
|
||||||
jerry_value_t result = jerry_call(fn, SCENE.scriptRef, NULL, 0);
|
|
||||||
jerry_value_free(fn);
|
|
||||||
|
|
||||||
if(jerry_value_is_exception(result)) {
|
|
||||||
char_t errMsg[512];
|
|
||||||
moduleBaseExceptionMessage(result, errMsg, sizeof(errMsg));
|
|
||||||
jerry_value_free(result);
|
|
||||||
errorThrow("Scene:%s failed: %s", method, errMsg);
|
|
||||||
}
|
|
||||||
|
|
||||||
jerry_value_free(result);
|
|
||||||
errorOk();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void moduleScene(void) {
|
|
||||||
scriptProtoInit(
|
|
||||||
&MODULE_SCENE_PROTO,
|
|
||||||
"Scene",
|
|
||||||
sizeof(uint8_t),
|
|
||||||
moduleSceneDefaultConstructor
|
|
||||||
);
|
|
||||||
|
|
||||||
scriptProtoDefineFunc(
|
|
||||||
&MODULE_SCENE_PROTO, "update", moduleSceneDefaultUpdate
|
|
||||||
);
|
|
||||||
scriptProtoDefineFunc(
|
|
||||||
&MODULE_SCENE_PROTO, "dispose", moduleSceneDefaultDispose
|
|
||||||
);
|
|
||||||
|
|
||||||
scriptProtoDefineStaticFunc(&MODULE_SCENE_PROTO, "set", moduleSceneSet);
|
|
||||||
scriptProtoDefineStaticProp(
|
|
||||||
&MODULE_SCENE_PROTO, "current", moduleSceneGetCurrent, NULL
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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/scriptmanager.h"
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleIncludeInclude) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireString(0);
|
|
||||||
|
|
||||||
char_t filename[1024];
|
|
||||||
moduleBaseToString(args[0], filename, sizeof(filename));
|
|
||||||
|
|
||||||
if(filename[0] == '\0') {
|
|
||||||
return moduleBaseThrow("Filename cannot be empty");
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t len = strlen(filename);
|
|
||||||
if(len < 3 || stringCompare(&filename[len - 3], ".js") != 0) {
|
|
||||||
return moduleBaseThrow("include: filename must end with .js");
|
|
||||||
}
|
|
||||||
|
|
||||||
jerry_value_t moduleVal = 0;
|
|
||||||
errorret_t err = scriptInclude(filename, &moduleVal);
|
|
||||||
if(err.code != ERROR_OK) {
|
|
||||||
errorCatch(errorPrint(err));
|
|
||||||
return moduleBaseThrow("Failed to include script file");
|
|
||||||
}
|
|
||||||
|
|
||||||
return moduleVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void moduleInclude(void) {
|
|
||||||
moduleBaseDefineGlobalMethod("include", moduleIncludeInclude);
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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 "story/storyflag.h"
|
|
||||||
|
|
||||||
static scriptproto_t MODULE_STORY_FLAG_PROTO;
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleStoryFlagGet) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireNumber(0);
|
|
||||||
storyflag_t flag = (storyflag_t)moduleBaseArgInt(0);
|
|
||||||
if(flag <= STORY_FLAG_NULL || flag >= STORY_FLAG_COUNT) {
|
|
||||||
return moduleBaseThrow("StoryFlag.get: invalid flag ID");
|
|
||||||
}
|
|
||||||
return jerry_number((double)storyFlagGet(flag));
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleStoryFlagSet) {
|
|
||||||
moduleBaseRequireArgs(2); moduleBaseRequireNumber(0); moduleBaseRequireNumber(1);
|
|
||||||
storyflag_t flag = (storyflag_t)moduleBaseArgInt(0);
|
|
||||||
if(flag <= STORY_FLAG_NULL || flag >= STORY_FLAG_COUNT) {
|
|
||||||
return moduleBaseThrow("StoryFlag.set: invalid flag ID");
|
|
||||||
}
|
|
||||||
storyFlagSet(flag, (storyflagvalue_t)moduleBaseArgInt(1));
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void moduleStory(void) {
|
|
||||||
moduleBaseEval(STORY_FLAG_SCRIPT);
|
|
||||||
|
|
||||||
scriptProtoInit(
|
|
||||||
&MODULE_STORY_FLAG_PROTO, "StoryFlag",
|
|
||||||
sizeof(uint8_t), NULL
|
|
||||||
);
|
|
||||||
scriptProtoDefineStaticFunc(
|
|
||||||
&MODULE_STORY_FLAG_PROTO, "get", moduleStoryFlagGet
|
|
||||||
);
|
|
||||||
scriptProtoDefineStaticFunc(
|
|
||||||
&MODULE_STORY_FLAG_PROTO, "set", moduleStoryFlagSet
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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 "time/time.h"
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleTimeGetDelta) {
|
|
||||||
return jerry_number(TIME.delta);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleTimeGetTime) {
|
|
||||||
return jerry_number(TIME.time);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void moduleTime(void) {
|
|
||||||
jerry_value_t obj = jerry_object();
|
|
||||||
moduleBaseDefineProperty(obj, "delta", moduleTimeGetDelta, NULL);
|
|
||||||
moduleBaseDefineProperty(obj, "time", moduleTimeGetTime, NULL);
|
|
||||||
moduleBaseSetValue("TIME", obj);
|
|
||||||
jerry_value_free(obj);
|
|
||||||
}
|
|
||||||
@@ -1,97 +0,0 @@
|
|||||||
// 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 "script/module/display/modulecolor.h"
|
|
||||||
#include "script/module/event/moduleEvent.h"
|
|
||||||
#include "ui/uifullbox.h"
|
|
||||||
|
|
||||||
static scriptproto_t MODULE_FULLBOX_UNDER_PROTO;
|
|
||||||
static scriptproto_t MODULE_FULLBOX_OVER_PROTO;
|
|
||||||
|
|
||||||
// Stored to allow getter to return the current callback without pool search.
|
|
||||||
static jerry_value_t MODULE_FULLBOX_UNDER_CALLBACK = 0;
|
|
||||||
static jerry_value_t MODULE_FULLBOX_OVER_CALLBACK = 0;
|
|
||||||
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleFullboxUnderTransition) {
|
|
||||||
moduleBaseRequireArgs(4); moduleBaseRequireNumber(2);
|
|
||||||
color_t *from = (color_t*)scriptProtoGetValue(&MODULE_COLOR_PROTO, args[0]);
|
|
||||||
if(!from) return moduleBaseThrow("FullboxUnder.transition: arg 0 must be a Color");
|
|
||||||
color_t *to = (color_t*)scriptProtoGetValue(&MODULE_COLOR_PROTO, args[1]);
|
|
||||||
if(!to) return moduleBaseThrow("FullboxUnder.transition: arg 1 must be a Color");
|
|
||||||
uiFullboxTransition(
|
|
||||||
&UI_FULLBOX_UNDER, *from, *to,
|
|
||||||
moduleBaseArgFloat(2), moduleReadEasing(args[3])
|
|
||||||
);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleFullboxOverTransition) {
|
|
||||||
moduleBaseRequireArgs(4); moduleBaseRequireNumber(2);
|
|
||||||
color_t *from = (color_t*)scriptProtoGetValue(&MODULE_COLOR_PROTO, args[0]);
|
|
||||||
if(!from) return moduleBaseThrow("FullboxOver.transition: arg 0 must be a Color");
|
|
||||||
color_t *to = (color_t*)scriptProtoGetValue(&MODULE_COLOR_PROTO, args[1]);
|
|
||||||
if(!to) return moduleBaseThrow("FullboxOver.transition: arg 1 must be a Color");
|
|
||||||
uiFullboxTransition(
|
|
||||||
&UI_FULLBOX_OVER, *from, *to,
|
|
||||||
moduleBaseArgFloat(2), moduleReadEasing(args[3])
|
|
||||||
);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleFullboxUnderGetOnTransitionEnd) {
|
|
||||||
(void)callInfo; (void)args; (void)argc;
|
|
||||||
if(!MODULE_FULLBOX_UNDER_CALLBACK) return jerry_null();
|
|
||||||
return jerry_value_copy(MODULE_FULLBOX_UNDER_CALLBACK);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleFullboxUnderSetOnTransitionEnd) {
|
|
||||||
(void)callInfo;
|
|
||||||
moduleEventSetCallback(
|
|
||||||
&MODULE_FULLBOX_UNDER_CALLBACK,
|
|
||||||
&UI_FULLBOX_UNDER.onTransitionEnd,
|
|
||||||
argc >= 1 ? args[0] : jerry_undefined()
|
|
||||||
);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleFullboxOverGetOnTransitionEnd) {
|
|
||||||
(void)callInfo; (void)args; (void)argc;
|
|
||||||
if(!MODULE_FULLBOX_OVER_CALLBACK) return jerry_null();
|
|
||||||
return jerry_value_copy(MODULE_FULLBOX_OVER_CALLBACK);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleFullboxOverSetOnTransitionEnd) {
|
|
||||||
(void)callInfo;
|
|
||||||
moduleEventSetCallback(
|
|
||||||
&MODULE_FULLBOX_OVER_CALLBACK,
|
|
||||||
&UI_FULLBOX_OVER.onTransitionEnd,
|
|
||||||
argc >= 1 ? args[0] : jerry_undefined()
|
|
||||||
);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void moduleFullbox(void) {
|
|
||||||
scriptProtoInit(&MODULE_FULLBOX_UNDER_PROTO, "FullboxUnder", sizeof(uint8_t), NULL);
|
|
||||||
scriptProtoDefineStaticFunc(
|
|
||||||
&MODULE_FULLBOX_UNDER_PROTO, "transition", moduleFullboxUnderTransition
|
|
||||||
);
|
|
||||||
scriptProtoDefineStaticProp(
|
|
||||||
&MODULE_FULLBOX_UNDER_PROTO, "onTransitionEnd",
|
|
||||||
moduleFullboxUnderGetOnTransitionEnd, moduleFullboxUnderSetOnTransitionEnd
|
|
||||||
);
|
|
||||||
|
|
||||||
scriptProtoInit(&MODULE_FULLBOX_OVER_PROTO, "FullboxOver", sizeof(uint8_t), NULL);
|
|
||||||
scriptProtoDefineStaticFunc(
|
|
||||||
&MODULE_FULLBOX_OVER_PROTO, "transition", moduleFullboxOverTransition
|
|
||||||
);
|
|
||||||
scriptProtoDefineStaticProp(
|
|
||||||
&MODULE_FULLBOX_OVER_PROTO, "onTransitionEnd",
|
|
||||||
moduleFullboxOverGetOnTransitionEnd, moduleFullboxOverSetOnTransitionEnd
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,158 +0,0 @@
|
|||||||
// 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 "script/module/event/moduleEvent.h"
|
|
||||||
#include "ui/uitextbox.h"
|
|
||||||
|
|
||||||
static jerry_value_t MODULE_TEXTBOX_PAGE_COMPLETE_CALLBACK = 0;
|
|
||||||
static jerry_value_t MODULE_TEXTBOX_LAST_PAGE_CALLBACK = 0;
|
|
||||||
|
|
||||||
static scriptproto_t MODULE_TEXTBOX_PROTO;
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleTextboxSetText) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireString(0);
|
|
||||||
char_t buf[UI_TEXTBOX_TEXT_MAX];
|
|
||||||
moduleBaseToString(args[0], buf, sizeof(buf));
|
|
||||||
uiTextboxSetText(buf);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleTextboxNextPage) {
|
|
||||||
uiTextboxNextPage();
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleTextboxUpdate) {
|
|
||||||
uiTextboxUpdate();
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleTextboxDraw) {
|
|
||||||
uiTextboxDraw();
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleTextboxGetScroll) {
|
|
||||||
return jerry_number((double)UI_TEXTBOX.scroll);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleTextboxSetScroll) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireNumber(0);
|
|
||||||
UI_TEXTBOX.scroll = moduleBaseArgInt(0);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleTextboxGetAdvanceAction) {
|
|
||||||
return jerry_number((double)UI_TEXTBOX.advanceAction);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleTextboxSetAdvanceAction) {
|
|
||||||
moduleBaseRequireArgs(1); moduleBaseRequireNumber(0);
|
|
||||||
UI_TEXTBOX.advanceAction = (inputaction_t)moduleBaseArgInt(0);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleTextboxGetPageComplete) {
|
|
||||||
return jerry_boolean(uiTextboxPageIsComplete());
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleTextboxGetHasNextPage) {
|
|
||||||
return jerry_boolean(uiTextboxHasNextPage());
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleTextboxGetCurrentPage) {
|
|
||||||
return jerry_number((double)UI_TEXTBOX.currentPage);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleTextboxGetPageCount) {
|
|
||||||
return jerry_number((double)UI_TEXTBOX.pageCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleTextboxGetOnPageComplete) {
|
|
||||||
(void)callInfo; (void)args; (void)argc;
|
|
||||||
if(!MODULE_TEXTBOX_PAGE_COMPLETE_CALLBACK) return jerry_null();
|
|
||||||
return jerry_value_copy(MODULE_TEXTBOX_PAGE_COMPLETE_CALLBACK);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleTextboxSetOnPageComplete) {
|
|
||||||
(void)callInfo;
|
|
||||||
moduleEventSetCallback(
|
|
||||||
&MODULE_TEXTBOX_PAGE_COMPLETE_CALLBACK,
|
|
||||||
&UI_TEXTBOX.onPageComplete,
|
|
||||||
argc >= 1 ? args[0] : jerry_undefined()
|
|
||||||
);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleTextboxGetOnLastPage) {
|
|
||||||
(void)callInfo; (void)args; (void)argc;
|
|
||||||
if(!MODULE_TEXTBOX_LAST_PAGE_CALLBACK) return jerry_null();
|
|
||||||
return jerry_value_copy(MODULE_TEXTBOX_LAST_PAGE_CALLBACK);
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleBaseFunction(moduleTextboxSetOnLastPage) {
|
|
||||||
(void)callInfo;
|
|
||||||
moduleEventSetCallback(
|
|
||||||
&MODULE_TEXTBOX_LAST_PAGE_CALLBACK,
|
|
||||||
&UI_TEXTBOX.onLastPage,
|
|
||||||
argc >= 1 ? args[0] : jerry_undefined()
|
|
||||||
);
|
|
||||||
return jerry_undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void moduleTextbox(void) {
|
|
||||||
scriptProtoInit(
|
|
||||||
&MODULE_TEXTBOX_PROTO, "Textbox", sizeof(uint8_t), NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
scriptProtoDefineStaticFunc(
|
|
||||||
&MODULE_TEXTBOX_PROTO, "setText", moduleTextboxSetText
|
|
||||||
);
|
|
||||||
scriptProtoDefineStaticFunc(
|
|
||||||
&MODULE_TEXTBOX_PROTO, "nextPage", moduleTextboxNextPage
|
|
||||||
);
|
|
||||||
scriptProtoDefineStaticFunc(
|
|
||||||
&MODULE_TEXTBOX_PROTO, "update", moduleTextboxUpdate
|
|
||||||
);
|
|
||||||
scriptProtoDefineStaticFunc(
|
|
||||||
&MODULE_TEXTBOX_PROTO, "draw", moduleTextboxDraw
|
|
||||||
);
|
|
||||||
|
|
||||||
scriptProtoDefineStaticProp(
|
|
||||||
&MODULE_TEXTBOX_PROTO, "scroll",
|
|
||||||
moduleTextboxGetScroll, moduleTextboxSetScroll
|
|
||||||
);
|
|
||||||
scriptProtoDefineStaticProp(
|
|
||||||
&MODULE_TEXTBOX_PROTO, "advanceAction",
|
|
||||||
moduleTextboxGetAdvanceAction, moduleTextboxSetAdvanceAction
|
|
||||||
);
|
|
||||||
scriptProtoDefineStaticProp(
|
|
||||||
&MODULE_TEXTBOX_PROTO, "pageComplete",
|
|
||||||
moduleTextboxGetPageComplete, NULL
|
|
||||||
);
|
|
||||||
scriptProtoDefineStaticProp(
|
|
||||||
&MODULE_TEXTBOX_PROTO, "hasNextPage",
|
|
||||||
moduleTextboxGetHasNextPage, NULL
|
|
||||||
);
|
|
||||||
scriptProtoDefineStaticProp(
|
|
||||||
&MODULE_TEXTBOX_PROTO, "currentPage",
|
|
||||||
moduleTextboxGetCurrentPage, NULL
|
|
||||||
);
|
|
||||||
scriptProtoDefineStaticProp(
|
|
||||||
&MODULE_TEXTBOX_PROTO, "pageCount",
|
|
||||||
moduleTextboxGetPageCount, NULL
|
|
||||||
);
|
|
||||||
scriptProtoDefineStaticProp(
|
|
||||||
&MODULE_TEXTBOX_PROTO, "onPageComplete",
|
|
||||||
moduleTextboxGetOnPageComplete, moduleTextboxSetOnPageComplete
|
|
||||||
);
|
|
||||||
scriptProtoDefineStaticProp(
|
|
||||||
&MODULE_TEXTBOX_PROTO, "onLastPage",
|
|
||||||
moduleTextboxGetOnLastPage, moduleTextboxSetOnLastPage
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,117 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2026 Dominic Masters
|
|
||||||
*
|
|
||||||
* This software is released under the MIT License.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "scriptmanager.h"
|
|
||||||
#include "assert/assert.h"
|
|
||||||
#include "asset/asset.h"
|
|
||||||
#include "util/memory.h"
|
|
||||||
#include "asset/loader/script/assetscriptloader.h"
|
|
||||||
#include "script/module/module.h"
|
|
||||||
|
|
||||||
#ifdef SCRIPT_GAME_INIT
|
|
||||||
#include "script/scriptgame.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
scriptmanager_t SCRIPT_MANAGER;
|
|
||||||
|
|
||||||
const jerry_object_native_info_t JS_PTR_NATIVE_INFO = {
|
|
||||||
.free_cb = NULL,
|
|
||||||
.number_of_references = 0,
|
|
||||||
.offset_of_references = 0
|
|
||||||
};
|
|
||||||
|
|
||||||
errorret_t scriptManagerInit(void) {
|
|
||||||
memoryZero(&SCRIPT_MANAGER, sizeof(scriptmanager_t));
|
|
||||||
|
|
||||||
jerry_init(JERRY_INIT_EMPTY);
|
|
||||||
|
|
||||||
moduleRegister();
|
|
||||||
|
|
||||||
#ifdef SCRIPT_GAME_INIT
|
|
||||||
SCRIPT_GAME_INIT();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
errorOk();
|
|
||||||
}
|
|
||||||
|
|
||||||
errorret_t scriptManagerExec(const char_t *script, jerry_value_t *resultOut) {
|
|
||||||
assertNotNull(script, "Script cannot be NULL");
|
|
||||||
|
|
||||||
jerry_value_t result = jerry_eval(
|
|
||||||
(const jerry_char_t *)script,
|
|
||||||
strlen(script),
|
|
||||||
JERRY_PARSE_NO_OPTS
|
|
||||||
);
|
|
||||||
|
|
||||||
if(jerry_value_is_exception(result)) {
|
|
||||||
jerry_value_t errVal = jerry_exception_value(result, false);
|
|
||||||
jerry_value_t errStr = jerry_value_to_string(errVal);
|
|
||||||
char_t buf[256];
|
|
||||||
jerry_size_t len = jerry_string_to_buffer(
|
|
||||||
errStr, JERRY_ENCODING_UTF8, (jerry_char_t *)buf, sizeof(buf) - 1
|
|
||||||
);
|
|
||||||
buf[len] = '\0';
|
|
||||||
jerry_value_free(errStr);
|
|
||||||
jerry_value_free(errVal);
|
|
||||||
jerry_value_free(result);
|
|
||||||
errorThrow("Failed to execute script: %s", buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(resultOut != NULL) {
|
|
||||||
*resultOut = result;
|
|
||||||
} else {
|
|
||||||
jerry_value_free(result);
|
|
||||||
}
|
|
||||||
errorOk();
|
|
||||||
}
|
|
||||||
|
|
||||||
errorret_t scriptManagerExecFile(
|
|
||||||
const char_t *fname,
|
|
||||||
jerry_value_t *resultOut
|
|
||||||
) {
|
|
||||||
assertNotNull(fname, "Filename cannot be NULL");
|
|
||||||
return assetScriptLoad(fname, resultOut);
|
|
||||||
}
|
|
||||||
|
|
||||||
errorret_t scriptInclude(const char_t *filename, jerry_value_t *out) {
|
|
||||||
assertNotNull(filename, "Filename cannot be NULL");
|
|
||||||
|
|
||||||
jerry_value_t global = jerry_current_realm();
|
|
||||||
jerry_value_t moduleKey = jerry_string_sz("module");
|
|
||||||
|
|
||||||
jerry_value_t prevModule = jerry_object_get(global, moduleKey);
|
|
||||||
jerry_value_t undef = jerry_undefined();
|
|
||||||
jerry_object_set(global, moduleKey, undef);
|
|
||||||
jerry_value_free(undef);
|
|
||||||
|
|
||||||
jerry_value_t execResult = 0;
|
|
||||||
errorret_t err = scriptManagerExecFile(filename, &execResult);
|
|
||||||
if(execResult != 0) jerry_value_free(execResult);
|
|
||||||
|
|
||||||
jerry_value_t moduleVal = jerry_object_get(global, moduleKey);
|
|
||||||
jerry_object_set(global, moduleKey, prevModule);
|
|
||||||
jerry_value_free(prevModule);
|
|
||||||
jerry_value_free(moduleKey);
|
|
||||||
jerry_value_free(global);
|
|
||||||
|
|
||||||
if(err.code != ERROR_OK) {
|
|
||||||
jerry_value_free(moduleVal);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(out != NULL) {
|
|
||||||
*out = moduleVal;
|
|
||||||
} else {
|
|
||||||
jerry_value_free(moduleVal);
|
|
||||||
}
|
|
||||||
errorOk();
|
|
||||||
}
|
|
||||||
|
|
||||||
errorret_t scriptManagerDispose(void) {
|
|
||||||
jerry_cleanup();
|
|
||||||
errorOk();
|
|
||||||
}
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2026 Dominic Masters
|
|
||||||
*
|
|
||||||
* This software is released under the MIT License.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include "error/error.h"
|
|
||||||
#include "scriptvalue.h"
|
|
||||||
|
|
||||||
#define SCRIPT_MANAGER_MAX_EVENT_SUBSCRIPTIONS 64
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
void* nothing;
|
|
||||||
} scriptmanager_t;
|
|
||||||
|
|
||||||
extern scriptmanager_t SCRIPT_MANAGER;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Singleton native-info tag for engine-owned C pointers wrapped in JS objects.
|
|
||||||
* A single global instance ensures jerry_object_get_native_ptr() matches across
|
|
||||||
* all compilation units (including event.c and module headers).
|
|
||||||
*/
|
|
||||||
extern const jerry_object_native_info_t JS_PTR_NATIVE_INFO;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize the script manager (and the underlying JerryScript context).
|
|
||||||
*
|
|
||||||
* @return The error return value.
|
|
||||||
*/
|
|
||||||
errorret_t scriptManagerInit(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Execute a JS string in the active script context.
|
|
||||||
*
|
|
||||||
* @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.
|
|
||||||
*/
|
|
||||||
errorret_t scriptManagerExec(const char_t *script, jerry_value_t *result);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Execute a JS file in the active script context.
|
|
||||||
*
|
|
||||||
* @param fname The filename of the script 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.
|
|
||||||
*/
|
|
||||||
errorret_t scriptManagerExecFile(
|
|
||||||
const char_t *fname,
|
|
||||||
jerry_value_t *result
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Execute a JS file using the module-export pattern and return the exported
|
|
||||||
* value. The script is expected to assign its public API to the global
|
|
||||||
* `module` variable. The caller owns the returned jerry_value_t and must
|
|
||||||
* call jerry_value_free() on it when done.
|
|
||||||
*
|
|
||||||
* @param filename Path to the .js asset file.
|
|
||||||
* @param out Receives the value assigned to `module` by the script.
|
|
||||||
* @return The error return value.
|
|
||||||
*/
|
|
||||||
errorret_t scriptInclude(const char_t *filename, jerry_value_t *out);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dispose of the script manager.
|
|
||||||
*
|
|
||||||
* @return The error return value.
|
|
||||||
*/
|
|
||||||
errorret_t scriptManagerDispose(void);
|
|
||||||
@@ -1,197 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2026 Dominic Masters
|
|
||||||
*
|
|
||||||
* This software is released under the MIT License.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "scriptproto.h"
|
|
||||||
#include "assert/assert.h"
|
|
||||||
#include "util/memory.h"
|
|
||||||
#include "script/module/modulebase.h"
|
|
||||||
|
|
||||||
void scriptProtoInit(
|
|
||||||
scriptproto_t *proto,
|
|
||||||
const char_t *name,
|
|
||||||
const size_t size,
|
|
||||||
jerry_external_handler_t constructor
|
|
||||||
) {
|
|
||||||
assertNotNull(proto, "Script prototype struct must not be null");
|
|
||||||
memoryZero(proto, sizeof(scriptproto_t));
|
|
||||||
|
|
||||||
proto->info = (jerry_object_native_info_t){
|
|
||||||
.free_cb = moduleBaseFreeProto,
|
|
||||||
.number_of_references = 0,
|
|
||||||
.offset_of_references = 0
|
|
||||||
};
|
|
||||||
proto->prototype = jerry_object();
|
|
||||||
proto->size = size;
|
|
||||||
|
|
||||||
if(constructor != NULL) {
|
|
||||||
proto->constructor = jerry_function_external(constructor);
|
|
||||||
jerry_value_t protoKey = jerry_string_sz("prototype");
|
|
||||||
jerry_object_set(proto->constructor, protoKey, proto->prototype);
|
|
||||||
jerry_value_free(protoKey);
|
|
||||||
jerry_value_t ctorKey = jerry_string_sz("constructor");
|
|
||||||
jerry_object_set(proto->prototype, ctorKey, proto->constructor);
|
|
||||||
jerry_value_free(ctorKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(name != NULL) {
|
|
||||||
jerry_value_t global = jerry_current_realm();
|
|
||||||
jerry_value_t key = jerry_string_sz(name);
|
|
||||||
jerry_value_t val;
|
|
||||||
if(proto->constructor) {
|
|
||||||
val = proto->constructor;
|
|
||||||
} else {
|
|
||||||
val = proto->prototype;
|
|
||||||
}
|
|
||||||
jerry_object_set(global, key, val);
|
|
||||||
jerry_value_free(key);
|
|
||||||
jerry_value_free(global);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void scriptProtoDefineProp(
|
|
||||||
scriptproto_t *proto,
|
|
||||||
const char_t *name,
|
|
||||||
jerry_external_handler_t getter,
|
|
||||||
jerry_external_handler_t setter
|
|
||||||
) {
|
|
||||||
assertNotNull(proto, "Script prototype struct must not be null");
|
|
||||||
assertStrLenMin(name, 1, "Property name must not be empty");
|
|
||||||
assertNotNull(getter, "Getter must not be null");
|
|
||||||
|
|
||||||
jerry_property_descriptor_t desc;
|
|
||||||
memoryZero(&desc, sizeof(desc));
|
|
||||||
desc.flags = (uint16_t)(
|
|
||||||
JERRY_PROP_IS_GET_DEFINED |
|
|
||||||
JERRY_PROP_IS_ENUMERABLE_DEFINED | JERRY_PROP_IS_ENUMERABLE |
|
|
||||||
JERRY_PROP_IS_CONFIGURABLE_DEFINED | JERRY_PROP_IS_CONFIGURABLE
|
|
||||||
);
|
|
||||||
|
|
||||||
desc.getter = jerry_function_external(getter);
|
|
||||||
|
|
||||||
if(setter != NULL) {
|
|
||||||
desc.flags |= JERRY_PROP_IS_SET_DEFINED;
|
|
||||||
desc.setter = jerry_function_external(setter);
|
|
||||||
}
|
|
||||||
|
|
||||||
jerry_value_t key = jerry_string_sz(name);
|
|
||||||
jerry_value_t result = jerry_object_define_own_prop(
|
|
||||||
proto->prototype, key, &desc
|
|
||||||
);
|
|
||||||
jerry_value_free(result);
|
|
||||||
jerry_value_free(key);
|
|
||||||
jerry_value_free(desc.getter);
|
|
||||||
if(setter != NULL) jerry_value_free(desc.setter);
|
|
||||||
}
|
|
||||||
|
|
||||||
void scriptProtoDefineFunc(
|
|
||||||
scriptproto_t *proto,
|
|
||||||
const char_t *name,
|
|
||||||
jerry_external_handler_t fn
|
|
||||||
) {
|
|
||||||
assertNotNull(proto, "Script prototype struct must not be null");
|
|
||||||
assertStrLenMin(name, 1, "Method name must not be empty");
|
|
||||||
assertNotNull(fn, "Function handler must not be null");
|
|
||||||
|
|
||||||
jerry_value_t key = jerry_string_sz(name);
|
|
||||||
jerry_value_t func = jerry_function_external(fn);
|
|
||||||
jerry_object_set(proto->prototype, key, func);
|
|
||||||
jerry_value_free(func);
|
|
||||||
jerry_value_free(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
void scriptProtoDefineStaticProp(
|
|
||||||
scriptproto_t *proto,
|
|
||||||
const char_t *name,
|
|
||||||
jerry_external_handler_t getter,
|
|
||||||
jerry_external_handler_t setter
|
|
||||||
) {
|
|
||||||
assertNotNull(proto, "Script prototype struct must not be null");
|
|
||||||
assertStrLenMin(name, 1, "Property name must not be empty");
|
|
||||||
assertNotNull(getter, "Getter must not be null");
|
|
||||||
|
|
||||||
jerry_value_t target = (
|
|
||||||
proto->constructor ? proto->constructor : proto->prototype
|
|
||||||
);
|
|
||||||
|
|
||||||
jerry_property_descriptor_t desc;
|
|
||||||
memoryZero(&desc, sizeof(desc));
|
|
||||||
desc.flags = (uint16_t)(
|
|
||||||
JERRY_PROP_IS_GET_DEFINED |
|
|
||||||
JERRY_PROP_IS_ENUMERABLE_DEFINED | JERRY_PROP_IS_ENUMERABLE |
|
|
||||||
JERRY_PROP_IS_CONFIGURABLE_DEFINED | JERRY_PROP_IS_CONFIGURABLE
|
|
||||||
);
|
|
||||||
|
|
||||||
desc.getter = jerry_function_external(getter);
|
|
||||||
|
|
||||||
if(setter != NULL) {
|
|
||||||
desc.flags |= JERRY_PROP_IS_SET_DEFINED;
|
|
||||||
desc.setter = jerry_function_external(setter);
|
|
||||||
}
|
|
||||||
|
|
||||||
jerry_value_t key = jerry_string_sz(name);
|
|
||||||
jerry_value_t result = jerry_object_define_own_prop(target, key, &desc);
|
|
||||||
jerry_value_free(result);
|
|
||||||
jerry_value_free(key);
|
|
||||||
jerry_value_free(desc.getter);
|
|
||||||
if(setter != NULL) jerry_value_free(desc.setter);
|
|
||||||
}
|
|
||||||
|
|
||||||
void scriptProtoDefineStaticFunc(
|
|
||||||
scriptproto_t *proto,
|
|
||||||
const char_t *name,
|
|
||||||
jerry_external_handler_t fn
|
|
||||||
) {
|
|
||||||
assertNotNull(proto, "Script prototype struct must not be null");
|
|
||||||
assertStrLenMin(name, 1, "Method name must not be empty");
|
|
||||||
assertNotNull(fn, "Function handler must not be null");
|
|
||||||
|
|
||||||
jerry_value_t target = (
|
|
||||||
proto->constructor ? proto->constructor : proto->prototype
|
|
||||||
);
|
|
||||||
jerry_value_t key = jerry_string_sz(name);
|
|
||||||
jerry_value_t func = jerry_function_external(fn);
|
|
||||||
jerry_object_set(target, key, func);
|
|
||||||
jerry_value_free(func);
|
|
||||||
jerry_value_free(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
jerry_value_t scriptProtoCreateValue(
|
|
||||||
const scriptproto_t *proto,
|
|
||||||
const void *value
|
|
||||||
) {
|
|
||||||
assertNotNull(proto, "Script prototype struct must not be null");
|
|
||||||
assertNotNull(value, "Value pointer must not be null");
|
|
||||||
|
|
||||||
void *ptr = memoryAllocate(proto->size);
|
|
||||||
memoryCopy(ptr, value, proto->size);
|
|
||||||
jerry_value_t obj = jerry_object();
|
|
||||||
jerry_object_set_native_ptr(obj, &proto->info, ptr);
|
|
||||||
jerry_object_set_proto(obj, proto->prototype);
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *scriptProtoGetValue(
|
|
||||||
const scriptproto_t *proto,
|
|
||||||
const jerry_value_t obj
|
|
||||||
) {
|
|
||||||
assertNotNull(proto, "Script prototype struct must not be null");
|
|
||||||
if(!jerry_value_is_object(obj)) return NULL;
|
|
||||||
return jerry_object_get_native_ptr(obj, &proto->info);
|
|
||||||
}
|
|
||||||
|
|
||||||
void scriptProtoDefineToString(
|
|
||||||
scriptproto_t *proto,
|
|
||||||
jerry_external_handler_t fn
|
|
||||||
) {
|
|
||||||
scriptProtoDefineFunc(proto, "toString", fn);
|
|
||||||
}
|
|
||||||
|
|
||||||
void scriptProtoDispose(scriptproto_t *proto) {
|
|
||||||
assertNotNull(proto, "Script prototype struct must not be null");
|
|
||||||
jerry_value_free(proto->prototype);
|
|
||||||
if(proto->constructor) jerry_value_free(proto->constructor);
|
|
||||||
}
|
|
||||||
@@ -1,140 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2026 Dominic Masters
|
|
||||||
*
|
|
||||||
* This software is released under the MIT License.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include "dusk.h"
|
|
||||||
#include <jerryscript.h>
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
jerry_object_native_info_t info;
|
|
||||||
jerry_value_t prototype;
|
|
||||||
jerry_value_t constructor;
|
|
||||||
size_t size;
|
|
||||||
} scriptproto_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize a JS class prototype.
|
|
||||||
*
|
|
||||||
* If name is non-NULL the class is registered as a global. When ctor is also
|
|
||||||
* non-NULL the global is the constructor function (enabling `new Name(...)`);
|
|
||||||
* otherwise the prototype object itself becomes the global.
|
|
||||||
*
|
|
||||||
* @param proto The struct to initialize.
|
|
||||||
* @param name JS global name, or NULL to skip global registration.
|
|
||||||
* @param size sizeof the C struct this class wraps.
|
|
||||||
* @param ctor Constructor handler, or NULL if the class has no constructor.
|
|
||||||
*/
|
|
||||||
void scriptProtoInit(
|
|
||||||
scriptproto_t *proto,
|
|
||||||
const char_t *name,
|
|
||||||
const size_t size,
|
|
||||||
jerry_external_handler_t ctor
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Define an instance property with a getter and optional setter.
|
|
||||||
*
|
|
||||||
* @param proto The class prototype.
|
|
||||||
* @param name Property name.
|
|
||||||
* @param getter Getter handler (must not be NULL).
|
|
||||||
* @param setter Setter handler, or NULL for a read-only property.
|
|
||||||
*/
|
|
||||||
void scriptProtoDefineProp(
|
|
||||||
scriptproto_t *proto,
|
|
||||||
const char_t *name,
|
|
||||||
jerry_external_handler_t getter,
|
|
||||||
jerry_external_handler_t setter
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Define an instance method on the class prototype.
|
|
||||||
*
|
|
||||||
* @param proto The class prototype.
|
|
||||||
* @param name Method name.
|
|
||||||
* @param fn C handler called when the method is invoked.
|
|
||||||
*/
|
|
||||||
void scriptProtoDefineFunc(
|
|
||||||
scriptproto_t *proto,
|
|
||||||
const char_t *name,
|
|
||||||
jerry_external_handler_t fn
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Define a static property on the class (e.g. Scene.current).
|
|
||||||
*
|
|
||||||
* Attaches to the constructor function when one exists, otherwise attaches
|
|
||||||
* directly to the prototype object (which is the global in that case).
|
|
||||||
*
|
|
||||||
* @param proto The class prototype.
|
|
||||||
* @param name Property name.
|
|
||||||
* @param getter Getter handler (must not be NULL).
|
|
||||||
* @param setter Setter handler, or NULL for a read-only property.
|
|
||||||
*/
|
|
||||||
void scriptProtoDefineStaticProp(
|
|
||||||
scriptproto_t *proto,
|
|
||||||
const char_t *name,
|
|
||||||
jerry_external_handler_t getter,
|
|
||||||
jerry_external_handler_t setter
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Define a static method on the class (e.g. Color.fromRGBA).
|
|
||||||
*
|
|
||||||
* Attaches to the constructor function when one exists, otherwise attaches
|
|
||||||
* directly to the prototype object (which is the global in that case).
|
|
||||||
*
|
|
||||||
* @param proto The class prototype.
|
|
||||||
* @param name Method name.
|
|
||||||
* @param fn C handler called when the static method is invoked.
|
|
||||||
*/
|
|
||||||
void scriptProtoDefineStaticFunc(
|
|
||||||
scriptproto_t *proto,
|
|
||||||
const char_t *name,
|
|
||||||
jerry_external_handler_t fn
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a JS instance wrapping a copy of a C value.
|
|
||||||
*
|
|
||||||
* @param proto The class prototype.
|
|
||||||
* @param value Pointer to the C value to copy into the new JS object.
|
|
||||||
* @return A new JS object with the class prototype and native pointer set.
|
|
||||||
*/
|
|
||||||
jerry_value_t scriptProtoCreateValue(
|
|
||||||
const scriptproto_t *proto,
|
|
||||||
const void *value
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unwrap the native C pointer from a JS object.
|
|
||||||
*
|
|
||||||
* @param proto The class prototype.
|
|
||||||
* @param obj The JS object to inspect.
|
|
||||||
* @return Pointer to the wrapped C value, or NULL if not an instance.
|
|
||||||
*/
|
|
||||||
void *scriptProtoGetValue(
|
|
||||||
const scriptproto_t *proto,
|
|
||||||
const jerry_value_t obj
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Define the toString() method on the class prototype.
|
|
||||||
*
|
|
||||||
* @param proto The class prototype.
|
|
||||||
* @param fn C handler called when toString() is invoked on an instance.
|
|
||||||
*/
|
|
||||||
void scriptProtoDefineToString(
|
|
||||||
scriptproto_t *proto,
|
|
||||||
jerry_external_handler_t fn
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Release all JerryScript resources held by the prototype.
|
|
||||||
*
|
|
||||||
* @param proto The class prototype to dispose.
|
|
||||||
*/
|
|
||||||
void scriptProtoDispose(scriptproto_t *proto);
|
|
||||||
@@ -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 "dusk.h"
|
|
||||||
|
|
||||||
#define SCRIPT_VALUE_TYPE_NIL 0
|
|
||||||
#define SCRIPT_VALUE_TYPE_INT 1
|
|
||||||
#define SCRIPT_VALUE_TYPE_FLOAT 2
|
|
||||||
#define SCRIPT_VALUE_TYPE_STRING 3
|
|
||||||
#define SCRIPT_VALUE_TYPE_BOOL 4
|
|
||||||
#define SCRIPT_VALUE_TYPE_USERDATA 5
|
|
||||||
|
|
||||||
typedef struct scriptvalue_s {
|
|
||||||
uint8_t type;
|
|
||||||
|
|
||||||
union {
|
|
||||||
int32_t intValue;
|
|
||||||
float_t floatValue;
|
|
||||||
char_t *strValue;
|
|
||||||
bool_t boolValue;
|
|
||||||
} value;
|
|
||||||
} scriptvalue_t;
|
|
||||||
+7
-45
@@ -7,7 +7,6 @@
|
|||||||
|
|
||||||
#include "uielement.h"
|
#include "uielement.h"
|
||||||
#include "assert/assert.h"
|
#include "assert/assert.h"
|
||||||
#include "script/scriptmanager.h"
|
|
||||||
#include "console/console.h"
|
#include "console/console.h"
|
||||||
#include "ui/uifps.h"
|
#include "ui/uifps.h"
|
||||||
#include "engine/engine.h"
|
#include "engine/engine.h"
|
||||||
@@ -16,16 +15,16 @@
|
|||||||
|
|
||||||
uielement_t UI_ELEMENTS[] = {
|
uielement_t UI_ELEMENTS[] = {
|
||||||
// Fullbox under: above scene, below system UI.
|
// Fullbox under: above scene, below system UI.
|
||||||
{ .type = UI_ELEMENT_TYPE_NATIVE, .native = { .draw = uiFullboxUnderDraw } },
|
{ .type = UI_ELEMENT_TYPE_NATIVE, .draw = uiFullboxUnderDraw },
|
||||||
|
|
||||||
{ .type = UI_ELEMENT_TYPE_SCRIPT, .script = { .script = "ui/test.js" } },
|
// { .type = UI_ELEMENT_TYPE_SCRIPT, .script = { .script = "ui/test.js" } },
|
||||||
|
|
||||||
{ .type = UI_ELEMENT_TYPE_NATIVE, .native = { .draw = consoleDraw } },
|
{ .type = UI_ELEMENT_TYPE_NATIVE, .draw = consoleDraw },
|
||||||
{ .type = UI_ELEMENT_TYPE_NATIVE, .native = { .draw = uiFPSDraw } },
|
{ .type = UI_ELEMENT_TYPE_NATIVE, .draw = uiFPSDraw },
|
||||||
{ .type = UI_ELEMENT_TYPE_NATIVE, .native = { .draw = uiTextboxDraw } },
|
{ .type = UI_ELEMENT_TYPE_NATIVE, .draw = uiTextboxDraw },
|
||||||
|
|
||||||
// Fullbox over: above absolutely everything.
|
// Fullbox over: above absolutely everything.
|
||||||
{ .type = UI_ELEMENT_TYPE_NATIVE, .native = { .draw = uiFullboxOverDraw } },
|
{ .type = UI_ELEMENT_TYPE_NATIVE, .draw = uiFullboxOverDraw },
|
||||||
|
|
||||||
{ .type = UI_ELEMENT_TYPE_NULL },
|
{ .type = UI_ELEMENT_TYPE_NULL },
|
||||||
};
|
};
|
||||||
@@ -33,52 +32,15 @@ uielement_t UI_ELEMENTS[] = {
|
|||||||
errorret_t uiElementInit(uielement_t *element) {
|
errorret_t uiElementInit(uielement_t *element) {
|
||||||
assertNotNull(element, "element must not be NULL");
|
assertNotNull(element, "element must not be NULL");
|
||||||
|
|
||||||
if(element->type == UI_ELEMENT_TYPE_SCRIPT) {
|
|
||||||
errorChain(scriptInclude(element->script.script, &element->script.module));
|
|
||||||
}
|
|
||||||
|
|
||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
errorret_t uiElementDraw(const uielement_t *element) {
|
errorret_t uiElementDraw(const uielement_t *element) {
|
||||||
switch(element->type) {
|
switch(element->type) {
|
||||||
case UI_ELEMENT_TYPE_NATIVE:
|
case UI_ELEMENT_TYPE_NATIVE:
|
||||||
errorChain(element->native.draw());
|
errorChain(element->draw());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case UI_ELEMENT_TYPE_SCRIPT: {
|
|
||||||
jerry_value_t renderKey = jerry_string_sz("render");
|
|
||||||
jerry_value_t renderFn = jerry_object_get(
|
|
||||||
element->script.module, renderKey
|
|
||||||
);
|
|
||||||
jerry_value_free(renderKey);
|
|
||||||
|
|
||||||
if(!jerry_value_is_function(renderFn)) {
|
|
||||||
jerry_value_free(renderFn);
|
|
||||||
errorThrow("UI script module has no render function");
|
|
||||||
}
|
|
||||||
|
|
||||||
jerry_value_t ret = jerry_call(renderFn, element->script.module, NULL, 0);
|
|
||||||
jerry_value_free(renderFn);
|
|
||||||
|
|
||||||
if(jerry_value_is_exception(ret)) {
|
|
||||||
jerry_value_t errVal = jerry_exception_value(ret, false);
|
|
||||||
jerry_value_t errStr = jerry_value_to_string(errVal);
|
|
||||||
char_t buf[256];
|
|
||||||
jerry_size_t len = jerry_string_to_buffer(
|
|
||||||
errStr, JERRY_ENCODING_UTF8, (jerry_char_t *)buf, sizeof(buf) - 1
|
|
||||||
);
|
|
||||||
buf[len] = '\0';
|
|
||||||
jerry_value_free(errStr);
|
|
||||||
jerry_value_free(errVal);
|
|
||||||
jerry_value_free(ret);
|
|
||||||
errorThrow("UI script render error: %s", buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
jerry_value_free(ret);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assertUnreachable("Invalid UI element type");
|
assertUnreachable("Invalid UI element type");
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-12
@@ -11,23 +11,12 @@
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
UI_ELEMENT_TYPE_NULL,
|
UI_ELEMENT_TYPE_NULL,
|
||||||
UI_ELEMENT_TYPE_NATIVE,
|
UI_ELEMENT_TYPE_NATIVE,
|
||||||
UI_ELEMENT_TYPE_SCRIPT,
|
|
||||||
UI_ELEMENT_TYPE_COUNT
|
UI_ELEMENT_TYPE_COUNT
|
||||||
} uielementtype_t;
|
} uielementtype_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uielementtype_t type;
|
uielementtype_t type;
|
||||||
|
errorret_t (*draw)();
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
errorret_t (*draw)();
|
|
||||||
} native;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
const char_t *script;
|
|
||||||
jerry_value_t module;
|
|
||||||
} script;
|
|
||||||
};
|
|
||||||
} uielement_t;
|
} uielement_t;
|
||||||
|
|
||||||
extern uielement_t UI_ELEMENTS[];
|
extern uielement_t UI_ELEMENTS[];
|
||||||
|
|||||||
Reference in New Issue
Block a user