cleanup
This commit is contained in:
@@ -275,16 +275,10 @@ static const JSCFunctionListEntry js_SDL_Camera_funcs[] =
|
|||||||
MIST_FUNC_DEF(camera, get_format, 0),
|
MIST_FUNC_DEF(camera, get_format, 0),
|
||||||
};
|
};
|
||||||
|
|
||||||
JSValue js_camera_use(JSContext *js) {
|
CELL_USE_INIT(
|
||||||
SDL_Init(SDL_INIT_CAMERA);
|
SDL_Init(SDL_INIT_CAMERA);
|
||||||
JSValue mod = JS_NewObject(js);
|
JSValue mod = JS_NewObject(js);
|
||||||
JS_SetPropertyFunctionList(js,mod,js_camera_funcs,countof(js_camera_funcs));
|
JS_SetPropertyFunctionList(js,mod,js_camera_funcs,countof(js_camera_funcs));
|
||||||
QJSCLASSPREP_FUNCS(SDL_Camera)
|
QJSCLASSPREP_FUNCS(SDL_Camera)
|
||||||
return mod;
|
return mod;
|
||||||
}
|
)
|
||||||
|
|
||||||
JSValue js_sdl_use(JSContext *js) {
|
|
||||||
JSValue mod = JS_NewObject(js);
|
|
||||||
JS_SetPropertyStr(js, mod, "camera", js_camera_use(js));
|
|
||||||
return mod;
|
|
||||||
}
|
|
||||||
@@ -105,8 +105,4 @@ static const JSCFunctionListEntry js_video_funcs[] = {
|
|||||||
MIST_FUNC_DEF(os, make_video, 1),
|
MIST_FUNC_DEF(os, make_video, 1),
|
||||||
};
|
};
|
||||||
|
|
||||||
JSValue js_video_use(JSContext *js) {
|
CELL_USE_FUNCS(js_video_funcs)
|
||||||
JSValue mod = JS_NewObject(js);
|
|
||||||
JS_SetPropertyFunctionList(js,mod,js_video_funcs,countof(js_video_funcs));
|
|
||||||
return mod;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ extern void *get_gpu_buffer(JSContext *js, JSValue argv, size_t *stride, size_t
|
|||||||
|
|
||||||
// GEOMETRY FUNCTIONS
|
// GEOMETRY FUNCTIONS
|
||||||
|
|
||||||
|
|
||||||
JSC_CCALL(geometry_rect_intersection,
|
JSC_CCALL(geometry_rect_intersection,
|
||||||
rect a = js2rect(js,argv[0]);
|
rect a = js2rect(js,argv[0]);
|
||||||
rect b = js2rect(js,argv[1]);
|
rect b = js2rect(js,argv[1]);
|
||||||
@@ -1185,8 +1186,4 @@ static const JSCFunctionListEntry js_geometry_funcs[] = {
|
|||||||
MIST_FUNC_DEF(geometry, make_rect_quad, 3),
|
MIST_FUNC_DEF(geometry, make_rect_quad, 3),
|
||||||
};
|
};
|
||||||
|
|
||||||
JSValue js_geometry_use(JSContext *js) {
|
CELL_USE_FUNCS(js_geometry_funcs)
|
||||||
JSValue mod = JS_NewObject(js);
|
|
||||||
JS_SetPropertyFunctionList(js,mod,js_geometry_funcs,countof(js_geometry_funcs));
|
|
||||||
return mod;
|
|
||||||
}
|
|
||||||
@@ -280,8 +280,4 @@ const JSCFunctionListEntry js_graphics_funcs[] = {
|
|||||||
MIST_FUNC_DEF(graphics, hsl_to_rgb, 3),
|
MIST_FUNC_DEF(graphics, hsl_to_rgb, 3),
|
||||||
};
|
};
|
||||||
|
|
||||||
JSValue js_graphics_use(JSContext *js) {
|
CELL_USE_FUNCS(js_graphics_funcs)
|
||||||
JSValue mod = JS_NewObject(js);
|
|
||||||
JS_SetPropertyFunctionList(js,mod,js_graphics_funcs,countof(js_graphics_funcs));
|
|
||||||
return mod;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "quickjs.h"
|
#include "cell.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
@@ -188,8 +188,7 @@ static const JSCFunctionListEntry js_layout_funcs[] = {
|
|||||||
JS_CFUNC_DEF("make_context", 0, js_layout_context_new)
|
JS_CFUNC_DEF("make_context", 0, js_layout_context_new)
|
||||||
};
|
};
|
||||||
|
|
||||||
JSValue js_layout_use(JSContext *js)
|
CELL_USE_INIT(
|
||||||
{
|
|
||||||
JS_NewClassID(&js_layout_class_id);
|
JS_NewClassID(&js_layout_class_id);
|
||||||
JS_NewClass(JS_GetRuntime(js), js_layout_class_id, &js_layout_class);
|
JS_NewClass(JS_GetRuntime(js), js_layout_class_id, &js_layout_class);
|
||||||
|
|
||||||
@@ -229,4 +228,4 @@ JSValue js_layout_use(JSContext *js)
|
|||||||
JS_SetPropertyStr(js, export, "contain", contain);
|
JS_SetPropertyStr(js, export, "contain", contain);
|
||||||
|
|
||||||
return export;
|
return export;
|
||||||
}
|
)
|
||||||
@@ -505,8 +505,4 @@ static const JSCFunctionListEntry js_math_funcs[] = {
|
|||||||
MIST_FUNC_DEF(math, from_to, 5),
|
MIST_FUNC_DEF(math, from_to, 5),
|
||||||
};
|
};
|
||||||
|
|
||||||
JSValue js_math_use(JSContext *js) {
|
CELL_USE_FUNCS(js_math_funcs)
|
||||||
JSValue mod = JS_NewObject(js);
|
|
||||||
JS_SetPropertyFunctionList(js,mod,js_math_funcs,countof(js_math_funcs));
|
|
||||||
return mod;
|
|
||||||
}
|
|
||||||
@@ -31,7 +31,6 @@ SDL_Window *js2SDL_Window(JSContext *js, JSValue v);
|
|||||||
JSValue SDL_Window2js(JSContext *js, SDL_Window *w);
|
JSValue SDL_Window2js(JSContext *js, SDL_Window *w);
|
||||||
void *get_gpu_buffer(JSContext *js, JSValue argv, size_t *stride, size_t *size);
|
void *get_gpu_buffer(JSContext *js, JSValue argv, size_t *stride, size_t *size);
|
||||||
double js_getnum_str(JSContext *js, JSValue v, const char *str);
|
double js_getnum_str(JSContext *js, JSValue v, const char *str);
|
||||||
sprite *js2sprite(JSContext *js, JSValue v);
|
|
||||||
HMM_Vec3 js2vec3(JSContext *js, JSValue v);
|
HMM_Vec3 js2vec3(JSContext *js, JSValue v);
|
||||||
JSValue vec32js(JSContext *js, HMM_Vec3 v);
|
JSValue vec32js(JSContext *js, HMM_Vec3 v);
|
||||||
HMM_Vec4 js2vec4(JSContext *js, JSValue v);
|
HMM_Vec4 js2vec4(JSContext *js, JSValue v);
|
||||||
|
|||||||
@@ -122,12 +122,11 @@ static const JSCFunctionListEntry js_dmon_funcs[] = {
|
|||||||
JS_CFUNC_DEF("poll", 1, js_dmon_poll)
|
JS_CFUNC_DEF("poll", 1, js_dmon_poll)
|
||||||
};
|
};
|
||||||
|
|
||||||
JSValue js_dmon_use(JSContext *js)
|
CELL_USE_INIT(
|
||||||
{
|
|
||||||
JSValue export = JS_NewObject(js);
|
JSValue export = JS_NewObject(js);
|
||||||
JS_SetPropertyFunctionList(js, export, js_dmon_funcs, sizeof(js_dmon_funcs)/sizeof(JSCFunctionListEntry));
|
JS_SetPropertyFunctionList(js, export, js_dmon_funcs, sizeof(js_dmon_funcs)/sizeof(JSCFunctionListEntry));
|
||||||
|
|
||||||
dmon_init();
|
dmon_init();
|
||||||
|
|
||||||
return export;
|
return export;
|
||||||
}
|
)
|
||||||
|
|||||||
@@ -505,8 +505,7 @@ static const JSCFunctionListEntry js_mod_funcs[] = {
|
|||||||
JS_CFUNC_DEF("create", 1, js_mod_create)
|
JS_CFUNC_DEF("create", 1, js_mod_create)
|
||||||
};
|
};
|
||||||
|
|
||||||
JSValue js_renderer_use(JSContext *ctx) {
|
CELL_USE_INIT(
|
||||||
// Create an object that will hold all the "renderer" methods
|
|
||||||
JSValue obj = JS_NewObject(ctx);
|
JSValue obj = JS_NewObject(ctx);
|
||||||
|
|
||||||
// Add all the above C functions as properties of that object
|
// Add all the above C functions as properties of that object
|
||||||
@@ -514,4 +513,4 @@ JSValue js_renderer_use(JSContext *ctx) {
|
|||||||
js_renderer_funcs,
|
js_renderer_funcs,
|
||||||
sizeof(js_renderer_funcs)/sizeof(JSCFunctionListEntry));
|
sizeof(js_renderer_funcs)/sizeof(JSCFunctionListEntry));
|
||||||
return obj;
|
return obj;
|
||||||
}
|
)
|
||||||
|
|||||||
@@ -4,11 +4,6 @@
|
|||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
#include "cell.h"
|
#include "cell.h"
|
||||||
|
|
||||||
JSValue js_input_use(JSContext *ctx);
|
|
||||||
JSValue js_camera_use(JSContext *ctx);
|
|
||||||
JSValue js_sdl_audio_use(JSContext *ctx);
|
|
||||||
JSValue js_sdl_use(JSContext *js);
|
|
||||||
|
|
||||||
SDL_PixelFormat str2pixelformat(const char *str);
|
SDL_PixelFormat str2pixelformat(const char *str);
|
||||||
SDL_PixelFormat js2pixelformat(JSContext *js, JSValue v);
|
SDL_PixelFormat js2pixelformat(JSContext *js, JSValue v);
|
||||||
JSValue pixelformat2js(JSContext *js, SDL_PixelFormat format);
|
JSValue pixelformat2js(JSContext *js, SDL_PixelFormat format);
|
||||||
@@ -31,4 +26,4 @@ typedef struct SDL_Surface SDL_Surface;
|
|||||||
SDL_Surface *js2SDL_Surface(JSContext *js, JSValue v);
|
SDL_Surface *js2SDL_Surface(JSContext *js, JSValue v);
|
||||||
JSValue SDL_Surface2js(JSContext *js, SDL_Surface *s);
|
JSValue SDL_Surface2js(JSContext *js, SDL_Surface *s);
|
||||||
|
|
||||||
#endif /* QJS_SDL_H */
|
#endif
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
#ifndef QJS_SDL_GPU_H
|
|
||||||
#define QJS_SDL_GPU_H
|
|
||||||
|
|
||||||
#include "cell.h"
|
|
||||||
#include "sprite.h"
|
|
||||||
|
|
||||||
// Forward declarations for sprite sorting functions
|
|
||||||
int sort_sprite(const sprite *a, const sprite *b);
|
|
||||||
int sort_sprite_backtofront(const sprite *a, const sprite *b);
|
|
||||||
int sort_sprite_fronttoback(const sprite *a, const sprite *b);
|
|
||||||
int sort_sprite_texture(const sprite *a, const sprite *b);
|
|
||||||
|
|
||||||
JSValue js_sdl_gpu_use(JSContext *js);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
#ifndef QJS_SDL_INPUT_H
|
|
||||||
#define QJS_SDL_INPUT_H
|
|
||||||
|
|
||||||
#include <quickjs.h>
|
|
||||||
|
|
||||||
const char* event_type_to_string(uint32_t event_type);
|
|
||||||
const char* mouse_button_to_string(int mouse);
|
|
||||||
|
|
||||||
// JavaScript module entry point
|
|
||||||
JSValue js_input_use(JSContext *js);
|
|
||||||
|
|
||||||
#endif // QJS_SDL_INPUT_H
|
|
||||||
@@ -4,8 +4,6 @@
|
|||||||
#include "cell.h"
|
#include "cell.h"
|
||||||
#include <SDL3/SDL_surface.h>
|
#include <SDL3/SDL_surface.h>
|
||||||
|
|
||||||
JSValue js_sdl_surface_use(JSContext *js);
|
|
||||||
|
|
||||||
// Functions generated by QJSCLASS macro
|
// Functions generated by QJSCLASS macro
|
||||||
JSValue SDL_Surface2js(JSContext *js, SDL_Surface *s);
|
JSValue SDL_Surface2js(JSContext *js, SDL_Surface *s);
|
||||||
SDL_Surface *js2SDL_Surface(JSContext *js, JSValue val);
|
SDL_Surface *js2SDL_Surface(JSContext *js, JSValue val);
|
||||||
|
|||||||
107
qjs_sprite.c
107
qjs_sprite.c
@@ -1,107 +0,0 @@
|
|||||||
#include "qjs_sprite.h"
|
|
||||||
#include "prosperon.h"
|
|
||||||
#include "qjs_macros.h"
|
|
||||||
|
|
||||||
#include "sprite.h"
|
|
||||||
#include "HandmadeMath.h"
|
|
||||||
|
|
||||||
// Sprite class definitions
|
|
||||||
static JSClassID js_sprite_id;
|
|
||||||
static void js_sprite_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func) {
|
|
||||||
sprite *sp = JS_GetOpaque(val, js_sprite_id);
|
|
||||||
if (!sp) return;
|
|
||||||
JS_MarkValue(rt, sp->image, mark_func);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Class definition for sprite with mark function for GC
|
|
||||||
QJSCLASSMARK(sprite,)
|
|
||||||
|
|
||||||
// SPRITE GETTER/SETTER FUNCTIONS
|
|
||||||
JSC_GETSET(sprite, pos, vec2)
|
|
||||||
JSC_GETSET(sprite, center, vec2)
|
|
||||||
JSC_GETSET(sprite, layer, number)
|
|
||||||
JSC_GETSET(sprite, color, color)
|
|
||||||
JSC_GETSET(sprite, skew, vec2)
|
|
||||||
JSC_GETSET(sprite, scale, vec2)
|
|
||||||
JSC_GETSET(sprite, rotation, number)
|
|
||||||
|
|
||||||
// SPRITE ACTION FUNCTIONS
|
|
||||||
|
|
||||||
JSC_CCALL(sprite_move,
|
|
||||||
sprite *sp = js2sprite(js,self);
|
|
||||||
HMM_Vec2 mv = js2vec2(js,argv[0]);
|
|
||||||
sp->pos.x += mv.x;
|
|
||||||
sp->pos.y += mv.y;
|
|
||||||
)
|
|
||||||
|
|
||||||
JSC_CCALL(sprite_set_affine,
|
|
||||||
sprite *sp = js2sprite(js,self);
|
|
||||||
sprite_apply(sp);
|
|
||||||
)
|
|
||||||
|
|
||||||
JSC_CCALL(sprite_set_image,
|
|
||||||
sprite *sp = js2sprite(js,self);
|
|
||||||
if (!JS_IsNull(sp->image))
|
|
||||||
JS_FreeValue(js,sp->image);
|
|
||||||
sp->image = JS_DupValue(js, argv[0]);
|
|
||||||
)
|
|
||||||
|
|
||||||
static const JSCFunctionListEntry js_sprite_funcs[] = {
|
|
||||||
MIST_FUNC_DEF(sprite, set_affine, 0),
|
|
||||||
MIST_FUNC_DEF(sprite, set_image, 1),
|
|
||||||
MIST_FUNC_DEF(sprite, move, 1),
|
|
||||||
JS_CGETSET_DEF("pos", js_sprite_get_pos, js_sprite_set_pos),
|
|
||||||
JS_CGETSET_DEF("scale", js_sprite_get_scale, js_sprite_set_scale),
|
|
||||||
JS_CGETSET_DEF("skew", js_sprite_get_skew, js_sprite_set_skew),
|
|
||||||
JS_CGETSET_DEF("layer", js_sprite_get_layer, js_sprite_set_layer),
|
|
||||||
JS_CGETSET_DEF("color", js_sprite_get_color, js_sprite_set_color),
|
|
||||||
JS_CGETSET_DEF("center", js_sprite_get_center, js_sprite_set_center),
|
|
||||||
JS_CGETSET_DEF("rotation", js_sprite_get_rotation, js_sprite_set_rotation),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Constructor function for sprite
|
|
||||||
static JSValue js_sprite_constructor(JSContext *js, JSValueConst new_target, int argc, JSValueConst *argv) {
|
|
||||||
sprite *sp = make_sprite();
|
|
||||||
if (!sp) return JS_ThrowOutOfMemory(js);
|
|
||||||
|
|
||||||
// If an options object is provided, initialize the sprite with it
|
|
||||||
if (argc > 0 && JS_IsObject(argv[0])) {
|
|
||||||
JS_GETATOM(js, sp->pos, argv[0], pos, vec2)
|
|
||||||
JS_GETATOM(js, sp->center, argv[0], center, vec2)
|
|
||||||
JS_GETATOM(js, sp->skew, argv[0], skew, vec2)
|
|
||||||
JS_GETATOM(js, sp->scale, argv[0], scale, vec2)
|
|
||||||
JS_GETATOM(js, sp->rotation, argv[0], rotation, number)
|
|
||||||
JS_GETATOM(js, sp->layer, argv[0], layer, number)
|
|
||||||
JS_GETATOM(js, sp->color, argv[0], color, color)
|
|
||||||
|
|
||||||
JSValue image = JS_GetProperty(js, argv[0], JS_NewAtom(js, "image"));
|
|
||||||
if (!JS_IsNull(image)) {
|
|
||||||
sp->image = image; // Transfer ownership, no need to dup
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Default values if not provided
|
|
||||||
if (sp->scale.x == 0 && sp->scale.y == 0) {
|
|
||||||
sp->scale.x = 1;
|
|
||||||
sp->scale.y = 1;
|
|
||||||
}
|
|
||||||
if (sp->color.w == 0) sp->color.w = 1; // Default alpha to 1
|
|
||||||
|
|
||||||
sprite_apply(sp);
|
|
||||||
return sprite2js(js, sp);
|
|
||||||
}
|
|
||||||
|
|
||||||
JSValue js_sprite_use(JSContext *js) {
|
|
||||||
// Register the sprite class
|
|
||||||
QJSCLASSPREP_FUNCS(sprite);
|
|
||||||
|
|
||||||
// Create the constructor function
|
|
||||||
JSValue ctor = JS_NewCFunction2(js, js_sprite_constructor, "sprite", 1, JS_CFUNC_constructor, 0);
|
|
||||||
|
|
||||||
// Set the prototype on the constructor
|
|
||||||
JSValue proto = JS_GetClassProto(js, js_sprite_id);
|
|
||||||
JS_SetConstructor(js, ctor, proto);
|
|
||||||
JS_FreeValue(js, proto);
|
|
||||||
|
|
||||||
return ctor;
|
|
||||||
}
|
|
||||||
12
qjs_sprite.h
12
qjs_sprite.h
@@ -1,12 +0,0 @@
|
|||||||
#ifndef QJS_SPRITE_H
|
|
||||||
#define QJS_SPRITE_H
|
|
||||||
|
|
||||||
#include "cell.h"
|
|
||||||
|
|
||||||
#include "sprite.h"
|
|
||||||
|
|
||||||
JSValue js_sprite_use(JSContext *ctx);
|
|
||||||
|
|
||||||
sprite *js2sprite(JSContext *js, JSValue v);
|
|
||||||
|
|
||||||
#endif /* QJS_SPRITE_H */
|
|
||||||
245
qjs_transform.c
245
qjs_transform.c
@@ -1,245 +0,0 @@
|
|||||||
#include "cell.h"
|
|
||||||
#include "prosperon.h"
|
|
||||||
#include "qjs_macros.h"
|
|
||||||
#include "stb_ds.h"
|
|
||||||
|
|
||||||
#include "transform.h"
|
|
||||||
#include "HandmadeMath.h"
|
|
||||||
|
|
||||||
// Transform class definitions
|
|
||||||
JSClassID js_transform_id;
|
|
||||||
static void js_transform_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func) {
|
|
||||||
transform *t = JS_GetOpaque(val, js_transform_id);
|
|
||||||
if (!t) return;
|
|
||||||
// Mark the JSValue references stored in your struct
|
|
||||||
JS_MarkValue(rt, t->change_hook, mark_func);
|
|
||||||
JS_MarkValue(rt, t->jsparent, mark_func);
|
|
||||||
// Mark the array elements
|
|
||||||
for (int i = 0; i < arrlen(t->jschildren); i++)
|
|
||||||
JS_MarkValue(rt, t->jschildren[i], mark_func);
|
|
||||||
}
|
|
||||||
|
|
||||||
QJSCLASSMARK_EXTERN(transform,)
|
|
||||||
|
|
||||||
// TRANSFORM GETTER/SETTER FUNCTIONS
|
|
||||||
JSC_GETSET_APPLY(transform, pos, vec3)
|
|
||||||
JSC_GETSET_APPLY(transform, scale, vec3)
|
|
||||||
JSC_GETSET_APPLY(transform, rotation, quat)
|
|
||||||
|
|
||||||
static JSValue js_transform_get_change_hook(JSContext *js, JSValueConst self)
|
|
||||||
{
|
|
||||||
transform *t = js2transform(js,self);
|
|
||||||
return JS_DupValue(js,t->change_hook);
|
|
||||||
}
|
|
||||||
|
|
||||||
static JSValue js_transform_set_change_hook(JSContext *js, JSValueConst self, JSValue v)
|
|
||||||
{
|
|
||||||
transform *t = js2transform(js,self);
|
|
||||||
if (!JS_IsNull(v) && !JS_IsFunction(js,v)) return JS_ThrowReferenceError(js, "Hook must be a function.");
|
|
||||||
JS_FreeValue(js,t->change_hook);
|
|
||||||
t->change_hook = JS_DupValue(js,v);
|
|
||||||
return JS_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static JSValue js_transform_get_parent(JSContext *js, JSValueConst self)
|
|
||||||
{
|
|
||||||
transform *t = js2transform(js,self);
|
|
||||||
if (t->parent) return JS_DupValue(js,t->jsparent);
|
|
||||||
return JS_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static JSValue js_transform_set_parent(JSContext *js, JSValueConst self, JSValue v)
|
|
||||||
{
|
|
||||||
transform *p = js2transform(js,v);
|
|
||||||
if (!JS_IsNull(v) && !p)
|
|
||||||
return JS_ThrowReferenceError(js,"Parent must be another transform.");
|
|
||||||
|
|
||||||
transform *t = js2transform(js,self);
|
|
||||||
|
|
||||||
if (t == p)
|
|
||||||
return JS_ThrowReferenceError(js, "A transform cannot be its own parent.");
|
|
||||||
|
|
||||||
if (t->parent) {
|
|
||||||
transform *cur_parent = t->parent;
|
|
||||||
JS_FreeValue(js,t->jsparent);
|
|
||||||
t->jsparent = JS_NULL;
|
|
||||||
|
|
||||||
for (int i = 0; i < arrlen(cur_parent->children); i++) {
|
|
||||||
if (cur_parent->children[i] == t) {
|
|
||||||
arrdelswap(cur_parent->children,i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < arrlen(cur_parent->jschildren); i++) {
|
|
||||||
if (JS_SameValue(js,cur_parent->jschildren[i],self)) {
|
|
||||||
JS_FreeValue(js,cur_parent->jschildren[i]);
|
|
||||||
arrdelswap(cur_parent->jschildren,i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
t->parent = p;
|
|
||||||
t->jsparent = JS_DupValue(js,v);
|
|
||||||
|
|
||||||
if (p) {
|
|
||||||
arrput(p->children, t);
|
|
||||||
JSValue child = JS_DupValue(js,self);
|
|
||||||
arrput(p->jschildren,child);
|
|
||||||
}
|
|
||||||
|
|
||||||
transform_apply(t);
|
|
||||||
|
|
||||||
return JS_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TRANSFORM ACTION FUNCTIONS
|
|
||||||
|
|
||||||
JSC_CCALL(transform_move,
|
|
||||||
transform *t = js2transform(js,self);
|
|
||||||
transform_move(t, js2vec3(js,argv[0]));
|
|
||||||
)
|
|
||||||
|
|
||||||
JSC_CCALL(transform_lookat,
|
|
||||||
HMM_Vec3 point = js2vec3(js,argv[0]);
|
|
||||||
transform *go = js2transform(js,self);
|
|
||||||
HMM_Mat4 m = HMM_LookAt_RH(go->pos, point, vUP);
|
|
||||||
go->rotation = HMM_M4ToQ_RH(m);
|
|
||||||
transform_apply(go);
|
|
||||||
)
|
|
||||||
|
|
||||||
JSC_CCALL(transform_rotate,
|
|
||||||
HMM_Vec3 axis = js2vec3(js,argv[0]);
|
|
||||||
transform *t = js2transform(js,self);
|
|
||||||
HMM_Quat rot = HMM_QFromAxisAngle_RH(axis, js2angle(js,argv[1]));
|
|
||||||
t->rotation = HMM_MulQ(t->rotation,rot);
|
|
||||||
transform_apply(t);
|
|
||||||
)
|
|
||||||
|
|
||||||
JSC_CCALL(transform_angle,
|
|
||||||
HMM_Vec3 axis = js2vec3(js,argv[0]);
|
|
||||||
transform *t = js2transform(js,self);
|
|
||||||
if (axis.x) return angle2js(js,HMM_Q_Roll(t->rotation));
|
|
||||||
if (axis.y) return angle2js(js,HMM_Q_Pitch(t->rotation));
|
|
||||||
if (axis.z) return angle2js(js,HMM_Q_Yaw(t->rotation));
|
|
||||||
return angle2js(js,0);
|
|
||||||
)
|
|
||||||
|
|
||||||
JSC_CCALL(transform_direction,
|
|
||||||
transform *t = js2transform(js,self);
|
|
||||||
return vec32js(js, HMM_QVRot(js2vec3(js,argv[0]), t->rotation));
|
|
||||||
)
|
|
||||||
|
|
||||||
JSC_CCALL(transform_phys2d,
|
|
||||||
transform *t = js2transform(js,self);
|
|
||||||
HMM_Vec2 v = js2vec2(js,argv[0]);
|
|
||||||
float av = js2number(js,argv[1]);
|
|
||||||
float dt = js2number(js,argv[2]);
|
|
||||||
transform_move(t, (HMM_Vec3){v.x*dt,v.y*dt,0});
|
|
||||||
HMM_Quat rot = HMM_QFromAxisAngle_RH((HMM_Vec3){0,0,1}, av*dt);
|
|
||||||
t->rotation = HMM_MulQ(t->rotation, rot);
|
|
||||||
transform_apply(t);
|
|
||||||
)
|
|
||||||
|
|
||||||
JSC_CCALL(transform_unit,
|
|
||||||
transform *t = js2transform(js,self);
|
|
||||||
t->pos = v3zero;
|
|
||||||
t->rotation = QUAT1;
|
|
||||||
t->scale = v3one;
|
|
||||||
transform_apply(t);
|
|
||||||
)
|
|
||||||
|
|
||||||
JSC_CCALL(transform_trs,
|
|
||||||
transform *t = js2transform(js,self);
|
|
||||||
t->pos = JS_IsNull(argv[0]) ? v3zero : js2vec3(js,argv[0]);
|
|
||||||
t->rotation = JS_IsNull(argv[1]) ? QUAT1 : js2quat(js,argv[1]);
|
|
||||||
t->scale = JS_IsNull(argv[2]) ? v3one : js2vec3(js,argv[2]);
|
|
||||||
transform_apply(t);
|
|
||||||
)
|
|
||||||
|
|
||||||
JSC_CCALL(transform_rect,
|
|
||||||
transform *t = js2transform(js,self);
|
|
||||||
rect r = js2rect(js,argv[0]);
|
|
||||||
t->pos = (HMM_Vec3){r.x,r.y,0};
|
|
||||||
t->scale = (HMM_Vec3){r.w,r.h,1};
|
|
||||||
t->rotation = QUAT1;
|
|
||||||
transform_apply(t);
|
|
||||||
)
|
|
||||||
|
|
||||||
JSC_CCALL(transform_array,
|
|
||||||
transform *t = js2transform(js,self);
|
|
||||||
HMM_Mat4 m= transform2mat(t);
|
|
||||||
ret = JS_NewArray(js);
|
|
||||||
for (int i = 0; i < 16; i++)
|
|
||||||
JS_SetPropertyUint32(js,ret,i, number2js(js,m.em[i]));
|
|
||||||
)
|
|
||||||
|
|
||||||
JSC_CCALL(transform_torect,
|
|
||||||
transform *t = js2transform(js,self);
|
|
||||||
return rect2js(js,transform2rect(t));
|
|
||||||
)
|
|
||||||
|
|
||||||
JSC_CCALL(transform_children,
|
|
||||||
transform *t = js2transform(js,self);
|
|
||||||
ret = JS_NewArray(js);
|
|
||||||
for (int i = 0; i < arrlen(t->jschildren); i++)
|
|
||||||
JS_SetPropertyUint32(js,ret,i,JS_DupValue(js,t->jschildren[i]));
|
|
||||||
)
|
|
||||||
|
|
||||||
static const JSCFunctionListEntry js_transform_funcs[] = {
|
|
||||||
CGETSET_ADD(transform, pos),
|
|
||||||
CGETSET_ADD(transform, scale),
|
|
||||||
CGETSET_ADD(transform, rotation),
|
|
||||||
CGETSET_ADD(transform, parent),
|
|
||||||
CGETSET_ADD(transform, change_hook),
|
|
||||||
MIST_FUNC_DEF(transform, trs, 3),
|
|
||||||
MIST_FUNC_DEF(transform, phys2d, 3),
|
|
||||||
MIST_FUNC_DEF(transform, move, 1),
|
|
||||||
MIST_FUNC_DEF(transform, rotate, 2),
|
|
||||||
MIST_FUNC_DEF(transform, angle, 1),
|
|
||||||
MIST_FUNC_DEF(transform, lookat, 1),
|
|
||||||
MIST_FUNC_DEF(transform, direction, 1),
|
|
||||||
MIST_FUNC_DEF(transform, unit, 0),
|
|
||||||
MIST_FUNC_DEF(transform, rect, 1),
|
|
||||||
MIST_FUNC_DEF(transform, array, 0),
|
|
||||||
MIST_FUNC_DEF(transform, torect, 0),
|
|
||||||
MIST_FUNC_DEF(transform, children, 0),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Constructor function for transform
|
|
||||||
static JSValue js_transform_constructor(JSContext *js, JSValueConst new_target, int argc, JSValueConst *argv) {
|
|
||||||
transform *t = make_transform();
|
|
||||||
if (!t) return JS_ThrowOutOfMemory(js);
|
|
||||||
|
|
||||||
JSValue ret = transform2js(js, t);
|
|
||||||
t->self = ret;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
JSC_CCALL(transform_clean,
|
|
||||||
clean_all(js);
|
|
||||||
)
|
|
||||||
|
|
||||||
static const JSCFunctionListEntry js_transform_ctor_funcs[] = {
|
|
||||||
MIST_FUNC_DEF(transform, clean, 0),
|
|
||||||
};
|
|
||||||
|
|
||||||
JSValue js_transform_use(JSContext *js) {
|
|
||||||
// Register the transform class
|
|
||||||
QJSCLASSPREP_FUNCS(transform);
|
|
||||||
|
|
||||||
// Create the constructor function
|
|
||||||
JSValue ctor = JS_NewCFunction2(js, js_transform_constructor, "transform", 0, JS_CFUNC_constructor, 0);
|
|
||||||
|
|
||||||
// Set the prototype on the constructor
|
|
||||||
JSValue proto = JS_GetClassProto(js, js_transform_id);
|
|
||||||
JS_SetConstructor(js, ctor, proto);
|
|
||||||
JS_FreeValue(js, proto);
|
|
||||||
|
|
||||||
// Add static methods to the constructor
|
|
||||||
JS_SetPropertyFunctionList(js, ctor, js_transform_ctor_funcs, countof(js_transform_ctor_funcs));
|
|
||||||
|
|
||||||
return ctor;
|
|
||||||
}
|
|
||||||
@@ -172,9 +172,4 @@ static const JSCFunctionListEntry js_qoi_funcs[] = {
|
|||||||
MIST_FUNC_DEF(qoi, decode, 1)
|
MIST_FUNC_DEF(qoi, decode, 1)
|
||||||
};
|
};
|
||||||
|
|
||||||
JSValue js_qoi_use(JSContext *js)
|
CELL_USE_FUNCS(js_qoi_funcs)
|
||||||
{
|
|
||||||
JSValue mod = JS_NewObject(js);
|
|
||||||
JS_SetPropertyFunctionList(js, mod, js_qoi_funcs, countof(js_qoi_funcs));
|
|
||||||
return mod;
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,3 @@
|
|||||||
#include "qjs_macros.h"
|
|
||||||
#include "quickjs.h"
|
|
||||||
|
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
#include <SDL3/SDL_audio.h>
|
#include <SDL3/SDL_audio.h>
|
||||||
#include "cell.h"
|
#include "cell.h"
|
||||||
@@ -359,8 +356,7 @@ static const JSCFunctionListEntry js_sdl_audio_funcs[] = {
|
|||||||
JS_CFUNC_DEF("mix_audio", 4, js_mix_audio),
|
JS_CFUNC_DEF("mix_audio", 4, js_mix_audio),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Use function
|
CELL_USE_INIT(
|
||||||
JSValue js_sdl_audio_use(JSContext *js) {
|
|
||||||
JS_NewClassID(&js_SDL_AudioStream_id);
|
JS_NewClassID(&js_SDL_AudioStream_id);
|
||||||
JS_NewClass(JS_GetRuntime(js), js_SDL_AudioStream_id, &js_SDL_AudioStream_class);
|
JS_NewClass(JS_GetRuntime(js), js_SDL_AudioStream_id, &js_SDL_AudioStream_class);
|
||||||
JSValue proto = JS_NewObject(js);
|
JSValue proto = JS_NewObject(js);
|
||||||
@@ -370,4 +366,4 @@ JSValue js_sdl_audio_use(JSContext *js) {
|
|||||||
JSValue export = JS_NewObject(js);
|
JSValue export = JS_NewObject(js);
|
||||||
JS_SetPropertyFunctionList(js, export, js_sdl_audio_funcs, countof(js_sdl_audio_funcs));
|
JS_SetPropertyFunctionList(js, export, js_sdl_audio_funcs, countof(js_sdl_audio_funcs));
|
||||||
return export;
|
return export;
|
||||||
}
|
)
|
||||||
@@ -1656,8 +1656,7 @@ static JSValue js_gpu_constructor(JSContext *js, JSValueConst new_target, int ar
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Function to register module
|
// Function to register module
|
||||||
JSValue js_sdl_gpu_use(JSContext *js)
|
CELL_USE_INIT(
|
||||||
{
|
|
||||||
JSValue ret = JS_NewObject(js);
|
JSValue ret = JS_NewObject(js);
|
||||||
|
|
||||||
// Initialize classes
|
// Initialize classes
|
||||||
@@ -1708,4 +1707,4 @@ JSValue js_sdl_gpu_use(JSContext *js)
|
|||||||
JS_SetPropertyStr(js, ret, "texture", texture_ctor);
|
JS_SetPropertyStr(js, ret, "texture", texture_ctor);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
)
|
||||||
@@ -783,8 +783,4 @@ static const JSCFunctionListEntry js_input_funcs[] = {
|
|||||||
MIST_FUNC_DEF(input, gamepad_id_to_type, 1),
|
MIST_FUNC_DEF(input, gamepad_id_to_type, 1),
|
||||||
};
|
};
|
||||||
|
|
||||||
JSValue js_input_use(JSContext *js) {
|
CELL_USE_FUNCS(js_input_funcs)
|
||||||
JSValue mod = JS_NewObject(js);
|
|
||||||
JS_SetPropertyFunctionList(js,mod,js_input_funcs,countof(js_input_funcs));
|
|
||||||
return mod;
|
|
||||||
}
|
|
||||||
@@ -1056,8 +1056,7 @@ JSC_CCALL(surface_convert_generic,
|
|||||||
return result;
|
return result;
|
||||||
)
|
)
|
||||||
|
|
||||||
JSValue js_sdl_surface_use(JSContext *js)
|
CELL_USE_INIT(
|
||||||
{
|
|
||||||
QJSCLASSPREP_FUNCS(SDL_Surface)
|
QJSCLASSPREP_FUNCS(SDL_Surface)
|
||||||
|
|
||||||
// Add the surface constructor
|
// Add the surface constructor
|
||||||
@@ -1084,4 +1083,4 @@ JSValue js_sdl_surface_use(JSContext *js)
|
|||||||
JS_SetPropertyStr(js, ctor, "dup", JS_NewCFunction(js, js_surface_dup_img, "dup", 1));
|
JS_SetPropertyStr(js, ctor, "dup", JS_NewCFunction(js, js_surface_dup_img, "dup", 1));
|
||||||
|
|
||||||
return ctor;
|
return ctor;
|
||||||
}
|
)
|
||||||
@@ -749,7 +749,7 @@ JSC_CCALL(sdl_set_cursor,
|
|||||||
SDL_SetCursor(cursor);
|
SDL_SetCursor(cursor);
|
||||||
)
|
)
|
||||||
|
|
||||||
JSValue js_sdl_video_use(JSContext *js) {
|
CELL_USE_INIT(
|
||||||
if (!SDL_Init(SDL_INIT_VIDEO))
|
if (!SDL_Init(SDL_INIT_VIDEO))
|
||||||
return JS_ThrowInternalError(js, "Unable to initialize video subsystem: %s", SDL_GetError());
|
return JS_ThrowInternalError(js, "Unable to initialize video subsystem: %s", SDL_GetError());
|
||||||
|
|
||||||
@@ -775,4 +775,4 @@ JSValue js_sdl_video_use(JSContext *js) {
|
|||||||
JS_NewCFunction(js, js_sdl_set_cursor, "setCursor", 1));
|
JS_NewCFunction(js, js_sdl_set_cursor, "setCursor", 1));
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
)
|
||||||
85
spline.h
85
spline.h
@@ -1,85 +0,0 @@
|
|||||||
#ifndef SPLINE_H
|
|
||||||
#define SPLINE_H
|
|
||||||
|
|
||||||
#include "HandmadeMath.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
These were already in your original header:
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Adaptive Catmull–Rom in 2D / 3D / 4D (by minimum angle):
|
|
||||||
HMM_Vec2 *catmull_rom_ma_v2(HMM_Vec2 *cp, float ma);
|
|
||||||
HMM_Vec3 *catmull_rom_ma_v3(HMM_Vec3 *cp, float ma); /* not yet implemented in .c, placeholder */
|
|
||||||
HMM_Vec4 *catmull_rom_ma_v4(HMM_Vec4 *cp, float ma); /* not yet implemented in .c, placeholder */
|
|
||||||
|
|
||||||
// Adaptive Bezier in 2D (by minimum angle):
|
|
||||||
HMM_Vec2 *bezier_cb_ma_v2(HMM_Vec2 *cp, float ma);
|
|
||||||
|
|
||||||
// Generic “single-segment” query for 2D control points + basis matrix:
|
|
||||||
HMM_Vec2 spline_query(HMM_Vec2 *cp, float d, HMM_Mat4 *basis);
|
|
||||||
|
|
||||||
// Catmull–Rom “entire spline” queries:
|
|
||||||
HMM_Vec2 catmull_rom_pos(HMM_Vec2 *cp, float d); // position
|
|
||||||
HMM_Vec2 catmull_rom_tan(HMM_Vec2 *cp, float d); // tangent
|
|
||||||
HMM_Vec2 catmull_rom_curv(HMM_Vec2 *cp, float d); // curvature
|
|
||||||
HMM_Vec2 catmull_rom_wig(HMM_Vec2 *cp, float d); // 3rd derivative (“wiggle”)
|
|
||||||
|
|
||||||
// Computes approximate length of a 2D Catmull–Rom spline:
|
|
||||||
float catmull_rom_len(HMM_Vec2 *cp);
|
|
||||||
|
|
||||||
// Returns closest point on a 2D Catmull–Rom curve given an external 2D point `p`:
|
|
||||||
HMM_Vec2 catmull_rom_closest(HMM_Vec2 *cp, HMM_Vec2 p);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
Additional convenience functions for *single-segment* cubic splines:
|
|
||||||
|
|
||||||
Each of these expects exactly 4 control points in `p[0..3]`,
|
|
||||||
and a parameter t in [0..1]. They pick the appropriate matrix internally.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Hermite:
|
|
||||||
HMM_Vec2 cubic_hermite_pos(HMM_Vec2 *p, float d);
|
|
||||||
HMM_Vec2 cubic_hermite_tan(HMM_Vec2 *p, float d);
|
|
||||||
HMM_Vec2 cubic_hermite_curv(HMM_Vec2 *p, float d);
|
|
||||||
HMM_Vec2 cubic_hermite_wig(HMM_Vec2 *p, float d);
|
|
||||||
|
|
||||||
// B-spline:
|
|
||||||
HMM_Vec2 b_spline_pos(HMM_Vec2 *p, float d);
|
|
||||||
HMM_Vec2 b_spline_tan(HMM_Vec2 *p, float d);
|
|
||||||
HMM_Vec2 b_spline_curv(HMM_Vec2 *p, float d);
|
|
||||||
HMM_Vec2 b_spline_wig(HMM_Vec2 *p, float d);
|
|
||||||
|
|
||||||
// Bezier:
|
|
||||||
HMM_Vec2 bezier_pos(HMM_Vec2 *p, float d);
|
|
||||||
HMM_Vec2 bezier_tan(HMM_Vec2 *p, float d);
|
|
||||||
HMM_Vec2 bezier_curv(HMM_Vec2 *p, float d);
|
|
||||||
HMM_Vec2 bezier_wig(HMM_Vec2 *p, float d);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
Uniform sampling of a *single* 4-point segment in 2D:
|
|
||||||
Returns an array of points (stb_ds dynamic array).
|
|
||||||
*/
|
|
||||||
HMM_Vec2 *spline_v2(HMM_Vec2 *p, HMM_Mat4 *m, int segs);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Adaptive subdivision routines (single-segment) in 2D:
|
|
||||||
- Subdivide by min segment length
|
|
||||||
- Subdivide by “max angle” proxy
|
|
||||||
*/
|
|
||||||
HMM_Vec2 *spline2d_min_seg(float u0, float u1, float min_seg, HMM_Mat4 *C, HMM_Vec2 *ret);
|
|
||||||
HMM_Vec2 *catmull_rom_min_seg(HMM_Vec2 *a, HMM_Vec2 *b, HMM_Vec2 *c, HMM_Vec2 *d, float min_seg);
|
|
||||||
|
|
||||||
HMM_Vec2 *spline2d_min_angle_2(float u0, float u1, float max_angle, HMM_Mat4 *C, HMM_Vec2 *arr);
|
|
||||||
HMM_Vec2 *spline_min_angle(HMM_Vec2 *p, const HMM_Mat4 *B, float min_angle, HMM_Vec2 *arr);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* SPLINE_H */
|
|
||||||
107
sprite.c
107
sprite.c
@@ -1,4 +1,9 @@
|
|||||||
|
#include "qjs_sprite.h"
|
||||||
|
#include "prosperon.h"
|
||||||
|
#include "qjs_macros.h"
|
||||||
|
|
||||||
#include "sprite.h"
|
#include "sprite.h"
|
||||||
|
#include "HandmadeMath.h"
|
||||||
|
|
||||||
sprite *make_sprite(void)
|
sprite *make_sprite(void)
|
||||||
{
|
{
|
||||||
@@ -27,3 +32,105 @@ void sprite_apply(sprite *sp)
|
|||||||
.y = -k.y * s + c };
|
.y = -k.y * s + c };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Sprite class definitions
|
||||||
|
static JSClassID js_sprite_id;
|
||||||
|
static void js_sprite_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func) {
|
||||||
|
sprite *sp = JS_GetOpaque(val, js_sprite_id);
|
||||||
|
if (!sp) return;
|
||||||
|
JS_MarkValue(rt, sp->image, mark_func);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Class definition for sprite with mark function for GC
|
||||||
|
QJSCLASSMARK(sprite,)
|
||||||
|
|
||||||
|
// SPRITE GETTER/SETTER FUNCTIONS
|
||||||
|
JSC_GETSET(sprite, pos, vec2)
|
||||||
|
JSC_GETSET(sprite, center, vec2)
|
||||||
|
JSC_GETSET(sprite, layer, number)
|
||||||
|
JSC_GETSET(sprite, color, color)
|
||||||
|
JSC_GETSET(sprite, skew, vec2)
|
||||||
|
JSC_GETSET(sprite, scale, vec2)
|
||||||
|
JSC_GETSET(sprite, rotation, number)
|
||||||
|
|
||||||
|
// SPRITE ACTION FUNCTIONS
|
||||||
|
|
||||||
|
JSC_CCALL(sprite_move,
|
||||||
|
sprite *sp = js2sprite(js,self);
|
||||||
|
HMM_Vec2 mv = js2vec2(js,argv[0]);
|
||||||
|
sp->pos.x += mv.x;
|
||||||
|
sp->pos.y += mv.y;
|
||||||
|
)
|
||||||
|
|
||||||
|
JSC_CCALL(sprite_set_affine,
|
||||||
|
sprite *sp = js2sprite(js,self);
|
||||||
|
sprite_apply(sp);
|
||||||
|
)
|
||||||
|
|
||||||
|
JSC_CCALL(sprite_set_image,
|
||||||
|
sprite *sp = js2sprite(js,self);
|
||||||
|
if (!JS_IsNull(sp->image))
|
||||||
|
JS_FreeValue(js,sp->image);
|
||||||
|
sp->image = JS_DupValue(js, argv[0]);
|
||||||
|
)
|
||||||
|
|
||||||
|
static const JSCFunctionListEntry js_sprite_funcs[] = {
|
||||||
|
MIST_FUNC_DEF(sprite, set_affine, 0),
|
||||||
|
MIST_FUNC_DEF(sprite, set_image, 1),
|
||||||
|
MIST_FUNC_DEF(sprite, move, 1),
|
||||||
|
JS_CGETSET_DEF("pos", js_sprite_get_pos, js_sprite_set_pos),
|
||||||
|
JS_CGETSET_DEF("scale", js_sprite_get_scale, js_sprite_set_scale),
|
||||||
|
JS_CGETSET_DEF("skew", js_sprite_get_skew, js_sprite_set_skew),
|
||||||
|
JS_CGETSET_DEF("layer", js_sprite_get_layer, js_sprite_set_layer),
|
||||||
|
JS_CGETSET_DEF("color", js_sprite_get_color, js_sprite_set_color),
|
||||||
|
JS_CGETSET_DEF("center", js_sprite_get_center, js_sprite_set_center),
|
||||||
|
JS_CGETSET_DEF("rotation", js_sprite_get_rotation, js_sprite_set_rotation),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Constructor function for sprite
|
||||||
|
static JSValue js_sprite_constructor(JSContext *js, JSValueConst new_target, int argc, JSValueConst *argv) {
|
||||||
|
sprite *sp = make_sprite();
|
||||||
|
if (!sp) return JS_ThrowOutOfMemory(js);
|
||||||
|
|
||||||
|
// If an options object is provided, initialize the sprite with it
|
||||||
|
if (argc > 0 && JS_IsObject(argv[0])) {
|
||||||
|
JS_GETATOM(js, sp->pos, argv[0], pos, vec2)
|
||||||
|
JS_GETATOM(js, sp->center, argv[0], center, vec2)
|
||||||
|
JS_GETATOM(js, sp->skew, argv[0], skew, vec2)
|
||||||
|
JS_GETATOM(js, sp->scale, argv[0], scale, vec2)
|
||||||
|
JS_GETATOM(js, sp->rotation, argv[0], rotation, number)
|
||||||
|
JS_GETATOM(js, sp->layer, argv[0], layer, number)
|
||||||
|
JS_GETATOM(js, sp->color, argv[0], color, color)
|
||||||
|
|
||||||
|
JSValue image = JS_GetProperty(js, argv[0], JS_NewAtom(js, "image"));
|
||||||
|
if (!JS_IsNull(image)) {
|
||||||
|
sp->image = image; // Transfer ownership, no need to dup
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default values if not provided
|
||||||
|
if (sp->scale.x == 0 && sp->scale.y == 0) {
|
||||||
|
sp->scale.x = 1;
|
||||||
|
sp->scale.y = 1;
|
||||||
|
}
|
||||||
|
if (sp->color.w == 0) sp->color.w = 1; // Default alpha to 1
|
||||||
|
|
||||||
|
sprite_apply(sp);
|
||||||
|
return sprite2js(js, sp);
|
||||||
|
}
|
||||||
|
|
||||||
|
CELL_USE_INIT(
|
||||||
|
// Register the sprite class
|
||||||
|
QJSCLASSPREP_FUNCS(sprite);
|
||||||
|
|
||||||
|
// Create the constructor function
|
||||||
|
JSValue ctor = JS_NewCFunction2(js, js_sprite_constructor, "sprite", 1, JS_CFUNC_constructor, 0);
|
||||||
|
|
||||||
|
// Set the prototype on the constructor
|
||||||
|
JSValue proto = JS_GetClassProto(js, js_sprite_id);
|
||||||
|
JS_SetConstructor(js, ctor, proto);
|
||||||
|
JS_FreeValue(js, proto);
|
||||||
|
|
||||||
|
return ctor;
|
||||||
|
)
|
||||||
@@ -124,8 +124,7 @@ static JSValue js_font_constructor(JSContext *ctx, JSValueConst new_target, int
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the staef module
|
// Initialize the staef module
|
||||||
JSValue js_staef_use(JSContext *js)
|
CELL_USE_INIT(
|
||||||
{
|
|
||||||
JSValue mod = JS_NewObject(js);
|
JSValue mod = JS_NewObject(js);
|
||||||
JSValue proto;
|
JSValue proto;
|
||||||
|
|
||||||
@@ -144,4 +143,4 @@ JSValue js_staef_use(JSContext *js)
|
|||||||
JS_SetPropertyStr(js, mod, "font", font_ctor);
|
JS_SetPropertyStr(js, mod, "font", font_ctor);
|
||||||
|
|
||||||
return mod;
|
return mod;
|
||||||
}
|
)
|
||||||
247
transform.c
247
transform.c
@@ -1,7 +1,12 @@
|
|||||||
#include "transform.h"
|
#include "cell.h"
|
||||||
|
#include "prosperon.h"
|
||||||
|
#include "qjs_macros.h"
|
||||||
|
#include "stb_ds.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "stb_ds.h"
|
#include "transform.h"
|
||||||
|
#include "HandmadeMath.h"
|
||||||
|
|
||||||
|
|
||||||
static transform **dirties;
|
static transform **dirties;
|
||||||
|
|
||||||
@@ -154,3 +159,241 @@ transform mat2transform(HMM_Mat4 m)
|
|||||||
t.rotation = HMM_M4ToQ_RH(m);
|
t.rotation = HMM_M4ToQ_RH(m);
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Transform class definitions
|
||||||
|
JSClassID js_transform_id;
|
||||||
|
static void js_transform_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func) {
|
||||||
|
transform *t = JS_GetOpaque(val, js_transform_id);
|
||||||
|
if (!t) return;
|
||||||
|
// Mark the JSValue references stored in your struct
|
||||||
|
JS_MarkValue(rt, t->change_hook, mark_func);
|
||||||
|
JS_MarkValue(rt, t->jsparent, mark_func);
|
||||||
|
// Mark the array elements
|
||||||
|
for (int i = 0; i < arrlen(t->jschildren); i++)
|
||||||
|
JS_MarkValue(rt, t->jschildren[i], mark_func);
|
||||||
|
}
|
||||||
|
|
||||||
|
QJSCLASSMARK_EXTERN(transform,)
|
||||||
|
|
||||||
|
// TRANSFORM GETTER/SETTER FUNCTIONS
|
||||||
|
JSC_GETSET_APPLY(transform, pos, vec3)
|
||||||
|
JSC_GETSET_APPLY(transform, scale, vec3)
|
||||||
|
JSC_GETSET_APPLY(transform, rotation, quat)
|
||||||
|
|
||||||
|
static JSValue js_transform_get_change_hook(JSContext *js, JSValueConst self)
|
||||||
|
{
|
||||||
|
transform *t = js2transform(js,self);
|
||||||
|
return JS_DupValue(js,t->change_hook);
|
||||||
|
}
|
||||||
|
|
||||||
|
static JSValue js_transform_set_change_hook(JSContext *js, JSValueConst self, JSValue v)
|
||||||
|
{
|
||||||
|
transform *t = js2transform(js,self);
|
||||||
|
if (!JS_IsNull(v) && !JS_IsFunction(js,v)) return JS_ThrowReferenceError(js, "Hook must be a function.");
|
||||||
|
JS_FreeValue(js,t->change_hook);
|
||||||
|
t->change_hook = JS_DupValue(js,v);
|
||||||
|
return JS_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JSValue js_transform_get_parent(JSContext *js, JSValueConst self)
|
||||||
|
{
|
||||||
|
transform *t = js2transform(js,self);
|
||||||
|
if (t->parent) return JS_DupValue(js,t->jsparent);
|
||||||
|
return JS_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JSValue js_transform_set_parent(JSContext *js, JSValueConst self, JSValue v)
|
||||||
|
{
|
||||||
|
transform *p = js2transform(js,v);
|
||||||
|
if (!JS_IsNull(v) && !p)
|
||||||
|
return JS_ThrowReferenceError(js,"Parent must be another transform.");
|
||||||
|
|
||||||
|
transform *t = js2transform(js,self);
|
||||||
|
|
||||||
|
if (t == p)
|
||||||
|
return JS_ThrowReferenceError(js, "A transform cannot be its own parent.");
|
||||||
|
|
||||||
|
if (t->parent) {
|
||||||
|
transform *cur_parent = t->parent;
|
||||||
|
JS_FreeValue(js,t->jsparent);
|
||||||
|
t->jsparent = JS_NULL;
|
||||||
|
|
||||||
|
for (int i = 0; i < arrlen(cur_parent->children); i++) {
|
||||||
|
if (cur_parent->children[i] == t) {
|
||||||
|
arrdelswap(cur_parent->children,i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < arrlen(cur_parent->jschildren); i++) {
|
||||||
|
if (JS_SameValue(js,cur_parent->jschildren[i],self)) {
|
||||||
|
JS_FreeValue(js,cur_parent->jschildren[i]);
|
||||||
|
arrdelswap(cur_parent->jschildren,i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
t->parent = p;
|
||||||
|
t->jsparent = JS_DupValue(js,v);
|
||||||
|
|
||||||
|
if (p) {
|
||||||
|
arrput(p->children, t);
|
||||||
|
JSValue child = JS_DupValue(js,self);
|
||||||
|
arrput(p->jschildren,child);
|
||||||
|
}
|
||||||
|
|
||||||
|
transform_apply(t);
|
||||||
|
|
||||||
|
return JS_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TRANSFORM ACTION FUNCTIONS
|
||||||
|
|
||||||
|
JSC_CCALL(transform_move,
|
||||||
|
transform *t = js2transform(js,self);
|
||||||
|
transform_move(t, js2vec3(js,argv[0]));
|
||||||
|
)
|
||||||
|
|
||||||
|
JSC_CCALL(transform_lookat,
|
||||||
|
HMM_Vec3 point = js2vec3(js,argv[0]);
|
||||||
|
transform *go = js2transform(js,self);
|
||||||
|
HMM_Mat4 m = HMM_LookAt_RH(go->pos, point, vUP);
|
||||||
|
go->rotation = HMM_M4ToQ_RH(m);
|
||||||
|
transform_apply(go);
|
||||||
|
)
|
||||||
|
|
||||||
|
JSC_CCALL(transform_rotate,
|
||||||
|
HMM_Vec3 axis = js2vec3(js,argv[0]);
|
||||||
|
transform *t = js2transform(js,self);
|
||||||
|
HMM_Quat rot = HMM_QFromAxisAngle_RH(axis, js2angle(js,argv[1]));
|
||||||
|
t->rotation = HMM_MulQ(t->rotation,rot);
|
||||||
|
transform_apply(t);
|
||||||
|
)
|
||||||
|
|
||||||
|
JSC_CCALL(transform_angle,
|
||||||
|
HMM_Vec3 axis = js2vec3(js,argv[0]);
|
||||||
|
transform *t = js2transform(js,self);
|
||||||
|
if (axis.x) return angle2js(js,HMM_Q_Roll(t->rotation));
|
||||||
|
if (axis.y) return angle2js(js,HMM_Q_Pitch(t->rotation));
|
||||||
|
if (axis.z) return angle2js(js,HMM_Q_Yaw(t->rotation));
|
||||||
|
return angle2js(js,0);
|
||||||
|
)
|
||||||
|
|
||||||
|
JSC_CCALL(transform_direction,
|
||||||
|
transform *t = js2transform(js,self);
|
||||||
|
return vec32js(js, HMM_QVRot(js2vec3(js,argv[0]), t->rotation));
|
||||||
|
)
|
||||||
|
|
||||||
|
JSC_CCALL(transform_phys2d,
|
||||||
|
transform *t = js2transform(js,self);
|
||||||
|
HMM_Vec2 v = js2vec2(js,argv[0]);
|
||||||
|
float av = js2number(js,argv[1]);
|
||||||
|
float dt = js2number(js,argv[2]);
|
||||||
|
transform_move(t, (HMM_Vec3){v.x*dt,v.y*dt,0});
|
||||||
|
HMM_Quat rot = HMM_QFromAxisAngle_RH((HMM_Vec3){0,0,1}, av*dt);
|
||||||
|
t->rotation = HMM_MulQ(t->rotation, rot);
|
||||||
|
transform_apply(t);
|
||||||
|
)
|
||||||
|
|
||||||
|
JSC_CCALL(transform_unit,
|
||||||
|
transform *t = js2transform(js,self);
|
||||||
|
t->pos = v3zero;
|
||||||
|
t->rotation = QUAT1;
|
||||||
|
t->scale = v3one;
|
||||||
|
transform_apply(t);
|
||||||
|
)
|
||||||
|
|
||||||
|
JSC_CCALL(transform_trs,
|
||||||
|
transform *t = js2transform(js,self);
|
||||||
|
t->pos = JS_IsNull(argv[0]) ? v3zero : js2vec3(js,argv[0]);
|
||||||
|
t->rotation = JS_IsNull(argv[1]) ? QUAT1 : js2quat(js,argv[1]);
|
||||||
|
t->scale = JS_IsNull(argv[2]) ? v3one : js2vec3(js,argv[2]);
|
||||||
|
transform_apply(t);
|
||||||
|
)
|
||||||
|
|
||||||
|
JSC_CCALL(transform_rect,
|
||||||
|
transform *t = js2transform(js,self);
|
||||||
|
rect r = js2rect(js,argv[0]);
|
||||||
|
t->pos = (HMM_Vec3){r.x,r.y,0};
|
||||||
|
t->scale = (HMM_Vec3){r.w,r.h,1};
|
||||||
|
t->rotation = QUAT1;
|
||||||
|
transform_apply(t);
|
||||||
|
)
|
||||||
|
|
||||||
|
JSC_CCALL(transform_array,
|
||||||
|
transform *t = js2transform(js,self);
|
||||||
|
HMM_Mat4 m= transform2mat(t);
|
||||||
|
ret = JS_NewArray(js);
|
||||||
|
for (int i = 0; i < 16; i++)
|
||||||
|
JS_SetPropertyUint32(js,ret,i, number2js(js,m.em[i]));
|
||||||
|
)
|
||||||
|
|
||||||
|
JSC_CCALL(transform_torect,
|
||||||
|
transform *t = js2transform(js,self);
|
||||||
|
return rect2js(js,transform2rect(t));
|
||||||
|
)
|
||||||
|
|
||||||
|
JSC_CCALL(transform_children,
|
||||||
|
transform *t = js2transform(js,self);
|
||||||
|
ret = JS_NewArray(js);
|
||||||
|
for (int i = 0; i < arrlen(t->jschildren); i++)
|
||||||
|
JS_SetPropertyUint32(js,ret,i,JS_DupValue(js,t->jschildren[i]));
|
||||||
|
)
|
||||||
|
|
||||||
|
static const JSCFunctionListEntry js_transform_funcs[] = {
|
||||||
|
CGETSET_ADD(transform, pos),
|
||||||
|
CGETSET_ADD(transform, scale),
|
||||||
|
CGETSET_ADD(transform, rotation),
|
||||||
|
CGETSET_ADD(transform, parent),
|
||||||
|
CGETSET_ADD(transform, change_hook),
|
||||||
|
MIST_FUNC_DEF(transform, trs, 3),
|
||||||
|
MIST_FUNC_DEF(transform, phys2d, 3),
|
||||||
|
MIST_FUNC_DEF(transform, move, 1),
|
||||||
|
MIST_FUNC_DEF(transform, rotate, 2),
|
||||||
|
MIST_FUNC_DEF(transform, angle, 1),
|
||||||
|
MIST_FUNC_DEF(transform, lookat, 1),
|
||||||
|
MIST_FUNC_DEF(transform, direction, 1),
|
||||||
|
MIST_FUNC_DEF(transform, unit, 0),
|
||||||
|
MIST_FUNC_DEF(transform, rect, 1),
|
||||||
|
MIST_FUNC_DEF(transform, array, 0),
|
||||||
|
MIST_FUNC_DEF(transform, torect, 0),
|
||||||
|
MIST_FUNC_DEF(transform, children, 0),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Constructor function for transform
|
||||||
|
static JSValue js_transform_constructor(JSContext *js, JSValueConst new_target, int argc, JSValueConst *argv) {
|
||||||
|
transform *t = make_transform();
|
||||||
|
if (!t) return JS_ThrowOutOfMemory(js);
|
||||||
|
|
||||||
|
JSValue ret = transform2js(js, t);
|
||||||
|
t->self = ret;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
JSC_CCALL(transform_clean,
|
||||||
|
clean_all(js);
|
||||||
|
)
|
||||||
|
|
||||||
|
static const JSCFunctionListEntry js_transform_ctor_funcs[] = {
|
||||||
|
MIST_FUNC_DEF(transform, clean, 0),
|
||||||
|
};
|
||||||
|
|
||||||
|
CELL_USE_INIT(
|
||||||
|
// Register the transform class
|
||||||
|
QJSCLASSPREP_FUNCS(transform);
|
||||||
|
|
||||||
|
// Create the constructor function
|
||||||
|
JSValue ctor = JS_NewCFunction2(js, js_transform_constructor, "transform", 0, JS_CFUNC_constructor, 0);
|
||||||
|
|
||||||
|
// Set the prototype on the constructor
|
||||||
|
JSValue proto = JS_GetClassProto(js, js_transform_id);
|
||||||
|
JS_SetConstructor(js, ctor, proto);
|
||||||
|
JS_FreeValue(js, proto);
|
||||||
|
|
||||||
|
// Add static methods to the constructor
|
||||||
|
JS_SetPropertyFunctionList(js, ctor, js_transform_ctor_funcs, countof(js_transform_ctor_funcs));
|
||||||
|
|
||||||
|
return ctor;
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user