prosperon/source/engine/ffi.c

1509 lines
33 KiB
C
Raw Normal View History

2023-01-10 07:13:00 -06:00
#include "ffi.h"
#include "script.h"
2023-01-10 14:02:24 -06:00
#include "string.h"
2023-03-24 14:01:01 -05:00
#include "debug.h"
2023-01-10 14:02:24 -06:00
#include "window.h"
#include "editor.h"
#include "engine.h"
#include "log.h"
#include "input.h"
#include "gameobject.h"
#include "openglrender.h"
#include "2dphysics.h"
#include "sprite.h"
#include "anim.h"
#include "yugine.h"
#include "nuke.h"
2023-01-15 09:53:50 -06:00
#include "sound.h"
2023-01-10 15:41:43 -06:00
#include "font.h"
#include "sound.h"
#include "music.h"
#include "level.h"
2023-01-27 12:06:16 -06:00
#include "tinyspline.h"
#include "mix.h"
2023-02-05 17:42:36 -06:00
#include "debugdraw.h"
#include "stb_ds.h"
2023-02-13 21:02:14 -06:00
#include <ftw.h>
2023-04-21 16:57:30 -05:00
#include <assert.h>
2023-03-24 14:01:01 -05:00
#include "miniaudio.h"
#define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c"
#define BYTE_TO_BINARY(byte) \
(byte & 0x80 ? '1' : '0'), \
(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')
2023-01-25 21:32:58 -06:00
2023-04-18 14:49:17 -05:00
int js2int(JSValue v)
2023-02-06 16:41:47 -06:00
{
2023-04-19 15:16:35 -05:00
int32_t i;
2023-04-18 14:49:17 -05:00
JS_ToInt32(js,&i,v);
return i;
2023-02-06 16:41:47 -06:00
}
2023-04-18 17:58:44 -05:00
JSValue int2js(int i)
{
return JS_NewInt64(js, i);
}
2023-04-25 16:59:12 -05:00
JSValue str2js(const char *c)
{
return JS_NewString(js, c);
}
2023-04-18 17:58:44 -05:00
double js2number(JSValue v)
{
double g;
JS_ToFloat64(js,&g, v);
return g;
}
JSValue float2js(double g)
{
return JS_NewFloat64(js,g);
}
2023-04-19 15:16:35 -05:00
2023-04-18 17:58:44 -05:00
JSValue num2js(double g)
{
return float2js(g);
}
2023-04-18 14:49:17 -05:00
struct gameobject *js2go(JSValue v)
2023-03-05 22:05:22 -06:00
{
2023-04-18 14:49:17 -05:00
return id2go(js2int(v));
2023-03-05 22:05:22 -06:00
}
2023-04-18 17:58:44 -05:00
void *js2ptr(JSValue v)
{
void *p;
JS_ToInt64(js, &p, v);
return p;
}
JSValue ptr2js(void *ptr)
{
2023-04-19 15:16:35 -05:00
return JS_NewInt64(js,(long)ptr);
2023-04-18 17:58:44 -05:00
}
2023-04-18 14:49:17 -05:00
struct timer *js2timer(JSValue v)
{
return id2timer(js2int(v));
}
2023-01-16 02:16:39 -06:00
2023-04-19 15:16:35 -05:00
double js_get_prop_number(JSValue v, const char *p)
2023-03-05 22:05:22 -06:00
{
2023-04-19 15:16:35 -05:00
double num;
2023-04-18 14:49:17 -05:00
JS_ToFloat64(js, &num, JS_GetPropertyStr(js, v, p));
return num;
2023-03-05 22:05:22 -06:00
}
2023-04-18 17:58:44 -05:00
struct glrect js2glrect(JSValue v)
2023-03-05 22:05:22 -06:00
{
struct glrect rect;
2023-04-18 14:49:17 -05:00
rect.s0 = js_get_prop_number(v,"s0");
rect.s1 = js_get_prop_number(v,"s1");
rect.t0 = js_get_prop_number(v,"t0");
rect.t1 = js_get_prop_number(v,"t1");
2023-03-05 22:05:22 -06:00
return rect;
}
2023-04-19 15:16:35 -05:00
JSValue js_arridx(JSValue v, int idx)
{
return JS_GetPropertyUint32(js,v,idx);
}
2023-04-18 14:49:17 -05:00
int js_arrlen(JSValue v)
{
2023-04-18 14:49:17 -05:00
int len;
2023-04-19 15:16:35 -05:00
JS_ToInt32(js, &len, JS_GetPropertyStr(js, v, "length"));
2023-04-18 14:49:17 -05:00
return len;
}
2023-04-19 15:16:35 -05:00
struct color js2color(JSValue v)
{
struct color color = {0,0,0};
color.r = js2int(js_arridx(v,0));
color.g = js2int(js_arridx(v,1));
color.b = js2int(js_arridx(v,2));
return color;
}
2023-01-27 12:06:16 -06:00
2023-04-18 14:49:17 -05:00
cpVect js2vec2(JSValue v)
{
cpVect vect;
2023-04-19 15:16:35 -05:00
vect.x = js2number(js_arridx(v,0));
vect.y = js2number(js_arridx(v,1));
2023-04-18 14:49:17 -05:00
return vect;
2023-01-10 07:13:00 -06:00
}
2023-04-18 14:49:17 -05:00
cpBitmask js2bitmask(JSValue v)
{
cpBitmask mask = 0;
2023-04-18 14:49:17 -05:00
int len = js_arrlen(v);
for (int i = 0; i < len; i++) {
2023-04-18 14:49:17 -05:00
int val = JS_ToBool(js, JS_GetPropertyUint32(js, v, i));
2023-03-10 13:13:48 -06:00
if (!val) continue;
2023-03-10 13:13:48 -06:00
mask |= 1<<i;
}
return mask;
}
2023-04-18 14:49:17 -05:00
cpVect *js2cpvec2arr(JSValue v)
2023-02-08 15:30:12 -06:00
{
2023-04-18 14:49:17 -05:00
int n = js_arrlen(v);
2023-02-08 15:30:12 -06:00
cpVect *points = NULL;
2023-04-18 14:49:17 -05:00
for (int i = 0; i < n; i++)
arrput(points, js2vec2(JS_GetPropertyUint32(js, v, i)));
2023-02-08 15:30:12 -06:00
return points;
}
2023-04-18 14:49:17 -05:00
JSValue bitmask2js(cpBitmask mask)
{
2023-04-19 16:58:17 -05:00
JSValue arr = JS_NewArray(js);
for (int i = 0; i < 11; i++) {
int on = mask & 1<<i;
2023-04-18 14:49:17 -05:00
JS_SetPropertyUint32(js, arr, i, JS_NewBool(js, on));
}
2023-04-18 14:49:17 -05:00
return arr;
}
2023-01-19 18:30:23 -06:00
void vec2float(cpVect v, float *f)
{
f[0] = v.x;
f[1] = v.y;
}
2023-04-18 14:49:17 -05:00
JSValue vec2js(cpVect v)
2023-03-19 20:33:05 -05:00
{
2023-04-19 15:16:35 -05:00
JSValue array = JS_NewArray(js);
2023-04-18 14:49:17 -05:00
JS_SetPropertyInt64(js, array, 0, JS_NewFloat64(js,v.x));
JS_SetPropertyInt64(js, array, 1, JS_NewFloat64(js,v.y));
return array;
2023-03-19 20:33:05 -05:00
}
2023-04-18 14:49:17 -05:00
JSValue vecarr2js(cpVect *points, int n)
{
2023-04-19 16:58:17 -05:00
JSValue array = JS_NewArray(js);
2023-04-18 14:49:17 -05:00
for (int i = 0; i < n; i++)
JS_SetPropertyInt64(js, array, i, vec2js(points[i]));
return array;
}
2023-04-18 14:49:17 -05:00
JSValue duk_gui_text(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
{
const char *s = JS_ToCString(js, argv[0]);
cpVect pos = js2vec2(argv[1]);
2023-01-10 07:13:00 -06:00
2023-04-18 17:58:44 -05:00
float size = js2number(argv[2]);
2023-01-10 14:02:24 -06:00
const float white[3] = {1.f, 1.f, 1.f};
2023-03-10 13:13:48 -06:00
renderText(s, &pos, size, white, 500,-1);
2023-04-19 16:58:17 -05:00
JS_FreeCString(js, s);
2023-04-18 14:49:17 -05:00
return JS_NULL;
2023-01-10 07:13:00 -06:00
}
2023-04-18 14:49:17 -05:00
JSValue duk_ui_text(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
2023-03-03 13:07:59 -06:00
{
2023-04-18 14:49:17 -05:00
const char *s = JS_ToCString(js,argv[0]);
cpVect pos = js2vec2(argv[1]);
2023-03-03 13:07:59 -06:00
2023-04-18 17:58:44 -05:00
float size = js2number(argv[2]);
struct color c = js2color(argv[3]);
2023-03-03 13:07:59 -06:00
const float col[3] = {(float)c.r/255, (float)c.g/255, (float)c.b/255};
2023-04-18 17:58:44 -05:00
int wrap = js2int(argv[4]);
2023-04-19 16:58:17 -05:00
JSValue ret = JS_NewInt64(js, renderText(s, &pos, size, col, wrap,-1));
JS_FreeCString(js,s);
return ret;
2023-03-10 13:13:48 -06:00
}
2023-04-18 14:49:17 -05:00
JSValue duk_cursor_text(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
2023-03-10 13:13:48 -06:00
{
2023-04-18 14:49:17 -05:00
const char *s = JS_ToCString(js,argv[0]);
cpVect pos = js2vec2(argv[1]);
2023-03-03 13:07:59 -06:00
2023-04-18 17:58:44 -05:00
float size = js2number(argv[2]);
struct color c = js2color(argv[3]);
2023-03-10 13:13:48 -06:00
const float col[3] = {(float)c.r/255, (float)c.g/255, (float)c.b/255};
2023-04-18 17:58:44 -05:00
int wrap = js2int(argv[5]);
int cursor = js2int(argv[4]);
2023-04-07 12:52:35 -05:00
renderText(s, &pos, size, col, wrap,cursor);
2023-04-19 16:58:17 -05:00
JS_FreeCString(js,s);
2023-04-18 14:49:17 -05:00
return JS_NULL;
2023-03-03 13:07:59 -06:00
}
2023-04-18 14:49:17 -05:00
JSValue duk_gui_img(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
{
const char *img = JS_ToCString(js,argv[0]);
2023-04-18 17:58:44 -05:00
cpVect pos = js2vec2(argv[1]);
2023-01-10 17:23:11 -06:00
gui_draw_img(img, pos.x, pos.y);
2023-04-19 16:58:17 -05:00
JS_FreeCString(js,img);
2023-04-18 14:49:17 -05:00
return JS_NULL;
2023-01-10 17:23:11 -06:00
}
2023-04-18 17:58:44 -05:00
struct nk_rect js2nk_rect(JSValue v)
{
struct nk_rect rect;
rect.x = js2number(JS_GetPropertyStr(js, v, "x"));
rect.y = js2number(JS_GetPropertyStr(js, v, "y"));
rect.w = js2number(JS_GetPropertyStr(js, v, "w"));
rect.h = js2number(JS_GetPropertyStr(js, v, "h"));
return rect;
}
JSValue nk_rect2js(struct nk_rect rect)
{
JSValue obj = JS_NewObject(js);
JS_SetPropertyStr(js, obj, "x", JS_NewFloat64(js, rect.x));
JS_SetPropertyStr(js, obj, "y", JS_NewFloat64(js,rect.y));
JS_SetPropertyStr(js, obj, "w", JS_NewFloat64(js, rect.w));
JS_SetPropertyStr(js, obj, "h", JS_NewFloat64(js, rect.h));
return obj;
}
2023-04-18 14:49:17 -05:00
JSValue duk_nuke(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
2023-01-19 13:06:32 -06:00
{
2023-04-18 17:58:44 -05:00
int cmd = js2int(argv[0]);
2023-01-19 13:06:32 -06:00
float editnum;
2023-01-19 16:43:29 -06:00
int editint;
2023-02-05 11:40:59 -06:00
char textbox[130];
2023-04-19 16:58:17 -05:00
const char *str = NULL;
if (JS_IsString(argv[1]))
str = JS_ToCString(js,argv[1]);
2023-04-21 16:57:30 -05:00
else {
JSValue tostr = JS_ToString(js,argv[1]);
str = JS_ToCString(js,argv[1]);
JS_FreeValue(js,tostr);
}
2023-04-19 16:58:17 -05:00
2023-02-26 10:24:21 -06:00
struct nk_rect rect = nk_rect(0,0,0,0);
2023-04-19 16:58:17 -05:00
JSValue ret = JS_NULL;
2023-01-19 13:06:32 -06:00
switch(cmd) {
case 0:
2023-04-19 16:58:17 -05:00
rect = js2nk_rect(argv[2]);
nuke_begin(str,rect, NK_WINDOW_BORDER | NK_WINDOW_MOVABLE | NK_WINDOW_SCALABLE | NK_WINDOW_TITLE);
2023-01-19 13:06:32 -06:00
break;
case 1:
nuke_stop();
break;
case 2:
2023-04-18 17:58:44 -05:00
editnum = js2number(argv[2]);
2023-04-19 16:58:17 -05:00
nuke_property_float(str, js2number(argv[3]), &editnum, js2number(argv[4]), js2number(argv[5]), js2number(argv[5]));
ret = JS_NewFloat64(js, editnum);
break;
2023-01-19 13:06:32 -06:00
case 3:
2023-04-18 17:58:44 -05:00
nuke_nel(js2number(argv[1]));
2023-04-19 16:58:17 -05:00
break;
2023-01-19 16:43:29 -06:00
case 4:
2023-04-18 17:58:44 -05:00
editint = JS_ToBool(js, argv[2]);
2023-04-19 16:58:17 -05:00
nuke_checkbox(str, &editint);
ret = JS_NewBool(js,editint);
break;
2023-01-19 16:43:29 -06:00
case 5:
2023-04-19 16:58:17 -05:00
nuke_label(str);
break;
2023-02-03 13:41:53 -06:00
case 6:
2023-04-19 16:58:17 -05:00
ret = JS_NewBool(js, nuke_btn(str));
break;
2023-02-05 11:40:59 -06:00
case 7:
2023-04-19 16:58:17 -05:00
strncpy(textbox, str, 130);
2023-02-05 11:40:59 -06:00
nuke_edit_str(textbox);
2023-04-19 16:58:17 -05:00
ret = JS_NewString(js,textbox);
break;
2023-02-15 17:54:05 -06:00
case 8:
2023-04-19 16:58:17 -05:00
nuke_img(str);
2023-02-15 17:54:05 -06:00
break;
case 9:
2023-04-18 17:58:44 -05:00
editint = js2int(argv[2]);
2023-04-19 16:58:17 -05:00
nuke_radio_btn(str, &editint, js2int(argv[3]));
ret = JS_NewInt64(js, editint);
break;
2023-02-26 10:24:21 -06:00
case 10:
rect = nuke_win_get_bounds();
2023-04-19 16:58:17 -05:00
ret = nk_rect2js(rect);
break;
2023-03-01 14:42:44 -06:00
case 11:
2023-04-19 16:58:17 -05:00
ret = JS_NewBool(js,nuke_push_tree_id(str, js2int(argv[2])));
break;
2023-03-01 14:42:44 -06:00
case 12:
nuke_tree_pop();
2023-04-18 17:58:44 -05:00
return JS_NULL;
2023-03-10 13:13:48 -06:00
case 13:
2023-04-18 17:58:44 -05:00
nuke_row(js2int(argv[1]));
2023-03-10 13:13:48 -06:00
break;
2023-03-17 10:25:35 -05:00
case 14:
2023-04-19 16:58:17 -05:00
nuke_scrolltext(str);
2023-03-17 10:25:35 -05:00
break;
case 15:
2023-04-18 17:58:44 -05:00
nuke_nel_h(js2int(argv[1]), js2int(argv[2]));
2023-03-17 10:25:35 -05:00
break;
2023-01-19 13:06:32 -06:00
}
2023-04-19 16:58:17 -05:00
if (str)
JS_FreeCString(js, str);
return ret;
2023-01-19 13:06:32 -06:00
}
2023-04-18 14:49:17 -05:00
JSValue duk_win_make(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
{
2023-04-18 17:58:44 -05:00
const char *title = JS_ToCString(js, argv[0]);
int w = js2int(argv[1]);
int h = js2int(argv[2]);
2023-01-10 07:13:00 -06:00
struct window *win = MakeSDLWindow(title, w, h, 0);
2023-04-19 16:58:17 -05:00
JS_FreeCString(js,title);
2023-01-10 07:13:00 -06:00
2023-04-18 17:58:44 -05:00
return JS_NewInt64(js, win->id);
2023-01-10 07:13:00 -06:00
}
2023-04-18 14:49:17 -05:00
JSValue duk_spline_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
2023-01-27 12:06:16 -06:00
{
2023-04-21 16:57:30 -05:00
static_assert(sizeof(tsReal)*2 == sizeof(cpVect));
2023-01-27 12:06:16 -06:00
tsBSpline spline;
2023-04-21 16:57:30 -05:00
int d = js2int(argv[2]); /* dimensions */
int degrees = js2int(argv[1]);
int type = js2int(argv[3]);
JSValue ctrl_pts = argv[4];
int n = js_arrlen(ctrl_pts);
size_t nsamples = js2int(argv[5]);
cpVect points[n];
2023-01-27 12:06:16 -06:00
2023-02-10 14:31:59 -06:00
tsStatus status;
2023-04-21 16:57:30 -05:00
ts_bspline_new(n, d, degrees, type, &spline, &status);
2023-02-10 14:31:59 -06:00
2023-04-18 17:58:44 -05:00
if (status.code)
2023-02-10 14:31:59 -06:00
YughCritical("Spline creation error %d: %s", status.code, status.message);
2023-01-27 12:06:16 -06:00
2023-04-18 17:58:44 -05:00
for (int i = 0; i < n; i++)
2023-04-21 16:57:30 -05:00
points[i] = js2vec2(JS_GetPropertyUint32(js, ctrl_pts, i));
2023-01-27 12:06:16 -06:00
2023-04-21 16:57:30 -05:00
ts_bspline_set_control_points(&spline, (tsReal*)points, &status);
2023-01-27 12:06:16 -06:00
2023-04-21 16:57:30 -05:00
if (status.code)
YughCritical("Spline creation error %d: %s", status.code, status.message);
2023-01-27 12:06:16 -06:00
cpVect samples[nsamples];
2023-04-21 16:57:30 -05:00
2023-03-24 14:01:01 -05:00
size_t rsamples;
2023-04-21 16:57:30 -05:00
/* TODO: This does not work with Clang/GCC due to UB */
ts_bspline_sample(&spline, nsamples, (tsReal**)&samples, &rsamples, &status);
if (status.code)
YughCritical("Spline creation error %d: %s", status.code, status.message);
2023-01-27 12:06:16 -06:00
2023-04-19 16:58:17 -05:00
JSValue arr = JS_NewArray(js);
2023-01-27 12:06:16 -06:00
2023-03-24 14:01:01 -05:00
for (int i = 0; i < nsamples; i++) {
2023-04-21 16:57:30 -05:00
JSValue psample = JS_NewArray(js);
2023-04-18 17:58:44 -05:00
JS_SetPropertyUint32(js, psample, 0, float2js(samples[i].x));
JS_SetPropertyUint32(js, psample, 1, float2js(samples[i].y));
JS_SetPropertyUint32(js, arr, i, psample);
2023-03-24 14:01:01 -05:00
}
2023-01-27 12:06:16 -06:00
2023-03-24 14:01:01 -05:00
ts_bspline_free(&spline);
2023-01-27 12:06:16 -06:00
2023-04-18 17:58:44 -05:00
return arr;
2023-01-27 12:06:16 -06:00
}
2023-04-18 14:49:17 -05:00
2023-04-18 17:58:44 -05:00
JSValue ints2js(int *ints)
2023-02-05 17:42:36 -06:00
{
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++)
JS_SetPropertyUint32(js, arr, i, int2js(ints[i]));
return arr;
2023-02-05 17:42:36 -06:00
}
2023-02-10 14:31:58 -06:00
int vec_between(cpVect p, cpVect a, cpVect b)
{
cpVect n;
n.x = b.x - a.x;
n.y = b.y - a.y;
n = cpvnormalize(n);
return (cpvdot(n, cpvsub(p, a)) > 0 && cpvdot(cpvneg(n), cpvsub(p, b)) > 0);
}
/* 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-02-08 15:30:12 -06:00
int point2segindex(cpVect p, cpVect *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;
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);
float c = segs[i].y - (a * segs[i].x);
float b = -1;
float dist = abs(a*p.x + b*p.y + c) / sqrt(pow(a,2) + 1);
2023-02-10 14:31:58 -06:00
if (dist > shortest) continue;
int between = vec_between(p, segs[i], segs[i+1]);
if (between) {
2023-02-08 15:30:12 -06:00
shortest = dist;
2023-02-10 14:31:58 -06:00
best = i+1;
} else {
if (i == 0 && cpvdist(p, segs[0]) < slop) {
shortest = dist;
best = i;
} else if (i == arrlen(segs)-2 && cpvdist(p, arrlast(segs)) < slop) {
shortest = dist;
best = arrlen(segs);
}
2023-02-08 15:30:12 -06:00
}
}
2023-02-10 14:31:58 -06:00
if (best == 1) {
2023-02-08 15:30:12 -06:00
cpVect n;
n.x = segs[1].x-segs[0].x;
n.y = segs[1].y-segs[0].y;
n = cpvnormalize(n);
2023-02-10 14:31:58 -06:00
if (cpvdot(n, cpvsub(p, segs[0])) < 0)
if (cpvdist(p, segs[0]) >= slop)
best = -1;
else
best = 0;
2023-02-08 15:30:12 -06:00
}
if (best == arrlen(segs)-1) {
cpVect n;
n.x = segs[best-1].x-segs[best].x;
n.y = segs[best-1].y-segs[best-1].y;
n = cpvnormalize(n);
2023-02-10 14:31:58 -06:00
if (cpvdot(n, cpvsub(p, segs[best])) < 0)
if (cpvdist(p, segs[best]) >= slop)
best = -1;
else
best = arrlen(segs);
2023-02-08 15:30:12 -06:00
}
return best;
}
2023-02-13 21:02:14 -06:00
int file_exists(char *path)
{
FILE *o = fopen(path, "r");
if (o) {
fclose(o);
return 1;
}
return 0;
}
static char *dukext;
2023-04-18 17:58:44 -05:00
static JSValue dukarr;
2023-02-13 21:02:14 -06:00
static int dukidx;
static int duk2path(const char *path, const struct stat *sb, int typeflag)
{
if (typeflag == FTW_F) {
char *ext = strrchr(path, '.');
2023-04-18 17:58:44 -05:00
if (ext && !strcmp(ext, dukext))
JS_SetPropertyUint32(js, dukarr, dukidx++, JS_NewString(js, &path[2]));
2023-02-13 21:02:14 -06:00
}
return 0;
}
2023-04-18 17:58:44 -05:00
JSValue dukext2paths(char *ext)
2023-02-13 21:02:14 -06:00
{
dukext = ext;
2023-04-19 16:58:17 -05:00
dukarr = JS_NewArray(js);
2023-02-13 21:02:14 -06:00
dukidx = 0;
ftw(".", duk2path, 10);
2023-04-18 17:58:44 -05:00
return dukarr;
2023-02-13 21:02:14 -06:00
}
2023-04-18 14:49:17 -05:00
JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
{
2023-04-18 17:58:44 -05:00
int cmd = js2int(argv[0]);
const char *str = NULL;
const char *str2 = NULL;
2023-04-19 16:58:17 -05:00
JSValue ret = JS_NULL;
2023-01-10 14:02:24 -06:00
switch(cmd) {
case 0:
2023-04-19 16:58:17 -05:00
str = JS_ToCString(js,argv[1]);
ret = JS_NewInt64(js, script_dofile(str));
2023-04-25 11:55:33 -05:00
break;
2023-01-10 14:02:24 -06:00
case 1:
2023-04-18 17:58:44 -05:00
YughWarn("Do not set pawns here anymore; Do it entirely in script.");
//set_pawn(js2ptrduk_get_heapptr(duk, 1));
2023-01-10 14:02:24 -06:00
break;
case 2:
2023-04-18 17:58:44 -05:00
gameobject_delete(js2int(argv[1]));
2023-01-10 14:02:24 -06:00
break;
2023-01-10 17:23:11 -06:00
case 3:
2023-04-18 17:58:44 -05:00
set_timescale(js2number(argv[1]));
2023-01-10 17:23:11 -06:00
break;
case 4:
2023-04-18 17:58:44 -05:00
debug_draw_phys(JS_ToBool(js, argv[1]));
2023-01-10 17:23:11 -06:00
break;
case 5:
2023-04-18 17:58:44 -05:00
renderMS = js2number(argv[1]);
2023-01-10 17:23:11 -06:00
break;
case 6:
2023-04-18 17:58:44 -05:00
updateMS = js2number(argv[1]);
2023-01-10 17:23:11 -06:00
break;
case 7:
2023-04-18 17:58:44 -05:00
physMS = js2number(argv[1]);
2023-01-10 17:23:11 -06:00
break;
case 8:
2023-04-18 17:58:44 -05:00
phys2d_set_gravity(js2vec2(argv[1]));
2023-01-10 17:23:11 -06:00
break;
2023-01-11 16:57:34 -06:00
case 9:
2023-04-18 17:58:44 -05:00
sprite_delete(js2int(argv[1]));
2023-01-11 16:57:34 -06:00
break;
case 10:
2023-04-18 17:58:44 -05:00
YughWarn("Pawns are handled in script only now.");
2023-01-11 16:57:34 -06:00
break;
case 11:
2023-04-19 16:58:17 -05:00
str = JS_ToCString(js, argv[1]);
ret = JS_NewInt64(js, file_mod_secs(str));
break;
2023-01-11 16:57:34 -06:00
2023-01-13 13:07:44 -06:00
case 12:
str = JS_ToCString(js,argv[2]);
sprite_loadtex(id2sprite(js2int(argv[1])), str, js2glrect(argv[3]));
break;
2023-01-13 22:08:39 -06:00
case 13:
str = JS_ToCString(js,argv[1]);
str2 = JS_ToCString(js,argv[2]);
play_song(str,str2);
2023-01-11 16:57:34 -06:00
break;
2023-01-15 09:53:50 -06:00
case 14:
str = JS_ToCString(js, argv[1]);
mini_sound(str);
2023-01-15 09:53:50 -06:00
break;
case 15:
music_stop();
2023-01-15 09:53:50 -06:00
break;
case 16:
2023-04-18 17:58:44 -05:00
color2float(js2color(argv[1]), dbg_color);
2023-01-15 09:53:50 -06:00
break;
case 17:
2023-04-18 17:58:44 -05:00
color2float(js2color(argv[1]), trigger_color);
2023-01-15 09:53:50 -06:00
break;
case 18:
2023-04-18 17:58:44 -05:00
shape_set_sensor(js2ptr(argv[1]), JS_ToBool(js, argv[2]));
break;
case 19:
2023-04-18 17:58:44 -05:00
mini_master(js2number(argv[1]));
2023-01-17 15:09:14 -06:00
break;
2023-01-17 13:04:08 -06:00
case 20:
2023-04-18 17:58:44 -05:00
sprite_enabled(js2int(argv[1]), JS_ToBool(js, argv[2]));
2023-01-17 13:04:08 -06:00
break;
case 21:
2023-04-18 17:58:44 -05:00
return JS_NewBool(js, shape_get_sensor(js2ptr(argv[1])));
2023-01-17 13:04:08 -06:00
case 22:
2023-04-18 17:58:44 -05:00
shape_enabled(js2ptr(argv[1]), JS_ToBool(js, argv[2]));
2023-01-17 15:09:14 -06:00
break;
case 23:
2023-04-18 17:58:44 -05:00
return JS_NewBool(js, shape_is_enabled(js2ptr(argv[1])));
2023-01-18 17:15:36 -06:00
case 24:
2023-04-18 17:58:44 -05:00
timer_pause(js2timer(argv[1]));
2023-01-18 17:15:36 -06:00
break;
case 25:
2023-04-18 17:58:44 -05:00
timer_stop(js2timer(argv[1]));
2023-01-18 17:15:36 -06:00
break;
case 26:
2023-04-18 17:58:44 -05:00
timer_start(js2timer(argv[1]));
2023-01-18 17:15:36 -06:00
break;
case 27:
2023-04-18 17:58:44 -05:00
timer_remove(js2int(argv[1]));
2023-01-18 17:15:36 -06:00
break;
case 28:
2023-04-18 17:58:44 -05:00
timerr_settime(js2timer(argv[1]), js2number(argv[2]));
2023-01-18 17:15:36 -06:00
break;
case 29:
2023-04-18 17:58:44 -05:00
return JS_NewFloat64(js, js2timer(argv[1])->interval);
2023-01-18 17:15:36 -06:00
case 30:
2023-04-18 17:58:44 -05:00
sprite_setanim(id2sprite(js2int(argv[1])), js2ptr(argv[2]), js2int(argv[3]));
return JS_NULL;
2023-01-19 10:44:29 -06:00
case 31:
2023-04-18 17:58:44 -05:00
free(js2ptr(argv[1]));
2023-01-19 10:44:29 -06:00
break;
case 32:
2023-04-18 17:58:44 -05:00
return JS_NewFloat64(js, js2timer(argv[1])->remain_time);
2023-01-19 10:44:29 -06:00
case 33:
2023-04-18 17:58:44 -05:00
return JS_NewBool(js, js2timer(argv[1])->on);
2023-01-19 10:44:29 -06:00
case 34:
2023-04-18 17:58:44 -05:00
return JS_NewBool(js, js2timer(argv[1])->repeat);
2023-01-19 10:44:29 -06:00
case 35:
2023-04-18 17:58:44 -05:00
js2timer(argv[1])->repeat = JS_ToBool(js, argv[2]);
return JS_NULL;
2023-01-19 18:30:23 -06:00
case 36:
2023-04-18 17:58:44 -05:00
id2go(js2int(argv[1]))->scale = js2number(argv[2]);
cpSpaceReindexShapesForBody(space, id2go(js2int(argv[1]))->body);
return JS_NULL;
2023-01-19 18:30:23 -06:00
case 37:
2023-04-18 17:58:44 -05:00
if (!id2sprite(js2int(argv[1]))) return JS_NULL;
vec2float(js2vec2(argv[2]), id2sprite(js2int(argv[1]))->pos);
2023-01-19 18:30:23 -06:00
break;
2023-01-25 21:32:58 -06:00
case 38:
str = JS_ToCString(js,argv[1]);
ret = JS_NewString(js, slurp_text(str));
break;
2023-01-25 21:32:58 -06:00
case 39:
str = JS_ToCString(js,argv[1]);
str2 = JS_ToCString(js,argv[2]);
ret = JS_NewInt64(js, slurp_write(str, str2));
break;
case 40:
2023-04-18 17:58:44 -05:00
id2go(js2int(argv[1]))->filter.categories = js2bitmask(argv[2]);
gameobject_apply(id2go(js2int(argv[1])));
break;
case 41:
2023-04-18 17:58:44 -05:00
id2go(js2int(argv[1]))->filter.mask = js2bitmask(argv[2]);
gameobject_apply(id2go(js2int(argv[1])));
break;
case 42:
2023-04-18 17:58:44 -05:00
return bitmask2js(id2go(js2int(argv[1]))->filter.categories);
case 43:
2023-04-18 17:58:44 -05:00
return bitmask2js(id2go(js2int(argv[1]))->filter.mask);
case 44:
2023-04-18 17:58:44 -05:00
return JS_NewInt64(js, pos2gameobject(js2vec2(argv[1])));
case 45:
2023-04-18 17:58:44 -05:00
return vec2js(mouse_pos);
2023-02-04 22:53:54 -06:00
case 46:
2023-04-18 17:58:44 -05:00
set_mouse_mode(js2int(argv[1]));
return JS_NULL;
2023-02-05 11:40:59 -06:00
case 47:
2023-04-18 17:58:44 -05:00
draw_grid(js2int(argv[1]), js2int(argv[2]));
return JS_NULL;
2023-02-05 11:40:59 -06:00
case 48:
2023-04-18 17:58:44 -05:00
return JS_NewInt64(js, mainwin->width);
2023-02-05 11:40:59 -06:00
case 49:
2023-04-18 17:58:44 -05:00
return JS_NewInt64(js, mainwin->height);
2023-02-05 17:42:36 -06:00
case 50:
2023-04-18 17:58:44 -05:00
return JS_NewBool(js, action_down(js2int(argv[1])));
2023-02-05 17:42:36 -06:00
case 51:
2023-04-18 17:58:44 -05:00
draw_cppoint(js2vec2(argv[1]), js2number(argv[2]), js2color(argv[3]));
return JS_NULL;
2023-02-05 17:42:36 -06:00
case 52:
2023-04-18 17:58:44 -05:00
return ints2js(phys2d_query_box(js2vec2(argv[1]), js2vec2(argv[2])));
2023-02-05 17:42:36 -06:00
case 53:
2023-04-18 17:58:44 -05:00
draw_box(js2vec2(argv[1]), js2vec2(argv[2]), js2color(argv[3]));
return JS_NULL;
2023-02-06 16:41:47 -06:00
case 54:
2023-04-18 17:58:44 -05:00
gameobject_apply(js2go(argv[1]));
return JS_NULL;
2023-02-06 16:41:47 -06:00
case 55:
2023-04-18 17:58:44 -05:00
js2go(argv[1])->flipx = JS_ToBool(js, argv[2]) ? -1 : 1;
return JS_NULL;
2023-02-06 16:41:47 -06:00
case 56:
2023-04-18 17:58:44 -05:00
js2go(argv[1])->flipy = JS_ToBool(js, argv[2]) ? -1 : 1;
return JS_NULL;
2023-02-06 16:41:47 -06:00
case 57:
2023-04-18 17:58:44 -05:00
return JS_NewBool(js, js2go(argv[1])->flipx == -1 ? 1 : 0);
2023-02-06 16:41:47 -06:00
case 58:
2023-04-18 17:58:44 -05:00
return JS_NewBool(js, js2go(argv[1])->flipy == -1 ? 1 : 0);
2023-02-08 15:30:12 -06:00
case 59:
2023-04-18 17:58:44 -05:00
return JS_NewInt64(js, point2segindex(js2vec2(argv[1]), js2cpvec2arr(argv[2]), js2number(argv[3])));
2023-02-10 14:31:59 -06:00
case 60:
2023-04-18 17:58:44 -05:00
if (!id2sprite(js2int(argv[1]))) return JS_NULL;
id2sprite(js2int(argv[1]))->layer = js2int(argv[2]);
2023-02-10 14:31:59 -06:00
break;
2023-02-13 08:30:35 -06:00
case 61:
2023-04-18 17:58:44 -05:00
set_cam_body(id2body(js2int(argv[1])));
2023-02-13 08:30:35 -06:00
break;
case 62:
2023-04-18 17:58:44 -05:00
add_zoom(js2number(argv[1]));
2023-02-13 08:30:35 -06:00
break;
case 63:
2023-04-18 17:58:44 -05:00
return JS_NewFloat64(js, deltaT);
2023-02-13 08:30:35 -06:00
case 64:
str = JS_ToCString(js,argv[1]);
ret = vec2js(tex_get_dimensions(texture_pullfromfile(str)));
break;
2023-02-13 08:30:35 -06:00
2023-02-13 21:02:14 -06:00
case 65:
str = JS_ToCString(js,argv[1]);
ret = JS_NewBool(js, file_exists(str));
break;
2023-02-13 21:02:14 -06:00
case 66:
str = JS_ToCString(js,argv[1]);
ret = dukext2paths(str);
break;
2023-02-16 16:13:07 -06:00
case 67:
opengl_rendermode(LIT);
break;
case 68:
opengl_rendermode(WIREFRAME);
break;
2023-02-17 13:15:56 -06:00
case 69:
2023-04-18 17:58:44 -05:00
gameobject_set_sensor(js2int(argv[1]), JS_ToBool(js, argv[2]));
2023-02-17 13:15:56 -06:00
break;
2023-02-20 11:10:03 -06:00
case 70:
2023-04-18 17:58:44 -05:00
return vec2js(world2go(js2go(argv[1]), js2vec2(argv[2])));
2023-02-20 11:10:03 -06:00
case 71:
2023-04-18 17:58:44 -05:00
return vec2js(go2world(js2go(argv[1]), js2vec2(argv[2])));
2023-02-24 14:13:35 -06:00
case 72:
2023-04-18 17:58:44 -05:00
return vec2js(cpSpaceGetGravity(space));
2023-02-24 14:13:35 -06:00
case 73:
2023-04-18 17:58:44 -05:00
cpSpaceSetDamping(space, js2number(argv[1]));
return JS_NULL;
2023-02-24 14:13:35 -06:00
case 74:
2023-04-18 17:58:44 -05:00
return JS_NewFloat64(js, cpSpaceGetDamping(space));
2023-03-10 13:13:48 -06:00
case 75:
2023-04-18 17:58:44 -05:00
js2go(argv[1])->layer = js2int(argv[2]);
return JS_NULL;
2023-03-10 13:13:48 -06:00
case 76:
2023-04-18 17:58:44 -05:00
set_cat_mask(js2int(argv[1]), js2bitmask(argv[2]));
return JS_NULL;
2023-03-10 13:13:48 -06:00
case 77:
input_to_game();
break;
case 78:
input_to_nuke();
break;
case 79:
2023-04-18 17:58:44 -05:00
return JS_NewBool(js, phys_stepping());
2023-03-13 09:27:32 -05:00
case 80:
2023-04-18 17:58:44 -05:00
return ints2js(phys2d_query_shape(js2ptr(argv[1])));
2023-03-13 09:27:32 -05:00
case 81:
2023-04-18 17:58:44 -05:00
draw_arrow(js2vec2(argv[1]), js2vec2(argv[2]), js2color(argv[3]), js2int(argv[4]));
return JS_NULL;
2023-03-17 10:25:35 -05:00
case 82:
2023-04-18 17:58:44 -05:00
gameobject_draw_debug(js2int(argv[1]));
return JS_NULL;
2023-03-17 10:25:35 -05:00
case 83:
2023-04-18 17:58:44 -05:00
draw_edge(js2cpvec2arr(argv[1]), 2, js2color(argv[2]), 1);
return JS_NULL;
2023-03-17 10:25:35 -05:00
case 84:
2023-04-18 17:58:44 -05:00
return JS_NewString(js, consolelog);
2023-03-17 10:25:35 -05:00
case 85:
2023-04-18 17:58:44 -05:00
return vec2js(cpvproject(js2vec2(argv[1]), js2vec2(argv[2])));
2023-03-19 20:33:05 -05:00
case 86:
2023-04-18 17:58:44 -05:00
return ints2js(phys2d_query_box_points(js2vec2(argv[1]), js2vec2(argv[2]), js2cpvec2arr(argv[3]), js2int(argv[4])));
2023-03-24 14:01:01 -05:00
case 87:
str = JS_ToCString(js, argv[1]);
mini_music_play(str);
break;
2023-03-24 14:01:01 -05:00
case 88:
mini_music_pause();
2023-04-18 17:58:44 -05:00
return JS_NULL;
2023-03-24 14:01:01 -05:00
case 89:
mini_music_stop();
2023-04-18 17:58:44 -05:00
return JS_NULL;
2023-03-24 14:01:01 -05:00
case 90:
str = JS_ToCString(js, argv[1]);
window_set_icon(str);
2023-03-24 14:01:01 -05:00
break;
case 91:
str = JS_ToCString(js,argv[1]);
log_print(str);
break;
case 92:
logLevel = js2int(argv[1]);
break;
case 93:
ret = int2js(logLevel);
2023-01-10 14:02:24 -06:00
}
if (str)
JS_FreeCString(js,str);
if (str2)
JS_FreeCString(js,str2);
if (!JS_IsNull(ret))
return ret;
2023-04-18 17:58:44 -05:00
return JS_NULL;
2023-01-10 14:02:24 -06:00
}
2023-04-18 14:49:17 -05:00
JSValue duk_register(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
{
2023-04-18 17:58:44 -05:00
int cmd = js2int(argv[0]);
2023-01-11 16:57:34 -06:00
2023-04-19 15:16:35 -05:00
struct callee c;
c.fn = argv[1];
c.obj = argv[2];
2023-01-11 16:57:34 -06:00
switch(cmd) {
case 0:
register_update(c);
break;
case 1:
register_physics(c);
break;
case 2:
register_gui(c);
break;
2023-01-19 13:06:32 -06:00
case 3:
register_nk_gui(c);
break;
case 4:
2023-04-19 15:16:35 -05:00
// unregister_obj(obj);
break;
case 5:
2023-04-19 15:16:35 -05:00
// unregister_gui(c);
break;
2023-03-17 10:25:35 -05:00
case 6:
register_debug(c);
break;
2023-04-19 15:16:35 -05:00
case 7:
register_pawn(c);
break;
2023-04-25 16:59:12 -05:00
case 8:
register_gamepad(c);
break;
2023-04-28 12:49:18 -05:00
case 9:
stacktrace_callee = c;
break;
2023-01-11 16:57:34 -06:00
}
2023-04-18 17:58:44 -05:00
return JS_NULL;
2023-04-19 15:16:35 -05:00
2023-01-11 16:57:34 -06:00
}
2023-02-17 01:16:52 -06:00
void gameobject_add_shape_collider(int go, struct callee c, struct phys2d_shape *shape)
{
struct shape_cb shapecb;
2023-03-10 13:13:48 -06:00
shapecb.shape = shape;
2023-02-17 01:16:52 -06:00
shapecb.cbs.begin = c;
arrpush(id2go(go)->shape_cbs, shapecb);
}
2023-04-18 14:49:17 -05:00
JSValue duk_register_collide(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
{
2023-04-18 17:58:44 -05:00
int cmd = js2int(argv[0]);
int go = js2int(argv[3]);
2023-04-21 16:57:30 -05:00
struct callee c;
c.fn = argv[1];
c.obj = argv[2];
2023-02-17 01:16:52 -06:00
switch(cmd) {
case 0:
2023-03-10 13:13:48 -06:00
id2go(go)->cbs.begin = c;
2023-02-17 01:16:52 -06:00
break;
case 1:
2023-04-19 15:16:35 -05:00
gameobject_add_shape_collider(go, c, js2ptr(argv[4]));
2023-02-17 01:16:52 -06:00
break;
case 2:
phys2d_rm_go_handlers(go);
2023-03-17 10:25:35 -05:00
break;
case 3:
id2go(go)->cbs.separate = c;
break;
2023-02-17 01:16:52 -06:00
}
2023-01-11 16:57:34 -06:00
2023-04-18 17:58:44 -05:00
return JS_NULL;
2023-01-11 16:57:34 -06:00
}
2023-04-18 14:49:17 -05:00
JSValue duk_sys_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
{
2023-04-18 17:58:44 -05:00
int cmd = js2int(argv[0]);
2023-01-10 07:13:00 -06:00
switch (cmd) {
case 0:
quit();
break;
case 1:
sim_start();
2023-01-25 21:32:58 -06:00
cpSpaceReindexStatic(space);
2023-01-10 07:13:00 -06:00
break;
case 2:
sim_stop();
break;
case 3:
2023-01-10 07:13:00 -06:00
sim_pause();
break;
case 4:
sim_step();
break;
case 5:
2023-04-18 17:58:44 -05:00
return JS_NewBool(js, sim_playing());
2023-01-10 07:13:00 -06:00
case 6:
2023-04-18 17:58:44 -05:00
return JS_NewBool(js, sim_paused());
2023-01-10 07:13:00 -06:00
case 7:
2023-04-18 17:58:44 -05:00
return JS_NewInt64(js, MakeGameobject());
2023-01-10 07:13:00 -06:00
case 8:
2023-04-18 17:58:44 -05:00
return JS_NewInt64(js, frame_fps());
2023-01-10 07:13:00 -06:00
case 9: /* Clear the level out */
new_level();
break;
}
2023-04-18 17:58:44 -05:00
return JS_NULL;
2023-01-10 07:13:00 -06:00
}
2023-04-18 14:49:17 -05:00
JSValue duk_make_gameobject(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
{
2023-01-10 07:13:00 -06:00
int g = MakeGameobject();
struct gameobject *go = get_gameobject_from_id(g);
2023-04-18 17:58:44 -05:00
go->scale = js2number(argv[0]);
go->bodytype = js2int(argv[1]);
go->mass = js2number(argv[2]);
go->f = js2number(argv[3]);
go->e = js2number(argv[4]);
2023-02-06 16:41:47 -06:00
go->flipx = 1.f;
go->flipy = 1.f;
2023-01-10 07:13:00 -06:00
gameobject_apply(go);
2023-04-18 17:58:44 -05:00
return JS_NewInt64(js,g);
2023-01-10 07:13:00 -06:00
}
2023-04-18 14:49:17 -05:00
JSValue duk_yughlog(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
{
2023-04-18 17:58:44 -05:00
int cmd = js2int(argv[0]);
const char *s = JS_ToCString(js, argv[1]);
const char *f = JS_ToCString(js, argv[2]);
int line = js2int(argv[3]);
2023-01-10 14:02:24 -06:00
2023-01-13 22:08:39 -06:00
mYughLog(1, cmd, line, f, s);
2023-01-10 14:02:24 -06:00
2023-04-19 16:58:17 -05:00
JS_FreeCString(js,s);
JS_FreeCString(js,f);
2023-04-18 17:58:44 -05:00
return JS_NULL;
2023-01-10 14:02:24 -06:00
}
2023-04-18 14:49:17 -05:00
JSValue duk_set_body(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
{
2023-04-18 17:58:44 -05:00
int cmd = js2int(argv[0]);
int id = js2int(argv[1]);
2023-01-10 14:02:24 -06:00
struct gameobject *go = get_gameobject_from_id(id);
2023-04-18 17:58:44 -05:00
if (!go) return JS_NULL;
2023-01-10 14:02:24 -06:00
2023-01-13 13:07:44 -06:00
/* TODO: Possible that reindexing shapes only needs done for static shapes? */
2023-01-10 14:02:24 -06:00
switch (cmd) {
case 0:
2023-04-18 17:58:44 -05:00
gameobject_setangle(go, js2number(argv[2]));
2023-01-10 14:02:24 -06:00
break;
case 1:
2023-04-18 17:58:44 -05:00
go->bodytype = js2int(argv[2]);
2023-01-10 14:02:24 -06:00
break;
case 2:
2023-04-18 17:58:44 -05:00
cpBodySetPosition(go->body, js2vec2(argv[2]));
2023-01-10 14:02:24 -06:00
break;
case 3:
2023-04-18 17:58:44 -05:00
gameobject_move(go, js2vec2(argv[2]));
2023-01-10 14:02:24 -06:00
break;
case 4:
2023-04-18 17:58:44 -05:00
cpBodyApplyImpulseAtWorldPoint(go->body, js2vec2(argv[2]), cpBodyGetPosition(go->body));
return JS_NULL;
2023-01-10 14:02:24 -06:00
case 5:
2023-04-18 17:58:44 -05:00
go->flipx = JS_ToBool(js, argv[2]);
2023-01-10 14:02:24 -06:00
break;
case 6:
2023-04-18 17:58:44 -05:00
go->flipy = JS_ToBool(js, argv[2]);
2023-01-10 14:02:24 -06:00
break;
2023-01-12 17:41:54 -06:00
case 7:
2023-04-18 17:58:44 -05:00
cpBodySetMass(go->body, js2number(argv[2]));
2023-01-12 17:41:54 -06:00
break;
2023-01-13 13:07:44 -06:00
case 8:
2023-04-18 17:58:44 -05:00
cpBodySetAngularVelocity(go->body, js2number(argv[2]));
return JS_NULL;
2023-01-13 13:07:44 -06:00
case 9:
2023-04-18 17:58:44 -05:00
cpBodySetVelocity(go->body, js2vec2(argv[2]));
return JS_NULL;
2023-01-13 13:07:44 -06:00
2023-02-24 14:13:35 -06:00
case 10:
2023-04-18 17:58:44 -05:00
go->e = fmax(js2number(argv[2]),0);
2023-02-24 14:13:35 -06:00
break;
case 11:
2023-04-18 17:58:44 -05:00
go->f = fmax(js2number(argv[2]),0);
2023-02-24 14:13:35 -06:00
break;
2023-03-17 10:25:35 -05:00
case 12:
2023-04-18 17:58:44 -05:00
cpBodyApplyForceAtWorldPoint(go->body, js2vec2(argv[2]), cpBodyGetPosition(go->body));
return JS_NULL;
2023-01-10 14:02:24 -06:00
}
2023-01-25 21:32:58 -06:00
cpSpaceReindexShapesForBody(space, go->body);
2023-04-18 17:58:44 -05:00
return JS_NULL;
2023-01-10 14:02:24 -06:00
}
2023-04-18 14:49:17 -05:00
JSValue duk_q_body(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
{
2023-04-18 17:58:44 -05:00
int q = js2int(argv[0]);
struct gameobject *go = get_gameobject_from_id(js2int(argv[1]));
2023-01-10 14:02:24 -06:00
2023-04-18 17:58:44 -05:00
if (!go) return JS_NULL;
2023-01-11 16:57:34 -06:00
2023-01-10 14:02:24 -06:00
switch(q) {
case 0:
2023-04-18 17:58:44 -05:00
return JS_NewInt64(js, cpBodyGetType(go->body));
2023-01-10 14:02:24 -06:00
case 1:
2023-04-18 17:58:44 -05:00
return vec2js(cpBodyGetPosition(go->body));
2023-01-10 14:02:24 -06:00
case 2:
2023-04-18 17:58:44 -05:00
return JS_NewFloat64(js, cpBodyGetAngle(go->body));
2023-01-11 16:57:34 -06:00
case 3:
2023-04-18 17:58:44 -05:00
return vec2js(cpBodyGetVelocity(go->body));
2023-01-11 16:57:34 -06:00
case 4:
2023-04-18 17:58:44 -05:00
return JS_NewFloat64(js, cpBodyGetAngularVelocity(go->body));
2023-01-11 16:57:34 -06:00
case 5:
2023-04-18 17:58:44 -05:00
return JS_NewFloat64(js, cpBodyGetMass(go->body));
2023-03-10 13:13:48 -06:00
case 6:
2023-04-18 17:58:44 -05:00
return JS_NewFloat64(js, cpBodyGetMoment(go->body));
2023-03-17 10:25:35 -05:00
case 7:
2023-04-18 17:58:44 -05:00
return JS_NewBool(js, phys2d_in_air(go->body));
2023-01-10 14:02:24 -06:00
}
2023-04-18 17:58:44 -05:00
return JS_NULL;
2023-01-10 14:02:24 -06:00
}
2023-04-18 14:49:17 -05:00
JSValue duk_make_sprite(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
{
2023-04-18 17:58:44 -05:00
int go = js2int(argv[0]);
const char *path = JS_ToCString(js, argv[1]);
cpVect pos = js2vec2(argv[2]);
2023-01-12 17:41:54 -06:00
int sprite = make_sprite(go);
struct sprite *sp = id2sprite(sprite);
2023-03-05 22:05:22 -06:00
sprite_loadtex(sp, path, ST_UNIT);
2023-01-12 17:41:54 -06:00
sp->pos[0] = pos.x;
sp->pos[1] = pos.y;
2023-04-19 16:58:17 -05:00
JS_FreeCString(js,path);
2023-04-18 17:58:44 -05:00
return JS_NewInt64(js, sprite);
2023-01-12 17:41:54 -06:00
}
2023-01-18 14:43:07 -06:00
/* Make anim from texture */
2023-04-18 14:49:17 -05:00
JSValue duk_make_anim2d(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
{
2023-04-18 17:58:44 -05:00
const char *path = JS_ToCString(js, argv[0]);
int frames = js2int(argv[1]);
int fps = js2int(argv[2]);
2023-01-15 09:53:50 -06:00
2023-01-18 17:15:36 -06:00
struct TexAnim *anim = anim2d_from_tex(path, frames, fps);
2023-01-15 09:53:50 -06:00
2023-04-19 16:58:17 -05:00
JS_FreeCString(js,path);
2023-04-18 17:58:44 -05:00
return ptr2js(anim);
2023-01-13 13:07:44 -06:00
}
2023-04-18 14:49:17 -05:00
JSValue duk_make_box2d(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
{
2023-04-18 17:58:44 -05:00
int go = js2int(argv[0]);
cpVect size = js2vec2(argv[1]);
cpVect offset = js2vec2(argv[2]);
2023-01-10 17:23:11 -06:00
2023-01-12 17:41:54 -06:00
struct phys2d_box *box = Make2DBox(go);
2023-01-10 17:23:11 -06:00
box->w = size.x;
box->h = size.y;
box->offset[0] = offset.x;
box->offset[1] = offset.y;
2023-01-12 17:41:54 -06:00
phys2d_applybox(box);
2023-01-10 17:23:11 -06:00
2023-04-18 17:58:44 -05:00
JSValue boxval = JS_NewObject(js);
JS_SetPropertyStr(js, boxval, "id", ptr2js(box));
JS_SetPropertyStr(js, boxval, "shape", ptr2js(&box->shape));
return boxval;
2023-01-17 13:04:08 -06:00
}
2023-04-18 14:49:17 -05:00
JSValue duk_cmd_box2d(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
2023-01-19 10:44:29 -06:00
{
2023-04-18 17:58:44 -05:00
int cmd = js2int(argv[0]);
struct phys2d_box *box = js2ptr(argv[1]);
2023-01-25 21:32:58 -06:00
cpVect arg;
2023-01-19 18:30:23 -06:00
2023-04-18 17:58:44 -05:00
if (!box) return JS_NULL;
2023-01-19 10:44:29 -06:00
2023-01-19 18:30:23 -06:00
switch(cmd) {
case 0:
2023-04-18 17:58:44 -05:00
arg = js2vec2(argv[2]);
2023-01-19 18:30:23 -06:00
box->w = arg.x;
box->h = arg.y;
break;
case 1:
2023-04-18 17:58:44 -05:00
arg = js2vec2(argv[2]);
2023-01-19 18:30:23 -06:00
box->offset[0] = arg.x;
box->offset[1] = arg.y;
break;
2023-01-25 21:32:58 -06:00
case 2:
2023-04-18 17:58:44 -05:00
box->rotation = js2number(argv[2]);
2023-01-25 21:32:58 -06:00
break;
2023-01-19 18:30:23 -06:00
}
phys2d_applybox(box);
2023-04-18 17:58:44 -05:00
return JS_NULL;
2023-01-19 10:44:29 -06:00
}
2023-04-18 14:49:17 -05:00
JSValue duk_make_circle2d(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
{
2023-04-21 16:57:30 -05:00
int go = js2int(argv[0]);
2023-04-18 17:58:44 -05:00
double radius = js2number(argv[1]);
2023-01-10 17:23:11 -06:00
2023-04-21 16:57:30 -05:00
struct phys2d_circle *circle = Make2DCircle(go);
circle->radius = radius;
circle->offset = js2vec2(argv[2]);
2023-01-10 17:23:11 -06:00
2023-04-21 16:57:30 -05:00
phys2d_applycircle(circle);
2023-04-18 17:58:44 -05:00
JSValue circleval = JS_NewObject(js);
JS_SetPropertyStr(js, circleval, "id", ptr2js(circle));
JS_SetPropertyStr(js, circleval, "shape", ptr2js(&circle->shape));
return circleval;
2023-01-10 17:23:11 -06:00
}
2023-04-18 14:49:17 -05:00
JSValue duk_cmd_circle2d(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
2023-01-19 10:44:29 -06:00
{
2023-04-18 17:58:44 -05:00
int cmd = js2int(argv[0]);
struct phys2d_circle *circle = js2ptr(argv[1]);
2023-01-19 13:06:32 -06:00
2023-04-18 17:58:44 -05:00
if (!circle) return JS_NULL;
2023-01-19 13:06:32 -06:00
switch(cmd) {
case 0:
2023-04-18 17:58:44 -05:00
circle->radius = js2number(argv[2]);
2023-01-19 18:30:23 -06:00
break;
2023-01-19 13:06:32 -06:00
2023-01-19 18:30:23 -06:00
case 1:
2023-04-18 17:58:44 -05:00
circle->offset = js2vec2(argv[2]);
2023-01-19 18:30:23 -06:00
break;
2023-01-19 13:06:32 -06:00
}
2023-01-19 18:30:23 -06:00
phys2d_applycircle(circle);
2023-04-18 17:58:44 -05:00
return JS_NULL;
2023-01-19 10:44:29 -06:00
}
2023-04-18 14:49:17 -05:00
JSValue duk_make_poly2d(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
2023-01-25 21:32:58 -06:00
{
2023-04-18 17:58:44 -05:00
int go = js2int(argv[0]);
2023-01-25 21:32:58 -06:00
struct phys2d_poly *poly = Make2DPoly(go);
2023-04-18 17:58:44 -05:00
phys2d_poly_setverts(poly, js2cpvec2arr(argv[1]));
2023-01-25 21:32:58 -06:00
2023-04-18 17:58:44 -05:00
JSValue polyval = JS_NewObject(js);
JS_SetPropertyStr(js, polyval, "id", ptr2js(poly));
JS_SetPropertyStr(js, polyval, "shape", ptr2js(&poly->shape));
return polyval;
2023-01-25 21:32:58 -06:00
}
2023-04-18 14:49:17 -05:00
JSValue duk_cmd_poly2d(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
2023-01-25 21:32:58 -06:00
{
2023-04-18 17:58:44 -05:00
int cmd = js2int(argv[0]);
struct phys2d_poly *poly = js2ptr(argv[1]);
2023-02-24 14:13:35 -06:00
2023-04-18 17:58:44 -05:00
if (!poly) return JS_NULL;
2023-02-17 22:32:23 -06:00
switch(cmd) {
case 0:
2023-04-18 17:58:44 -05:00
phys2d_poly_setverts(poly, js2cpvec2arr(argv[2]));
2023-02-17 22:32:23 -06:00
break;
}
2023-04-18 17:58:44 -05:00
return JS_NULL;
2023-01-25 21:32:58 -06:00
}
2023-04-18 14:49:17 -05:00
JSValue duk_make_edge2d(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
2023-01-25 21:32:58 -06:00
{
2023-04-18 17:58:44 -05:00
int go = js2int(argv[0]);
2023-01-25 21:32:58 -06:00
struct phys2d_edge *edge = Make2DEdge(go);
2023-04-18 17:58:44 -05:00
int n = js_arrlen(argv[1]);
2023-01-25 21:32:58 -06:00
cpVect points[n];
for (int i = 0; i < n; i++) {
2023-04-18 17:58:44 -05:00
points[i] = js2vec2(JS_GetPropertyUint32(js, argv[1], i));
2023-01-25 21:32:58 -06:00
phys2d_edgeaddvert(edge);
phys2d_edge_setvert(edge, i, points[i]);
}
2023-04-18 17:58:44 -05:00
JSValue edgeval = JS_NewObject(js);
JS_SetPropertyStr(js, edgeval, "id", ptr2js(edge));
JS_SetPropertyStr(js, edgeval, "shape", ptr2js(&edge->shape));
return edgeval;
2023-01-25 21:32:58 -06:00
}
2023-04-18 14:49:17 -05:00
JSValue duk_cmd_edge2d(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
2023-01-25 21:32:58 -06:00
{
2023-04-18 17:58:44 -05:00
int cmd = js2int(argv[0]);
struct phys2d_edge *edge = js2ptr(argv[1]);
2023-02-08 15:30:12 -06:00
2023-04-18 17:58:44 -05:00
if (!edge) return JS_NULL;
2023-02-24 14:13:35 -06:00
2023-02-08 15:30:12 -06:00
switch(cmd) {
case 0:
phys2d_edge_clearverts(edge);
2023-04-18 17:58:44 -05:00
phys2d_edge_addverts(edge, js2cpvec2arr(argv[2]));
2023-02-08 15:30:12 -06:00
break;
2023-02-13 08:30:35 -06:00
case 1:
2023-04-18 17:58:44 -05:00
edge->thickness = js2number(argv[2]);
2023-02-13 08:30:35 -06:00
break;
2023-02-08 15:30:12 -06:00
}
2023-04-18 17:58:44 -05:00
return JS_NULL;
2023-01-25 21:32:58 -06:00
}
2023-04-18 14:49:17 -05:00
JSValue duk_inflate_cpv(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
2023-03-19 20:33:05 -05:00
{
2023-04-18 17:58:44 -05:00
cpVect *points = js2cpvec2arr(argv[0]);
int n = js2int(argv[1]);
double d = js2number(argv[2]);
2023-03-24 14:01:01 -05:00
2023-03-19 20:33:05 -05:00
cpVect inflate_out[n];
cpVect inflate_in[n];
inflatepoints(inflate_out, points, d, n);
inflatepoints(inflate_in, points, -d, n);
2023-04-19 16:58:17 -05:00
JSValue arr = JS_NewArray(js);
2023-04-18 17:58:44 -05:00
JS_SetPropertyUint32(js, arr, 0, vecarr2js(inflate_out, n));
JS_SetPropertyUint32(js, arr, 1, vecarr2js(inflate_in, n));
return arr;
2023-03-19 20:33:05 -05:00
}
2023-01-18 17:15:36 -06:00
/* These are anims for controlling properties on an object */
2023-04-18 14:49:17 -05:00
JSValue duk_anim(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
{
2023-04-18 17:58:44 -05:00
JSValue prop = argv[0];
int keyframes = js_arrlen(argv[1]);
2023-01-10 17:23:11 -06:00
YughInfo("Processing %d keyframes.", keyframes);
struct anim a = make_anim();
for (int i = 0; i < keyframes; i++) {
struct keyframe k;
2023-04-18 17:58:44 -05:00
cpVect v = js2vec2(JS_GetPropertyUint32(js, argv[1], i));
2023-01-10 17:23:11 -06:00
k.time = v.y;
k.val = v.x;
a = anim_add_keyframe(a, k);
}
for (double i = 0; i < 3.0; i = i + 0.1) {
YughInfo("Val is now %f at time %f", anim_val(a, i), i);
2023-04-18 17:58:44 -05:00
JSValue vv = num2js(anim_val(a,i));
JS_Call(js, prop, JS_GetGlobalObject(js), 1, &vv);
2023-01-10 17:23:11 -06:00
}
2023-04-18 17:58:44 -05:00
return JS_NULL;
2023-01-10 17:23:11 -06:00
}
2023-04-18 14:49:17 -05:00
JSValue duk_make_timer(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
{
2023-04-18 17:58:44 -05:00
double secs = js2number(argv[1]);
2023-01-18 17:15:36 -06:00
struct callee *c = malloc(sizeof(*c));
2023-04-28 12:49:18 -05:00
c->fn = JS_DupValue(js,argv[0]);
c->obj = JS_GetGlobalObject(js);
2023-03-17 10:25:35 -05:00
int id = timer_make(secs, call_callee, c, 1);
2023-01-12 17:41:54 -06:00
2023-04-18 17:58:44 -05:00
return JS_NewInt64(js, id);
2023-01-10 17:23:11 -06:00
}
2023-04-19 15:16:35 -05:00
#define DUK_FUNC(NAME, ARGS) JS_SetPropertyStr(js, JS_GetGlobalObject(js), #NAME, JS_NewCFunction(js, duk_##NAME, #NAME, ARGS));
2023-01-10 14:02:24 -06:00
2023-01-10 07:13:00 -06:00
void ffi_load()
{
2023-04-18 17:58:44 -05:00
DUK_FUNC(yughlog, 4)
DUK_FUNC(nuke, 6)
DUK_FUNC(make_gameobject, 7)
DUK_FUNC(set_body, 3)
DUK_FUNC(q_body, 2)
DUK_FUNC(sys_cmd, 1)
DUK_FUNC(win_make, 3)
DUK_FUNC(make_sprite, 3)
DUK_FUNC(make_anim2d, 3)
DUK_FUNC(spline_cmd, 6)
2023-04-18 17:58:44 -05:00
DUK_FUNC(make_box2d, 3)
DUK_FUNC(cmd_box2d, 6)
DUK_FUNC(make_circle2d, 3)
DUK_FUNC(cmd_circle2d, 6)
DUK_FUNC(make_poly2d, 2)
DUK_FUNC(cmd_poly2d, 6)
DUK_FUNC(make_edge2d, 3)
DUK_FUNC(cmd_edge2d, 6)
DUK_FUNC(make_timer, 3)
DUK_FUNC(cmd, 6)
DUK_FUNC(register, 3)
DUK_FUNC(register_collide, 6)
DUK_FUNC(gui_text, 6)
DUK_FUNC(ui_text, 5)
DUK_FUNC(cursor_text,5)
DUK_FUNC(gui_img, 2)
2023-03-19 20:33:05 -05:00
2023-04-18 17:58:44 -05:00
DUK_FUNC(inflate_cpv, 3)
2023-01-10 17:23:11 -06:00
2023-04-18 17:58:44 -05:00
DUK_FUNC(anim, 2)
2023-01-10 15:41:43 -06:00
}