prosperon/source/engine/jsffi.c

3000 lines
79 KiB
C
Raw Permalink Normal View History

2023-11-03 22:01:30 -05:00
#include "jsffi.h"
2023-01-10 07:13:00 -06:00
#include "script.h"
2023-01-10 15:41:43 -06:00
#include "font.h"
2023-05-12 13:22:05 -05:00
#include "input.h"
#include "log.h"
2023-11-27 14:29:55 -06:00
#include "datastream.h"
2023-02-05 17:42:36 -06:00
#include "stb_ds.h"
2024-10-18 12:51:21 -05:00
#include "stb_image.h"
#include "stb_rect_pack.h"
2023-05-12 13:22:05 -05:00
#include "string.h"
#include "window.h"
2023-12-04 13:38:37 -06:00
#include "spline.h"
2023-05-12 13:22:05 -05:00
#include "yugine.h"
2023-04-21 16:57:30 -05:00
#include <assert.h>
#include "resources.h"
2023-09-11 02:46:12 -05:00
#include <sokol/sokol_time.h>
2024-02-25 17:31:48 -06:00
#include <sokol/sokol_app.h>
#include <time.h>
#include <sys/time.h>
2024-02-23 16:05:30 -06:00
#include <sys/stat.h>
#include <sys/types.h>
2024-02-25 17:31:48 -06:00
#include <unistd.h>
#include <limits.h>
#include "render.h"
#include "model.h"
#include "HandmadeMath.h"
2024-05-06 21:59:22 -05:00
#include "par/par_streamlines.h"
2024-05-08 11:07:19 -05:00
#include "par/par_shapes.h"
#include "sokol_glue.h"
2024-09-29 06:10:42 -05:00
#include "sokol/util/sokol_gl.h"
2024-08-06 14:23:21 -05:00
#include <stdint.h>
2024-08-04 15:20:11 -05:00
#include "timer.h"
2024-10-03 17:36:29 -05:00
2024-10-18 12:51:21 -05:00
#include "cute_aseprite.h"
2024-10-03 17:36:29 -05:00
#ifndef _WIN32
2024-09-29 06:10:42 -05:00
#include <sys/resource.h>
2024-10-03 17:36:29 -05:00
#endif
2024-02-25 17:31:48 -06:00
#include "stb_perlin.h"
2024-02-25 17:31:48 -06:00
#if (defined(_WIN32) || defined(__WIN32__))
#include <direct.h>
#define mkdir(x,y) _mkdir(x)
#endif
2024-02-23 16:05:30 -06:00
2024-10-17 17:23:33 -05:00
struct lrtb {
float l;
float r;
float t;
float b;
};
typedef struct lrtb lrtb;
lrtb js2lrtb(JSValue v)
{
lrtb ret = {0};
ret.l = js2number(js_getpropstr(v,"l"));
ret.b = js2number(js_getpropstr(v,"b"));
ret.t = js2number(js_getpropstr(v,"t"));
ret.r = js2number(js_getpropstr(v,"r"));
return ret;
}
2023-05-24 20:45:50 -05:00
2024-10-17 17:23:33 -05:00
static JSValue globalThis;
JSValue str2js(const char *c, ...) {
2024-03-20 14:32:35 -05:00
if (!c) return JS_UNDEFINED;
char *result = NULL;
va_list args;
va_start(args, c);
va_list args2;
va_copy(args2,args);
char buf[1+vsnprintf(NULL, 0, c, args)];
va_end(args);
vsnprintf(buf, sizeof buf, c, args2);
va_end(args2);
return JS_NewString(js, buf);
2024-03-20 14:32:35 -05:00
}
2024-08-15 12:26:37 -05:00
int JS_Is(JSValue v) { return JS_ToBool(js, v); }
2024-03-19 23:01:31 -05:00
const char *js2str(JSValue v) {
return JS_ToCString(js, v);
}
2024-10-29 12:41:17 -05:00
/*
JSValue sapp_event2js(JSContext *js, sapp_event *e)
{
JSValue event = JS_NewObject(js);
JS_SetPropertyStr(js, event, "frame_count", JS_NewIntt64(js, e->frame_count));
JS_SetPropertyStr(js, event, "type", JS_NewInt64(js, e->type));
JS_SetPropertyStr(js, event, "mouse_dx", JS_NewFloat64(js, e->mouse_dx));
JS_SetPropertyStr(js, event, "mouse_dy", JS_NewFloat64(js, e->mouse_dy));
JS_SetPropertyStr(js, event, "window_width", JS_NewFloat64(js, e->window_width));
JS_SetPropertyStr(js, event, "window_height", JS_NewFloat64(js, e->window_height));
JS_SetPropertyStr(js, event, "framebuffer_height", JS_NewFloat64(js, e->framebuffer_height));
JS_SetPropertyStr(js, event, "framebuffer_height", JS_NewFloat64(js, e->framebuffer_height));
switch(e->type) {
case MOUSE_SCROLL:
JS_SetPropertyStr(js, event, "scroll_dx", JS_NewFloat64(js, e->scroll_dx));
JS_SetPropertyStr(js, event, "scroll_dy", JS_NewFloat64(js, e->scroll_dy));
JS_SetPropertyStr(js, event, "modifiers", JS_NewBool(js, e->modifiers));
break;
case KEY_UP:
case KEY_DOWN:
JS_SetPropertyStr(js, event, "key_code", JS_NewInt64(js, e->key_code));
JS_SetPropertyStr(js, event, "char_code", JS_NewUint32(js, e->char_code));
JS_SetPropertyStr(js, event, "key_repeat", JS_NewBool(js, e->key_repeat));
JS_SetPropertyStr(js, event, "modifiers", JS_NewBool(js, e->modifiers));
break;
case CHAR:
JS_SetPropertyStr(js, event, "char_code", JS_NewUint32(js, e->char_code));
JS_SetPropertyStr(js, event, "key_repeat", JS_NewBool(js, e->key_repeat));
JS_SetPropertyStr(js, event, "modifiers", JS_NewBool(js, e->modifiers));
break;
case TOUCHES_BEGIN:
case TOUCHES_MOVED:
case TOUCHES_ENDED:
break;
case MOUSE_UP:
case MOUSE_DOWN:
JS_SetPropertyStr(js, event, "mouse_button", JS_NewUint32(js, e->mouse_button));
JS_SetPropertyStr(js, event, "modifiers", JS_NewBool(js, e->modifiers));
break;
}
return event;
}
*/
2024-05-15 16:34:03 -05:00
char *js2strdup(JSValue v) {
2024-09-29 06:10:42 -05:00
const char *str = JS_ToCString(js, v);
2024-05-15 16:34:03 -05:00
char *ret = strdup(str);
JS_FreeCString(js, str);
return ret;
}
2024-05-06 21:59:22 -05:00
void sg_buffer_free(sg_buffer *b)
{
2024-05-12 18:36:14 -05:00
sg_destroy_buffer(*b);
free(b);
2024-05-06 21:59:22 -05:00
}
2024-10-03 09:31:06 -05:00
void sg_pipeline_free(sg_pipeline *p)
{
sg_destroy_pipeline(*p);
free(p);
}
2024-08-08 17:32:58 -05:00
void skin_free(skin *sk) {
arrfree(sk->invbind);
free(sk);
}
2024-04-30 10:32:27 -05:00
void jsfreestr(const char *s) { JS_FreeCString(js, s); }
2024-05-12 18:36:14 -05:00
QJSCLASS(transform)
QJSCLASS(texture)
2024-04-09 16:48:15 -05:00
QJSCLASS(font)
2024-10-29 12:41:17 -05:00
//QJSCLASS(warp_gravity)
//QJSCLASS(warp_damp)
2024-03-13 16:30:55 -05:00
QJSCLASS(window)
2024-05-06 21:59:22 -05:00
QJSCLASS(sg_buffer)
2024-10-03 09:31:06 -05:00
QJSCLASS(sg_pipeline)
QJSCLASS(datastream)
2024-08-04 15:20:11 -05:00
QJSCLASS(timer)
2024-10-20 08:28:13 -05:00
QJSCLASS(skin)
2023-11-29 12:40:13 -06:00
#define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c"
2023-05-12 13:22:05 -05:00
#define BYTE_TO_BINARY(byte) \
2024-01-14 10:24:31 -06:00
(byte & 0x80 ? '1' : '0'), \
2023-05-12 13:22:05 -05:00
(byte & 0x40 ? '1' : '0'), \
(byte & 0x20 ? '1' : '0'), \
(byte & 0x10 ? '1' : '0'), \
(byte & 0x08 ? '1' : '0'), \
(byte & 0x04 ? '1' : '0'), \
(byte & 0x02 ? '1' : '0'), \
(byte & 0x01 ? '1' : '0')
2024-03-20 14:32:35 -05:00
int js2boolean(JSValue v) { return JS_ToBool(js, v); }
JSValue boolean2js(int b) { return JS_NewBool(js,b); }
2023-12-09 22:09:15 -06:00
2024-03-19 23:01:31 -05:00
void js_setprop_num(JSValue obj, uint32_t i, JSValue v) { JS_SetPropertyUint32(js, obj, i, v); }
JSValue js_getpropidx(JSValue v, uint32_t i)
{
if (!JS_IsArray(js, v)) return JS_UNDEFINED;
2024-03-19 23:01:31 -05:00
JSValue p = JS_GetPropertyUint32(js, v, i);
JS_FreeValue(js,p);
return p;
}
2024-10-29 12:41:17 -05:00
//
static inline HMM_Mat4 js2transform_mat(JSContext *js, JSValue v)
{
transform *T = js2transform(v);
transform *P = js2transform(js_getpropstr(v, "parent"));
if (P) {
HMM_Mat4 pm = transform2mat(P);
HMM_Mat4 tm = transform2mat(T);
return HMM_MulM4(pm, tm);
}
return transform2mat(T);
}
2024-03-19 14:39:19 -05:00
void js_setprop_str(JSValue obj, const char *prop, JSValue v) { JS_SetPropertyStr(js, obj, prop, v); }
2023-05-24 20:45:50 -05:00
JSValue js_getpropstr(JSValue v, const char *str)
{
JSValue p = JS_GetPropertyStr(js,v,str);
JS_FreeValue(js,p);
return p;
}
2024-05-06 21:59:22 -05:00
void js_setpropstr(JSValue v, const char *str, JSValue p)
{
JS_SetPropertyStr(js, v, str, p);
}
2024-09-04 13:23:20 -05:00
char **js2strarr(JSValue v)
{
int n = js_arrlen(v);
char **arr = malloc(sizeof(*arr));
arr = NULL;
for (int i = 0; i < n; i++)
arrput(arr, js2strdup(js_getpropidx(v, i)));
return arr;
}
JSValue strarr2js(char **c)
2023-09-11 02:46:12 -05:00
{
JSValue arr = JS_NewArray(js);
for (int i = 0; i < arrlen(c); i++)
js_setprop_num(arr,i,JS_NewString(js, c[i]));
2023-09-11 02:46:12 -05:00
return arr;
}
2024-03-19 14:39:19 -05:00
JSValue number2js(double g) { return JS_NewFloat64(js,g); }
2023-05-12 13:22:05 -05:00
double js2number(JSValue v) {
2023-04-18 17:58:44 -05:00
double g;
2023-05-12 13:22:05 -05:00
JS_ToFloat64(js, &g, v);
2024-05-12 18:36:14 -05:00
if (isnan(g)) g = 0;
2023-04-18 17:58:44 -05:00
return g;
}
2024-05-21 18:50:53 -05:00
uint64_t js2uint64(JSValue v)
{
uint64_t g;
JS_ToIndex(js, &g, v);
return g;
}
JSValue angle2js(double g) {
return number2js(g*HMM_RadToTurn);
}
2024-08-08 17:32:58 -05:00
double js2angle(JSValue v) {
double n = js2number(v);
return n * HMM_TurnToRad;
}
2023-05-12 13:22:05 -05:00
int js_arrlen(JSValue v) {
2024-05-02 13:52:28 -05:00
if (JS_IsUndefined(v)) return 0;
2023-04-18 14:49:17 -05:00
int len;
2023-05-24 20:45:50 -05:00
JS_ToInt32(js, &len, js_getpropstr( v, "length"));
2023-04-18 14:49:17 -05:00
return len;
}
2023-05-16 01:31:13 -05:00
struct rgba js2color(JSValue v) {
2023-05-24 20:45:50 -05:00
JSValue c[4];
for (int i = 0; i < 4; i++)
2024-03-18 14:27:52 -05:00
c[i] = js_getpropidx(v,i);
float a = JS_IsUndefined(c[3]) ? 1.0 : js2number(c[3]);
2023-05-16 01:31:13 -05:00
struct rgba color = {
.r = js2number(c[0])*RGBA_MAX,
.g = js2number(c[1])*RGBA_MAX,
.b = js2number(c[2])*RGBA_MAX,
.a = a*RGBA_MAX,
2023-05-16 01:31:13 -05:00
};
2023-05-24 20:45:50 -05:00
for (int i = 0; i < 4; i++)
JS_FreeValue(js,c[i]);
2023-05-12 13:22:05 -05:00
return color;
2023-04-19 15:16:35 -05:00
}
2023-01-27 12:06:16 -06:00
JSValue color2js(struct rgba color)
{
JSValue arr = JS_NewArray(js);
2024-03-18 14:27:52 -05:00
js_setprop_num(arr,0,number2js((double)color.r/255));
js_setprop_num(arr,1,number2js((double)color.g/255));
js_setprop_num(arr,2,number2js((double)color.b/255));
js_setprop_num(arr,3,number2js((double)color.a/255));
return arr;
}
2023-10-04 08:18:09 -05:00
struct boundingbox js2bb(JSValue v)
{
struct boundingbox bb;
bb.t = js2number(js_getpropstr(v,"t"));
bb.b = js2number(js_getpropstr(v,"b"));
bb.r = js2number(js_getpropstr(v,"r"));
bb.l = js2number(js_getpropstr(v,"l"));
return bb;
}
2024-03-19 14:39:19 -05:00
cpVect js2cvec2(JSValue v) { return js2vec2(v).cp; }
JSValue cvec22js(cpVect v) { return vec22js((HMM_Vec2)v); }
2023-10-04 08:18:09 -05:00
2024-09-04 07:41:48 -05:00
void js2floatarr(JSValue v, int n, float *a) {
if (!JS_IsArray(js,v)) return;
for (int i = 0; i < n; i++)
a[i] = js2number(js_getpropidx(v,i));
}
JSValue floatarr2js(int n, float *a) {
JSValue arr = JS_NewArray(js);
for (int i = 0; i < n; i++)
js_setprop_num(arr, i, number2js(a[i]));
return arr;
}
2024-09-14 09:36:40 -05:00
float *js2newfloatarr(JSValue v)
{
float *arr = NULL;
for (int i = 0; i < js_arrlen(v); i++)
arrpush(arr, js2number(js_getpropidx(v,i)));
return arr;
}
2023-11-14 09:20:09 -06:00
HMM_Vec2 js2vec2(JSValue v)
2023-05-24 20:45:50 -05:00
{
HMM_Vec2 v2;
v2.X = js2number(js_getpropidx(v,0));
v2.Y = js2number(js_getpropidx(v,1));
return v2;
}
JSValue vec22js(HMM_Vec2 v)
{
JSValue array = JS_NewArray(js);
js_setprop_num(array,0,number2js(v.x));
js_setprop_num(array,1,number2js(v.y));
return array;
}
2024-01-14 10:24:31 -06:00
HMM_Vec3 js2vec3(JSValue v)
{
HMM_Vec3 v3;
v3.x = js2number(js_getpropidx(v,0));
v3.y = js2number(js_getpropidx(v,1));
v3.z = js2number(js_getpropidx(v,2));
return v3;
}
HMM_Vec3 js2vec3f(JSValue v)
{
HMM_Vec3 vec;
2024-08-19 07:47:27 -05:00
if (JS_IsArray(js, v))
return js2vec3(v);
else
vec.x = vec.y = vec.z = js2number(v);
return vec;
}
2024-01-14 10:24:31 -06:00
JSValue vec32js(HMM_Vec3 v)
{
JSValue array = JS_NewArray(js);
js_setprop_num(array,0,number2js(v.x));
js_setprop_num(array,1,number2js(v.y));
js_setprop_num(array,2,number2js(v.z));
return array;
}
JSValue vec3f2js(HMM_Vec3 v) { return vec32js(v); }
2024-05-12 18:36:14 -05:00
JSValue quat2js(HMM_Quat q)
{
JSValue arr = JS_NewArray(js);
js_setprop_num(arr, 0, number2js(q.x));
js_setprop_num(arr,1,number2js(q.y));
js_setprop_num(arr,2,number2js(q.z));
js_setprop_num(arr,3,number2js(q.w));
return arr;
}
2024-05-02 13:52:28 -05:00
HMM_Vec4 js2vec4(JSValue v)
{
HMM_Vec4 v4;
for (int i = 0; i < 4; i++)
v4.e[i] = js2number(js_getpropidx(v,i));
return v4;
}
double arr_vec_length(JSValue v)
{
int len = js_arrlen(v);
switch(len) {
case 2: return HMM_LenV2(js2vec2(v));
case 3: return HMM_LenV3(js2vec3(v));
case 4: return HMM_LenV4(js2vec4(v));
}
double sum = 0;
for (int i = 0; i < len; i++)
sum += pow(js2number(js_getpropidx(v, i)), 2);
return sqrt(sum);
}
2024-05-12 18:36:14 -05:00
HMM_Quat js2quat(JSValue v)
{
return js2vec4(v).quat;
}
2024-05-02 13:52:28 -05:00
JSValue vec42js(HMM_Vec4 v)
{
JSValue array = JS_NewArray(js);
for (int i = 0; i < 4; i++)
js_setprop_num(array,i,number2js(v.e[i]));
return array;
}
2023-05-12 13:22:05 -05:00
cpBitmask js2bitmask(JSValue v) {
2024-04-12 13:53:00 -05:00
cpBitmask a;
JS_ToUint32(js, &a, v);
return a;
}
2024-04-12 13:53:00 -05:00
JSValue bitmask2js(cpBitmask mask) { return JS_NewUint32(js, mask); }
2023-11-14 09:20:09 -06:00
HMM_Vec2 *js2cpvec2arr(JSValue v) {
2023-12-12 19:35:34 -06:00
HMM_Vec2 *arr = NULL;
2023-04-18 14:49:17 -05:00
int n = js_arrlen(v);
2023-12-18 06:45:27 -06:00
arrsetlen(arr,n);
2023-04-18 14:49:17 -05:00
for (int i = 0; i < n; i++)
2023-12-18 06:45:27 -06:00
arr[i] = js2vec2(js_getpropidx( v, i));
return arr;
}
2023-02-08 15:30:12 -06:00
2024-04-20 12:55:20 -05:00
HMM_Vec3 *js2cpvec3arr(JSValue v)
{
HMM_Vec3 *arr = NULL;
int n = js_arrlen(v);
arrsetlen(arr,n);
for (int i = 0; i < n; i++)
arr[i] = js2vec3(js_getpropidx(v,i));
return arr;
}
2023-12-18 06:45:27 -06:00
HMM_Vec2 *jsfloat2vec(JSValue v)
{
size_t s;
void *buf = JS_GetArrayBuffer(js, &s, v);
HMM_Vec2 *arr = NULL;
int n = s/2;
n /= sizeof(float);
2023-12-12 19:35:34 -06:00
return arr;
2023-02-08 15:30:12 -06:00
}
2023-11-14 09:20:09 -06:00
JSValue vecarr2js(HMM_Vec2 *points, int n) {
2023-04-19 16:58:17 -05:00
JSValue array = JS_NewArray(js);
2023-05-12 13:22:05 -05:00
for (int i = 0; i < n; i++)
js_setprop_num(array,i,vec22js(points[i]));
2023-04-18 14:49:17 -05:00
return array;
}
2023-10-10 17:37:58 -05:00
int js_print_exception(JSValue v)
{
if (!js) return 0;
2023-10-10 17:37:58 -05:00
#ifndef NDEBUG
if (!JS_IsException(v))
return 0;
JSValue ex = JS_GetException(js);
const char *name = JS_ToCString(js, js_getpropstr(ex, "name"));
const char *msg = js2str(js_getpropstr(ex, "message"));
const char *stack = js2str(js_getpropstr(ex, "stack"));
int line = 0;
mYughLog(LOG_SCRIPT, LOG_ERROR, line, "script", "%s :: %s\n%s", name, msg, stack);
JS_FreeCString(js, name);
JS_FreeCString(js, msg);
JS_FreeCString(js, stack);
JS_FreeValue(js,ex);
2024-08-08 17:32:58 -05:00
2023-10-10 17:37:58 -05:00
return 1;
#endif
return 0;
}
2023-09-05 09:38:52 -05:00
struct rect js2rect(JSValue v) {
struct rect rect;
2023-05-24 20:45:50 -05:00
rect.x = js2number(js_getpropstr(v, "x"));
rect.y = js2number(js_getpropstr(v, "y"));
2024-10-15 17:15:50 -05:00
rect.w = js2number(js_getpropstr(v, "width"));
rect.h = js2number(js_getpropstr(v, "height"));
2024-10-17 17:23:33 -05:00
float anchor_x = js2number(js_getpropstr(v, "anchor_x"));
float anchor_y = js2number(js_getpropstr(v, "anchor_y"));
rect.y -= anchor_y*rect.h;
rect.x -= anchor_x*rect.w;
2023-04-18 17:58:44 -05:00
return rect;
}
2023-09-05 09:38:52 -05:00
JSValue rect2js(struct rect rect) {
2023-04-18 17:58:44 -05:00
JSValue obj = JS_NewObject(js);
2024-03-18 14:27:52 -05:00
js_setprop_str(obj, "x", number2js(rect.x));
js_setprop_str(obj, "y", number2js(rect.y));
2024-10-18 12:51:21 -05:00
js_setprop_str(obj, "width", number2js(rect.w));
js_setprop_str(obj, "height", number2js(rect.h));
2023-04-18 17:58:44 -05:00
return obj;
}
2023-05-30 13:07:18 -05:00
JSValue bb2js(struct boundingbox bb)
{
JSValue obj = JS_NewObject(js);
2024-03-18 14:27:52 -05:00
js_setprop_str(obj,"t", number2js(bb.t));
js_setprop_str(obj,"b", number2js(bb.b));
js_setprop_str(obj,"r", number2js(bb.r));
js_setprop_str(obj,"l", number2js(bb.l));
2023-05-30 13:07:18 -05:00
return obj;
}
2023-05-12 13:22:05 -05:00
JSValue ints2js(int *ints) {
2023-04-19 16:58:17 -05:00
JSValue arr = JS_NewArray(js);
2023-04-18 17:58:44 -05:00
for (int i = 0; i < arrlen(ints); i++)
2024-03-18 14:27:52 -05:00
js_setprop_num(arr,i, number2js(ints[i]));
2023-04-18 17:58:44 -05:00
return arr;
2023-02-05 17:42:36 -06:00
}
2023-11-14 09:20:09 -06:00
int vec_between(HMM_Vec2 p, HMM_Vec2 a, HMM_Vec2 b) {
HMM_Vec2 n;
2023-02-10 14:31:58 -06:00
n.x = b.x - a.x;
n.y = b.y - a.y;
2023-11-14 09:20:09 -06:00
n = HMM_NormV2(n);
2023-02-10 14:31:58 -06:00
2023-11-14 09:20:09 -06:00
return HMM_DotV2(n, HMM_SubV2(p,a)) > 0 && HMM_DotV2(HMM_MulV2F(n, -1), HMM_SubV2(p,b)) > 0;
2023-02-10 14:31:58 -06:00
}
/* Determines between which two points in 'segs' point 'p' falls.
0 indicates 'p' comes before the first point.
arrlen(segs) indicates it comes after the last point.
*/
2023-11-14 09:20:09 -06:00
int point2segindex(HMM_Vec2 p, HMM_Vec2 *segs, double slop) {
2023-02-10 14:31:58 -06:00
float shortest = slop < 0 ? INFINITY : slop;
2023-02-08 15:30:12 -06:00
int best = -1;
2023-05-12 13:22:05 -05:00
for (int i = 0; i < arrlen(segs) - 1; i++) {
float a = (segs[i + 1].y - segs[i].y) / (segs[i + 1].x - segs[i].x);
2023-02-08 15:30:12 -06:00
float c = segs[i].y - (a * segs[i].x);
float b = -1;
float dist = fabsf(a * p.x + b * p.y + c) / sqrt(pow(a, 2) + 1);
2023-02-08 15:30:12 -06:00
2023-02-10 14:31:58 -06:00
if (dist > shortest) continue;
2023-05-12 13:22:05 -05:00
int between = vec_between(p, segs[i], segs[i + 1]);
2023-02-10 14:31:58 -06:00
if (between) {
2023-02-08 15:30:12 -06:00
shortest = dist;
2023-05-12 13:22:05 -05:00
best = i + 1;
2023-02-10 14:31:58 -06:00
} else {
2023-11-14 09:20:09 -06:00
if (i == 0 && HMM_DistV2(p,segs[0]) < slop) {
2023-02-10 14:31:58 -06:00
shortest = dist;
2023-05-12 13:22:05 -05:00
best = i;
2023-11-14 09:20:09 -06:00
} else if (i == arrlen(segs) - 2 && HMM_DistV2(p,arrlast(segs)) < slop) {
2023-02-10 14:31:58 -06:00
shortest = dist;
2023-05-12 13:22:05 -05:00
best = arrlen(segs);
2023-02-10 14:31:58 -06:00
}
2023-02-08 15:30:12 -06:00
}
}
2023-02-10 14:31:58 -06:00
if (best == 1) {
2023-11-14 09:20:09 -06:00
HMM_Vec2 n;
2023-05-12 13:22:05 -05:00
n.x = segs[1].x - segs[0].x;
n.y = segs[1].y - segs[0].y;
2023-11-14 09:20:09 -06:00
n = HMM_NormV2(n);
if (HMM_DotV2(n, HMM_SubV2(p,segs[0])) < 0 ){
if (HMM_DistV2(p, segs[0]) >= slop)
2023-02-10 14:31:58 -06:00
best = -1;
else
best = 0;
}
2023-02-08 15:30:12 -06:00
}
2023-05-12 13:22:05 -05:00
if (best == arrlen(segs) - 1) {
2023-11-14 09:20:09 -06:00
HMM_Vec2 n;
2023-05-12 13:22:05 -05:00
n.x = segs[best - 1].x - segs[best].x;
n.y = segs[best - 1].y - segs[best - 1].y;
2023-11-14 09:20:09 -06:00
n = HMM_NormV2(n);
2023-02-08 15:30:12 -06:00
2023-11-14 09:20:09 -06:00
if (HMM_DotV2(n, HMM_SubV2(p, segs[best])) < 0) {
if (HMM_DistV2(p, segs[best]) >= slop)
2023-02-10 14:31:58 -06:00
best = -1;
else
best = arrlen(segs);
}
2023-02-08 15:30:12 -06:00
}
return best;
}
2024-10-29 12:41:17 -05:00
/*JSC_GETSET(warp_gravity, strength, number)
2024-03-20 14:32:35 -05:00
JSC_GETSET(warp_gravity, decay, number)
JSC_GETSET(warp_gravity, spherical, boolean)
JSC_GETSET(warp_gravity, mask, bitmask)
JSC_GETSET(warp_gravity, planar_force, vec3)
2024-01-14 10:24:31 -06:00
static const JSCFunctionListEntry js_warp_gravity_funcs [] = {
CGETSET_ADD(warp_gravity, strength),
CGETSET_ADD(warp_gravity, decay),
CGETSET_ADD(warp_gravity, spherical),
CGETSET_ADD(warp_gravity, mask),
CGETSET_ADD(warp_gravity, planar_force),
};
2024-03-20 14:32:35 -05:00
JSC_GETSET(warp_damp, damp, vec3)
2024-01-14 10:24:31 -06:00
static const JSCFunctionListEntry js_warp_damp_funcs [] = {
CGETSET_ADD(warp_damp, damp)
};
2024-10-29 12:41:17 -05:00
*/
sg_bindings js2bind(JSValue v)
2024-05-06 21:59:22 -05:00
{
sg_bindings bind = {0};
JSValue attrib = js_getpropstr(v, "attrib");
2024-08-09 14:39:31 -05:00
2024-09-27 10:19:05 -05:00
for (int i = 0; i < js_arrlen(attrib); i++)
bind.vertex_buffers[i] = *js2sg_buffer(js_getpropidx(attrib,i));
JSValue index = js_getpropstr(v, "index");
if (!JS_IsUndefined(index))
bind.index_buffer = *js2sg_buffer(index);
JSValue imgs = js_getpropstr(v, "images");
JSValue samplers = js_getpropstr(v, "samplers");
for (int i = 0; i < js_arrlen(imgs); i++) {
bind.fs.images[i] = js2texture(js_getpropidx(imgs, i))->id;
int use_std = js2boolean(js_getpropidx(samplers, i));
bind.fs.samplers[i] = use_std ? std_sampler : tex_sampler;
2024-05-06 21:59:22 -05:00
}
2024-05-10 07:55:53 -05:00
JSValue ssbo = js_getpropstr(v, "ssbo");
2024-07-11 14:25:45 -05:00
for (int i = 0; i < js_arrlen(ssbo); i++)
2024-05-10 07:55:53 -05:00
bind.vs.storage_buffers[i] = *js2sg_buffer(js_getpropidx(ssbo,i));
2024-05-06 21:59:22 -05:00
return bind;
}
2024-05-12 18:36:14 -05:00
JSC_CCALL(render_flushtext,
2024-07-18 17:09:35 -05:00
sg_buffer *buf = js2sg_buffer(argv[0]);
int amt = text_flush(buf);
return number2js(amt);
)
JSC_CCALL(render_make_textssbo,
sg_buffer *b = malloc(sizeof(*b));
*b = sg_make_buffer(&(sg_buffer_desc){
.type = SG_BUFFERTYPE_STORAGEBUFFER,
.size = 4,
.usage = SG_USAGE_STREAM
});
return sg_buffer2js(b);
2024-05-12 18:36:14 -05:00
)
2024-05-03 16:26:40 -05:00
2024-05-16 14:50:18 -05:00
JSC_CCALL(render_glue_pass,
2024-05-08 11:07:19 -05:00
sg_begin_pass(&(sg_pass){
.swapchain = sglue_swapchain(),
.action = (sg_pass_action){
.colors[0] = {
.load_action = SG_LOADACTION_CLEAR,
.clear_value = (sg_color){0,0,0,1}
2024-10-03 09:31:06 -05:00
},
.stencil = { .clear_value = 1
2024-05-08 11:07:19 -05:00
}
}
2024-05-14 15:22:24 -05:00
});
2024-03-27 15:00:59 -05:00
)
2024-05-12 18:36:14 -05:00
2024-07-01 17:00:01 -05:00
// Set the portion of the window to be rendered to
2024-09-29 06:10:42 -05:00
JSC_CCALL(render_viewport,
2024-10-17 17:23:33 -05:00
rect view = js2rect(argv[0]);
sg_apply_viewportf(view.x, view.y,view.w,view.h, js2boolean(argv[1]));
2024-09-29 06:10:42 -05:00
)
2024-05-16 14:50:18 -05:00
2024-05-13 14:07:00 -05:00
JSC_CCALL(render_commit, sg_commit())
2024-05-16 14:50:18 -05:00
JSC_CCALL(render_end_pass, sg_end_pass())
2024-05-13 14:07:00 -05:00
HMM_Mat4 transform2view(transform *t)
{
HMM_Vec3 look = HMM_AddV3(t->pos, transform_direction(t, vFWD));
2024-10-17 17:23:33 -05:00
HMM_Mat4 ret = HMM_LookAt_RH(t->pos, look, vUP);
ret = HMM_MulM4(ret, HMM_Scale(t->scale));
return ret;
}
2024-05-16 14:50:18 -05:00
JSC_CCALL(render_camera_screen2world,
HMM_Mat4 view = transform2view(js2transform(js_getpropstr(argv[0], "transform")));
view = HMM_InvGeneralM4(view);
HMM_Vec4 p = js2vec4(argv[1]);
return vec42js(HMM_MulM4V4(view, p));
)
2024-10-17 17:23:33 -05:00
JSC_CCALL(render_set_projection_ortho,
lrtb extents = js2lrtb(argv[0]);
float near = js2number(argv[1]);
float far = js2number(argv[2]);
globalview.p = HMM_Orthographic_RH_NO(
extents.l,
extents.r,
extents.b,
extents.t,
near,
far
);
2024-10-16 07:53:05 -05:00
globalview.vp = HMM_MulM4(globalview.p, globalview.v);
)
2024-10-17 17:23:33 -05:00
JSC_CCALL(render_set_projection_perspective,
float fov = js2number(argv[0]);
float aspect = js2number(argv[1]);
float near = js2number(argv[2]);
float far = js2number(argv[3]);
globalview.p = HMM_Perspective_RH_NO(fov, aspect, near, far);
2024-10-16 07:53:05 -05:00
globalview.vp = HMM_MulM4(globalview.p, globalview.v);
)
2024-10-17 17:23:33 -05:00
JSC_CCALL(render_set_view,
globalview.v = transform2view(js2transform(argv[0]));
2024-05-12 18:36:14 -05:00
globalview.vp = HMM_MulM4(globalview.p, globalview.v);
)
2024-03-18 08:16:25 -05:00
2024-05-16 14:50:18 -05:00
sg_shader_uniform_block_desc js2uniform_block(JSValue v)
{
sg_shader_uniform_block_desc desc = {0};
int slot = js2number(js_getpropstr(v, "slot"));
desc.size = js2number(js_getpropstr(v, "size"));
desc.layout = SG_UNIFORMLAYOUT_STD140;
JSValue uniforms = js_getpropstr(v, "uniforms");
for (int j = 0; j < js_arrlen(uniforms); j++) {
JSValue uniform = js_getpropidx(uniforms, j);
desc.uniforms[j].name = js2strdup(js_getpropstr(v, "struct_name"));
desc.uniforms[j].array_count = js2number(js_getpropstr(uniform, "array_count"));
desc.uniforms[j].type = SG_UNIFORMTYPE_FLOAT4;
}
return desc;
}
2024-05-02 13:52:28 -05:00
sg_shader js2shader(JSValue v)
{
2024-04-30 10:32:27 -05:00
sg_shader_desc desc = {0};
2024-05-02 13:52:28 -05:00
JSValue prog = v;
2024-05-16 14:50:18 -05:00
desc.label = js2strdup(js_getpropstr(v, "name"));
2024-04-30 10:32:27 -05:00
JSValue vs = js_getpropstr(prog, "vs");
JSValue fs = js_getpropstr(prog, "fs");
2024-09-29 06:10:42 -05:00
const char *vsf = js2str(js_getpropstr(vs, "code"));
const char *fsf = js2str(js_getpropstr(fs, "code"));
2024-04-30 10:32:27 -05:00
desc.vs.source = vsf;
desc.fs.source = fsf;
2024-09-29 06:10:42 -05:00
const char *vsmain = js2str(js_getpropstr(vs, "entry_point"));
const char *fsmain = js2str(js_getpropstr(fs, "entry_point"));
2024-04-30 10:32:27 -05:00
desc.vs.entry = vsmain;
desc.fs.entry = fsmain;
2024-05-15 16:34:03 -05:00
desc.vs.d3d11_target = "vs_4_0";
desc.fs.d3d11_target = "ps_4_0";
JSValue attrs = js_getpropstr(vs, "inputs");
int atin = js_arrlen(attrs);
for (int i = 0; i < atin; i++) {
JSValue u = js_getpropidx(attrs, i);
2024-05-29 20:21:19 -05:00
int slot = js2number(js_getpropstr(u, "slot"));
desc.attrs[slot].sem_name = js2strdup(js_getpropstr(u,"sem_name"));
desc.attrs[slot].sem_index = js2number(js_getpropstr(u, "sem_index"));
2024-05-15 16:34:03 -05:00
}
2024-05-16 14:50:18 -05:00
2024-04-30 10:32:27 -05:00
JSValue vsu = js_getpropstr(vs, "uniform_blocks");
2024-05-16 14:50:18 -05:00
for (int i = 0; i < js_arrlen(vsu); i++)
desc.vs.uniform_blocks[i] = js2uniform_block(js_getpropidx(vsu, i));
2024-04-30 10:32:27 -05:00
JSValue fsu = js_getpropstr(fs, "uniform_blocks");
2024-05-16 14:50:18 -05:00
for (int i = 0; i < js_arrlen(fsu); i++)
desc.fs.uniform_blocks[i] = js2uniform_block(js_getpropidx(fsu, i));
2024-04-30 10:32:27 -05:00
JSValue imgs = js_getpropstr(fs, "images");
2024-05-16 14:50:18 -05:00
for (int i = 0; i < js_arrlen(imgs); i++) {
2024-04-30 10:32:27 -05:00
JSValue u = js_getpropidx(imgs, i);
int slot = js2number(js_getpropstr(u, "slot"));
desc.fs.images[i].used = true;
desc.fs.images[i].multisampled = js2boolean(js_getpropstr(u, "multisampled"));
desc.fs.images[i].image_type = SG_IMAGETYPE_2D;
desc.fs.images[i].sample_type = SG_IMAGESAMPLETYPE_FLOAT;
}
JSValue samps = js_getpropstr(fs, "samplers");
2024-05-16 14:50:18 -05:00
for (int i = 0; i < js_arrlen(samps); i++) {
JSValue sampler = js_getpropidx(samps, i);
2024-04-30 10:32:27 -05:00
desc.fs.samplers[0].used = true;
desc.fs.samplers[0].sampler_type = SG_SAMPLERTYPE_FILTERING;
}
JSValue pairs = js_getpropstr(fs, "image_sampler_pairs");
2024-05-16 14:50:18 -05:00
for (int i = 0; i < js_arrlen(pairs); i++) {
JSValue pair = js_getpropidx(pairs, i);
2024-04-30 10:32:27 -05:00
desc.fs.image_sampler_pairs[0].used = true;
desc.fs.image_sampler_pairs[0].image_slot = js2number(js_getpropstr(pair, "slot"));
2024-04-30 10:32:27 -05:00
desc.fs.image_sampler_pairs[0].sampler_slot = 0;
2024-05-16 14:50:18 -05:00
desc.fs.image_sampler_pairs[0].glsl_name = js2strdup(js_getpropstr(pair, "name"));
2024-04-30 10:32:27 -05:00
}
2024-05-10 07:55:53 -05:00
JSValue ssbos = js_getpropstr(vs, "storage_buffers");
2024-05-16 14:50:18 -05:00
for (int i = 0; i < js_arrlen(ssbos); i++) {
2024-05-10 07:55:53 -05:00
desc.vs.storage_buffers[i].used = true;
desc.vs.storage_buffers[i].readonly = true;
}
2024-05-02 13:52:28 -05:00
sg_shader sh = sg_make_shader(&desc);
jsfreestr(vsf);
jsfreestr(fsf);
jsfreestr(vsmain);
jsfreestr(fsmain);
return sh;
}
2024-08-08 17:32:58 -05:00
static int mat2type(int mat)
{
switch(mat) {
case MAT_POS:
case MAT_NORM:
return SG_VERTEXFORMAT_FLOAT3;
case MAT_PPOS:
case MAT_WH:
case MAT_ST:
return SG_VERTEXFORMAT_FLOAT2;
case MAT_UV:
return SG_VERTEXFORMAT_USHORT2N;
2024-08-09 14:39:31 -05:00
case MAT_TAN:
2024-08-08 17:32:58 -05:00
return SG_VERTEXFORMAT_UINT10_N2;
case MAT_BONE:
return SG_VERTEXFORMAT_UBYTE4;
case MAT_WEIGHT:
case MAT_COLOR:
return SG_VERTEXFORMAT_UBYTE4N;
case MAT_ANGLE:
case MAT_SCALE:
return SG_VERTEXFORMAT_FLOAT;
};
2024-08-09 14:39:31 -05:00
return -1;
2024-08-08 17:32:58 -05:00
}
2024-10-13 19:44:28 -05:00
sg_vertex_layout_state js2vertex_layout(JSValue v)
2024-05-06 21:59:22 -05:00
{
sg_vertex_layout_state st = {0};
JSValue inputs = js_getpropstr(js_getpropstr(v, "vs"), "inputs");
for (int i = 0; i < js_arrlen(inputs); i++) {
JSValue attr = js_getpropidx(inputs, i);
int slot = js2number(js_getpropstr(attr, "slot"));
int mat = js2number(js_getpropstr(attr, "mat"));
st.attrs[slot].format = mat2type(mat);
st.attrs[slot].buffer_index = slot;
}
return st;
}
2024-10-03 09:31:06 -05:00
sg_depth_state js2depth(JSValue v)
{
sg_depth_state depth = {0};
depth.compare = js2number(js_getpropstr(v, "compare"));
depth.write_enabled = js2boolean(js_getpropstr(v, "write"));
depth.bias = js2number(js_getpropstr(v, "bias"));
depth.bias_slope_scale = js2number(js_getpropstr(v, "bias_slope_scale"));
depth.bias_clamp = js2number(js_getpropstr(v, "bias_clamp"));
return depth;
}
sg_stencil_face_state js2face_state(JSValue v)
{
sg_stencil_face_state face = {0};
face.compare = js2number(js_getpropstr(v, "compare"));
face.fail_op = js2number(js_getpropstr(v, "fail"));
face.depth_fail_op = js2number(js_getpropstr(v, "depth_fail"));
face.pass_op = js2number(js_getpropstr(v, "pass_op"));
return face;
}
sg_stencil_state js2stencil(JSValue v)
{
sg_stencil_state stencil = {0};
stencil.enabled = js2boolean(js_getpropstr(v, "enabled"));
stencil.read_mask = js2boolean(js_getpropstr(v, "read")) ? 0xFF : 0x00;
stencil.write_mask = js2boolean(js_getpropstr(v, "write")) ? 0xFF : 0x00;
stencil.front = js2face_state(js_getpropstr(v, "front"));
stencil.back = js2face_state(js_getpropstr(v, "back"));
2024-10-04 00:45:44 -05:00
stencil.ref = js2number(js_getpropstr(v, "ref"));
2024-10-03 09:31:06 -05:00
return stencil;
}
#define GETNUMVALUE(STRUCT, NAME) STRUCT.NAME = js2number(js_getpropstr(v, #NAME));
sg_blend_state js2blend(JSValue v)
{
sg_blend_state blend = {0};
blend.enabled = js2boolean(js_getpropstr(v, "enabled"));
GETNUMVALUE(blend, src_factor_rgb);
GETNUMVALUE(blend, dst_factor_rgb);
GETNUMVALUE(blend, op_rgb);
GETNUMVALUE(blend, src_factor_alpha);
GETNUMVALUE(blend, dst_factor_alpha);
GETNUMVALUE(blend, op_alpha);
return blend;
}
2024-10-03 23:35:40 -05:00
JSC_CCALL(render_make_pipeline,
2024-05-06 21:59:22 -05:00
sg_pipeline_desc p = {0};
p.shader = js2shader(argv[0]);
2024-10-13 19:44:28 -05:00
p.layout = js2vertex_layout(argv[0]);
2024-05-08 11:07:19 -05:00
p.primitive_type = js2number(js_getpropstr(argv[0], "primitive"));
2024-05-16 08:21:13 -05:00
if (js2boolean(js_getpropstr(argv[0], "indexed")))
p.index_type = SG_INDEXTYPE_UINT16;
2024-04-30 10:32:27 -05:00
2024-10-03 09:31:06 -05:00
JSValue pipe = argv[1];
p.primitive_type = js2number(js_getpropstr(pipe, "primitive"));
p.cull_mode = js2number(js_getpropstr(pipe, "cull"));
p.face_winding = js2number(js_getpropstr(pipe, "face"));
p.colors[0].blend = js2blend(js_getpropstr(pipe, "blend"));
p.colors[0].write_mask = js2number(js_getpropstr(pipe, "write_mask"));
p.alpha_to_coverage_enabled = js2boolean(js_getpropstr(pipe, "alpha_to_coverage"));
p.depth = js2depth(js_getpropstr(pipe, "depth"));
p.stencil = js2stencil(js_getpropstr(pipe, "stencil"));
sg_pipeline *g = malloc(sizeof(*g));
*g = sg_make_pipeline(&p);
return sg_pipeline2js(g);
2024-04-30 10:32:27 -05:00
)
2024-05-02 13:52:28 -05:00
JSC_CCALL(render_setuniv,
2024-05-09 21:15:19 -05:00
HMM_Vec4 f = {0};
f.x = js2number(argv[2]);
2024-05-02 13:52:28 -05:00
sg_apply_uniforms(js2number(argv[0]), js2number(argv[1]), SG_RANGE_REF(f));
2024-04-30 10:32:27 -05:00
)
2024-05-02 13:52:28 -05:00
JSC_CCALL(render_setuniv2,
2024-10-29 12:41:17 -05:00
HMM_Vec4 v = {0};
2024-05-09 21:15:19 -05:00
v.xy = js2vec2(argv[2]);
2024-05-02 13:52:28 -05:00
sg_apply_uniforms(js2number(argv[0]), js2number(argv[1]), SG_RANGE_REF(v.e));
2024-04-30 10:32:27 -05:00
)
JSC_CCALL(render_setuniv3,
2024-05-09 21:15:19 -05:00
HMM_Vec4 f = {0};
f.xyz = js2vec3(argv[2]);
sg_apply_uniforms(js2number(argv[0]), js2number(argv[1]), SG_RANGE_REF(f.e));
2024-04-30 10:32:27 -05:00
)
2024-05-02 13:52:28 -05:00
JSC_CCALL(render_setuniv4,
2024-05-09 21:15:19 -05:00
HMM_Vec4 v = {0};
if (JS_IsArray(js, argv[2])) {
for (int i = 0; i < js_arrlen(argv[2]); i++)
v.e[i] = js2number(js_getpropidx(argv[2], i));
} else
v.x = js2number(argv[2]);
2024-05-02 13:52:28 -05:00
sg_apply_uniforms(js2number(argv[0]), js2number(argv[1]), SG_RANGE_REF(v.e));
)
JSC_CCALL(render_setuniproj,
2024-10-29 12:41:17 -05:00
sg_apply_uniforms(js2number(argv[0]), js2number(argv[1]), SG_RANGE_REF(globalview.p.e));
2024-05-13 14:07:00 -05:00
)
JSC_CCALL(render_setuniview,
2024-10-29 12:41:17 -05:00
sg_apply_uniforms(js2number(argv[0]), js2number(argv[1]), SG_RANGE_REF(globalview.v.e));
2024-05-13 14:07:00 -05:00
)
JSC_CCALL(render_setunivp,
2024-10-29 12:41:17 -05:00
sg_apply_uniforms(js2number(argv[0]), js2number(argv[1]), SG_RANGE_REF(globalview.vp.e));
2024-05-02 13:52:28 -05:00
)
2024-08-09 14:39:31 -05:00
JSC_CCALL(render_setunibones,
skin *sk = js2skin(argv[2]);
sg_apply_uniforms(js2number(argv[0]), js2number(argv[1]), SG_RANGE_REF(sk->binds));
)
2024-05-02 13:52:28 -05:00
JSC_CCALL(render_setunim4,
2024-05-02 17:13:09 -05:00
HMM_Mat4 m = MAT1;
if (JS_IsArray(js, argv[2])) {
JSValue arr = argv[2];
int n = js_arrlen(arr);
if (n == 1)
2024-07-23 14:30:41 -05:00
m = transform2mat(js2transform(js_getpropidx(arr,0)));
2024-05-02 17:13:09 -05:00
else {
for (int i = 0; i < n; i++) {
2024-07-23 14:30:41 -05:00
HMM_Mat4 p = transform2mat(js2transform(js_getpropidx(arr, i)));
2024-05-02 17:13:09 -05:00
m = HMM_MulM4(p,m);
}
}
2024-05-21 09:33:17 -05:00
} else if (!JS_IsUndefined(argv[2]))
2024-07-23 14:30:41 -05:00
m = transform2mat(js2transform(argv[2]));
2024-05-16 14:50:18 -05:00
2024-05-02 13:52:28 -05:00
sg_apply_uniforms(js2number(argv[0]), js2number(argv[1]), SG_RANGE_REF(m.e));
2024-05-12 18:36:14 -05:00
);
2024-05-02 13:52:28 -05:00
2024-07-11 14:25:45 -05:00
JSC_CCALL(render_setbind,
sg_bindings bind = js2bind(argv[0]);
2024-04-30 10:32:27 -05:00
sg_apply_bindings(&bind);
2024-07-11 14:25:45 -05:00
)
2024-07-22 15:40:58 -05:00
typedef struct particle_ss {
HMM_Mat4 model;
HMM_Vec4 color;
} particle_ss;
JSC_CCALL(render_make_particle_ssbo,
JSValue array = argv[0];
size_t size = js_arrlen(array)*(sizeof(particle_ss));
sg_buffer *b = js2sg_buffer(argv[1]);
if (!b) return JS_UNDEFINED;
particle_ss ms[js_arrlen(array)];
if (sg_query_buffer_will_overflow(*b, size)) {
2024-09-29 06:10:42 -05:00
sg_buffer_desc desc = sg_query_buffer_desc(*b);
2024-07-22 15:40:58 -05:00
sg_destroy_buffer(*b);
2024-09-29 06:10:42 -05:00
2024-07-22 15:40:58 -05:00
*b = sg_make_buffer(&(sg_buffer_desc){
.type = SG_BUFFERTYPE_STORAGEBUFFER,
2024-09-29 06:10:42 -05:00
.size = size+desc.size,
2024-07-22 15:40:58 -05:00
.usage = SG_USAGE_STREAM,
.label = "particle ssbo buffer"
2024-07-22 15:40:58 -05:00
});
}
for (int i = 0; i < js_arrlen(array); i++) {
JSValue sub = js_getpropidx(array,i);
2024-07-23 14:30:41 -05:00
ms[i].model = transform2mat(js2transform(js_getpropstr(sub, "transform")));
2024-07-22 19:07:02 -05:00
ms[i].color = js2vec4(js_getpropstr(sub,"color"));
2024-07-22 15:40:58 -05:00
}
2024-09-29 06:10:42 -05:00
int offset = sg_append_buffer(*b, (&(sg_range){
2024-07-22 15:40:58 -05:00
.ptr = ms,
.size = size
}));
2024-09-29 06:10:42 -05:00
ret = number2js(offset/sizeof(particle_ss));
2024-07-22 19:07:02 -05:00
)
typedef struct sprite_ss {
HMM_Mat4 model;
2024-10-17 22:59:59 -05:00
rect rect;
2024-09-10 14:33:49 -05:00
HMM_Vec4 shade;
2024-07-22 19:07:02 -05:00
} sprite_ss;
JSC_CCALL(render_make_sprite_ssbo,
JSValue array = argv[0];
size_t size = js_arrlen(array)*(sizeof(sprite_ss));
sg_buffer *b = js2sg_buffer(argv[1]);
if (!b) return JS_UNDEFINED;
sprite_ss ms[js_arrlen(array)];
2024-07-22 19:07:02 -05:00
if (sg_query_buffer_will_overflow(*b, size)) {
2024-09-29 06:10:42 -05:00
sg_buffer_desc desc = sg_query_buffer_desc(*b);
2024-07-22 19:07:02 -05:00
sg_destroy_buffer(*b);
*b = sg_make_buffer(&(sg_buffer_desc){
.type = SG_BUFFERTYPE_STORAGEBUFFER,
2024-09-29 06:10:42 -05:00
.size = size+desc.size,
2024-07-22 19:07:02 -05:00
.usage = SG_USAGE_STREAM,
.label = "sprite ssbo buffer"
2024-07-22 19:07:02 -05:00
});
}
2024-07-22 15:40:58 -05:00
2024-07-22 19:07:02 -05:00
for (int i = 0; i < js_arrlen(array); i++) {
JSValue sub = js_getpropidx(array,i);
2024-09-27 10:19:05 -05:00
2024-10-29 12:41:17 -05:00
// transform *tr = js2transform(js_getpropstr(sub, "transform"));
2024-10-05 08:43:51 -05:00
JSValue image = js_getpropstr(sub, "image");
2024-09-27 14:30:15 -05:00
2024-10-29 12:41:17 -05:00
ms[i].model = js2transform_mat(js, js_getpropstr(sub,"transform"));// transform2mat(tr);
2024-10-17 22:59:59 -05:00
ms[i].rect = js2rect(js_getpropstr(image,"rect"));
2024-09-10 14:33:49 -05:00
ms[i].shade = js2vec4(js_getpropstr(sub,"shade"));
2024-07-22 19:07:02 -05:00
}
2024-09-29 06:10:42 -05:00
int offset = sg_append_buffer(*b, (&(sg_range){
2024-07-22 19:07:02 -05:00
.ptr = ms,
.size = size
}));
2024-10-19 18:37:27 -05:00
ret = number2js(offset/96); // 96 size of a sprite struct
2024-07-22 15:40:58 -05:00
)
2024-07-11 14:25:45 -05:00
JSC_CCALL(render_make_t_ssbo,
JSValue array = argv[0];
2024-07-22 15:40:58 -05:00
size_t size = js_arrlen(array)*sizeof(HMM_Mat4);
sg_buffer *b = js2sg_buffer(argv[1]);
if (!b) return JS_UNDEFINED;
2024-07-11 14:25:45 -05:00
HMM_Mat4 ms[js_arrlen(array)];
2024-07-22 15:40:58 -05:00
if (sg_query_buffer_will_overflow(*b, size)) {
sg_destroy_buffer(*b);
*b = sg_make_buffer(&(sg_buffer_desc){
.type = SG_BUFFERTYPE_STORAGEBUFFER,
.size = size,
.usage = SG_USAGE_STREAM,
.label = "transform buffer"
});
}
2024-07-11 14:25:45 -05:00
for (int i = 0; i < js_arrlen(array); i++)
2024-07-23 14:30:41 -05:00
ms[i] = transform2mat(js2transform(js_getpropidx(array, i)));
2024-07-11 14:25:45 -05:00
2024-07-22 15:40:58 -05:00
sg_append_buffer(*b, (&(sg_range){
.ptr = ms,
.size = size
}));
2024-07-11 14:25:45 -05:00
)
JSC_CCALL(render_spdraw,
2024-09-07 00:11:34 -05:00
sg_draw(js2number(argv[0]),js2number(argv[1]),js2number(argv[2]));
2024-04-30 10:32:27 -05:00
)
2024-10-03 09:31:06 -05:00
JSC_CCALL(render_setpipeline, sg_apply_pipeline(*js2sg_pipeline(argv[0]));)
2024-06-05 16:07:44 -05:00
2024-10-15 07:55:49 -05:00
JSC_SCALL(render_text_size,
font *f = js2font(argv[1]);
float size = js2number(argv[2]);
if (!size) size = f->height;
float letterSpacing = js2number(argv[3]);
float wrap = js2number(argv[4]);
ret = vec22js(measure_text(str, f, size, letterSpacing, wrap));
)
2024-03-18 08:16:25 -05:00
static const JSCFunctionListEntry js_render_funcs[] = {
2024-07-18 17:09:35 -05:00
MIST_FUNC_DEF(render, flushtext, 1),
MIST_FUNC_DEF(render, camera_screen2world, 2),
2024-07-18 17:09:35 -05:00
MIST_FUNC_DEF(render, make_textssbo, 0),
2024-05-16 14:50:18 -05:00
MIST_FUNC_DEF(render, viewport, 4),
MIST_FUNC_DEF(render, end_pass, 0),
MIST_FUNC_DEF(render, commit, 0),
MIST_FUNC_DEF(render, glue_pass, 0),
2024-10-15 07:55:49 -05:00
MIST_FUNC_DEF(render, text_size, 5),
2024-10-17 17:23:33 -05:00
MIST_FUNC_DEF(render, set_projection_ortho, 3),
MIST_FUNC_DEF(render, set_projection_perspective, 4),
2024-10-16 07:53:05 -05:00
MIST_FUNC_DEF(render, set_view, 1),
2024-10-03 23:35:40 -05:00
MIST_FUNC_DEF(render, make_pipeline, 1),
2024-04-30 10:32:27 -05:00
MIST_FUNC_DEF(render, setuniv3, 2),
MIST_FUNC_DEF(render, setuniv, 2),
2024-09-07 00:11:34 -05:00
MIST_FUNC_DEF(render, spdraw, 3),
2024-08-09 14:39:31 -05:00
MIST_FUNC_DEF(render, setunibones, 3),
2024-07-11 14:25:45 -05:00
MIST_FUNC_DEF(render, setbind, 1),
2024-05-02 13:52:28 -05:00
MIST_FUNC_DEF(render, setuniproj, 2),
2024-05-13 14:07:00 -05:00
MIST_FUNC_DEF(render, setuniview, 2),
MIST_FUNC_DEF(render, setunivp, 2),
2024-05-02 13:52:28 -05:00
MIST_FUNC_DEF(render, setunim4, 3),
MIST_FUNC_DEF(render, setuniv2, 2),
MIST_FUNC_DEF(render, setuniv4, 2),
2024-05-13 14:07:00 -05:00
MIST_FUNC_DEF(render, setpipeline, 1),
2024-07-22 15:40:58 -05:00
MIST_FUNC_DEF(render, make_t_ssbo, 2),
2024-07-22 19:07:02 -05:00
MIST_FUNC_DEF(render, make_particle_ssbo, 2),
MIST_FUNC_DEF(render, make_sprite_ssbo, 2)
2024-03-18 08:16:25 -05:00
};
2024-09-29 06:10:42 -05:00
JSC_DCALL(sgl_enable_texture)
JSC_DCALL(sgl_disable_texture)
JSC_CCALL(sgl_texture, sgl_texture(js2texture(argv[0])->id, std_sampler))
JSC_DCALL(sgl_matrix_mode_modelview)
JSC_DCALL(sgl_matrix_mode_projection)
JSC_DCALL(sgl_matrix_mode_texture)
JSC_DCALL(sgl_load_identity)
JSC_CCALL(sgl_translate,
HMM_Vec3 v = js2vec3(argv[0]);
sgl_translate(v.x,v.y,v.z);
)
JSC_CCALL(sgl_rotate,
float rad = js2angle(argv[0]);
HMM_Vec3 axis = js2vec3(argv[1]);
sgl_rotate(rad, axis.x, axis.y, axis.z);
)
JSC_CCALL(sgl_scale,
HMM_Vec3 v = js2vec3(argv[0]);
sgl_scale(v.x, v.y, v.z);
)
JSC_CCALL(sgl_load_matrix,
transform *t = js2transform(argv[0]);
sgl_load_matrix(t->cache.e);
)
JSC_6CALL(sgl_frustum)
JSC_6CALL(sgl_ortho)
JSC_4CALL(sgl_perspective)
JSC_DCALL(sgl_push_matrix)
JSC_DCALL(sgl_pop_matrix)
JSC_1CALL(sgl_point_size)
JSC_DCALL(sgl_begin_points)
JSC_DCALL(sgl_begin_lines)
JSC_DCALL(sgl_begin_line_strip)
JSC_DCALL(sgl_begin_triangles)
JSC_DCALL(sgl_begin_triangle_strip)
JSC_DCALL(sgl_begin_quads)
JSC_DCALL(sgl_end)
JSC_DCALL(sgl_draw)
JSC_1CALL(sgl_layer)
JSC_1CALL(sgl_draw_layer)
JSC_CCALL(sgl_image,
texture *t = js2texture(argv[0]);
// transform *tr = js2transform(argv[1]);
HMM_Vec4 rect = js2vec4(argv[2]);
HMM_Vec4 color = js2vec4(argv[3]);
sgl_begin_quads();
sgl_c4f(color.r, color.g, color.b, color.a);
sgl_v2f(0,0);
sgl_v2f(0,1);
sgl_v2f(1,1);
sgl_v2f(1,0);
sgl_end();
// sgl_defaults();
)
JSC_CCALL(sgl_image_array,
JSValue array = argv[0];
sgl_begin_quads();
for (int i = 0; i < js_arrlen(array); i++) {
sgl_v2f(0,0);
sgl_v2f(0,1);
sgl_v2f(1,1);
sgl_v2f(1,0);
}
sgl_end();
)
static const JSCFunctionListEntry js_sgl_funcs[] = {
MIST_FUNC_DEF(sgl, enable_texture, 0),
MIST_FUNC_DEF(sgl, disable_texture, 0),
MIST_FUNC_DEF(sgl, texture, 1),
MIST_FUNC_DEF(sgl, matrix_mode_modelview, 0),
MIST_FUNC_DEF(sgl, matrix_mode_projection, 0),
MIST_FUNC_DEF(sgl, matrix_mode_texture, 0),
MIST_FUNC_DEF(sgl, load_identity, 0),
MIST_FUNC_DEF(sgl, translate, 1),
MIST_FUNC_DEF(sgl, rotate, 2),
MIST_FUNC_DEF(sgl, scale, 1),
MIST_FUNC_DEF(sgl, load_matrix, 1),
MIST_FUNC_DEF(sgl, frustum, 6),
MIST_FUNC_DEF(sgl, ortho, 6),
MIST_FUNC_DEF(sgl, perspective, 4),
MIST_FUNC_DEF(sgl, push_matrix, 0),
MIST_FUNC_DEF(sgl, pop_matrix, 0),
MIST_FUNC_DEF(sgl, point_size, 1),
MIST_FUNC_DEF(sgl, draw, 0),
MIST_FUNC_DEF(sgl, layer, 1),
MIST_FUNC_DEF(sgl, draw_layer, 1),
MIST_FUNC_DEF(sgl, image, 4),
MIST_FUNC_DEF(sgl, image_array, 1),
};
JSC_CCALL(gui_scissor,
sg_apply_scissor_rect(js2number(argv[0]), js2number(argv[1]), js2number(argv[2]), js2number(argv[3]), 0);
)
2024-10-15 07:55:49 -05:00
JSC_CCALL(gui_text,
const char *s = JS_ToCString(js, argv[0]);
2024-03-19 14:39:19 -05:00
HMM_Vec2 pos = js2vec2(argv[1]);
float size = js2number(argv[2]);
2024-10-15 17:15:50 -05:00
font *f = js2font(argv[5]);
if (!size) size = f->height;
2024-03-19 14:39:19 -05:00
struct rgba c = js2color(argv[3]);
int wrap = js2number(argv[4]);
2024-10-15 17:15:50 -05:00
renderText(s, pos, f, size, c, wrap);
2024-10-15 07:55:49 -05:00
JS_FreeCString(js, s);
return ret;
2024-03-19 14:39:19 -05:00
)
2024-03-18 08:16:25 -05:00
static const JSCFunctionListEntry js_gui_funcs[] = {
MIST_FUNC_DEF(gui, scissor, 4),
2024-03-19 14:39:19 -05:00
MIST_FUNC_DEF(gui, text, 6),
2024-03-18 08:16:25 -05:00
};
2024-03-19 14:39:19 -05:00
JSC_CCALL(spline_catmull,
HMM_Vec2 *points = js2cpvec2arr(argv[0]);
float param = js2number(argv[1]);
HMM_Vec2 *samples = catmull_rom_ma_v2(points,param);
arrfree(points);
if (!samples) return JS_UNDEFINED;
JSValue arr = vecarr2js(samples, arrlen(samples));
arrfree(samples);
return arr;
)
JSC_CCALL(spline_bezier,
HMM_Vec2 *points = js2cpvec2arr(argv[0]);
float param = js2number(argv[1]);
HMM_Vec2 *samples = catmull_rom_ma_v2(points,param);
arrfree(points);
if (!samples) return JS_UNDEFINED;
JSValue arr = vecarr2js(samples, arrlen(samples));
arrfree(samples);
return arr;
)
static const JSCFunctionListEntry js_spline_funcs[] = {
MIST_FUNC_DEF(spline, catmull, 2),
MIST_FUNC_DEF(spline, bezier, 2)
};
2024-05-21 18:50:53 -05:00
JSValue js_vector_dot(JSContext *js, JSValue self, int argc, JSValue *argv) { return number2js(HMM_DotV2(js2vec2(argv[0]), js2vec2(argv[1]))) ; };
2024-03-18 08:16:25 -05:00
2024-03-20 14:32:35 -05:00
JSC_CCALL(vector_project, return vec22js(HMM_ProjV2(js2vec2(argv[0]), js2vec2(argv[1]))))
JSC_CCALL(vector_midpoint,
HMM_Vec2 a = js2vec2(argv[0]);
HMM_Vec2 b = js2vec2(argv[1]);
// HMM_Vec2 c = HMM_AddV2(a,b);
// c = HMM_DivV2F(c, 2);
return vec22js((HMM_Vec2){(a.x+b.x)/2, (a.y+b.y)/2});
)
JSC_CCALL(vector_distance,
HMM_Vec2 a = js2vec2(argv[0]);
HMM_Vec2 b = js2vec2(argv[1]);
return number2js(HMM_DistV2(a,b));
)
JSC_CCALL(vector_angle,
HMM_Vec2 a = js2vec2(argv[0]);
return angle2js(atan2(a.y,a.x));
)
2024-05-08 11:07:19 -05:00
/* Given a series of points p, computes a new series with them expanded on either side by d */
HMM_Vec2 *inflatepoints(HMM_Vec2 *p, float d, int n)
{
if (d == 0) {
HMM_Vec2 *ret = NULL;
arraddn(ret,n);
for (int i = 0; i < n; i++)
ret[i] = p[i];
return ret;
}
parsl_position par_v[n];
uint16_t spine_lens[] = {n};
for (int i = 0; i < n; i++) {
par_v[i].x = p[i].x;
par_v[i].y = p[i].y;
};
parsl_context *par_ctx = parsl_create_context((parsl_config){
.thickness = d,
.flags= PARSL_FLAG_ANNOTATIONS,
.u_mode = PAR_U_MODE_DISTANCE
});
parsl_mesh *mesh = parsl_mesh_from_lines(par_ctx, (parsl_spine_list){
.num_vertices = n,
.num_spines = 1,
.vertices = par_v,
.spine_lengths = spine_lens,
.closed = 0,
});
HMM_Vec2 *ret = NULL;
arraddn(ret,mesh->num_vertices);
for (int i = 0; i < mesh->num_vertices; i++) {
ret[i].x = mesh->positions[i].x;
ret[i].y = mesh->positions[i].y;
};
return ret;
}
2024-03-20 14:32:35 -05:00
JSC_CCALL(vector_inflate,
HMM_Vec2 *p = js2cpvec2arr(argv[0]);
double d = js2number(argv[1]);
HMM_Vec2 *infl = inflatepoints(p,d, js_arrlen(argv[0]));
ret = vecarr2js(infl, arrlen(infl));
arrfree(infl);
arrfree(p);
)
2024-03-18 14:27:52 -05:00
2024-07-24 08:26:29 -05:00
JSC_CCALL(vector_rotate,
HMM_Vec2 vec = js2vec2(argv[0]);
double angle = js2angle(argv[1]);
2024-08-29 10:20:22 -05:00
HMM_Vec2 pivot = JS_IsUndefined(argv[2]) ? v2zero : js2vec2(argv[2]);
vec = HMM_SubV2(vec,pivot);
float r = HMM_LenV2(vec);
2024-07-24 08:26:29 -05:00
angle += atan2(vec.y,vec.x);
vec.x = r*cos(angle);
vec.y = r*sin(angle);
2024-08-29 10:20:22 -05:00
return vec22js(HMM_AddV2(vec,pivot));
2024-07-24 08:26:29 -05:00
)
JSC_CCALL(vector_add,
HMM_Vec4 a = js2vec4(argv[0]);
HMM_Vec4 b = js2vec4(argv[1]);
HMM_Vec4 c = HMM_AddV4(a,b);
return vec42js(c);
)
JSC_CCALL(vector_norm,
int len = js_arrlen(argv[0]);
switch(len) {
case 2: return vec22js(HMM_NormV2(js2vec2(argv[0])));
case 3: return vec32js(HMM_NormV3(js2vec3(argv[0])));
case 4: return vec42js(HMM_NormV4(js2vec4(argv[0])));
}
double length = arr_vec_length(argv[0]);
JSValue newarr = JS_NewArray(js);
for (int i = 0; i < len; i++)
js_setprop_num(newarr, i, number2js(js2number(js_getpropidx(argv[0],i))/length));
return newarr;
)
JSC_CCALL(vector_angle_between,
int len = js_arrlen(argv[0]);
switch(len) {
case 2: return angle2js(HMM_AngleV2(js2vec2(argv[0]), js2vec2(argv[1])));
case 3: return angle2js(HMM_AngleV3(js2vec3(argv[0]), js2vec3(argv[1])));
case 4: return angle2js(HMM_AngleV4(js2vec4(argv[0]), js2vec4(argv[1])));
}
return angle2js(0);
)
JSC_CCALL(vector_lerp,
double s = js2number(argv[0]);
double f = js2number(argv[1]);
double t = js2number(argv[2]);
return number2js((f-s)*t+s);
)
int gcd(int a, int b) {
if (b == 0)
return a;
return gcd(b, a % b);
}
JSC_CCALL(vector_gcd,
return number2js(gcd(js2number(argv[0]), js2number(argv[1])));
)
JSC_CCALL(vector_lcm,
double a = js2number(argv[0]);
double b = js2number(argv[1]);
return number2js((a*b)/gcd(a,b));
)
JSC_CCALL(vector_clamp,
double x = js2number(argv[0]);
double l = js2number(argv[1]);
double h = js2number(argv[2]);
return number2js(x > h ? h : x < l ? l : x);
)
JSC_SSCALL(vector_trimchr,
int len = js2number(js_getpropstr(argv[0], "length"));
2024-09-29 06:10:42 -05:00
const char *start = str;
while (*start == *str2)
start++;
2024-09-29 06:10:42 -05:00
const char *end = str + len-1;
while(*end == *str2)
end--;
ret = JS_NewStringLen(js, start, end-start+1);
)
JSC_CCALL(vector_angledist,
double a1 = js2number(argv[0]);
double a2 = js2number(argv[1]);
a1 = fmod(a1,1);
a2 = fmod(a2,1);
double dist = a2-a1;
if (dist == 0) return number2js(dist);
if (dist > 0) {
if (dist > 0.5) return number2js(dist-1);
return number2js(dist);
}
if (dist < -0.5) return number2js(dist+1);
return number2js(dist);
)
2024-08-05 15:26:18 -05:00
JSC_CCALL(vector_length,
return number2js(arr_vec_length(argv[0]));
2024-08-05 15:26:18 -05:00
)
double r2()
{
return (double)rand() / (double)RAND_MAX ;
}
double rand_range(double min, double max) {
return r2() * (max-min) + min;
}
JSC_CCALL(vector_variate,
double n = js2number(argv[0]);
double pct = js2number(argv[1]);
return number2js(n + (rand_range(-pct,pct)*n));
)
JSC_CCALL(vector_random_range, return number2js(rand_range(js2number(argv[0]), js2number(argv[1]))))
JSC_CCALL(vector_mean,
double len = js_arrlen(argv[0]);
double sum;
for (int i = 0; i < len; i++)
sum += js2number(js_getpropidx(argv[0], i));
return number2js(sum/len);
)
JSC_CCALL(vector_sum,
double sum;
int len = js_arrlen(argv[0]);
for (int i = 0; i < len; i++)
sum += js2number(js_getpropidx(argv[0], i));
return number2js(sum);
)
JSC_CCALL(vector_sigma,
int len = js_arrlen(argv[0]);
double sum;
for (int i = 0; i < len; i++)
sum += js2number(js_getpropidx(argv[0], i));
double mean = sum/(double)len;
double sq_diff = 0;
for (int i = 0; i < len; i++) {
double x = js2number(js_getpropidx(argv[0],i));
sq_diff += pow(x-mean, 2);
}
double variance = sq_diff/((double)len);
return number2js(sqrt(variance));
)
JSC_CCALL(vector_median,
int len = js_arrlen(argv[0]);
double arr[len];
double temp;
for (int i = 0; i < len; i++)
arr[i] = js2number(js_getpropidx(argv[0], i));
for (int i = 0; i < len-1; i++) {
for (int j = i+1; j < len; j++) {
if (arr[i] > arr[j]) {
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
if (len % 2 == 0) return number2js((arr[len/2-1] + arr[len/2])/2.0);
return number2js(arr[len/2]);
)
2024-03-18 08:16:25 -05:00
static const JSCFunctionListEntry js_vector_funcs[] = {
MIST_FUNC_DEF(vector, dot,2),
MIST_FUNC_DEF(vector, project,2),
2024-07-24 08:26:29 -05:00
MIST_FUNC_DEF(vector, inflate, 2),
MIST_FUNC_DEF(vector, rotate, 2),
MIST_FUNC_DEF(vector, add, 2),
MIST_FUNC_DEF(vector, midpoint, 2),
MIST_FUNC_DEF(vector, distance, 2),
MIST_FUNC_DEF(vector, angle, 1),
MIST_FUNC_DEF(vector, norm, 1),
MIST_FUNC_DEF(vector, angle_between, 2),
MIST_FUNC_DEF(vector, lerp, 3),
MIST_FUNC_DEF(vector, gcd, 2),
MIST_FUNC_DEF(vector, lcm, 2),
MIST_FUNC_DEF(vector, clamp, 3),
MIST_FUNC_DEF(vector, trimchr, 2),
MIST_FUNC_DEF(vector, angledist, 2),
MIST_FUNC_DEF(vector, variate, 2),
MIST_FUNC_DEF(vector, random_range, 2),
MIST_FUNC_DEF(vector, mean, 1),
MIST_FUNC_DEF(vector, sum, 1),
MIST_FUNC_DEF(vector, sigma, 1),
2024-08-05 15:26:18 -05:00
MIST_FUNC_DEF(vector, median, 1),
MIST_FUNC_DEF(vector, length, 1)
};
#define JS_HMM_FN(OP, HMM, SIGN) \
JSC_CCALL(array_##OP, \
int len = js_arrlen(self); \
if (!JS_IsArray(js, argv[0])) { \
double n = js2number(argv[0]); \
JSValue arr = JS_NewArray(js); \
for (int i = 0; i < len; i++) \
js_setprop_num(arr, i, number2js(js2number(js_getpropidx(self,i)) SIGN n)); \
return arr; \
} \
switch(len) { \
case 2: \
return vec22js(HMM_##HMM##V2(js2vec2(self), js2vec2(argv[0]))); \
case 3: \
return vec32js(HMM_##HMM##V3(js2vec3(self), js2vec3(argv[0]))); \
case 4: \
return vec42js(HMM_##HMM##V4(js2vec4(self), js2vec4(argv[0]))); \
} \
\
JSValue arr = JS_NewArray(js); \
for (int i = 0; i < len; i++) { \
double a = js2number(js_getpropidx(self,i)); \
double b = js2number(js_getpropidx(argv[0],i)); \
js_setprop_num(arr, i, number2js(a SIGN b)); \
} \
return arr; \
) \
JS_HMM_FN(add, Add, +)
JS_HMM_FN(sub, Sub, -)
JS_HMM_FN(div, Div, /)
JS_HMM_FN(scale, Mul, *)
JSC_CCALL(array_lerp,
2024-08-25 17:42:43 -05:00
double t = js2number(argv[1]);
int len = js_arrlen(self);
JSValue arr = JS_NewArray(js);
for (int i = 0; i < len; i++) {
double from = js2number(js_getpropidx(self, i));
double to = js2number(js_getpropidx(argv[0], i));
js_setprop_num(arr, i, number2js((to - from) * t + from));
}
return arr;
)
static const JSCFunctionListEntry js_array_funcs[] = {
2024-08-08 13:25:47 -05:00
PROTO_FUNC_DEF(array, add, 1),
PROTO_FUNC_DEF(array, sub, 1),
PROTO_FUNC_DEF(array, div,1),
PROTO_FUNC_DEF(array, scale, 1),
PROTO_FUNC_DEF(array, lerp, 2)
2024-03-18 08:16:25 -05:00
};
2024-05-16 14:50:18 -05:00
JSC_CCALL(game_engine_start, engine_start(argv[0],argv[1], js2number(argv[2]), js2number(argv[3])))
2024-03-20 14:32:35 -05:00
2024-03-18 08:16:25 -05:00
static const JSCFunctionListEntry js_game_funcs[] = {
2024-05-16 14:50:18 -05:00
MIST_FUNC_DEF(game, engine_start, 4),
2024-03-18 08:16:25 -05:00
};
2024-03-20 14:32:35 -05:00
JSC_CCALL(input_show_keyboard, sapp_show_keyboard(js2boolean(argv[0])))
2024-05-21 18:50:53 -05:00
JSValue js_input_keyboard_shown(JSContext *js, JSValue self) { return boolean2js(sapp_keyboard_shown()); }
2024-10-06 17:18:18 -05:00
JSC_CCALL(input_mouse_lock, sapp_lock_mouse(js2number(argv[0])))
2024-03-18 14:27:52 -05:00
JSC_CCALL(input_mouse_cursor, sapp_set_mouse_cursor(js2number(argv[0])))
2024-10-06 17:18:18 -05:00
JSC_CCALL(input_mouse_show, sapp_show_mouse(js2boolean(argv[0])))
2024-03-18 08:16:25 -05:00
static const JSCFunctionListEntry js_input_funcs[] = {
MIST_FUNC_DEF(input, show_keyboard, 1),
MIST_FUNC_DEF(input, keyboard_shown, 0),
MIST_FUNC_DEF(input, mouse_cursor, 1),
2024-10-06 17:18:18 -05:00
MIST_FUNC_DEF(input, mouse_show, 1),
MIST_FUNC_DEF(input, mouse_lock, 1),
};
2024-05-16 14:50:18 -05:00
JSC_CCALL(prosperon_window_render, openglRender(js2vec2(argv[0])))
2024-04-03 00:44:08 -05:00
JSC_CCALL(prosperon_guid,
int bits = 32;
char guid[33];
for (int i = 0; i < 4; i++) {
int r = rand();
for (int j = 0; j < 8; j++) {
guid[i*8+j] = "0123456789abcdef"[r%16];
r /= 16;
}
}
guid[32] = 0;
return str2js(guid);
2024-04-03 00:44:08 -05:00
)
static const JSCFunctionListEntry js_prosperon_funcs[] = {
2024-05-16 14:50:18 -05:00
MIST_FUNC_DEF(prosperon, window_render, 1),
2024-04-03 00:44:08 -05:00
MIST_FUNC_DEF(prosperon, guid, 0),
};
2024-09-29 06:10:42 -05:00
static const JSCFunctionListEntry js_sg_buffer_funcs[] = {
};
2024-03-20 14:32:35 -05:00
JSC_CCALL(time_now,
struct timeval ct;
gettimeofday(&ct, NULL);
return number2js((double)ct.tv_sec+(double)(ct.tv_usec/1000000.0));
2024-03-20 14:32:35 -05:00
)
2024-05-21 18:50:53 -05:00
JSValue js_time_computer_dst(JSContext *js, JSValue self) {
time_t t = time(NULL);
2024-03-20 14:32:35 -05:00
return boolean2js(localtime(&t)->tm_isdst);
}
2024-05-21 18:50:53 -05:00
JSValue js_time_computer_zone(JSContext *js, JSValue self) {
time_t t = time(NULL);
time_t local_t = mktime(localtime(&t));
double diff = difftime(t, local_t);
return number2js(diff/3600);
}
static const JSCFunctionListEntry js_time_funcs[] = {
MIST_FUNC_DEF(time, now, 0),
MIST_FUNC_DEF(time, computer_dst, 0),
MIST_FUNC_DEF(time, computer_zone, 0)
};
2024-03-20 14:32:35 -05:00
JSC_SCALL(console_print, log_print(str))
2024-08-24 18:46:21 -05:00
JSC_SCALL(console_term_print, term_print(str));
2024-05-21 18:50:53 -05:00
JSValue js_console_rec(JSContext *js, JSValue self, int argc, JSValue *argv)
{
2024-03-18 14:27:52 -05:00
int level = js2number(argv[0]);
const char *msg = JS_ToCString(js, argv[1]);
const char *file = JS_ToCString(js, argv[2]);
2024-03-18 14:27:52 -05:00
int line = js2number(argv[3]);
mYughLog(LOG_SCRIPT, level, line, file, msg);
JS_FreeCString(js, msg);
JS_FreeCString(js, file);
return JS_UNDEFINED;
}
2024-03-20 14:32:35 -05:00
JSC_GETSET_GLOBAL(stdout_lvl, number)
static const JSCFunctionListEntry js_console_funcs[] = {
MIST_FUNC_DEF(console,print,1),
2024-08-24 18:46:21 -05:00
MIST_FUNC_DEF(console, term_print, 1),
MIST_FUNC_DEF(console,rec,4),
CGETSET_ADD(global, stdout_lvl)
};
2024-03-20 14:32:35 -05:00
JSC_CCALL(profile_now, return number2js(stm_now()))
2024-07-24 08:26:29 -05:00
static JSValue instr_v = JS_UNDEFINED;
int iiihandle(JSRuntime *rt, void *data)
{
script_call_sym(instr_v, 0, NULL);
return 0;
}
JSC_CCALL(profile_gather,
int count = js2number(argv[0]);
instr_v = JS_DupValue(js, argv[1]);
2024-07-25 22:07:22 -05:00
JS_SetInterruptHandler(rt, iiihandle, NULL);
2024-07-24 08:26:29 -05:00
)
JSC_CCALL(profile_gather_rate,
JS_SetInterruptRate(js2number(argv[0]));
)
2024-07-25 08:38:10 -05:00
JSC_CCALL(profile_gather_stop,
2024-07-25 22:07:22 -05:00
JS_SetInterruptHandler(rt,NULL,NULL);
2024-07-25 08:38:10 -05:00
)
JSC_CCALL(profile_best_t,
char* result[50];
double seconds = stm_sec(js2number(argv[0]));
if (seconds < 1e-6)
snprintf(result, 50, "%.2f ns", seconds * 1e9);
else if (seconds < 1e-3)
snprintf(result, 50, "%.2f µs", seconds * 1e6);
else if (seconds < 1)
snprintf(result, 50, "%.2f ms", seconds * 1e3);
else
snprintf(result, 50, "%.2f s", seconds);
ret = str2js(result);
)
2024-09-22 10:45:31 -05:00
JSC_CCALL(profile_secs, return number2js(stm_sec(js2number(argv[0]))); )
static const JSCFunctionListEntry js_profile_funcs[] = {
MIST_FUNC_DEF(profile,now,0),
MIST_FUNC_DEF(profile,best_t, 1),
2024-07-24 08:26:29 -05:00
MIST_FUNC_DEF(profile,gather,2),
2024-07-25 08:38:10 -05:00
MIST_FUNC_DEF(profile,gather_rate,1),
MIST_FUNC_DEF(profile,gather_stop,0),
2024-09-22 10:45:31 -05:00
MIST_FUNC_DEF(profile,secs,1),
};
2024-03-20 14:32:35 -05:00
JSC_SCALL(io_exists, ret = boolean2js(fexists(str)))
JSC_CCALL(io_ls, return strarr2js(ls(".")))
JSC_SSCALL(io_cp, ret = number2js(cp(str,str2)))
JSC_SSCALL(io_mv, ret = number2js(rename(str,str2)))
JSC_SCALL(io_chdir, ret = number2js(chdir(str)))
JSC_SCALL(io_rm, ret = number2js(remove(str)))
JSC_SCALL(io_mkdir, ret = number2js(mkdir(str,0777)))
2024-05-21 18:50:53 -05:00
JSValue js_io_slurpbytes(JSContext *js, JSValue self, int argc, JSValue *argv)
{
2024-09-29 06:10:42 -05:00
const char *f = js2str(argv[0]);
size_t len;
unsigned char *d = slurp_file(f,&len);
2024-05-30 17:12:32 -05:00
if (!d) {
JS_FreeCString(js,f);
return JS_UNDEFINED;
}
JSValue ret = JS_NewArrayBufferCopy(js,d,len);
JS_FreeCString(js,f);
free(d);
return ret;
}
2024-05-21 18:50:53 -05:00
JSValue js_io_slurp(JSContext *js, JSValue self, int argc, JSValue *argv)
{
2024-08-30 14:17:37 -05:00
2024-09-29 06:10:42 -05:00
const char *f = js2str(argv[0]);
size_t len;
char *s = slurp_text(f,&len);
JS_FreeCString(js,f);
if (!s) return JS_UNDEFINED;
JSValue ret = JS_NewStringLen(js, s, len);
free(s);
return ret;
}
2024-05-21 18:50:53 -05:00
JSValue js_io_slurpwrite(JSContext *js, JSValue self, int argc, JSValue *argv)
{
2024-09-29 06:10:42 -05:00
const char *f = js2str(argv[0]);
size_t len;
JSValue ret;
if (JS_IsString(argv[1])) {
2024-09-29 06:10:42 -05:00
const char *data = JS_ToCStringLen(js, &len, argv[1]);
2024-03-18 14:27:52 -05:00
ret = number2js(slurp_write(data, f, len));
JS_FreeCString(js,data);
} else {
unsigned char *data = JS_GetArrayBuffer(js, &len, argv[1]);
2024-03-18 14:27:52 -05:00
ret = number2js(slurp_write(data, f, len));
}
return ret;
}
2024-05-21 18:50:53 -05:00
JSValue js_io_chmod(JSContext *js, JSValue self, int argc, JSValue *argv)
{
2024-09-29 06:10:42 -05:00
const char *f = js2str(argv[0]);
2024-03-18 14:27:52 -05:00
int mod = js2number(argv[1]);
chmod(f, mod);
return JS_UNDEFINED;
}
2024-05-21 18:50:53 -05:00
JSC_SCALL(io_mod,
#ifndef __EMSCRIPTEN__
ret = number2js(file_mod_secs(str));
#endif
)
static const JSCFunctionListEntry js_io_funcs[] = {
2024-03-18 08:16:25 -05:00
MIST_FUNC_DEF(io, exists,1),
MIST_FUNC_DEF(io, ls, 0),
MIST_FUNC_DEF(io, cp, 2),
MIST_FUNC_DEF(io, mv, 2),
MIST_FUNC_DEF(io, rm, 1),
MIST_FUNC_DEF(io, chdir, 1),
MIST_FUNC_DEF(io, mkdir, 1),
MIST_FUNC_DEF(io, chmod, 2),
MIST_FUNC_DEF(io, slurp, 1),
MIST_FUNC_DEF(io, slurpbytes, 1),
MIST_FUNC_DEF(io, slurpwrite, 2),
2024-04-30 10:32:27 -05:00
MIST_FUNC_DEF(io, mod,1)
2024-03-18 08:16:25 -05:00
};
2024-10-29 12:41:17 -05:00
/*
2024-03-19 14:39:19 -05:00
JSC_CCALL(physics_closest_point,
void *v1 = js2cpvec2arr(argv[1]);
2024-10-20 08:28:13 -05:00
ret = number2js(point2segindex(js2vec2(argv[0]), v1, js2number(argv[2])));
2024-03-19 14:39:19 -05:00
arrfree(v1);
return ret;
)
2024-04-01 17:58:29 -05:00
void bb_query_fn(cpShape *shape, JSValue *cb)
{
JSValue go = JS_DupValue(js,shape2go(shape)->ref);
script_call_sym(*cb, 1, &go);
JS_FreeValue(js, go);
}
JSC_CCALL(physics_box_query,
HMM_Vec2 pos = js2vec2(argv[0]);
HMM_Vec2 wh = js2vec2(argv[1]);
cpBB bbox;
bbox.l = pos.x-wh.x/2;
bbox.r = pos.x+wh.x/2;
bbox.t = pos.y+wh.y/2;
bbox.b = pos.y-wh.y/2;
2024-04-12 13:53:00 -05:00
cpSpaceBBQuery(space, bbox, CP_SHAPE_FILTER_ALL, bb_query_fn, &argv[3]);
2024-04-01 17:58:29 -05:00
return ret;
)
2024-03-26 18:31:20 -05:00
static void ray_query_fn(cpShape *shape, float t, cpVect n, float a, JSValue *cb)
{
JSValue argv[3] = {
JS_DupValue(js, shape2go(shape)->ref),
vec22js((HMM_Vec2)n),
number2js(a)
};
script_call_sym(*cb, 3, argv);
2024-04-03 00:44:08 -05:00
for (int i = 0; i < 3; i++) JS_FreeValue(js, argv[i]);
2024-03-26 18:31:20 -05:00
}
JSC_CCALL(physics_ray_query,
2024-04-12 13:53:00 -05:00
cpSpaceSegmentQuery(space, js2vec2(argv[0]).cp, js2vec2(argv[1]).cp, js2number(argv[2]), CP_SHAPE_FILTER_ALL, ray_query_fn, &argv[3]);
2024-03-26 18:31:20 -05:00
);
2024-04-03 00:44:08 -05:00
static void point_query_fn(cpShape *shape, float dist, cpVect point, JSValue *cb)
{
JSValue argv[3] = {
JS_DupValue(js,cpShape2js(shape)),
2024-04-03 00:44:08 -05:00
vec22js((HMM_Vec2)point),
number2js(dist)
};
script_call_sym(*cb, 3, argv);
for (int i = 0; i < 3; i++) JS_FreeValue(js, argv[i]);
}
JSC_CCALL(physics_point_query,
2024-04-12 13:53:00 -05:00
cpSpacePointQuery(space, js2vec2(argv[0]).cp, js2number(argv[1]), CP_SHAPE_FILTER_ALL, point_query_fn, &argv[2]);
2024-04-03 00:44:08 -05:00
);
JSValue pointinfo2js(cpPointQueryInfo info)
{
JSValue o = JS_NewObject(js);
2024-05-17 12:39:04 -05:00
js_setpropstr(o, "distance", number2js(info.distance));
js_setpropstr(o, "point", vec22js((HMM_Vec2)info.point));
js_setpropstr(o, "entity", JS_DupValue(js, shape2go(info.shape)->ref));
2024-04-03 00:44:08 -05:00
return o;
}
JSC_CCALL(physics_point_query_nearest,
cpPointQueryInfo info;
2024-04-12 13:53:00 -05:00
cpShape *sh = cpSpacePointQueryNearest(space, js2vec2(argv[0]).cp, js2number(argv[1]), CP_SHAPE_FILTER_ALL, &info);
2024-04-03 00:44:08 -05:00
if (!sh) return JS_UNDEFINED;
return pointinfo2js(info);
)
void space_shape_fn(cpShape *shape, JSValue *fn) {
JSValue v = *(JSValue*)cpShapeGetUserData(shape);
script_call_sym(*fn, 1, &v);
}
2024-03-18 08:16:25 -05:00
static const JSCFunctionListEntry js_physics_funcs[] = {
2024-04-03 00:44:08 -05:00
MIST_FUNC_DEF(physics, point_query, 3),
2024-04-11 17:17:49 -05:00
MIST_FUNC_DEF(physics, point_query_nearest, 2),
MIST_FUNC_DEF(physics, ray_query, 4),
2024-04-01 17:58:29 -05:00
MIST_FUNC_DEF(physics, box_query, 2),
2024-03-19 14:39:19 -05:00
MIST_FUNC_DEF(physics, closest_point, 3),
2024-02-23 16:05:30 -06:00
};
2024-10-29 12:41:17 -05:00
*/
2024-02-23 16:05:30 -06:00
2024-07-23 17:21:27 -05:00
JSC_GETSET(transform, pos, vec3)
JSC_GETSET(transform, scale, vec3f)
2024-07-23 17:21:27 -05:00
JSC_GETSET(transform, rotation, quat)
2024-05-21 18:50:53 -05:00
JSC_CCALL(transform_move, transform_move(js2transform(self), js2vec3(argv[0])); )
2024-06-18 16:14:23 -05:00
2024-05-12 18:36:14 -05:00
JSC_CCALL(transform_lookat,
HMM_Vec3 point = js2vec3(argv[0]);
2024-05-21 18:50:53 -05:00
transform *go = js2transform(self);
2024-10-17 17:23:33 -05:00
HMM_Mat4 m = HMM_LookAt_RH(go->pos, point, vUP);
go->rotation = HMM_M4ToQ_RH(m);
2024-07-23 14:30:41 -05:00
go->dirty = true;
2024-05-12 18:36:14 -05:00
)
JSC_CCALL(transform_rotate,
HMM_Vec3 axis = js2vec3(argv[0]);
2024-05-21 18:50:53 -05:00
transform *t = js2transform(self);
2024-10-17 17:23:33 -05:00
HMM_Quat rot = HMM_QFromAxisAngle_RH(axis, js2angle(argv[1]));
2024-05-15 07:54:19 -05:00
t->rotation = HMM_MulQ(t->rotation,rot);
2024-07-23 14:30:41 -05:00
t->dirty = true;
2024-05-15 07:54:19 -05:00
)
2024-06-18 16:14:23 -05:00
JSC_CCALL(transform_angle,
HMM_Vec3 axis = js2vec3(argv[0]);
transform *t = js2transform(self);
if (axis.x) return angle2js(HMM_Q_Roll(t->rotation));
if (axis.y) return angle2js(HMM_Q_Pitch(t->rotation));
if (axis.z) return angle2js(HMM_Q_Yaw(t->rotation));
return angle2js(0);
)
2024-05-15 07:54:19 -05:00
JSC_CCALL(transform_direction,
2024-05-21 18:50:53 -05:00
transform *t = js2transform(self);
2024-05-15 07:54:19 -05:00
return vec32js(HMM_QVRot(js2vec3(argv[0]), t->rotation));
2024-05-12 18:36:14 -05:00
)
2024-05-02 13:52:28 -05:00
2024-07-22 15:40:58 -05:00
JSC_CCALL(transform_phys2d,
transform *t = js2transform(self);
HMM_Vec2 v = js2vec2(argv[0]);
float av = js2number(argv[1]);
float dt = js2number(argv[2]);
transform_move(t, (HMM_Vec3){v.x*dt,v.y*dt,0});
2024-10-17 17:23:33 -05:00
HMM_Quat rot = HMM_QFromAxisAngle_RH((HMM_Vec3){0,0,1}, av*dt);
2024-07-22 15:40:58 -05:00
t->rotation = HMM_MulQ(t->rotation, rot);
)
JSC_CCALL(transform_unit,
transform *t = js2transform(self);
t->pos = v3zero;
t->rotation = QUAT1;
t->scale = v3one;
)
2024-09-26 19:28:54 -05:00
JSC_CCALL(transform_trs,
transform *t = js2transform(self);
t->pos = JS_IsUndefined(argv[0]) ? v3zero : js2vec3(argv[0]);
t->rotation = JS_IsUndefined(argv[1]) ? QUAT1 : js2quat(argv[1]);
2024-09-29 06:10:42 -05:00
t->scale = JS_IsUndefined(argv[2]) ? v3one : js2vec3(argv[2]);
2024-09-26 19:28:54 -05:00
)
2024-05-12 18:36:14 -05:00
static const JSCFunctionListEntry js_transform_funcs[] = {
CGETSET_ADD(transform, pos),
CGETSET_ADD(transform, scale),
CGETSET_ADD(transform, rotation),
2024-09-26 19:28:54 -05:00
MIST_FUNC_DEF(transform, trs, 3),
2024-07-22 15:40:58 -05:00
MIST_FUNC_DEF(transform, phys2d, 3),
2024-05-15 07:54:19 -05:00
MIST_FUNC_DEF(transform, move, 1),
2024-05-12 18:36:14 -05:00
MIST_FUNC_DEF(transform, rotate, 2),
2024-06-18 16:14:23 -05:00
MIST_FUNC_DEF(transform, angle, 1),
2024-05-15 07:54:19 -05:00
MIST_FUNC_DEF(transform, lookat, 1),
MIST_FUNC_DEF(transform, direction, 1),
MIST_FUNC_DEF(transform, unit, 0),
2024-05-02 13:52:28 -05:00
};
2024-05-21 18:50:53 -05:00
static JSValue js_window_get_fullscreen(JSContext *js, JSValue self) { return boolean2js(js2window(self)->fullscreen); }
static JSValue js_window_set_fullscreen(JSContext *js, JSValue self, JSValue v) { window_setfullscreen(js2window(self), js2boolean(v)); return JS_UNDEFINED; }
2024-03-13 16:30:55 -05:00
2024-05-21 18:50:53 -05:00
static JSValue js_window_set_title(JSContext *js, JSValue self, JSValue v)
2024-03-13 16:30:55 -05:00
{
2024-05-21 18:50:53 -05:00
window *w = js2window(self);
2024-03-13 16:30:55 -05:00
if (w->title) JS_FreeCString(js, w->title);
w->title = js2str(v);
if (w->start)
sapp_set_window_title(w->title);
return JS_UNDEFINED;
}
2024-05-21 18:50:53 -05:00
JSC_CCALL(window_get_title, return str2js(js2window(self)->title))
JSC_CCALL(window_set_icon, window_seticon(&mainwin, js2texture(argv[0])))
2024-04-10 16:21:46 -05:00
JSC_GETSET(window, vsync, boolean)
JSC_GETSET(window, enable_clipboard, boolean)
JSC_GETSET(window, enable_dragndrop, boolean)
JSC_GETSET(window, high_dpi, boolean)
JSC_GETSET(window, sample_count, number)
2024-03-18 08:16:25 -05:00
2024-03-13 16:30:55 -05:00
static const JSCFunctionListEntry js_window_funcs[] = {
CGETSET_ADD(window, fullscreen),
2024-08-25 06:35:04 -05:00
CGETSET_ADD(window, title),
2024-04-10 16:21:46 -05:00
CGETSET_ADD(window, vsync),
CGETSET_ADD(window, enable_clipboard),
CGETSET_ADD(window, enable_dragndrop),
CGETSET_ADD(window, high_dpi),
CGETSET_ADD(window, sample_count),
2024-03-20 14:32:35 -05:00
MIST_FUNC_DEF(window, set_icon, 1)
2024-03-13 16:30:55 -05:00
};
2024-05-21 18:50:53 -05:00
JSC_CCALL(datastream_time, return number2js(plm_get_time(js2datastream(self)->plm)); )
2024-05-21 18:50:53 -05:00
JSC_CCALL(datastream_advance_frames, ds_advanceframes(js2datastream(self), js2number(argv[0])))
2024-05-21 18:50:53 -05:00
JSC_CCALL(datastream_seek, ds_seek(js2datastream(self), js2number(argv[0])))
2024-05-21 18:50:53 -05:00
JSC_CCALL(datastream_advance, ds_advance(js2datastream(self), js2number(argv[0])))
2024-05-21 18:50:53 -05:00
JSC_CCALL(datastream_duration, return number2js(ds_length(js2datastream(self))))
2024-05-21 18:50:53 -05:00
JSC_CCALL(datastream_framerate, return number2js(plm_get_framerate(js2datastream(self)->plm)))
static const JSCFunctionListEntry js_datastream_funcs[] = {
MIST_FUNC_DEF(datastream, time, 0),
MIST_FUNC_DEF(datastream, advance_frames, 1),
MIST_FUNC_DEF(datastream, seek, 1),
MIST_FUNC_DEF(datastream, advance, 1),
MIST_FUNC_DEF(datastream, duration, 0),
MIST_FUNC_DEF(datastream, framerate, 0),
};
JSC_GET(texture, width, number)
JSC_GET(texture, height, number)
2024-09-29 06:10:42 -05:00
JSC_GET(texture, vram, number)
2024-03-18 14:27:52 -05:00
2024-06-18 16:14:23 -05:00
JSC_SCALL(texture_save, texture_save(js2texture(self), str));
JSC_CCALL(texture_blit,
texture_blit(js2texture(self), js2texture(argv[0]), js2rect(argv[1]), js2rect(argv[2]), js2boolean(argv[3]));
)
2024-06-18 16:14:23 -05:00
2024-08-12 15:19:34 -05:00
JSC_CCALL(texture_getid,
texture *tex = js2texture(self);
return number2js(tex->id.id);
)
2024-10-29 12:41:17 -05:00
JSC_CCALL(texture_inram, return boolean2js((int)js2texture(self)->data));
2024-09-29 06:10:42 -05:00
2024-10-01 17:57:05 -05:00
JSC_CCALL(texture_fill,
texture_fill(js2texture(self), js2color(argv[0]));
)
JSC_CCALL(texture_fill_rect,
texture_fill_rect(js2texture(self), js2rect(argv[0]), js2color(argv[1]));
)
JSC_CCALL(texture_flip,
texture_flip(js2texture(self), js2boolean(argv[0]));
)
JSC_CCALL(texture_write_pixel,
HMM_Vec2 c = js2vec2(argv[0]);
texture_write_pixel(js2texture(self), c.x, c.y, js2color(argv[1]));
)
JSC_CCALL(texture_dup,
ret = texture2js(texture_dup(js2texture(self)));
)
JSC_CCALL(texture_scale,
ret = texture2js(texture_scale(js2texture(self), js2number(argv[0]), js2number(argv[1])));
)
JSC_CCALL(texture_load_gpu,
texture_load_gpu(js2texture(self));
)
JSC_CCALL(texture_offload,
texture_offload(js2texture(self));
)
static const JSCFunctionListEntry js_texture_funcs[] = {
MIST_GET(texture, width),
MIST_GET(texture, height),
2024-09-29 06:10:42 -05:00
MIST_GET(texture, vram),
2024-06-18 17:10:24 -05:00
MIST_FUNC_DEF(texture, save, 1),
2024-10-01 17:57:05 -05:00
MIST_FUNC_DEF(texture, write_pixel, 2),
MIST_FUNC_DEF(texture, fill, 1),
MIST_FUNC_DEF(texture, fill_rect, 2),
MIST_FUNC_DEF(texture, dup, 0),
MIST_FUNC_DEF(texture, scale, 2),
MIST_FUNC_DEF(texture, flip, 1),
MIST_FUNC_DEF(texture, blit, 4),
2024-08-12 15:19:34 -05:00
MIST_FUNC_DEF(texture, getid, 0),
2024-09-29 06:10:42 -05:00
MIST_FUNC_DEF(texture, inram, 0),
2024-10-01 17:57:05 -05:00
MIST_FUNC_DEF(texture, load_gpu, 0),
MIST_FUNC_DEF(texture, offload, 0),
};
2024-09-30 10:14:56 -05:00
JSC_GETSET_CALLBACK(timer, fn)
2024-09-30 04:36:53 -05:00
JSC_GETSET(timer, remain, number)
2024-08-04 15:20:11 -05:00
static const JSCFunctionListEntry js_timer_funcs[] = {
2024-09-30 04:36:53 -05:00
CGETSET_ADD(timer, remain),
2024-09-30 10:14:56 -05:00
CGETSET_ADD(timer, fn),
2024-08-04 15:20:11 -05:00
};
2024-04-09 16:48:15 -05:00
JSC_GETSET(font, linegap, number)
JSC_GET(font, height, number)
2024-10-17 17:23:33 -05:00
JSC_GET(font, ascent, number)
JSC_GET(font, descent, number)
2024-04-09 16:48:15 -05:00
static const JSCFunctionListEntry js_font_funcs[] = {
CGETSET_ADD(font, linegap),
MIST_GET(font, height),
2024-10-17 17:23:33 -05:00
MIST_GET(font, ascent),
MIST_GET(font, descent)
2024-04-09 16:48:15 -05:00
};
2023-12-18 06:45:27 -06:00
const char *STRTEST = "TEST STRING";
JSC_CCALL(performance_barecall,)
JSC_CCALL(performance_unpack_num, int i = js2number(argv[0]))
2024-04-20 12:55:20 -05:00
JSC_CCALL(performance_unpack_array,
void *v = js2cpvec2arr(argv[0]);
arrfree(v);
)
JSC_CCALL(performance_pack_num, return number2js(1.0))
JSC_CCALL(performance_pack_string, return JS_NewStringLen(js, STRTEST, sizeof(*STRTEST)))
JSC_CCALL(performance_unpack_string, js2str(argv[0]))
JSC_CCALL(performance_unpack_32farr, jsfloat2vec(argv[0]))
JSC_CCALL(performance_call_fn_n,
for (int i = 0; i < js2number(argv[1]); i++)
script_call_sym(argv[0],0,NULL);
script_call_sym(argv[2],0,NULL);
)
static const JSCFunctionListEntry js_performance_funcs[] = {
MIST_FUNC_DEF(performance, barecall,0),
MIST_FUNC_DEF(performance, unpack_num, 1),
MIST_FUNC_DEF(performance, unpack_array, 1),
MIST_FUNC_DEF(performance, pack_num, 0),
MIST_FUNC_DEF(performance, pack_string, 0),
MIST_FUNC_DEF(performance, unpack_string, 1),
MIST_FUNC_DEF(performance, unpack_32farr, 1),
MIST_FUNC_DEF(performance, call_fn_n, 3)
};
2023-12-18 06:45:27 -06:00
2024-10-06 17:18:18 -05:00
JSC_CCALL(geometry_rect_intersect,
rect a = js2rect(argv[0]);
rect b = js2rect(argv[1]);
return boolean2js(a.x < (b.x+b.w) &&
(a.x + a.w) > b.x &&
a.y < (b.y + b.h) &&
(a.y + a.h) > b.y );
)
JSC_CCALL(geometry_rect_inside,
rect inner = js2rect(argv[0]);
rect outer = js2rect(argv[1]);
return boolean2js(
inner.x >= outer.x &&
inner.x + inner.w <= outer.x + outer.w &&
inner.y >= outer.y &&
inner.y + inner.h <= outer.y + outer.h
);
)
JSC_CCALL(geometry_rect_random,
rect a = js2rect(argv[0]);
return vec22js((HMM_Vec2){
a.x + rand_range(-0.5,0.5)*a.w,
a.y + rand_range(-0.5,0.5)*a.h
});
)
JSC_CCALL(geometry_rect_point_inside,
rect a = js2rect(argv[0]);
HMM_Vec2 p = js2vec2(argv[1]);
2024-10-17 17:23:33 -05:00
return boolean2js(p.x >= a.x && p.x <= a.x+a.w && p.y <= a.y+a.h && p.y >= a.y);
2024-10-06 17:18:18 -05:00
)
JSC_CCALL(geometry_cwh2rect,
HMM_Vec2 c = js2vec2(argv[0]);
HMM_Vec2 wh = js2vec2(argv[1]);
rect r;
r.x = c.x;
r.y = c.y;
r.w = wh.x;
r.h = wh.y;
return rect2js(r);
)
static const JSCFunctionListEntry js_geometry_funcs[] = {
MIST_FUNC_DEF(geometry, rect_intersect, 2),
MIST_FUNC_DEF(geometry, rect_inside, 2),
MIST_FUNC_DEF(geometry, rect_random, 1),
MIST_FUNC_DEF(geometry, cwh2rect, 2),
MIST_FUNC_DEF(geometry, rect_point_inside, 2),
};
2024-05-21 18:50:53 -05:00
JSValue js_os_cwd(JSContext *js, JSValue self, int argc, JSValue *argv)
2024-04-03 17:17:32 -05:00
{
char cwd[PATH_MAX];
#ifndef __EMSCRIPTEN__
getcwd(cwd, sizeof(cwd));
#else
cwd[0] = '.';
cwd[1] = 0;
#endif
return str2js(cwd);
}
JSC_SCALL(os_env, ret = str2js(getenv(str)))
2024-05-21 18:50:53 -05:00
JSValue js_os_sys(JSContext *js, JSValue self, int argc, JSValue *argv)
2024-04-03 17:17:32 -05:00
{
#ifdef __linux__
return str2js("linux");
#elif defined(_WIN32) || defined(_WIN64)
return str2js("windows");
2024-05-06 21:59:22 -05:00
#elif defined(IOS)
return str2js("ios");
2024-04-03 17:17:32 -05:00
#elif defined(__APPLE__)
return str2js("macos");
2024-05-21 18:50:53 -05:00
#elif defined(__EMSCRIPTEN__)
2024-05-06 21:59:22 -05:00
return str2js("web");
2024-04-03 17:17:32 -05:00
#endif
return JS_UNDEFINED;
}
2024-10-03 17:36:29 -05:00
JSC_CCALL(os_backend,
#ifdef SOKOL_GLCORE
return str2js("opengl");
#elifdef SOKOL_WGPU
return str2js("wgpu");
#elifdef SOKOL_D3D11
return str2js("directx");
#elifdef SOKOL_METAL
return str2js("metal");
#endif
)
2024-04-03 17:17:32 -05:00
JSC_CCALL(os_quit, quit();)
JSC_CCALL(os_exit, exit(js2number(argv[0]));)
JSC_CCALL(os_gc, script_gc());
2024-08-05 15:26:18 -05:00
JSC_CCALL(os_mem_limit, script_mem_limit(js2number(argv[0])))
JSC_CCALL(os_gc_threshold, script_gc_threshold(js2number(argv[0])))
JSC_CCALL(os_max_stacksize, script_max_stacksize(js2number(argv[0])))
2024-08-06 14:23:21 -05:00
static JSValue tmp2js(FILE *tmp)
{
size_t size = ftell(tmp);
rewind(tmp);
char *buffer = calloc(size+1, sizeof(char));
fread(buffer, sizeof(char),size, tmp);
JSValue ret = str2js(buffer);
free(buffer);
return ret;
}
JSC_CCALL(os_dump_value,
FILE *tmp = tmpfile();
quickjs_set_dumpout(tmp);
JS_DumpMyValue(rt, argv[0]);
ret = tmp2js(tmp);
)
JSC_CCALL(os_dump_atoms,
FILE *tmp = tmpfile();
quickjs_set_dumpout(tmp);
JS_PrintAtoms(rt);
ret = tmp2js(tmp);
)
JSC_CCALL(os_dump_shapes,
FILE *tmp = tmpfile();
quickjs_set_dumpout(tmp);
JS_PrintShapes(rt);
size_t size = ftell(tmp);
rewind(tmp);
char buffer[size];
fgets(buffer, sizeof(char)*size, tmp);
fclose(tmp);
ret = str2js(buffer);
)
JSC_CCALL(os_calc_mem,
return number2js(JS_MyValueSize(rt, argv[0]));
)
2024-08-05 15:26:18 -05:00
#define JSOBJ_ADD_FIELD(OBJ, STRUCT, FIELD, TYPE) \
js_setpropstr(OBJ, #FIELD, TYPE##2js(STRUCT.FIELD));\
#define JSJMEMRET(FIELD) JSOBJ_ADD_FIELD(ret, jsmem, FIELD, number)
2024-08-06 14:23:21 -05:00
JSC_CCALL(os_memstate,
JSMemoryUsage jsmem;
JS_FillMemoryState(rt, &jsmem);
ret = JS_NewObject(js);
JSJMEMRET(malloc_size)
JSJMEMRET(malloc_limit)
JSJMEMRET(gc_threshold)
)
2024-09-29 06:10:42 -05:00
JSC_CCALL(os_mallinfo,
2024-09-30 04:36:53 -05:00
ret = JS_UNDEFINED;
/*struct mallinfo jsmem = mallinfo();
2024-09-29 06:10:42 -05:00
ret = JS_NewObject(js);
JSJMEMRET(arena);
JSJMEMRET(ordblks);
JSJMEMRET(smblks);
JSJMEMRET(hblks);
JSJMEMRET(hblkhd);
JSJMEMRET(usmblks);
JSJMEMRET(uordblks);
JSJMEMRET(fordblks);
2024-09-30 04:36:53 -05:00
JSJMEMRET(keepcost);*/
2024-09-29 06:10:42 -05:00
)
JSC_CCALL(os_rusage,
2024-10-03 17:36:29 -05:00
ret = JS_NewObject(js);
#ifndef _WIN32
2024-09-29 06:10:42 -05:00
struct rusage jsmem;
getrusage(RUSAGE_SELF, &jsmem);
JSJMEMRET(ru_maxrss);
JSJMEMRET(ru_ixrss);
JSJMEMRET(ru_idrss);
JSJMEMRET(ru_isrss);
JSJMEMRET(ru_minflt);
JSJMEMRET(ru_majflt);
JSJMEMRET(ru_nswap);
JSJMEMRET(ru_inblock);
JSJMEMRET(ru_oublock);
JSJMEMRET(ru_msgsnd);
JSJMEMRET(ru_msgrcv);
JSJMEMRET(ru_nsignals);
JSJMEMRET(ru_nvcsw);
JSJMEMRET(ru_nivcsw);
2024-10-03 17:36:29 -05:00
#endif
2024-09-29 06:10:42 -05:00
)
2024-08-05 15:26:18 -05:00
JSC_CCALL(os_mem,
JSMemoryUsage jsmem;
JS_ComputeMemoryUsage(rt, &jsmem);
ret = JS_NewObject(js);
JSJMEMRET(malloc_size)
JSJMEMRET(malloc_limit)
2024-08-06 14:23:21 -05:00
JSJMEMRET(gc_threshold)
2024-08-05 15:26:18 -05:00
JSJMEMRET(memory_used_size)
JSJMEMRET(memory_used_count)
JSJMEMRET(atom_count)
JSJMEMRET(atom_size)
JSJMEMRET(str_count)
JSJMEMRET(str_size)
JSJMEMRET(obj_count)
JSJMEMRET(obj_size)
JSJMEMRET(prop_count)
JSJMEMRET(prop_size)
JSJMEMRET(shape_count)
JSJMEMRET(shape_size)
JSJMEMRET(js_func_count)
JSJMEMRET(js_func_size)
JSJMEMRET(js_func_code_size)
JSJMEMRET(js_func_pc2line_count)
JSJMEMRET(js_func_pc2line_size)
JSJMEMRET(c_func_count)
JSJMEMRET(array_count)
JSJMEMRET(fast_array_count)
JSJMEMRET(fast_array_elements)
JSJMEMRET(binary_object_count)
JSJMEMRET(binary_object_size)
)
2024-08-06 14:23:21 -05:00
JSC_CCALL(os_dump_mem,
FILE *tmp = tmpfile();
JSMemoryUsage mem = {0};
JS_DumpMemoryUsage(tmp, &mem, rt);
ret = tmp2js(tmp);
)
JSC_CCALL(os_value_id,
return number2js((intptr_t)JS_VALUE_GET_PTR(argv[0]));
)
2024-08-06 14:23:21 -05:00
static double gc_t = 0;
static double gc_mem = 0;
static double gc_startmem = 0;
void script_report_gc_time(double t, double startmem, double mem)
{
gc_t = t;
gc_mem = mem;
gc_startmem = startmem;
}
static FILE *cycles;
JSC_CCALL(os_check_cycles,
if (ftell(cycles) == 0) return JS_UNDEFINED;
cycles = tmpfile();
quickjs_set_cycleout(cycles);
2024-09-04 07:41:48 -05:00
ret = tmp2js(cycles);
2024-08-06 14:23:21 -05:00
)
JSC_CCALL(os_check_gc,
if (gc_t == 0) return JS_UNDEFINED;
JSValue gc = JS_NewObject(js);
js_setpropstr(gc, "time", number2js(gc_t));
js_setpropstr(gc, "mem", number2js(gc_mem));
js_setpropstr(gc, "startmem", number2js(gc_startmem));
gc_t = 0;
gc_mem = 0;
gc_startmem = 0;
return gc;
)
2024-04-03 17:17:32 -05:00
JSC_SSCALL(os_eval, ret = script_eval(str, str2))
2024-09-30 04:36:53 -05:00
JSC_CCALL(os_make_timer, return timer2js(timer_make(argv[0])))
2024-08-05 15:26:18 -05:00
JSC_CCALL(os_update_timers, timer_update(js2number(argv[0])))
JSC_CCALL(os_obj_size,
)
2024-04-03 17:17:32 -05:00
JSC_SCALL(os_make_texture,
ret = texture2js(texture_from_file(str));
JS_SetPropertyStr(js, ret, "path", JS_DupValue(js,argv[0]));
)
2024-10-18 12:51:21 -05:00
JSC_SCALL(os_make_gif,
size_t rawlen;
unsigned char *raw = slurp_file(str, &rawlen);
if (!raw) goto ENDEND;
int n;
texture *tex = calloc(1,sizeof(*tex));
int frames;
int *delays;
tex->data = stbi_load_gif_from_memory(raw, rawlen, &delays, &tex->width, &tex->height, &frames, &n, 4);
JSValue gif = JS_NewObject(js);
JSValue delay_arr = JS_NewArray(js);
2024-10-19 18:37:27 -05:00
JSValue jstex = texture2js(tex);
2024-10-18 12:51:21 -05:00
float yslice = 1.0/frames;
for (int i = 0; i < frames; i++) {
JSValue frame = JS_NewObject(js);
js_setpropstr(frame, "time", number2js((float)delays[i]/1000.0));
js_setpropstr(frame, "rect", rect2js((rect){
.x = 0,
.y = yslice*i,
.w = 1,
.h = yslice
}));
2024-10-19 18:37:27 -05:00
js_setpropstr(frame, "texture", JS_DupValue(js,jstex));
2024-10-18 12:51:21 -05:00
js_setprop_num(delay_arr, i, frame);
}
2024-10-19 05:34:08 -05:00
js_setpropstr(gif, "frames", delay_arr);
2024-10-19 18:37:27 -05:00
JS_FreeValue(js,jstex);
2024-10-18 12:51:21 -05:00
free(delays);
ret = gif;
END:
free(raw);
ENDEND:
)
2024-10-05 08:43:51 -05:00
JSC_SCALL(os_make_aseprite,
2024-10-18 12:51:21 -05:00
size_t rawlen;
unsigned char *raw = slurp_file(str, &rawlen);
ase_t *ase = cute_aseprite_load_from_memory(raw, rawlen, NULL);
JSValue obj = JS_NewObject(js);
int w = ase->w;
int h = ase->h;
int pixels = w*h;
for (int t = 0; t < ase->tag_count; t++) {
ase_tag_t tag = ase->tags[t];
JSValue anim = JS_NewObject(js);
js_setpropstr(anim, "repeat", number2js(tag.repeat));
switch(tag.loop_animation_direction) {
case ASE_ANIMATION_DIRECTION_FORWARDS:
js_setpropstr(anim, "loop", str2js("forward"));
break;
case ASE_ANIMATION_DIRECTION_BACKWORDS:
js_setpropstr(anim, "loop", str2js("backward"));
break;
case ASE_ANIMATION_DIRECTION_PINGPONG:
js_setpropstr(anim, "loop", str2js("pingpong"));
break;
}
int _frame = 0;
JSValue frames = JS_NewArray(js);
for (int f = tag.from_frame; f <= tag.to_frame; f++) {
ase_frame_t aframe = ase->frames[f];
JSValue frame = JS_NewObject(js);
texture *tex = calloc(1,sizeof(*tex));
tex->width = w;
tex->height = h;
tex->data = malloc(w*h*4);
memcpy(tex->data, aframe.pixels, w*h*4);
js_setpropstr(frame, "texture", texture2js(tex));
js_setpropstr(frame, "rect", rect2js((rect){.x=0,.y=0,.w=1,.h=1}));
js_setpropstr(frame, "time", number2js((float)aframe.duration_milliseconds/1000.0));
js_setprop_num(frames, _frame, frame);
_frame++;
}
js_setpropstr(anim, "frames", frames);
js_setpropstr(obj, tag.name, anim);
}
ret = obj;
cute_aseprite_free(ase);
)
2024-08-12 15:19:34 -05:00
JSC_SCALL(os_texture_swap,
texture *old = js2texture(argv[1]);
texture *tex = texture_from_file(str);
JS_SetOpaque(argv[1], tex);
texture_free(old);
)
2024-06-18 17:10:24 -05:00
JSC_CCALL(os_make_tex_data,
ret = texture2js(texture_empty(js2number(argv[0]), js2number(argv[1])))
2024-06-18 17:10:24 -05:00
)
2024-06-18 16:14:23 -05:00
2024-05-12 18:36:14 -05:00
JSC_CCALL(os_make_font,
font *f = MakeFont(js2str(argv[0]), js2number(argv[1]));
ret = font2js(f);
js_setpropstr(ret, "texture", texture2js(f->texture));
2024-05-02 13:52:28 -05:00
)
2024-05-12 18:36:14 -05:00
JSC_CCALL(os_make_transform, return transform2js(make_transform()))
2024-05-02 13:52:28 -05:00
JSC_SCALL(os_system, return number2js(system(str)); )
2024-05-14 15:22:24 -05:00
2024-08-08 17:32:58 -05:00
JSC_SCALL(os_gltf_buffer,
int buffer_idx = js2number(argv[1]);
int type = js2number(argv[2]);
cgltf_options options = {0};
cgltf_data *data = NULL;
cgltf_result result = cgltf_parse_file(&options, str, &data);
result = cgltf_load_buffers(&options, data, str);
2024-05-14 15:22:24 -05:00
2024-08-08 17:32:58 -05:00
sg_buffer *b = malloc(sizeof(*b));
*b = accessor2buffer(&data->accessors[buffer_idx], type);
cgltf_free(data);
2024-08-08 17:32:58 -05:00
ret = sg_buffer2js(b);
)
2024-05-14 15:22:24 -05:00
2024-08-08 17:32:58 -05:00
JSC_SCALL(os_gltf_skin,
cgltf_options options = {0};
cgltf_data *data = NULL;
cgltf_parse_file(&options,str,&data);
cgltf_load_buffers(&options,data,str);
if (data->skins_count <= 0) {
ret = (JS_UNDEFINED);
goto CLEANUP;
}
2024-08-10 04:06:44 -05:00
ret = skin2js(make_gltf_skin(data->skins+0, data));
2024-08-09 14:39:31 -05:00
2024-08-08 17:32:58 -05:00
CLEANUP:
cgltf_free(data);
2024-05-14 15:22:24 -05:00
)
2024-07-18 17:09:35 -05:00
2024-05-06 21:59:22 -05:00
JSC_CCALL(os_make_buffer,
int type = js2number(argv[1]);
float *b = malloc(sizeof(float)*js_arrlen(argv[0]));
for (int i = 0; i < js_arrlen(argv[0]); i++)
b[i] = js2number(js_getpropidx(argv[0],i));
sg_buffer *p = malloc(sizeof(sg_buffer));
switch(type) {
case 0:
*p = sg_make_buffer(&(sg_buffer_desc){
.size = sizeof(float)*js_arrlen(argv[0]),
.data = b
});
break;
case 1:
*p = index_buffer(b, js_arrlen(argv[0]));
break;
case 2:
*p = texcoord_floats(b, js_arrlen(argv[0]));
break;
}
free(b);
return sg_buffer2js(p);
)
JSC_CCALL(os_make_line_prim,
JSValue prim = JS_NewObject(js);
HMM_Vec2 *v = js2cpvec2arr(argv[0]);
parsl_position par_v[arrlen(v)];
for (int i = 0; i < arrlen(v); i++) {
par_v[i].x = v[i].x;
par_v[i].y = v[i].y;
}
parsl_context *par_ctx = parsl_create_context((parsl_config){
.thickness = js2number(argv[1]),
.flags= PARSL_FLAG_ANNOTATIONS,
2024-05-08 11:07:19 -05:00
.u_mode = js2number(argv[2])
2024-05-06 21:59:22 -05:00
});
uint16_t spine_lens[] = {arrlen(v)};
parsl_mesh *m = parsl_mesh_from_lines(par_ctx, (parsl_spine_list){
.num_vertices = arrlen(v),
.num_spines = 1,
.vertices = par_v,
2024-05-08 11:07:19 -05:00
.spine_lengths = spine_lens,
.closed = js2boolean(argv[3])
2024-05-06 21:59:22 -05:00
});
2024-05-08 11:07:19 -05:00
HMM_Vec3 a_pos[m->num_vertices];
for (int i = 0; i < m->num_vertices; i++) {
a_pos[i].x = m->positions[i].x;
a_pos[i].y = m->positions[i].y;
a_pos[i].z = 0;
}
2024-05-06 21:59:22 -05:00
sg_buffer *pos = malloc(sizeof(*pos));
*pos = sg_make_buffer(&(sg_buffer_desc){
2024-05-08 11:07:19 -05:00
.data = SG_RANGE(a_pos),
2024-05-06 21:59:22 -05:00
});
js_setpropstr(prim, "pos", sg_buffer2js(pos));
js_setpropstr(prim, "count", number2js(m->num_triangles*3));
sg_buffer *idx = malloc(sizeof(*idx));
*idx = par_idx_buffer(m->triangle_indices, m->num_triangles*3);
js_setpropstr(prim, "index", sg_buffer2js(idx));
float uv[m->num_vertices*2];
for (int i = 0; i < m->num_vertices; i++) {
uv[i*2] = m->annotations[i].u_along_curve;
uv[i*2+1] = m->annotations[i].v_across_curve;
}
sg_buffer *buv = malloc(sizeof(*buv));
*buv = texcoord_floats(uv, m->num_vertices*2);
js_setpropstr(prim, "uv", sg_buffer2js(buv));
return prim;
2024-05-08 11:07:19 -05:00
)
JSValue parmesh2js(par_shapes_mesh *m)
{
JSValue obj = JS_NewObject(js);
sg_buffer *pos = malloc(sizeof(*pos));
*pos = float_buffer(m->points, 3*m->npoints);
js_setpropstr(obj, "pos", sg_buffer2js(pos));
if (m->tcoords) {
sg_buffer *uv = malloc(sizeof(*uv));
*uv = texcoord_floats(m->tcoords, 2*m->npoints);
js_setpropstr(obj, "uv", sg_buffer2js(uv));
}
if (m->normals) {
sg_buffer *norm = malloc(sizeof(*norm));
2024-05-14 15:22:24 -05:00
*norm = normal_floats(m->normals, 3*m->npoints);
2024-05-08 11:07:19 -05:00
js_setpropstr(obj, "norm", sg_buffer2js(norm));
}
sg_buffer *index = malloc(sizeof(*index));
*index = sg_make_buffer(&(sg_buffer_desc){
.data = {
.ptr = m->triangles,
.size = sizeof(*m->triangles)*3*m->ntriangles
},
.type = SG_BUFFERTYPE_INDEXBUFFER
});
js_setpropstr(obj, "index", sg_buffer2js(index));
js_setpropstr(obj, "count", number2js(3*m->ntriangles));
par_shapes_free_mesh(m);
return obj;
}
JSC_CCALL(os_make_cylinder,
return parmesh2js(par_shapes_create_cylinder(js2number(argv[0]), js2number(argv[1])));
)
JSC_CCALL(os_make_cone,
return parmesh2js(par_shapes_create_cone(js2number(argv[0]), js2number(argv[1])));
)
JSC_CCALL(os_make_disk,
return parmesh2js(par_shapes_create_parametric_disk(js2number(argv[0]), js2number(argv[1])));
)
JSC_CCALL(os_make_torus,
return parmesh2js(par_shapes_create_torus(js2number(argv[0]), js2number(argv[1]), js2number(argv[2])));
)
JSC_CCALL(os_make_sphere,
return parmesh2js(par_shapes_create_parametric_sphere(js2number(argv[0]), js2number(argv[1])));
)
JSC_CCALL(os_make_klein_bottle,
return parmesh2js(par_shapes_create_klein_bottle(js2number(argv[0]), js2number(argv[1])));
)
JSC_CCALL(os_make_trefoil_knot,
return parmesh2js(par_shapes_create_trefoil_knot(js2number(argv[0]), js2number(argv[1]), js2number(argv[2])));
)
JSC_CCALL(os_make_hemisphere,
return parmesh2js(par_shapes_create_hemisphere(js2number(argv[0]), js2number(argv[1])));
)
JSC_CCALL(os_make_plane,
return parmesh2js(par_shapes_create_plane(js2number(argv[0]), js2number(argv[1])));
)
2024-04-20 12:55:20 -05:00
JSC_SCALL(os_make_video,
datastream *ds = ds_openvideo(str);
ret = datastream2js(ds);
texture *t = malloc(sizeof(texture));
t->id = ds->img;
js_setpropstr(ret, "texture", texture2js(t));
)
2024-08-08 17:32:58 -05:00
JSC_CCALL(os_skin_calculate,
skin *sk = js2skin(argv[0]);
skin_calculate(sk);
)
JSC_CCALL(os_rectpack,
int width = js2number(argv[0]);
int height = js2number(argv[1]);
int num = js_arrlen(argv[2]);
stbrp_context ctx[1];
stbrp_rect rects[num];
for (int i = 0; i < num; i++) {
HMM_Vec2 wh = js2vec2(js_getpropidx(argv[2], i));
rects[i].w = wh.x;
rects[i].h = wh.y;
rects[i].id = i;
}
stbrp_node nodes[width];
stbrp_init_target(ctx, width, height, nodes, width);
int packed = stbrp_pack_rects(ctx, rects, num);
2024-10-05 08:43:51 -05:00
if (!packed) {
return JS_UNDEFINED;
2024-10-05 08:43:51 -05:00
}
ret = JS_NewArray(js);
for (int i = 0; i < num; i++) {
HMM_Vec2 pos;
pos.x = rects[i].x;
pos.y = rects[i].y;
js_setprop_num(ret, i, vec22js(pos));
}
)
JSC_CCALL(os_perlin,
HMM_Vec3 coord = js2vec3(argv[0]);
HMM_Vec3 wrap = js2vec3(argv[2]);
return number2js(stb_perlin_noise3_seed(coord.x, coord.y, coord.z, wrap.x, wrap.y, wrap.z, js2number(argv[1])));
)
JSC_CCALL(os_ridge,
HMM_Vec3 c = js2vec3(argv[0]);
return number2js(stb_perlin_ridge_noise3(c.x, c.y, c.z, js2number(argv[1]), js2number(argv[2]), js2number(argv[3]), js2number(argv[4])));
)
JSC_CCALL(os_fbm,
HMM_Vec3 c = js2vec3(argv[0]);
return number2js(stb_perlin_fbm_noise3(c.x, c.y, c.z, js2number(argv[1]), js2number(argv[2]), js2number(argv[3])));
)
JSC_CCALL(os_turbulence,
HMM_Vec3 c = js2vec3(argv[0]);
return number2js(stb_perlin_turbulence_noise3(c.x, c.y, c.z, js2number(argv[1]), js2number(argv[2]), js2number(argv[3])));
)
2024-04-03 17:17:32 -05:00
static const JSCFunctionListEntry js_os_funcs[] = {
MIST_FUNC_DEF(os, turbulence, 4),
MIST_FUNC_DEF(os, fbm, 4),
2024-10-03 17:36:29 -05:00
MIST_FUNC_DEF(os, backend, 0),
MIST_FUNC_DEF(os, ridge, 5),
MIST_FUNC_DEF(os, perlin, 3),
MIST_FUNC_DEF(os, rectpack, 3),
2024-04-03 17:17:32 -05:00
MIST_FUNC_DEF(os, cwd, 0),
2024-09-29 06:10:42 -05:00
MIST_FUNC_DEF(os, rusage, 0),
MIST_FUNC_DEF(os, mallinfo, 0),
2024-04-03 17:17:32 -05:00
MIST_FUNC_DEF(os, env, 1),
MIST_FUNC_DEF(os, sys, 0),
MIST_FUNC_DEF(os, system, 1),
MIST_FUNC_DEF(os, quit, 0),
MIST_FUNC_DEF(os, exit, 1),
MIST_FUNC_DEF(os, gc, 0),
MIST_FUNC_DEF(os, eval, 2),
MIST_FUNC_DEF(os, make_texture, 1),
2024-10-18 12:51:21 -05:00
MIST_FUNC_DEF(os, make_gif, 1),
MIST_FUNC_DEF(os, make_aseprite, 1),
2024-08-12 15:19:34 -05:00
MIST_FUNC_DEF(os, texture_swap, 2),
2024-06-18 16:14:23 -05:00
MIST_FUNC_DEF(os, make_tex_data, 3),
2024-04-09 16:48:15 -05:00
MIST_FUNC_DEF(os, make_font, 2),
2024-05-12 18:36:14 -05:00
MIST_FUNC_DEF(os, make_transform, 0),
2024-05-06 21:59:22 -05:00
MIST_FUNC_DEF(os, make_buffer, 1),
2024-05-17 12:39:04 -05:00
MIST_FUNC_DEF(os, make_line_prim, 4),
2024-05-08 11:07:19 -05:00
MIST_FUNC_DEF(os, make_cylinder, 2),
MIST_FUNC_DEF(os, make_cone, 2),
MIST_FUNC_DEF(os, make_disk, 2),
MIST_FUNC_DEF(os, make_torus, 3),
MIST_FUNC_DEF(os, make_sphere, 2),
MIST_FUNC_DEF(os, make_klein_bottle, 2),
MIST_FUNC_DEF(os, make_trefoil_knot, 3),
MIST_FUNC_DEF(os, make_hemisphere, 2),
MIST_FUNC_DEF(os, make_plane, 2),
MIST_FUNC_DEF(os, make_video, 1),
2024-09-30 04:36:53 -05:00
MIST_FUNC_DEF(os, make_timer, 1),
2024-08-05 15:26:18 -05:00
MIST_FUNC_DEF(os, update_timers, 1),
MIST_FUNC_DEF(os, mem, 1),
MIST_FUNC_DEF(os, mem_limit, 1),
MIST_FUNC_DEF(os, gc_threshold, 1),
2024-08-06 14:23:21 -05:00
MIST_FUNC_DEF(os, max_stacksize, 1),
MIST_FUNC_DEF(os, dump_value, 1),
MIST_FUNC_DEF(os, dump_mem, 0),
MIST_FUNC_DEF(os, dump_shapes, 0),
MIST_FUNC_DEF(os, dump_atoms,0),
MIST_FUNC_DEF(os, calc_mem, 1),
MIST_FUNC_DEF(os, check_gc, 0),
MIST_FUNC_DEF(os, check_cycles, 0),
MIST_FUNC_DEF(os, memstate, 0),
2024-08-08 17:32:58 -05:00
MIST_FUNC_DEF(os, value_id, 1),
MIST_FUNC_DEF(os, gltf_buffer, 3),
MIST_FUNC_DEF(os, gltf_skin, 1),
MIST_FUNC_DEF(os, skin_calculate, 1),
2024-04-03 17:17:32 -05:00
};
#define JSSTATIC(NAME, PARENT) \
js_##NAME = JS_NewObject(js); \
JS_SetPropertyFunctionList(js, js_##NAME, js_##NAME##_funcs, countof(js_##NAME##_funcs)); \
JS_SetPrototype(js, js_##NAME, PARENT); \
2024-10-29 12:41:17 -05:00
JSValue js_layout(JSContext *js);
JSValue js_miniz(JSContext *js);
JSValue js_soloud_use(JSContext *js);
JSValue js_chipmunk2d_use(JSContext *js);
#ifndef NEDITOR
JSValue js_imgui(JSContext *js);
#endif
2023-05-12 13:22:05 -05:00
void ffi_load() {
2024-08-06 14:23:21 -05:00
cycles = tmpfile();
quickjs_set_cycleout(cycles);
2023-05-24 20:45:50 -05:00
globalThis = JS_GetGlobalObject(js);
2024-09-29 06:10:42 -05:00
QJSGLOBALCLASS(os);
2024-09-29 06:10:42 -05:00
QJSCLASSPREP_FUNCS(sg_buffer);
2024-05-12 18:36:14 -05:00
QJSCLASSPREP_FUNCS(transform);
2024-10-29 12:41:17 -05:00
// QJSCLASSPREP_FUNCS(warp_gravity);
// QJSCLASSPREP_FUNCS(warp_damp);
QJSCLASSPREP_FUNCS(texture);
2024-04-09 16:48:15 -05:00
QJSCLASSPREP_FUNCS(font);
2024-03-13 16:30:55 -05:00
QJSCLASSPREP_FUNCS(window);
QJSCLASSPREP_FUNCS(datastream);
2024-08-04 15:20:11 -05:00
QJSCLASSPREP_FUNCS(timer);
2024-02-25 17:31:48 -06:00
2024-03-18 08:16:25 -05:00
QJSGLOBALCLASS(input);
QJSGLOBALCLASS(io);
QJSGLOBALCLASS(prosperon);
QJSGLOBALCLASS(time);
QJSGLOBALCLASS(console);
QJSGLOBALCLASS(profile);
2024-03-18 08:16:25 -05:00
QJSGLOBALCLASS(game);
QJSGLOBALCLASS(gui);
QJSGLOBALCLASS(render);
2024-09-29 06:10:42 -05:00
// QJSGLOBALCLASS(sgl);
2024-03-18 08:16:25 -05:00
QJSGLOBALCLASS(vector);
2024-03-19 14:39:19 -05:00
QJSGLOBALCLASS(spline);
QJSGLOBALCLASS(performance);
2024-10-06 17:18:18 -05:00
QJSGLOBALCLASS(geometry);
2024-10-29 12:41:17 -05:00
JS_SetPropertyStr(js, prosperon, "version", str2js("ver"));
JS_SetPropertyStr(js, prosperon, "revision", str2js("com"));
JS_SetPropertyStr(js, prosperon, "date", str2js("date"));
2024-03-18 08:16:25 -05:00
JS_SetPropertyStr(js, globalThis, "window", window2js(&mainwin));
JS_SetPropertyStr(js, globalThis, "texture", JS_DupValue(js,texture_proto));
2024-05-21 18:50:53 -05:00
JSValue array_proto = js_getpropstr(globalThis, "Array");
array_proto = js_getpropstr(array_proto, "prototype");
2024-08-08 13:25:47 -05:00
JS_SetPropertyFunctionList(js, array_proto, js_array_funcs, countof(js_array_funcs));
2024-10-06 17:18:18 -05:00
srand(stm_now());
2024-10-29 12:41:17 -05:00
JS_SetPropertyStr(js, globalThis, "layout", js_layout(js));
JS_SetPropertyStr(js, globalThis, "miniz", js_miniz(js));
JS_SetPropertyStr(js, globalThis, "soloud", js_soloud_use(js));
JS_SetPropertyStr(js, globalThis, "chipmunk2d", js_chipmunk2d_use(js));
#ifndef NEDITOR
JS_SetPropertyStr(js, globalThis, "imgui", js_imgui(js));
#endif
2024-10-15 07:55:49 -05:00
2024-03-22 09:02:10 -05:00
JS_FreeValue(js,globalThis);
2023-01-10 15:41:43 -06:00
}
2024-07-03 16:38:29 -05:00