Build script on PSP, Dolphin and Engine.

This commit is contained in:
2026-04-28 21:34:09 -05:00
parent 194255bffe
commit bd248ee91c
12 changed files with 367 additions and 1883 deletions
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -4,7 +4,7 @@
# https://opensource.org/licenses/MIT
# Setup
cmake_minimum_required(VERSION 4.0)
cmake_minimum_required(VERSION 3.13)
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
+1
View File
@@ -22,6 +22,7 @@ var Cube = {
var dz = inputAxis(INPUT_ACTION_UP, INPUT_ACTION_DOWN);
this._e.position.x += dx * speed * TIME.delta;
this._e.position.z += dz * speed * TIME.delta;
this._e.material.setColor(colorRainbow());
},
dispose: function() {
+2
View File
@@ -1,5 +1,7 @@
var Cube = include('entities/cube.js');
print('Screen.aspect in JavaScript: ' + Screen.aspect);
var cam;
var cube;
+7 -3
View File
@@ -14,8 +14,8 @@ set(ENABLE_LTO OFF CACHE BOOL "" FORCE)
include(FetchContent)
FetchContent_Declare(
jerryscript
GIT_REPOSITORY https://github.com/jerryscript-project/jerryscript.git
GIT_TAG v3.0.0
GIT_REPOSITORY https://git.wish.moe/YourWishes/jerryscript
GIT_TAG float32-fix
)
FetchContent_MakeAvailable(jerryscript)
@@ -64,6 +64,10 @@ foreach(tgt IN ITEMS
)
if(TARGET ${tgt})
set_property(TARGET ${tgt} PROPERTY INTERPROCEDURAL_OPTIMIZATION OFF)
target_compile_definitions(${JERRY_CORE_TARGET} PRIVATE
JERRY_NUMBER_TYPE_FLOAT64=0
JERRY_BUILTIN_DATE=0
)
endif()
endforeach()
@@ -83,7 +87,7 @@ target_include_directories(${JERRY_PORT_TARGET} INTERFACE
# Suppress JerryScript-only warning
if(CMAKE_C_COMPILER_ID MATCHES "GNU|Clang")
target_compile_options(${JERRY_CORE_TARGET} PRIVATE
-Wno-error=unterminated-string-initialization
-Wno-error
)
endif()
+1
View File
@@ -21,6 +21,7 @@
#include <cglm/cglm.h>
#include <cglm/types.h>
#include <cglm/vec2.h>
#include <jerryscript.h>
#include "duskplatform.h"
-2
View File
@@ -24,8 +24,6 @@
#include "system/system.h"
#include "console/console.h"
#include "jerryscript.h"
double jerry_port_current_time(void) {
dusktimeepoch_t epoch = timeGetEpoch();
return epoch.time * 1000.0;
+119 -120
View File
@@ -10,146 +10,145 @@
#include "display/color.h"
#include "time/time.h"
// ---------------------------------------------------------------------------
// Native info / prototype
// ---------------------------------------------------------------------------
// Define the prototype.
moduleBaseProtoDefine(MODULE_COLOR);
static void freeColorNative(void *ptr, jerry_object_native_info_t *info) {
(void)info;
free(ptr);
}
static const jerry_object_native_info_t COLOR_NATIVE_INFO = {
.free_cb = freeColorNative,
.number_of_references = 0,
.offset_of_references = 0
};
static jerry_value_t s_colorProto = 0;
// ---------------------------------------------------------------------------
// Property getters / setters
// ---------------------------------------------------------------------------
JS_FUNC(moduleColorGetR) {
color_t *color = (color_t *)jerry_object_get_native_ptr(
call_info_p->this_value, &COLOR_NATIVE_INFO
// Getters
moduleBaseFunction(moduleColorGetR) {
color_t *color = (color_t*)moduleBaseGetProto(
callInfo->this_value, &MODULE_COLOR_INFO
);
return color ? jerry_number(color->r) : jerry_undefined();
if(!color) return jerry_undefined();
return jerry_number(color->r);
}
JS_FUNC(moduleColorSetR) {
color_t *color = (color_t *)jerry_object_get_native_ptr(
call_info_p->this_value, &COLOR_NATIVE_INFO
moduleBaseFunction(moduleColorGetG) {
color_t *color = (color_t*)moduleBaseGetProto(
callInfo->this_value, &MODULE_COLOR_INFO
);
if(color && args_count > 0) {
color->r = (colorchannel8_t)jerry_value_as_number(args_p[0]);
if(!color) return jerry_undefined();
return jerry_number(color->g);
}
moduleBaseFunction(moduleColorGetB) {
color_t *color = (color_t*)moduleBaseGetProto(
callInfo->this_value, &MODULE_COLOR_INFO
);
if(!color) return jerry_undefined();
return jerry_number(color->b);
}
moduleBaseFunction(moduleColorGetA) {
color_t *color = (color_t*)moduleBaseGetProto(
callInfo->this_value, &MODULE_COLOR_INFO
);
if(!color) return jerry_undefined();
return jerry_number(color->a);
}
// Setters
moduleBaseFunction(moduleColorSetR) {
color_t *color = (color_t*)moduleBaseGetProto(
callInfo->this_value, &MODULE_COLOR_INFO
);
if(color && argc > 0) {
color->r = (colorchannel8_t)jerry_value_as_number(args[0]);
}
return jerry_undefined();
}
JS_FUNC(moduleColorGetG) {
color_t *color = (color_t *)jerry_object_get_native_ptr(
call_info_p->this_value, &COLOR_NATIVE_INFO
moduleBaseFunction(moduleColorSetG) {
color_t *color = (color_t*)moduleBaseGetProto(
callInfo->this_value, &MODULE_COLOR_INFO
);
return color ? jerry_number(color->g) : jerry_undefined();
}
JS_FUNC(moduleColorSetG) {
color_t *color = (color_t *)jerry_object_get_native_ptr(
call_info_p->this_value, &COLOR_NATIVE_INFO
);
if(color && args_count > 0) {
color->g = (colorchannel8_t)jerry_value_as_number(args_p[0]);
if(color && argc > 0) {
color->g = (colorchannel8_t)jerry_value_as_number(args[0]);
}
return jerry_undefined();
}
JS_FUNC(moduleColorGetB) {
color_t *color = (color_t *)jerry_object_get_native_ptr(
call_info_p->this_value, &COLOR_NATIVE_INFO
moduleBaseFunction(moduleColorSetB) {
color_t *color = (color_t*)moduleBaseGetProto(
callInfo->this_value, &MODULE_COLOR_INFO
);
return color ? jerry_number(color->b) : jerry_undefined();
}
JS_FUNC(moduleColorSetB) {
color_t *color = (color_t *)jerry_object_get_native_ptr(
call_info_p->this_value, &COLOR_NATIVE_INFO
);
if(color && args_count > 0) {
color->b = (colorchannel8_t)jerry_value_as_number(args_p[0]);
if(color && argc > 0) {
color->b = (colorchannel8_t)jerry_value_as_number(args[0]);
}
return jerry_undefined();
}
JS_FUNC(moduleColorGetA) {
color_t *color = (color_t *)jerry_object_get_native_ptr(
call_info_p->this_value, &COLOR_NATIVE_INFO
moduleBaseFunction(moduleColorSetA) {
color_t *color = (color_t*)moduleBaseGetProto(
callInfo->this_value, &MODULE_COLOR_INFO
);
return color ? jerry_number(color->a) : jerry_undefined();
}
JS_FUNC(moduleColorSetA) {
color_t *color = (color_t *)jerry_object_get_native_ptr(
call_info_p->this_value, &COLOR_NATIVE_INFO
);
if(color && args_count > 0) {
color->a = (colorchannel8_t)jerry_value_as_number(args_p[0]);
if(color && argc > 0) {
color->a = (colorchannel8_t)jerry_value_as_number(args[0]);
}
return jerry_undefined();
}
// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------
/**
* Creates a new JS color object wrapping a heap-allocated color_t.
*
* @param color Value to copy into the new object.
* @return Owned jerry_value_t with COLOR_NATIVE_INFO and prototype set.
*/
static inline jerry_value_t moduleColorMakeObject(color_t color) {
color_t *ptr = (color_t *)malloc(sizeof(color_t));
*ptr = color;
jerry_value_t obj = jerry_object();
jerry_object_set_native_ptr(obj, &COLOR_NATIVE_INFO, ptr);
if(s_colorProto != 0) jerry_object_set_proto(obj, s_colorProto);
return obj;
// Constructor
static jerry_value_t moduleColorMakeObject(color_t color) {
return moduleBaseCreateProto(
&color,
sizeof(color_t),
&MODULE_COLOR_INFO, MODULE_COLOR_PROTOTYPE
);
}
/**
* Returns the native color_t pointer stored in a JS value, or NULL.
*
* @param val JS value to inspect.
* @return Pointer to the color_t, or NULL if not a color object.
*/
static inline color_t *moduleColorGetNative(jerry_value_t val) {
return (color_t *)jerry_object_get_native_ptr(val, &COLOR_NATIVE_INFO);
}
// ---------------------------------------------------------------------------
// Constructors
// ---------------------------------------------------------------------------
JS_FUNC(moduleColorCreate) {
JS_REQUIRE_ARGS(4);
JS_REQUIRE_NUMBER(0);
JS_REQUIRE_NUMBER(1);
JS_REQUIRE_NUMBER(2);
JS_REQUIRE_NUMBER(3);
moduleBaseFunction(moduleColorCreate) {
color_t c;
c.r = (colorchannel8_t)jerry_value_as_number(args_p[0]);
c.g = (colorchannel8_t)jerry_value_as_number(args_p[1]);
c.b = (colorchannel8_t)jerry_value_as_number(args_p[2]);
c.a = (colorchannel8_t)jerry_value_as_number(args_p[3]);
if(argc > 0) {
if(!jerry_value_is_number(args[0])) {
return moduleBaseThrow("Expected number argument for r");
}
c.r = (colorchannel8_t)jerry_value_as_number(args[0]);
} else {
c.r = 255;
}
if(argc > 1) {
if(!jerry_value_is_number(args[1])) {
return moduleBaseThrow("Expected number argument for g");
}
c.g = (colorchannel8_t)jerry_value_as_number(args[1]);
} else {
c.g = 255;
}
if(argc > 2) {
if(!jerry_value_is_number(args[2])) {
return moduleBaseThrow("Expected number argument for b");
}
c.b = (colorchannel8_t)jerry_value_as_number(args[2]);
} else {
c.b = 255;
}
if(argc > 3) {
if(!jerry_value_is_number(args[3])) {
return moduleBaseThrow("Expected number argument for a");
}
c.a = (colorchannel8_t)jerry_value_as_number(args[3]);
} else {
c.a = 255;
}
return moduleColorMakeObject(c);
}
JS_FUNC(moduleColorRainbow) {
float_t t = TIME.time * 4.0f;
moduleBaseFunction(moduleColorRainbow) {
float_t t;
if(args_count >= 1 && jerry_value_is_number(args_p[0])) {
t += (float_t)jerry_value_as_number(args_p[0]);
if(argc >= 1 && jerry_value_is_number(args[0])) {
t = (float_t)jerry_value_as_number(args[0]);
} else {
t = TIME.time * 4.0f;
}
if(args_count >= 2 && jerry_value_is_number(args_p[1])) {
t *= (float_t)jerry_value_as_number(args_p[1]);
if(argc >= 2 && jerry_value_is_number(args[1])) {
t *= (float_t)jerry_value_as_number(args[1]);
}
color_t c;
@@ -160,20 +159,20 @@ JS_FUNC(moduleColorRainbow) {
return moduleColorMakeObject(c);
}
// ---------------------------------------------------------------------------
// Module init
// ---------------------------------------------------------------------------
// Root Module
static void moduleColor(void) {
s_colorProto = jerry_object();
MODULE_COLOR_PROTOTYPE = jerry_object();
jsDefineProperty(s_colorProto, "r", moduleColorGetR, moduleColorSetR);
jsDefineProperty(s_colorProto, "g", moduleColorGetG, moduleColorSetG);
jsDefineProperty(s_colorProto, "b", moduleColorGetB, moduleColorSetB);
jsDefineProperty(s_colorProto, "a", moduleColorGetA, moduleColorSetA);
#define X(x, g, s) \
moduleBaseProtoDefineProp(MODULE_COLOR_PROTOTYPE, #x, g, s);
X(r, moduleColorGetR, moduleColorSetR);
X(g, moduleColorGetG, moduleColorSetG);
X(b, moduleColorGetB, moduleColorSetB);
X(a, moduleColorGetA, moduleColorSetA);
#undef X
jsRegister("color", moduleColorCreate);
jsRegister("colorRainbow", moduleColorRainbow);
moduleBaseFunctionRegister("color", moduleColorCreate);
moduleBaseFunctionRegister("colorRainbow", moduleColorRainbow);
jsEvalStr(COLOR_SCRIPT);
moduleBaseEval(COLOR_SCRIPT);
}
+50 -34
View File
@@ -6,53 +6,69 @@
*/
#pragma once
#include "script/module/modulebase.h"
#include "script/module/display/modulecolor.h"
#include "display/screen/screen.h"
#include "display/color.h"
JS_FUNC(moduleScreenGetWidth) {
// Define the prototype.
moduleBaseProtoDefine(MODULE_SCREEN);
// Getters
moduleBaseFunction(moduleScreenGetWidth) {
return jerry_number(SCREEN.width);
}
JS_FUNC(moduleScreenGetHeight) {
moduleBaseFunction(moduleScreenGetHeight) {
return jerry_number(SCREEN.height);
}
JS_FUNC(moduleScreenSetBackground) {
if(args_count < 1 || !jerry_value_is_object(args_p[0])) {
return JS_THROW("Screen background color must be a color object");
moduleBaseFunction(moduleScreenGetAspect) {
printf("Screen.aspect in C: %f\n", SCREEN.aspect);
return jerry_number(SCREEN.aspect);
}
moduleBaseFunction(moduleScreenGetBackground) {
return moduleColorMakeObject(SCREEN.background);
}
// Setters
moduleBaseFunction(moduleScreenSetBackground) {
if(argc < 1 || !jerry_value_is_object(args[0])) {
return moduleBaseThrow("Screen background color must be a color object");
}
jerry_value_t keyR = jerry_string_sz("r");
jerry_value_t keyG = jerry_string_sz("g");
jerry_value_t keyB = jerry_string_sz("b");
jerry_value_t keyA = jerry_string_sz("a");
jerry_value_t valR = jerry_object_get(args_p[0], keyR);
jerry_value_t valG = jerry_object_get(args_p[0], keyG);
jerry_value_t valB = jerry_object_get(args_p[0], keyB);
jerry_value_t valA = jerry_object_get(args_p[0], keyA);
jerry_value_free(keyR);
jerry_value_free(keyG);
jerry_value_free(keyB);
jerry_value_free(keyA);
SCREEN.background.r = (colorchannel8_t)jerry_value_as_number(valR);
SCREEN.background.g = (colorchannel8_t)jerry_value_as_number(valG);
SCREEN.background.b = (colorchannel8_t)jerry_value_as_number(valB);
SCREEN.background.a = (colorchannel8_t)jerry_value_as_number(valA);
jerry_value_free(valR);
jerry_value_free(valG);
jerry_value_free(valB);
jerry_value_free(valA);
// Get color pointer from the object.
color_t *color = (color_t*)moduleBaseGetProto(args[0], &MODULE_COLOR_INFO);
if(!color) {
return moduleBaseThrow("Background must be a valid color object");
}
return jerry_undefined();
}
static void moduleScreen(void) {
jsRegister("screenGetWidth", moduleScreenGetWidth);
jsRegister("screenGetHeight", moduleScreenGetHeight);
jsRegister("screenSetBackground", moduleScreenSetBackground);
jerry_value_t proto = jerry_object();
MODULE_SCREEN_PROTOTYPE = proto;
#define X(x, g, s) \
moduleBaseProtoDefineProp(MODULE_SCREEN_PROTOTYPE, #x, g, s);
X(width, moduleScreenGetWidth, NULL)
X(height, moduleScreenGetHeight, NULL)
X(aspect, moduleScreenGetAspect, NULL)
X(background, moduleScreenGetBackground, moduleScreenSetBackground)
#undef X
jsDefineMethod(proto, "getWidth", moduleScreenGetWidth);
jsDefineMethod(proto, "getHeight", moduleScreenGetHeight);
jsDefineMethod(proto, "getAspect", moduleScreenGetAspect);
jsDefineMethod(proto, "getBackground", moduleScreenGetBackground);
jsDefineMethod(proto, "setBackground", moduleScreenSetBackground);
// Create global Scene object
jerry_value_t global = jerry_current_realm();
jerry_value_t key = jerry_string_sz("Screen");
jerry_object_set(global, key, proto);
jerry_value_free(key);
jerry_value_free(global);
}
+183 -16
View File
@@ -13,29 +13,196 @@
#include <stdlib.h>
/**
* Standard JerryScript external function signature.
* Usage: JS_FUNC(myFunction) { ... }
* 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);
// return (void*)jerry_object_get_native_ptr(callInfo->this_value, 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);
}
#define JS_FUNC(name) \
static jerry_value_t name( \
const jerry_call_info_t *call_info_p, \
const jerry_value_t args_p[], \
const jerry_length_t args_count)
/**
* Return a type-error exception from a module function.
* Usage: return JS_THROW("message");
*/
#define JS_THROW(msg) jerry_throw_sz(JERRY_ERROR_TYPE, (msg))
/**
* Assert minimum argument count; return type error if not met.
*/
#define JS_REQUIRE_ARGS(n) do { \
if((jerry_length_t)(args_count) < (jerry_length_t)(n)) { \
return JS_THROW("Not enough arguments"); \
} \
} while(0)
#define JS_THROW(msg) moduleBaseThrow((msg))
#define JS_REQUIRE_ARGS(n) \
if((args_count) < (n)) { \
return JS_THROW("Expected at least " #n " arguments"); \
}
/**
* Assert an argument is a number; return type error if not.
-1
View File
@@ -8,7 +8,6 @@
#pragma once
#include "error/error.h"
#include "scriptvalue.h"
#include <jerryscript.h>
typedef struct event_s event_t;
+1 -1
View File
@@ -37,5 +37,5 @@ inputbuttondata_t INPUT_BUTTON_DATA[] = {
};
float_t inputGetDeadzoneSDL2(const inputbutton_t button) {
return 0.17f;
return 0.2f;
}