diff --git a/Makefile b/Makefile index 20f5e05..0294608 100755 --- a/Makefile +++ b/Makefile @@ -72,8 +72,8 @@ UNZIP = cp $(DISTDIR)/$(DIST) $(DESTDIR) && tar xzf $(DESTDIR)/$(DIST) -C $(DEST ARCH = x64 ifeq ($(OS), Windows_NT) - LDFLAGS += -mwin32 -static - CFLAGS += -mwin32 + LDFLAGS += -mwin32 -static -g + CFLAGS += -mwin32 -g LDLIBS += mingw32 kernel32 d3d11 user32 shell32 dxgi gdi32 ws2_32 ole32 winmm setupapi m EXT = .exe PLAT = w64 @@ -221,6 +221,7 @@ tools/libquickjs.a: ./jso $< > $@ WINCC = x86_64-w64-mingw32-gcc +#WINCC = i686-w64-mingw32-g++ .PHONY: crosswin crosswin: make CC=$(WINCC) OS=Windows_NT diff --git a/scripts/base.js b/scripts/base.js index 3e38e51..e3b69af 100644 --- a/scripts/base.js +++ b/scripts/base.js @@ -54,14 +54,7 @@ Object.extend = function(from, src) Object.mixin = function(target, source) { if (typeof source !== 'object') return target; - - Object.keys(source).forEach(function (k) { - if (Object.isAccessor(source,k)) - Object.defineProperty(target, k, Object.getOwnPropertyDescriptor(source,k)); - else - target[k] = source[k]; - }); - + Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); return target; }; diff --git a/scripts/components.js b/scripts/components.js index 400847d..3eb97a1 100644 --- a/scripts/components.js +++ b/scripts/components.js @@ -406,14 +406,17 @@ component.polygon2d = Object.copy(collider2d, { }, }); -component.polygon2d.impl = Object.extend(collider2d.impl, { +component.polygon2d.impl = { + set sensor(x) { cmd(18,this.shape,x); }, + get sensor() { return cmd(21,this.shape); }, + sync() { cmd_poly2d(0, this.id, this.spoints); }, query() { return cmd(80, this.shape); }, -}); +}; var polygon2d = component.polygon2d; @@ -540,7 +543,7 @@ component.edge2d = Object.copy(collider2d, { return points2bb(this.points.map(x => x.scale(this.gameobject.scale))); }, - hides: ['gameobject', 'id', 'shape', 'points'], + hides: ['gameobject', 'id', 'shape'], _enghook: make_edge2d, /* EDITOR */ @@ -570,7 +573,10 @@ component.edge2d = Object.copy(collider2d, { }, }); -component.edge2d.impl = Object.extend(collider2d.impl, { +component.edge2d.impl = { + set sensor(x) { cmd(18,this.shape,x); }, + get sensor() { return cmd(21,this.shape); }, + set thickness(x) { cmd_edge2d(1,this.id,x); }, @@ -581,7 +587,7 @@ component.edge2d.impl = Object.extend(collider2d.impl, { cmd_edge2d(0,this.id,points); this.sensor = sensor; }, -}); +}; var bucket = component.edge2d; bucket.inputs = {}; @@ -715,7 +721,10 @@ component.circle2d = Object.copy(collider2d, { _enghook: make_circle2d, }); -component.circle2d.impl = Object.extend(collider2d.impl, { +component.circle2d.impl = { + set sensor(x) { cmd(18,this.shape,x); }, + get sensor() { return cmd(21,this.shape); }, + set radius(x) { cmd_circle2d(0,this.id,x); }, get radius() { return cmd_circle2d(2,this.id); }, @@ -724,7 +733,7 @@ component.circle2d.impl = Object.extend(collider2d.impl, { set offset(x) { cmd_circle2d(1,this.id,x); }, get offset() { return cmd_circle2d(3,this.id); }, -}); +}; /* ASSETS */ diff --git a/scripts/engine.js b/scripts/engine.js index 17732d4..c8fb379 100644 --- a/scripts/engine.js +++ b/scripts/engine.js @@ -479,7 +479,6 @@ var Register = { Register.add_cb(0, "update").doc = "Called once per frame."; Register.add_cb(1, "physupdate"); Register.add_cb(2, "gui"); -Register.add_cb(3, "nk_gui"); Register.add_cb(6, "debug"); register(7, Register.kbm_input, Register); Register.add_cb(8, "gamepad_input"); @@ -489,8 +488,6 @@ register(9, Log.stack, this); Register.gamepad_playermap[0] = Player.players[0]; - - Player.players[0].control(GUI); var Signal = { @@ -531,6 +528,7 @@ var game_quit = function() Signal.register("quit", game_quit); var Window = { + fullscreen(f) { cmd(145, f); }, set width(w) { cmd(125, w); }, set height(h) { cmd(126, h); }, get width() { return cmd(48); }, @@ -550,7 +548,6 @@ var Window = { Window.icon = function(path) { cmd(90, path); }; Window.icon.doc = "Set the icon of the window using the PNG image at path."; - function reloadfiles() { Object.keys(files).forEach(function (x) { load(x); }); } diff --git a/scripts/entity.js b/scripts/entity.js index ad80fbb..56e9bf9 100644 --- a/scripts/entity.js +++ b/scripts/entity.js @@ -13,9 +13,10 @@ function grab_from_points(pos, points, slop) { var gameobject = { impl: { clear() { - this.objects.forEach(function(x) { - x.kill(); - }); + for (var k in this.objects) { + Log.info(`Killing ${k}`); + this.objects[k].kill(); + }; this.objects = {}; }, gscale() { return cmd(103,this.body); }, @@ -377,9 +378,11 @@ var gameobject = { Log.warn(`Object is already dead!`); return; } + // Register.endofloop(() => { - cmd(2, this.body); +// cmd(2, this.body); + q_body(8,this.body); Game.unregister_obj(this); if (this.level) { @@ -390,17 +393,17 @@ var gameobject = { Player.uncontrol(this); Register.unregister_obj(this); // this.instances.remove(this); - this.body = -1; + for (var key in this.components) { Register.unregister_obj(this.components[key]); + Log.info(`Destroying component ${key}`); this.components[key].kill(); this.components.gameobject = undefined; } delete this.components; - for (var key in this.objects) - this.objects[key].kill(); + this.clear(); if (typeof this.stop === 'function') this.stop(); diff --git a/scripts/input.js b/scripts/input.js index f4ddecc..ea51dc0 100644 --- a/scripts/input.js +++ b/scripts/input.js @@ -178,7 +178,10 @@ var Player = { var n = Object.create(this); n.pawns = []; n.gamepads = []; - n.control = function(pawn) { n.pawns.push_unique(pawn); }; + n.control = function(pawn) { + Log.info(`Player taking control of ${pawn.toString()}`); + n.pawns.push_unique(pawn); + }; n.uncontrol = function(pawn) { n.pawns = n.pawns.filter(x => x !== pawn); }; this.players.push(n); return n; diff --git a/source/engine/debug/debugdraw.c b/source/engine/debug/debugdraw.c index d11b51e..849a330 100644 --- a/source/engine/debug/debugdraw.c +++ b/source/engine/debug/debugdraw.c @@ -246,7 +246,7 @@ void debugdraw_init() }; circle_bind.vertex_buffers[1] = sg_make_buffer(&(sg_buffer_desc){ - .data = SG_RANGE(circleverts), + .data = (sg_range){.ptr = circleverts, .size = sizeof(float)*8}, .usage = SG_USAGE_IMMUTABLE, }); diff --git a/source/engine/debug/log.c b/source/engine/debug/log.c index 548aa94..d31b525 100644 --- a/source/engine/debug/log.c +++ b/source/engine/debug/log.c @@ -64,6 +64,7 @@ void mYughLog(int category, int priority, int line, const char *file, const char void log_print(const char *str) { +#ifndef NDEBUG fprintf(stderr, "%s", str); fflush(stderr); @@ -73,11 +74,14 @@ void log_print(const char *str) fprintf(logfile, "%s", str); fflush(logfile); } +#endif } void console_print(const char *str) { +#ifndef NDEBUG strncat(consolelog, str, CONSOLE_BUF); +#endif } void log_setfile(char *file) { diff --git a/source/engine/ffi.c b/source/engine/ffi.c index 6466678..696a627 100644 --- a/source/engine/ffi.c +++ b/source/engine/ffi.c @@ -33,6 +33,9 @@ static JSValue globalThis; +static JSClassID js_ptr_id; +static JSClassDef js_ptr_class = { "POINTER" }; + #define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c" #define BYTE_TO_BINARY(byte) \ (byte & 0x80 ? '1' : '0'), \ @@ -136,13 +139,13 @@ struct gameobject *js2go(JSValue v) { struct sprite *js2sprite(JSValue v) { return id2sprite(js2int(v)); } void *js2ptr(JSValue v) { - void *p; - JS_ToInt64(js, &p, v); - return p; + return JS_GetOpaque(v,js_ptr_id); } JSValue ptr2js(void *ptr) { - return JS_NewInt64(js, (long)ptr); + JSValue obj = JS_NewObjectClass(js, js_ptr_id); + JS_SetOpaque(obj, ptr); + return obj; } struct timer *js2timer(JSValue v) { @@ -505,7 +508,9 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) break; case 2: + YughWarn("Deleting gameobject %d", js2int(argv[1])); gameobject_delete(js2int(argv[1])); + YughWarn("Deleted gameobject %d", js2int(argv[1])); break; case 3: @@ -1105,6 +1110,11 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) case 144: ret = str2js(DATA_PATH); break; + + case 145: + if (js2bool(argv[1])) window_makefullscreen(&mainwin); + else window_unfullscreen(&mainwin); + break; } if (str) @@ -1357,7 +1367,8 @@ JSValue duk_set_body(JSContext *js, JSValueConst this, int argc, JSValueConst *a JSValue duk_q_body(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) { int q = js2int(argv[0]); - struct gameobject *go = get_gameobject_from_id(js2int(argv[1])); + int goid = js2int(argv[1]); + struct gameobject *go = get_gameobject_from_id(goid); if (!go) return JS_NULL; @@ -1385,6 +1396,10 @@ JSValue duk_q_body(JSContext *js, JSValueConst this, int argc, JSValueConst *arg case 7: return JS_NewBool(js, phys2d_in_air(go->body)); + + case 8: + gameobject_delete(goid); + break; } return JS_NULL; @@ -1489,7 +1504,7 @@ JSValue duk_cmd_circle2d(JSContext *js, JSValueConst this, int argc, JSValueCons case 3: return vec2js(circle->offset); } - + phys2d_applycircle(circle); return JS_NULL; } @@ -1671,4 +1686,7 @@ void ffi_load() { DUK_FUNC(anim, 2) JS_FreeValue(js,globalThis); + + JS_NewClassID(&js_ptr_id); + JS_NewClass(JS_GetRuntime(js), js_ptr_id, &js_ptr_class); } diff --git a/source/engine/input.c b/source/engine/input.c index 47d0f91..76bb3b8 100644 --- a/source/engine/input.c +++ b/source/engine/input.c @@ -11,25 +11,11 @@ #include #include "resources.h" -#include "stb_ds.h" - float deltaT = 0; static int mouse_states[3] = {INPUT_UP}; static int key_states[512] = {INPUT_UP}; -JSValue jsinput; -JSValue jsnum; -JSValue jsgamepadstr[15]; -JSValue jsaxesstr[4]; -JSValue jsinputstate[5]; -JSValue jsaxis; -JSValue jsany; -JSValue jsmouse; -JSValue jspos; -JSValue jsmove; -JSValue jsscroll; - cpVect mousewheel = {0,0}; cpVect mouse_pos = {0, 0}; cpVect mouse_delta = {0, 0}; @@ -47,25 +33,6 @@ static int mquit = 0; static struct callee pawn_callee; static struct callee gamepad_callee; -static struct { - char *key; - JSValue value; -} *jshash = NULL; - -JSValue input2js(const char *input) { - int idx = shgeti(jshash, input); - if (idx != -1) - return jshash[idx].value; - - if (shlen(jshash) == 0) - sh_new_arena(jshash); - - JSValue n = str2js(input); - shput(jshash, input, n); - - return n; -} - void add_downkey(int key) { for (int i = 0; i < arrlen(downkeys); i++) if (downkeys[i] == key) return; @@ -97,6 +64,18 @@ char *mb2str(int btn) return "NULLMOUSE"; } +JSValue input2js(int state) +{ + switch(state) { + case INPUT_UP: return jstr("released"); + case INPUT_REPEAT: return jstr("rep"); + case INPUT_DOWN: return jstr("pressed"); + case 3: return jstr("pressrep"); + case 4: return jstr("down"); + } + return JS_NULL; +} + void input_mouse(int btn, int state, uint32_t mod) { char out[16] = {0}; @@ -108,12 +87,10 @@ void input_mouse(int btn, int state, uint32_t mod) ); JSValue argv[3]; - argv[0] = JS_NewString(js, "emacs"); - argv[1] = JS_NewString(js, out); - argv[2] = jsinputstate[state]; + argv[0] = jstr("emacs"); + argv[1] = jstr(out); + argv[2] = input2js(state); script_callee(pawn_callee, 3, argv); - JS_FreeValue(js, argv[0]); - JS_FreeValue(js, argv[1]); } void input_mouse_move(float x, float y, float dx, float dy, uint32_t mod) @@ -124,8 +101,8 @@ void input_mouse_move(float x, float y, float dx, float dy, uint32_t mod) mouse_delta.y = -dy; JSValue argv[4]; - argv[0] = jsmouse; - argv[1] = jsmove; + argv[0] = jstr("mouse"); + argv[1] = jstr("move"); argv[2] = vec2js(mouse_pos); argv[3] = vec2js(mouse_delta); script_callee(pawn_callee, 4, argv); @@ -139,23 +116,23 @@ void input_mouse_scroll(float x, float y, uint32_t mod) mousewheel.y = y; JSValue argv[4]; - argv[0] = jsmouse; + argv[0] = jstr("mouse"); char out[16] = {0}; snprintf(out, 16, "%s%s%sscroll", mod & SAPP_MODIFIER_CTRL ? "C-" : "", mod & SAPP_MODIFIER_ALT ? "M-" : "", mod & SAPP_MODIFIER_SUPER ? "S-" : "" ); - argv[1] = JS_NewString(js,out); + argv[1] = jstr(out); argv[2] = vec2js(mousewheel); script_callee(pawn_callee, 3, argv); - JS_FreeValue(js, argv[1]); JS_FreeValue(js, argv[2]); } void input_btn(int btn, int state, uint32_t mod) { - char *keystr = keyname_extd(btn); + char keystr[16] = {0}; + strncat(keystr,keyname_extd(btn),16); if (strlen(keystr) == 1 && mod & SAPP_MODIFIER_SHIFT) keystr[0] = toupper(keystr[0]); @@ -169,19 +146,15 @@ void input_btn(int btn, int state, uint32_t mod) ); JSValue argv[3]; - argv[1] = JS_NewString(js, out); - argv[2] = jsinputstate[state]; + argv[1] = jstr(out); + argv[2] = input2js(state); - argv[0] = JS_NewString(js, "emacs"); + argv[0] = jstr("emacs"); script_callee(pawn_callee, 3, argv); - JS_FreeValue(js, argv[0]); - argv[0] = JS_NewString(js, "action"); + argv[0] = jstr("action"); script_callee(pawn_callee, 3, argv); - JS_FreeValue(js, argv[0]); - JS_FreeValue(js, argv[1]); - if (state == INPUT_DOWN) { key_states[btn] = INPUT_DOWN; add_downkey(btn); @@ -201,12 +174,9 @@ void input_key(uint32_t key, uint32_t mod) JSValue argv[2]; char s[2] = {key, '\0'}; - argv[0] = JS_NewString(js, "char"); - argv[1] = JS_NewString(js, s); + argv[0] = jstr("char"); + argv[1] = jstr(s); script_callee(pawn_callee, 2, argv); - - JS_FreeValue(js, argv[0]); - JS_FreeValue(js, argv[1]); } void register_pawn(struct callee c) { @@ -219,9 +189,9 @@ void register_gamepad(struct callee c) { static void pawn_call_keydown(int key) { JSValue argv[4]; - argv[0] = jsinput; - argv[1] = jsnum; - argv[2] = jsinputstate[INPUT_DOWN]; + argv[0] = jstr("input"); + argv[1] = jstr("num"); + argv[2] = input2js(INPUT_DOWN); /* TODO: Could cache */ argv[3] = JS_NewInt32(js, key); script_callee(pawn_callee, 4, argv); @@ -235,24 +205,6 @@ static void pawn_call_keydown(int key) { void set_mouse_mode(int mousemode) { sapp_lock_mouse(mousemode); } void input_init() { - jsaxesstr[0] = str2js("ljoy"); - jsaxesstr[1] = str2js("rjoy"); - jsaxesstr[2] = str2js("ltrigger"); - jsaxesstr[3] = str2js("rtrigger"); - jsaxis = str2js("axis"); - jsinputstate[INPUT_UP] = str2js("released"); - jsinputstate[INPUT_REPEAT] = str2js("rep"); - jsinputstate[INPUT_DOWN] = str2js("pressed"); - jsinputstate[3] = str2js("pressrep"); - jsinputstate[4] = str2js("down"); - jsinput = str2js("input"); - jsnum = str2js("num"); - jsany = str2js("any"); - jsmouse = str2js("mouse"); - jspos = str2js("pos"); - jsmove = str2js("move"); - jsscroll = str2js("scroll"); - for (int i = 0; i < 512; i++) key_states[i] = INPUT_UP; @@ -339,11 +291,10 @@ const char *keyname_extd(int key) { void call_input_down(int *key) { JSValue argv[3]; - argv[0] = JS_NewString(js, "emacs"); - argv[1] = input2js(keyname_extd(*key)); - argv[2] = jsinputstate[4]; + argv[0] = jstr("emacs"); + argv[1] = jstr(keyname_extd(*key)); + argv[2] = input2js(4); script_callee(pawn_callee, 3, argv); - JS_FreeValue(js, argv[0]); } /* This is called once every frame - or more if we want it more! */ diff --git a/source/engine/script.c b/source/engine/script.c index 21964f7..8324cda 100644 --- a/source/engine/script.c +++ b/source/engine/script.c @@ -14,6 +14,7 @@ #include "sys/types.h" #include "time.h" #include "resources.h" +#include "input.h" #include @@ -26,6 +27,21 @@ JSRuntime *rt = NULL; #define JS_EVAL_FLAGS JS_EVAL_FLAG_STRICT | JS_EVAL_FLAG_STRIP #endif +static struct { + char *key; + JSValue value; +} *jsstrs = NULL; + +JSValue jstr(const char *str) +{ + int index = shgeti(jsstrs, str); + if (index != -1) return jsstrs[index].value; + + JSValue v = str2js(str); + shput(jsstrs, str, v); + return v; +} + static int load_prefab(const char *fpath, const struct stat *sb, int typeflag) { if (typeflag != FTW_F) return 0; @@ -39,6 +55,8 @@ static int load_prefab(const char *fpath, const struct stat *sb, int typeflag) { void script_startup() { rt = JS_NewRuntime(); js = JS_NewContext(rt); + + sh_new_arena(jsstrs); ffi_load(); @@ -52,6 +70,11 @@ void script_startup() { void script_stop() { send_signal("quit",0,NULL); + + for (int i = 0; i < shlen(jsstrs); i++) + JS_FreeValue(js,jsstrs[i].value); + + JS_FreeContext(js); JS_RunGC(rt); JS_FreeRuntime(rt); } @@ -253,12 +276,13 @@ void send_signal(const char *signal, int argc, JSValue *argv) JS_FreeValue(js, globalThis); JSValue fn = JS_GetPropertyStr(js, sig, "call"); JSValue args[argc+1]; - args[0] = str2js(signal); + args[0] = jstr(signal); for (int i = 0; i < argc; i++) args[1+i] = argv[i]; JS_FreeValue(js,JS_Call(js, fn, sig, argc+1, args)); - JS_FreeValue(js,sig); + JS_FreeValue(js, sig); + JS_FreeValue(js, fn); } static struct callee update_callee; diff --git a/source/engine/script.h b/source/engine/script.h index 8dee61f..266c4b2 100644 --- a/source/engine/script.h +++ b/source/engine/script.h @@ -15,6 +15,8 @@ struct callee { extern struct callee stacktrace_callee; extern JSValue num_cache[100]; +JSValue jstr(const char *str); + void js_stacktrace(); void script_startup(); void script_stop(); diff --git a/source/engine/yugine.c b/source/engine/yugine.c index 725ef0a..b6d2c1e 100644 --- a/source/engine/yugine.c +++ b/source/engine/yugine.c @@ -108,14 +108,16 @@ void print_stacktrace() { } void seghandle(int sig) { -#ifdef __GLIBC__ - if (strsignal(sig)) - YughCritical("CRASH! Signal: %s.", strsignal(sig)); +//#ifdef __GLIBC__ +// if (strsignal(sig)) + YughCritical("CRASH! Signal: %d.", sig); js_stacktrace(); exit(1); -#endif +//#endif +// js_stacktrace(); +// exit(1); } const char *engine_info() @@ -308,7 +310,7 @@ void app_name(char *name) sapp_desc sokol_main(int argc, char **argv) { #ifndef NDEBUG log_init(); - #ifdef __linux__ +// #ifdef __linux__ int logout = 0; if (logout) { time_t now = time(NULL); @@ -327,11 +329,12 @@ sapp_desc sokol_main(int argc, char **argv) { log_cat(sysinfo); pclose(sysinfo); }*/ +// #endif signal(SIGSEGV, seghandle); signal(SIGABRT, seghandle); signal(SIGFPE, seghandle); - signal(SIGBUS, seghandle); - #endif +// signal(SIGBUS, seghandle); + #endif stm_setup(); /* time */