Moved all component ffi into global objects

This commit is contained in:
John Alanbrook 2024-03-20 09:04:28 -05:00
parent 046b7c6f44
commit 7e6fc1ffbe
7 changed files with 214 additions and 293 deletions

View file

@ -338,7 +338,7 @@ component.polygon2d = Object.copy(collider2d, {
}, },
hides: ['id', 'shape', 'gameobject'], hides: ['id', 'shape', 'gameobject'],
_enghook: make_poly2d, _enghook: os.make_poly2d,
points:[], points:[],
setpoints(points) { setpoints(points) {
this.points = points; this.points = points;
@ -391,7 +391,7 @@ function pointscaler(x) {
} }
component.polygon2d.impl = Object.mix(collider2d.impl, { component.polygon2d.impl = Object.mix(collider2d.impl, {
sync() { cmd_poly2d(0, this.id, this.spoints());}, sync() { poly2d.setverts(this.id,this.spoints()); },
query() { return physics.shape_query(this.shape); }, query() { return physics.shape_query(this.shape); },
grow: pointscaler, grow: pointscaler,
}); });
@ -523,7 +523,7 @@ component.edge2d = Object.copy(collider2d, {
boundingbox() { return bbox.frompoints(this.points.map(x => x.scale(this.gameobject.scale))); }, boundingbox() { return bbox.frompoints(this.points.map(x => x.scale(this.gameobject.scale))); },
hides: ['gameobject', 'id', 'shape'], hides: ['gameobject', 'id', 'shape'],
_enghook: make_edge2d, _enghook: os.make_edge2d,
/* EDITOR */ /* EDITOR */
gizmo() { gizmo() {
@ -635,16 +635,14 @@ component.edge2d = Object.copy(collider2d, {
}); });
component.edge2d.impl = Object.mix(collider2d.impl, { component.edge2d.impl = Object.mix(collider2d.impl, {
set thickness(x) { set thickness(x) { edge2d.set_thickness(this.id,x); },
cmd_edge2d(1,this.id,x); get thickness() { return edge2d.get_thickness(this.id); },
},
get thickness() { return physics.edge_thickness(this.id); },
grow: pointscaler, grow: pointscaler,
sync() { sync() {
var sensor = this.sensor; var sensor = this.sensor;
var points = this.sample(); var points = this.sample();
if (!points) return; if (!points) return;
cmd_edge2d(0,this.id,points); edge2d.setverts(this.id,points);
this.sensor = sensor; this.sensor = sensor;
}, },
}); });
@ -788,7 +786,7 @@ component.circle2d = Object.copy(collider2d, {
}, },
hides: ['gameobject', 'id', 'shape', 'scale'], hides: ['gameobject', 'id', 'shape', 'scale'],
_enghook: make_circle2d, _enghook: os.make_circle2d,
}); });
component.circle2d.impl = Object.mix({ component.circle2d.impl = Object.mix({
@ -797,17 +795,17 @@ component.circle2d.impl = Object.mix({
"radius", "radius",
]), ]),
set radius(x) { cmd_circle2d(0,this.id,x); }, set radius(x) { circle2d.set_radius(this.id,x); circle2d.sync(this.id); },
get radius() { return cmd_circle2d(2,this.id); }, get radius() { return circle2d.get_radius(this.id); },
set scale(x) { this.radius = x; }, set scale(x) { this.radius = x; },
get scale() { return this.radius; }, get scale() { return this.radius; },
set offset(x) { cmd_circle2d(1,this.id,x); }, set offset(x) { circle2d.set_offset(this.id,x); circle2d.sync(this.id); },
get offset() { return cmd_circle2d(3,this.id); }, get offset() { circle2d.get_offset(this.id); },
get pos() { return cmd_circle2d(3,this.id); }, get pos() { return this.offset; },
set pos(x) { cmd_circle2d(1,this.id,x); }, set pos(x) { this.offset = x; },
grow(x) { grow(x) {
if (typeof x === 'number') this.scale *= x; if (typeof x === 'number') this.scale *= x;

View file

@ -66,65 +66,35 @@ var Gizmos = {
}, },
}; };
Object.assign(profile, { profile.best_t = function(t) {
best_t(t) { var qq = 'ns';
var qq = 'ns'; if (t > 1000) {
t /= 1000;
qq = 'us';
if (t > 1000) { if (t > 1000) {
t /= 1000; t /= 1000;
qq = 'us'; qq = 'ms';
if (t > 1000) {
t /= 1000;
qq = 'ms';
}
} }
return `${t.toPrecision(4)} ${qq}`; }
}, return `${t.toPrecision(4)} ${qq}`;
cpu(fn, times, q) { }
times ??= 1;
q ??= "unnamed";
var start = profile.now();
for (var i = 0; i < times; i++)
fn();
var elapsed = profile.now() - start;
var avgt = profile.best_t(elapsed/times);
var totalt = profile.best_t(elapsed);
say(`profile [${q}]: ${profile.best_t(avgt)} average [${profile.best_t(totalt)} for ${times} loops]`); profile.cpu = function(fn, times, q) {
}, times ??= 1;
q ??= "unnamed";
time(fn) { var start = profile.now();
var start = profile.now(); for (var i = 0; i < times; i++)
fn(); fn();
return profile.lap(start);
}, var elapsed = profile.now() - start;
var avgt = profile.best_t(elapsed/times);
var totalt = profile.best_t(elapsed);
lap(t) { say(`profile [${q}]: ${profile.best_t(avgt)} average [${profile.best_t(totalt)} for ${times} loops]`);
return profile.best_t(profile.now()-t); }
},
measure(fn, str) { profile.ms = function(t) { return t/1000000; }
str ??= 'unnamed'; profile.secs = function(t) { return t/1000000000; }
var start = profile.now();
fn();
say(`profile [${str}]: ${profile.lap(start)}`);
},
secs() { return this.now()/1000000000; },
});
performance.test = {
barecall() { performance(0); },
unpack_num(n) { performance(1,n); },
unpack_array(n) { performance(2,n); },
pack_num() { performance(3); },
pack_string() { performance(6); },
unpack_string(s) { performance(4,s); },
unpack_32farr(a) { performance(5,a); },
call_fn_n(fn1, n) { performance(7,fn1,n,fn2); },
};
performance.test.call_fn_n.doc = "Calls fn1 n times, and then fn2.";
/* These controls are available during editing, and during play of debug builds */ /* These controls are available during editing, and during play of debug builds */
debug.inputs = {}; debug.inputs = {};
@ -273,6 +243,16 @@ debug.api.print_doc = function(name)
return mdoc; return mdoc;
} }
debug.log = {};
debug.log.time = function(fn, name, avg=0)
{
debug.log.time[name] ??= [];
var start = profile.now();
fn();
debug.log.time[name].push(profile.now()-start);
}
return { return {
debug, debug,
Gizmos, Gizmos,

View file

@ -88,7 +88,7 @@ function eval_env(script, env, file)
{ {
env ??= {}; env ??= {};
file ??= "SCRIPT"; file ??= "SCRIPT";
console.info(`eval ${file}`); console.spam(`eval ${file}`);
script = `(function() { ${script}; }).call(this);\n`; script = `(function() { ${script}; }).call(this);\n`;
return os.eval_env(file,env,script); return os.eval_env(file,env,script);
} }
@ -102,10 +102,10 @@ global.check_registers = function(obj)
obj.timers.push(Register.physupdate.register(obj.physupdate.bind(obj))); obj.timers.push(Register.physupdate.register(obj.physupdate.bind(obj)));
if (typeof obj.collide === 'function') if (typeof obj.collide === 'function')
register_collide(0, obj.collide.bind(obj), obj.body); physics.collide_begin(obj.collide.bind(obj), obj.body);
if (typeof obj.separate === 'function') if (typeof obj.separate === 'function')
register_collide(3,obj.separate.bind(obj), obj.body); physics.collide_separate(obj.separate.bind(obj), obj.body);
if (typeof obj.draw === 'function') if (typeof obj.draw === 'function')
obj.timers.push(Register.draw.register(obj.draw.bind(obj), obj)); obj.timers.push(Register.draw.register(obj.draw.bind(obj), obj));
@ -146,7 +146,7 @@ global.obscure('global');
global.mixin("scripts/render.js"); global.mixin("scripts/render.js");
global.mixin("scripts/debug.js"); global.mixin("scripts/debug.js");
var frame_t = profile.secs(); var frame_t = profile.secs(profile.now());
var updateMS = 1/60; var updateMS = 1/60;
var physMS = 1/60; var physMS = 1/60;
@ -170,8 +170,8 @@ game.engine_start = function(s) {
function process() function process()
{ {
var dt = profile.secs() - frame_t; var dt = profile.secs(profile.now()) - frame_t;
frame_t = profile.secs(); frame_t = profile.secs(profile.now());
prosperon.appupdate(dt); prosperon.appupdate(dt);
prosperon.emitters_step(dt); prosperon.emitters_step(dt);
@ -286,7 +286,10 @@ prosperon.touchpress = function(touches){};
prosperon.touchrelease = function(touches){}; prosperon.touchrelease = function(touches){};
prosperon.touchmove = function(touches){}; prosperon.touchmove = function(touches){};
prosperon.clipboardpaste = function(str){}; prosperon.clipboardpaste = function(str){};
prosperon.quit = function(){}; prosperon.quit = function(){
for (var i in debug.log.time)
console.warn(debug.log.time[i].map(x=>profile.ms(x)));
};
global.mixin("scripts/input.js"); global.mixin("scripts/input.js");
global.mixin("scripts/std.js"); global.mixin("scripts/std.js");
@ -342,7 +345,7 @@ var Register = {
fn = fn.bind(obj); fn = fn.bind(obj);
fns.push(fn); fns.push(fn);
return function() { return function() {
console.info(`removed from ${name}.`); console.spam(`removed from ${name}.`);
fns.remove(fn); fns.remove(fn);
}; };
} }
@ -426,7 +429,7 @@ global.mixin("scripts/actor.js");
global.mixin("scripts/entity.js"); global.mixin("scripts/entity.js");
function world_start() { function world_start() {
gameobject.body = make_gameobject(); gameobject.body = os.make_gameobject();
gameobject.body.setref(gameobject); gameobject.body.setref(gameobject);
console.info("START WORLD"); console.info("START WORLD");

View file

@ -315,9 +315,11 @@ var gameobject = {
return; return;
} }
} }
console.info(`Creating entity of type ${ent.ur}`);
Object.mixin(ent, gameobject_impl); Object.mixin(ent, gameobject_impl);
ent.body = make_gameobject(); ent.body = os.make_gameobject();
ent.warp_layer = [true]; ent.warp_layer = [true];
ent.phys = 2; ent.phys = 2;
ent.components = {}; ent.components = {};
@ -359,7 +361,7 @@ var gameobject = {
check_registers(ent); check_registers(ent);
ent.components.forEach(function(x) { ent.components.forEach(function(x) {
if (typeof x.collide === 'function') if (typeof x.collide === 'function')
register_collide(1, x.collide.bind(x), ent.body, x.shape); physics.collide_shape(x.collide.bind(x), ent.body, x.shape);
}); });
@ -595,12 +597,13 @@ var gameobject = {
kill() { kill() {
if (this.__kill) return; if (this.__kill) return;
this.__kill = true; this.__kill = true;
console.info(`Killing entity of type ${this.ur}`);
this.timers.forEach(t => t()); this.timers.forEach(t => t());
this.timers = []; this.timers = [];
Event.rm_obj(this); Event.rm_obj(this);
Player.do_uncontrol(this); Player.do_uncontrol(this);
register_collide(2, undefined, this.body); physics.collide_rm(this.body);
if (this.master) { if (this.master) {
this.master.remove_obj(this); this.master.remove_obj(this);
@ -755,7 +758,6 @@ ur {
/* Apply an ur u to an entity e */ /* Apply an ur u to an entity e */
/* u is given as */ /* u is given as */
function apply_ur(u, e) { function apply_ur(u, e) {
console.info(`Applying ur named ${u}.`);
if (typeof u !== 'string') { if (typeof u !== 'string') {
console.warn("Must give u as a string."); console.warn("Must give u as a string.");
return; return;

View file

@ -105,10 +105,10 @@ void go_shape_moi(cpBody *body, cpShape *shape, gameobject *go) {
} }
void gameobject_apply(gameobject *go) { void gameobject_apply(gameobject *go) {
cpBodySetType(go->body, go->bodytype); cpBodySetType(go->body, go->phys);
cpBodyEachShape(go->body, go_shape_apply, go); cpBodyEachShape(go->body, go_shape_apply, go);
if (go->bodytype == CP_BODY_TYPE_DYNAMIC) { if (go->phys == CP_BODY_TYPE_DYNAMIC) {
cpBodySetMass(go->body, go->mass); cpBodySetMass(go->body, go->mass);
cpBodySetMoment(go->body, 0.f); cpBodySetMoment(go->body, 0.f);
cpBodyEachShape(go->body, go_shape_moi, go); cpBodyEachShape(go->body, go_shape_moi, go);
@ -149,7 +149,7 @@ gameobject *MakeGameobject() {
gameobject *ngo = malloc(sizeof(*ngo)); gameobject *ngo = malloc(sizeof(*ngo));
gameobject go = { gameobject go = {
.scale = (HMM_Vec3){1.f,1.f,1.f}, .scale = (HMM_Vec3){1.f,1.f,1.f},
.bodytype = CP_BODY_TYPE_STATIC, .phys = CP_BODY_TYPE_STATIC,
.maxvelocity = INFINITY, .maxvelocity = INFINITY,
.maxangularvelocity = INFINITY, .maxangularvelocity = INFINITY,
.mass = 1.f, .mass = 1.f,

View file

@ -27,7 +27,7 @@
}while(0) }while(0)
struct gameobject { struct gameobject {
cpBodyType bodytype; cpBodyType phys;
cpBody *body; /* NULL if this object is dead; has 2d position and rotation, relative to global 0 */ cpBody *body; /* NULL if this object is dead; has 2d position and rotation, relative to global 0 */
HMM_Vec3 scale; /* local */ HMM_Vec3 scale; /* local */
int next; int next;
@ -41,7 +41,6 @@ struct gameobject {
unsigned int layer; unsigned int layer;
cpShapeFilter filter; cpShapeFilter filter;
unsigned int warp_filter; unsigned int warp_filter;
// warpmask warpmask;
struct phys_cbs cbs; struct phys_cbs cbs;
struct shape_cb *shape_cbs; struct shape_cb *shape_cbs;
JSValue ref; JSValue ref;

View file

@ -23,28 +23,22 @@
#include "resources.h" #include "resources.h"
#include <sokol/sokol_time.h> #include <sokol/sokol_time.h>
#include <sokol/sokol_app.h> #include <sokol/sokol_app.h>
#include <time.h> #include <time.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
#include <limits.h> #include <limits.h>
#include "nota.h"
#include "render.h"
#include "model.h"
#include "HandmadeMath.h"
#if (defined(_WIN32) || defined(__WIN32__)) #if (defined(_WIN32) || defined(__WIN32__))
#include <direct.h> #include <direct.h>
#define mkdir(x,y) _mkdir(x) #define mkdir(x,y) _mkdir(x)
#endif #endif
#include "nota.h"
#include "render.h"
#include "model.h"
#include "HandmadeMath.h"
#define countof(x) (sizeof(x)/sizeof((x)[0])) #define countof(x) (sizeof(x)/sizeof((x)[0]))
static JSValue globalThis; static JSValue globalThis;
@ -57,6 +51,26 @@ const char *js2str(JSValue v) {
return JS_ToCString(js, v); return JS_ToCString(js, v);
} }
#define MIST_CFUNC_DEF(name, length, func1) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE | JS_PROP_ENUMERABLE, JS_DEF_CFUNC, 0, .u = { .func = { length, JS_CFUNC_generic, { .generic = func1 } } } }
#define MIST_FUNC_DEF(TYPE, FN, LEN) MIST_CFUNC_DEF(#FN, LEN, js_##TYPE##_##FN)
#define MIST_FN_STR(NAME) MIST_CFUNC_DEF(#NAME, 1, js_##NAME)
#define MIST_CGETSET_DEF(name, fgetter, fsetter) { name, JS_PROP_CONFIGURABLE | JS_PROP_ENUMERABLE, JS_DEF_CGETSET, 0, .u = { .getset = { .get = { .getter = fgetter }, .set = { .setter = fsetter } } } }
#define CGETSET_ADD(ID, ENTRY) MIST_CGETSET_DEF(#ENTRY, ID##_get_##ENTRY, ID##_set_##ENTRY)
#define GGETSET_ADD(ENTRY)
#define JSC_CCALL(NAME, FN) JSValue js_##NAME (JSContext *js, JSValue this, int argc, JSValue *argv) { \
{FN;} \
return JS_UNDEFINED; \
} \
#define JSC_RET(NAME, FN) JSValue js_##NAME (JSContext *js, JSValue this, int argc, JSValue *argv) { \
FN; } \
#define QJSCLASS(TYPE)\ #define QJSCLASS(TYPE)\
static JSClassID js_ ## TYPE ## _id;\ static JSClassID js_ ## TYPE ## _id;\
static void js_##TYPE##_finalizer(JSRuntime *rt, JSValue val){\ static void js_##TYPE##_finalizer(JSRuntime *rt, JSValue val){\
@ -571,118 +585,34 @@ void gameobject_add_shape_collider(gameobject *go, JSValue fn, struct phys2d_sha
arrpush(go->shape_cbs, shapecb); arrpush(go->shape_cbs, shapecb);
} }
JSValue duk_register_collide(JSContext *js, JSValue this, int argc, JSValue *argv) { struct phys2d_circle *js2circle2d(JSValue v) { return js2ptr(v); }
int cmd = js2number(argv[0]);
gameobject *go = js2gameobject(argv[2]);
JSValue fn = argv[1];
switch (cmd) { JSC_CCALL(circle2d_set_radius, js2circle2d(argv[0])->radius = js2number(argv[1]))
case 0: JSC_CCALL(circle2d_get_radius, return number2js(js2circle2d(argv[0])->radius))
go->cbs.begin = JS_DupValue(js,fn); JSC_CCALL(circle2d_set_offset, js2circle2d(argv[0])->offset = js2vec2(argv[1]))
break; JSC_CCALL(circle2d_get_offset, return vec22js(js2circle2d(argv[0])->offset))
JSC_CCALL(circle2d_sync, phys2d_shape_apply(&js2circle2d(argv[0])->shape))
case 1: static const JSCFunctionListEntry js_circle2d_funcs[] = {
gameobject_add_shape_collider(go, JS_DupValue(js,fn), js2ptr(argv[3])); MIST_FUNC_DEF(circle2d, set_radius, 2),
break; MIST_FUNC_DEF(circle2d, get_radius, 1),
MIST_FUNC_DEF(circle2d, set_offset, 2),
MIST_FUNC_DEF(circle2d, get_offset, 1),
MIST_FUNC_DEF(circle2d, sync, 1),
};
case 2: struct phys2d_poly *js2poly2d(JSValue v) { return js2ptr(v); }
phys2d_rm_go_handlers(go);
break;
case 3: JSC_CCALL(poly2d_setverts,
go->cbs.separate = JS_DupValue(js,fn); struct phys2d_poly *p = js2poly2d(argv[0]);
break; HMM_Vec2 *v = js2cpvec2arr(argv[1]);
} phys2d_poly_setverts(p,v);
arrfree(v);
)
return JS_UNDEFINED; static const JSCFunctionListEntry js_poly2d_funcs[] = {
} MIST_FUNC_DEF(poly2d, setverts, 2),
};
JSValue duk_make_circle2d(JSContext *js, JSValue this, int argc, JSValue *argv) {
gameobject *go = js2gameobject(argv[0]);
struct phys2d_circle *circle = Make2DCircle(go);
JSValue circleval = JS_NewObject(js);
js_setprop_str(circleval, "id", ptr2js(circle));
js_setprop_str(circleval, "shape", ptr2js(&circle->shape));
return circleval;
}
JSValue duk_make_model(JSContext *js, JSValue this, int argc, JSValue *argv)
{
gameobject *go = js2gameobject(argv[0]);
struct drawmodel *dm = make_drawmodel(go);
JSValue ret = JS_NewObject(js);
js_setprop_str(ret, "id", ptr2js(dm));
return ret;
}
JSValue duk_cmd_circle2d(JSContext *js, JSValue this, int argc, JSValue *argv) {
int cmd = js2number(argv[0]);
struct phys2d_circle *circle = js2ptr(argv[1]);
if (!circle) return JS_UNDEFINED;
switch (cmd) {
case 0:
circle->radius = js2number(argv[2]);
break;
case 1:
circle->offset = js2vec2(argv[2]);
break;
case 2:
return number2js(circle->radius);
case 3:
return vec22js(circle->offset);
}
phys2d_shape_apply(&circle->shape);
return JS_UNDEFINED;
}
JSValue duk_make_poly2d(JSContext *js, JSValue this, int argc, JSValue *argv) {
gameobject *go = js2gameobject(argv[0]);
struct phys2d_poly *poly = Make2DPoly(go);
phys2d_poly_setverts(poly, NULL);
JSValue polyval = JS_NewObject(js);
js_setprop_str(polyval, "id", ptr2js(poly));
js_setprop_str(polyval, "shape", ptr2js(&poly->shape));
return polyval;
}
JSValue duk_cmd_poly2d(JSContext *js, JSValue this, int argc, JSValue *argv) {
int cmd = js2number(argv[0]);
struct phys2d_poly *poly = js2ptr(argv[1]);
HMM_Vec2 *v1 = NULL;
if (!poly) return JS_UNDEFINED;
switch (cmd) {
case 0:
v1 = js2cpvec2arr(argv[2]);
phys2d_poly_setverts(poly, v1);
break;
}
if (v1) arrfree(v1);
return JS_UNDEFINED;
}
JSValue duk_make_edge2d(JSContext *js, JSValue this, int argc, JSValue *argv) {
gameobject *go = js2gameobject(argv[0]);
struct phys2d_edge *edge = Make2DEdge(go);
HMM_Vec2 *points = js2cpvec2arr(argv[1]);
phys2d_edge_update_verts(edge, points);
arrfree(points);
JSValue edgeval = JS_NewObject(js);
js_setprop_str(edgeval, "id", ptr2js(edge));
js_setprop_str(edgeval, "shape", ptr2js(&edge->shape));
return edgeval;
}
#define GETSET_PAIR(ID, ENTRY, TYPE) \ #define GETSET_PAIR(ID, ENTRY, TYPE) \
JSValue ID##_set_##ENTRY (JSContext *js, JSValue this, JSValue val) { \ JSValue ID##_set_##ENTRY (JSContext *js, JSValue this, JSValue val) { \
@ -732,26 +662,6 @@ GETSET_PAIR(warp_gravity, spherical, bool)
GETSET_PAIR(warp_gravity, mask, bitmask) GETSET_PAIR(warp_gravity, mask, bitmask)
GETSET_PAIR(warp_gravity, planar_force, vec3) GETSET_PAIR(warp_gravity, planar_force, vec3)
#define MIST_CFUNC_DEF(name, length, func1) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE | JS_PROP_ENUMERABLE, JS_DEF_CFUNC, 0, .u = { .func = { length, JS_CFUNC_generic, { .generic = func1 } } } }
#define MIST_FUNC_DEF(TYPE, FN, LEN) MIST_CFUNC_DEF(#FN, LEN, js_##TYPE##_##FN)
#define MIST_FN_STR(NAME) MIST_CFUNC_DEF(#NAME, 1, js_##NAME)
#define MIST_CGETSET_DEF(name, fgetter, fsetter) { name, JS_PROP_CONFIGURABLE | JS_PROP_ENUMERABLE, JS_DEF_CGETSET, 0, .u = { .getset = { .get = { .getter = fgetter }, .set = { .setter = fsetter } } } }
#define CGETSET_ADD(ID, ENTRY) MIST_CGETSET_DEF(#ENTRY, ID##_get_##ENTRY, ID##_set_##ENTRY)
#define GGETSET_ADD(ENTRY)
#define JSC_CCALL(NAME, FN) JSValue js_##NAME (JSContext *js, JSValue this, int argc, JSValue *argv) { \
{FN;} \
return JS_UNDEFINED; \
} \
#define JSC_RET(NAME, FN) JSValue js_##NAME (JSContext *js, JSValue this, int argc, JSValue *argv) { \
FN; } \
static const JSCFunctionListEntry js_warp_gravity_funcs [] = { static const JSCFunctionListEntry js_warp_gravity_funcs [] = {
CGETSET_ADD(warp_gravity, strength), CGETSET_ADD(warp_gravity, strength),
CGETSET_ADD(warp_gravity, decay), CGETSET_ADD(warp_gravity, decay),
@ -878,6 +788,47 @@ JSC_CCALL(os_sprite,
return sprite2js(sprite_make()); return sprite2js(sprite_make());
) )
JSC_CCALL(os_make_gameobject, return gameobject2js(MakeGameobject()))
JSC_CCALL(os_make_circle2d,
gameobject *go = js2gameobject(argv[0]);
struct phys2d_circle *circle = Make2DCircle(go);
JSValue circleval = JS_NewObject(js);
js_setprop_str(circleval, "id", ptr2js(circle));
js_setprop_str(circleval, "shape", ptr2js(&circle->shape));
return circleval;
)
JSC_CCALL(os_make_model,
gameobject *go = js2gameobject(argv[0]);
struct drawmodel *dm = make_drawmodel(go);
JSValue ret = JS_NewObject(js);
js_setprop_str(ret, "id", ptr2js(dm));
return ret;
)
JSC_CCALL(os_make_poly2d,
gameobject *go = js2gameobject(argv[0]);
struct phys2d_poly *poly = Make2DPoly(go);
phys2d_poly_setverts(poly, NULL);
JSValue polyval = JS_NewObject(js);
js_setprop_str(polyval, "id", ptr2js(poly));
js_setprop_str(polyval, "shape", ptr2js(&poly->shape));
return polyval;
)
JSC_CCALL(os_make_edge2d,
gameobject *go = js2gameobject(argv[0]);
struct phys2d_edge *edge = Make2DEdge(go);
HMM_Vec2 *points = js2cpvec2arr(argv[1]);
phys2d_edge_update_verts(edge, points);
arrfree(points);
JSValue edgeval = JS_NewObject(js);
js_setprop_str(edgeval, "id", ptr2js(edge));
js_setprop_str(edgeval, "shape", ptr2js(&edge->shape));
return edgeval;
)
static const JSCFunctionListEntry js_os_funcs[] = { static const JSCFunctionListEntry js_os_funcs[] = {
MIST_FUNC_DEF(os,sprite,1), MIST_FUNC_DEF(os,sprite,1),
MIST_FUNC_DEF(os, cwd, 0), MIST_FUNC_DEF(os, cwd, 0),
@ -888,6 +839,11 @@ static const JSCFunctionListEntry js_os_funcs[] = {
MIST_FUNC_DEF(os, gc, 0), MIST_FUNC_DEF(os, gc, 0),
MIST_FUNC_DEF(os, capture, 5), MIST_FUNC_DEF(os, capture, 5),
MIST_FUNC_DEF(os, eval_env, 3), MIST_FUNC_DEF(os, eval_env, 3),
MIST_FUNC_DEF(os, make_gameobject, 0),
MIST_FUNC_DEF(os, make_circle2d, 1),
MIST_FUNC_DEF(os, make_poly2d, 1),
MIST_FUNC_DEF(os, make_edge2d, 1),
MIST_FUNC_DEF(os, make_model, 2),
}; };
JSC_CCALL(render_normal, opengl_rendermode(LIT)) JSC_CCALL(render_normal, opengl_rendermode(LIT))
@ -1350,10 +1306,13 @@ JSC_CCALL(physics_closest_point,
JSC_CCALL(physics_make_gravity, return warp_gravity2js(warp_gravity_make())) JSC_CCALL(physics_make_gravity, return warp_gravity2js(warp_gravity_make()))
JSC_CCALL(physics_make_damp, return warp_damp2js(warp_damp_make())) JSC_CCALL(physics_make_damp, return warp_damp2js(warp_damp_make()))
JSC_CCALL(physics_edge_thickness, return number2js(((struct phys2d_edge*)js2ptr(argv[0]))->thickness))
JSC_CCALL(physics_collide_begin, js2gameobject(argv[1])->cbs.begin = JS_DupValue(js,argv[0]))
JSC_CCALL(physics_collide_rm, phys2d_rm_go_handlers(js2gameobject(argv[0])))
JSC_CCALL(physics_collide_separate, js2gameobject(argv[1])->cbs.separate = JS_DupValue(js,argv[0]))
JSC_CCALL(physics_collide_shape, gameobject_add_shape_collider(js2gameobject(argv[1]), JS_DupValue(js,argv[0]), js2ptr(argv[2])))
static const JSCFunctionListEntry js_physics_funcs[] = { static const JSCFunctionListEntry js_physics_funcs[] = {
MIST_FUNC_DEF(physics,edge_thickness,1),
MIST_FUNC_DEF(physics, sgscale, 2), MIST_FUNC_DEF(physics, sgscale, 2),
MIST_FUNC_DEF(physics, set_cat_mask, 2), MIST_FUNC_DEF(physics, set_cat_mask, 2),
MIST_FUNC_DEF(physics, box_query, 2), MIST_FUNC_DEF(physics, box_query, 2),
@ -1363,6 +1322,10 @@ static const JSCFunctionListEntry js_physics_funcs[] = {
MIST_FUNC_DEF(physics, closest_point, 3), MIST_FUNC_DEF(physics, closest_point, 3),
MIST_FUNC_DEF(physics, make_damp, 0), MIST_FUNC_DEF(physics, make_damp, 0),
MIST_FUNC_DEF(physics, make_gravity, 0), MIST_FUNC_DEF(physics, make_gravity, 0),
MIST_FUNC_DEF(physics, collide_begin, 2),
MIST_FUNC_DEF(physics, collide_rm, 1),
MIST_FUNC_DEF(physics, collide_separate, 2),
MIST_FUNC_DEF(physics, collide_shape, 3)
}; };
static const JSCFunctionListEntry js_emitter_funcs[] = { static const JSCFunctionListEntry js_emitter_funcs[] = {
@ -1517,7 +1480,8 @@ GETSET_PAIR(gameobject, scale, vec3)
BODY_GETSET(velocity, Velocity, cvec2) BODY_GETSET(velocity, Velocity, cvec2)
BODY_GETSET(angularvelocity, AngularVelocity, number) BODY_GETSET(angularvelocity, AngularVelocity, number)
BODY_GETSET(moi, Moment, number) BODY_GETSET(moi, Moment, number)
BODY_GETSET(phys, Type, number) //BODY_GETSET(phys, Type, number)
GETSET_PAIR(gameobject, phys, number)
BODY_GETSET(torque, Torque, number) BODY_GETSET(torque, Torque, number)
JSC_CCALL(gameobject_impulse, cpBodyApplyImpulseAtWorldPoint(js2gameobject(this)->body, js2vec2(argv[0]).cp, cpBodyGetPosition(js2gameobject(this)->body))) JSC_CCALL(gameobject_impulse, cpBodyApplyImpulseAtWorldPoint(js2gameobject(this)->body, js2vec2(argv[0]).cp, cpBodyGetPosition(js2gameobject(this)->body)))
JSC_CCALL(gameobject_force, cpBodyApplyForceAtWorldPoint(js2gameobject(this)->body, js2vec2(argv[0]).cp, cpBodyGetPosition(js2gameobject(this)->body))) JSC_CCALL(gameobject_force, cpBodyApplyForceAtWorldPoint(js2gameobject(this)->body, js2vec2(argv[0]).cp, cpBodyGetPosition(js2gameobject(this)->body)))
@ -1539,8 +1503,6 @@ GETSET_PAIR(gameobject, warp_filter, bitmask)
GETSET_PAIR(gameobject, drawlayer, number) GETSET_PAIR(gameobject, drawlayer, number)
JSC_CCALL(gameobject_setref, js2gameobject(this)->ref = argv[0]); JSC_CCALL(gameobject_setref, js2gameobject(this)->ref = argv[0]);
JSValue duk_make_gameobject(JSContext *js, JSValue this) { return gameobject2js(MakeGameobject()); }
static const JSCFunctionListEntry js_gameobject_funcs[] = { static const JSCFunctionListEntry js_gameobject_funcs[] = {
CGETSET_ADD(gameobject, f), CGETSET_ADD(gameobject, f),
CGETSET_ADD(gameobject, e), CGETSET_ADD(gameobject, e),
@ -1740,32 +1702,22 @@ static const JSCFunctionListEntry js_constraint_funcs[] = {
CGETSET_ADD(constraint, max_force), CGETSET_ADD(constraint, max_force),
CGETSET_ADD(constraint, collide), CGETSET_ADD(constraint, collide),
}; };
JSValue duk_cmd_edge2d(JSContext *js, JSValue this, int argc, JSValue *argv) {
int cmd = js2number(argv[0]);
struct phys2d_edge *edge = js2ptr(argv[1]);
if (!edge) { struct phys2d_edge *js2edge2d(JSValue v) { return js2ptr(v); }
YughError("Attempted to do a cmd on edge %p. Not found.", edge); JSC_CCALL(edge2d_setverts,
return JS_UNDEFINED; struct phys2d_edge *edge = js2edge2d(argv[0]);
} HMM_Vec2 *v = js2cpvec2arr(argv[1]);
phys2d_edge_update_verts(edge,v);
arrfree(v);
)
JSC_CCALL(edge2d_set_thickness, js2edge2d(argv[0])->thickness = js2number(argv[1]))
JSC_CCALL(edge2d_get_thickness, return number2js(js2edge2d(argv[0])->thickness))
HMM_Vec2 *v1 = NULL; static const JSCFunctionListEntry js_edge2d_funcs[] = {
MIST_FUNC_DEF(edge2d, setverts, 2),
switch (cmd) { MIST_FUNC_DEF(edge2d, set_thickness, 2),
case 0: MIST_FUNC_DEF(edge2d, get_thickness, 1),
v1 = js2cpvec2arr(argv[2]); };
phys2d_edge_update_verts(edge,v1);
break;
case 1:
edge->thickness = js2number(argv[2]);
break;
}
if (v1) arrfree(v1);
return JS_UNDEFINED;
}
JSValue duk_inflate_cpv(JSContext *js, JSValue this, int argc, JSValue *argv) { JSValue duk_inflate_cpv(JSContext *js, JSValue this, int argc, JSValue *argv) {
HMM_Vec2 *points = js2cpvec2arr(argv[0]); HMM_Vec2 *points = js2cpvec2arr(argv[0]);
@ -1781,36 +1733,29 @@ JSValue duk_inflate_cpv(JSContext *js, JSValue this, int argc, JSValue *argv) {
const char *STRTEST = "TEST STRING"; const char *STRTEST = "TEST STRING";
JSValue duk_performance(JSContext *js, JSValue this, int argc, JSValue *argv) JSC_CCALL(performance_barecall,)
{ JSC_CCALL(performance_unpack_num, int i = js2number(argv[0]))
int cmd = js2number(argv[0]); JSC_CCALL(performance_unpack_array, js2cpvec2arr(argv[0]))
switch(cmd) { JSC_CCALL(performance_pack_num, return number2js(1.0))
case 0: JSC_CCALL(performance_pack_string, return JS_NewStringLen(js, STRTEST, sizeof(*STRTEST)))
break; JSC_CCALL(performance_unpack_string, js2str(argv[0]))
case 1: JSC_CCALL(performance_unpack_32farr, jsfloat2vec(argv[0]))
js2number(argv[1]); JSC_CCALL(performance_call_fn_n,
break; for (int i = 0; i < js2number(argv[1]); i++)
case 2: script_call_sym(argv[0],0,NULL);
js2cpvec2arr(argv[1]); script_call_sym(argv[2],0,NULL);
break; )
case 3:
return number2js(1.0); static const JSCFunctionListEntry js_performance_funcs[] = {
case 4: MIST_FUNC_DEF(performance, barecall,0),
js2str(argv[1]); MIST_FUNC_DEF(performance, unpack_num, 1),
break; MIST_FUNC_DEF(performance, unpack_array, 1),
case 5: MIST_FUNC_DEF(performance, pack_num, 0),
jsfloat2vec(argv[1]); MIST_FUNC_DEF(performance, pack_string, 0),
break; MIST_FUNC_DEF(performance, unpack_string, 1),
case 6: MIST_FUNC_DEF(performance, unpack_32farr, 1),
return JS_NewStringLen(js, STRTEST, sizeof(*STRTEST)); MIST_FUNC_DEF(performance, call_fn_n, 3)
case 7: };
for (int i = 0; i < js2number(argv[2]); i++)
script_call_sym(argv[1],0,NULL);
script_call_sym(argv[3],0,NULL);
break;
}
return JS_UNDEFINED;
}
JSValue js_nota_encode(JSContext *js, JSValue this, int argc, JSValue *argv) JSValue js_nota_encode(JSContext *js, JSValue this, int argc, JSValue *argv)
{ {
@ -1843,19 +1788,8 @@ static const JSCFunctionListEntry js_nota_funcs[] = {
void ffi_load() { void ffi_load() {
globalThis = JS_GetGlobalObject(js); globalThis = JS_GetGlobalObject(js);
DUK_FUNC(make_gameobject, 0)
DUK_FUNC(make_circle2d, 1)
DUK_FUNC(cmd_circle2d, 6)
DUK_FUNC(make_poly2d, 1)
DUK_FUNC(cmd_poly2d, 6)
DUK_FUNC(make_edge2d, 3)
DUK_FUNC(cmd_edge2d, 6)
DUK_FUNC(make_model,2);
DUK_FUNC(register_collide, 6)
DUK_FUNC(inflate_cpv, 3) DUK_FUNC(inflate_cpv, 3)
DUK_FUNC(performance, 2)
QJSCLASSPREP(ptr); QJSCLASSPREP(ptr);
QJSCLASSPREP_FUNCS(gameobject); QJSCLASSPREP_FUNCS(gameobject);
@ -1892,6 +1826,11 @@ void ffi_load() {
QJSGLOBALCLASS(joint); QJSGLOBALCLASS(joint);
QJSGLOBALCLASS(dspsound); QJSGLOBALCLASS(dspsound);
QJSGLOBALCLASS(pshape); QJSGLOBALCLASS(pshape);
QJSGLOBALCLASS(performance);
QJSGLOBALCLASS(circle2d);
QJSGLOBALCLASS(poly2d);
QJSGLOBALCLASS(edge2d);
JS_SetPropertyStr(js, prosperon, "version", str2js(VER)); JS_SetPropertyStr(js, prosperon, "version", str2js(VER));
JS_SetPropertyStr(js, prosperon, "revision", str2js(COM)); JS_SetPropertyStr(js, prosperon, "revision", str2js(COM));