diff --git a/docs/export.md b/docs/export.md index e69de29..58e6d55 100644 --- a/docs/export.md +++ b/docs/export.md @@ -0,0 +1,18 @@ +# Exporting + +Available platforms + +## Linux + +## Windows PC + +## Mac OS + +## iOS + +## PS5 + +## Nintendo Switch + +## Xbox One + diff --git a/docs/scripting.md b/docs/scripting.md index b90c031..0fc7e6c 100644 --- a/docs/scripting.md +++ b/docs/scripting.md @@ -44,3 +44,5 @@ gui() debug() Called during a debug phase; Will not be called when debug draw is off +## Important objects +There are a number of possible ways to create a script in the context of the game world. diff --git a/source/engine/debug/debugdraw.c b/source/engine/debug/debugdraw.c index 1024e29..9c87e9a 100644 --- a/source/engine/debug/debugdraw.c +++ b/source/engine/debug/debugdraw.c @@ -85,8 +85,6 @@ struct circle_vertex { static struct circle_vertex circle_b[v_amt]; - - void debug_flush(HMM_Mat4 *view) { if (poly_c != 0) { diff --git a/source/engine/ffi.c b/source/engine/ffi.c index ee3c254..4f53433 100644 --- a/source/engine/ffi.c +++ b/source/engine/ffi.c @@ -1045,6 +1045,10 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) str = JS_ToCString(js, argv[1]); ret = JS_NewInt64(js, file_mod_secs(str)); break; + + case 120: + ret = str2js(engine_info()); + break; } if (str) @@ -1291,6 +1295,10 @@ JSValue duk_set_body(JSContext *js, JSValueConst this, int argc, JSValueConst *a case 12: cpBodyApplyForceAtWorldPoint(go->body, js2vec2(argv[2]), cpBodyGetPosition(go->body)); return JS_NULL; + + case 13: + cpBodySetMoment(go->body, js2number(argv[2])); + return JS_NULL; } cpSpaceReindexShapesForBody(space, go->body); diff --git a/source/engine/font.c b/source/engine/font.c index 181fda5..ae84af9 100644 --- a/source/engine/font.c +++ b/source/engine/font.c @@ -246,11 +246,11 @@ void draw_char_box(struct Character c, cpVect cursor, float scale, struct rgba c // draw_box(cursor, wh, color); } -void text_flush() { +void text_flush(HMM_Mat4 *proj) { if (curchar == 0) return; sg_apply_pipeline(pipe_text); sg_apply_bindings(&bind_text); - sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(hudproj)); + sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(*proj)); sg_range verts; verts.ptr = text_buffer; diff --git a/source/engine/font.h b/source/engine/font.h index 31c0e9d..b686664 100644 --- a/source/engine/font.h +++ b/source/engine/font.h @@ -37,7 +37,7 @@ struct boundingbox text_bb(const char *text, float scale, float lw, float tracki int renderText(const char *text, HMM_Vec2 pos, float scale, struct rgba color, float lw, int caret, float tracking); // void text_frame(); -void text_flush(); +void text_flush(HMM_Mat4 *proj); unsigned char *slurp_file(const char *filename); char *slurp_text(const char *filename); diff --git a/source/engine/openglrender.c b/source/engine/openglrender.c index 0232d3f..9b06b58 100644 --- a/source/engine/openglrender.c +++ b/source/engine/openglrender.c @@ -62,12 +62,6 @@ bool renderReflection = true; struct gameobject *selectedobject = NULL; char objectName[200] = {'\0'}; // object name buffer -struct sprite *tsprite = NULL; - -const char *donquixote; - -static struct model *duck; - sg_image ddimg; void debug_draw_phys(int draw) { @@ -99,15 +93,25 @@ static struct { void make_shader(sg_shader_desc *d, sg_shader result, void *data) { + if (sg_query_shader_state(result) == SG_RESOURCESTATE_FAILED) { + YughWarn("FAILED MAKING A SHADER: %s\n%s\n%s", d->label, d->vs.source, d->fs.source); + } } void fail_shader(sg_shader id, void *data) { + YughWarn("SHADER DID NOT COMPILE"); +} + +void destroy_shader(sg_shader shd, void *data) +{ + YughWarn("DESTROYED SHADER"); } static sg_trace_hooks hooks = { .fail_shader = fail_shader, - .make_shader = make_shader + .make_shader = make_shader, + .destroy_shader = destroy_shader, }; @@ -338,6 +342,7 @@ void openglRender(struct window *window) { } debug_flush(&projection); +// text_flush(&projection); ////// TEXT && GUI @@ -345,7 +350,7 @@ void openglRender(struct window *window) { call_gui(); debug_flush(&hudproj); - text_flush(); + text_flush(&hudproj); nuke_start(); call_nk_gui(); nuke_end(); diff --git a/source/engine/script.c b/source/engine/script.c index 36178ff..6d11af8 100644 --- a/source/engine/script.c +++ b/source/engine/script.c @@ -87,6 +87,21 @@ void script_run(const char *script, const char *file) { JS_FreeValue(js,obj); } +void script_evalf(const char *format, ...) +{ + char fmtbuf[4096]; + va_list args; + va_start(args, format); + vsnprintf(fmtbuf, 4096, format, args); + va_end(args); + + YughWarn(fmtbuf); + + JSValue obj = JS_Eval(js, fmtbuf, strlen(fmtbuf), "C eval", JS_EVAL_FLAGS); + js_print_exception(obj); + JS_FreeValue(js,obj); +} + void compile_script(const char *file) { const char *script = slurp_text(file); JSValue obj = JS_Eval(js, script, strlen(script), file, JS_EVAL_FLAG_COMPILE_ONLY | JS_EVAL_TYPE_GLOBAL | JS_EVAL_FLAGS); @@ -161,7 +176,8 @@ void script_call_sym(JSValue sym) { call_callee(&c); } -JSValue js_callee_exec(struct callee *c, int argc, JSValue *argv) { +JSValue js_callee_exec(struct callee *c, int argc, JSValue *argv) +{ JSValue ret = JS_Call(js, c->fn, c->obj, argc, argv); js_print_exception(ret); JS_FreeValue(js, ret); @@ -194,8 +210,6 @@ void script_callee(struct callee c, int argc, JSValue *argv) { js_callee_exec(&c, argc, argv); } - - void send_signal(const char *signal, int argc, JSValue *argv) { JSValue globalThis = JS_GetGlobalObject(js); diff --git a/source/engine/script.h b/source/engine/script.h index cb4d400..1a72248 100644 --- a/source/engine/script.h +++ b/source/engine/script.h @@ -19,6 +19,7 @@ void js_stacktrace(); void script_startup(); void script_init(); void script_run(const char *script, const char *file); +void script_evalf(const char *format, ...); int script_dofile(const char *file); JSValue script_runfile(const char *file); void script_update(double dt); diff --git a/source/engine/yugine.c b/source/engine/yugine.c index 71b8269..1fe366e 100644 --- a/source/engine/yugine.c +++ b/source/engine/yugine.c @@ -48,7 +48,6 @@ double renderMS = 1 / 165.f; double physMS = 1 / 165.f; double updateMS = 1 / 165.f; -static int ed = 1; static int sim_play = 0; double lastTick = 0.0; static int phys_step = 0; @@ -113,6 +112,12 @@ void seghandle(int sig) { #endif } +const char *engine_info() +{ + char str[100]; + snprintf(str, 100, "Yugine version %s, %s build.\nCopyright 2022-2023 odplot productions LLC.\n", VER, INFO); + return str; +} void sg_logging(const char *tag, uint32_t lvl, uint32_t id, const char *msg, uint32_t line, const char *file, void *data) { mYughLog(0, 1, line, file, "tag: %s, msg: %s", tag, msg); @@ -120,17 +125,12 @@ void sg_logging(const char *tag, uint32_t lvl, uint32_t id, const char *msg, uin int main(int argc, char **args) { int logout = 1; - ed = 1; script_startup(); for (int i = 1; i < argc; i++) { if (args[i][0] == '-') { switch (args[i][1]) { - case 'p': - ed = 0; - break; - case 'l': if (i + 1 < argc && args[i + 1][0] != '-') { log_setfile(args[i + 1]); @@ -142,8 +142,7 @@ int main(int argc, char **args) { } case 'v': - printf("Yugine version %s, %s build.\n", VER, INFO); - printf("Copyright 2022-2023 odplot productions LLC.\n"); + printf(engine_info()); exit(1); break; @@ -155,14 +154,6 @@ int main(int argc, char **args) { logLevel = atoi(args[2]); break; - case 'h': - printf("-l Set log file\n"); - printf("-p Launch engine in play mode instead of editor mode\n"); - printf("-v Display engine info\n"); - printf("-c Redirect logging to console\n"); - exit(0); - break; - case 'c': logout = 0; break; @@ -215,11 +206,23 @@ int main(int argc, char **args) { input_init(); openglInit(); - if (ed) - script_dofile("scripts/editor.js"); - else - script_dofile("scripts/play.js"); + int argsize = 0; + for (int i = 1; i < argc; i++) { + argsize += strlen(args[i]); + if (argc > i+1) argsize++; + } + char cmdstr[argsize]; + cmdstr[0] = '\0'; + + YughWarn("num is %d", argc); + + for (int i = 0; i < argc; i++) { + strcat(cmdstr, args[i]); + if (argc > i+1) strcat(cmdstr, " "); + } + + script_evalf("cmd_args('%s');", cmdstr); while (!want_quit()) { double elapsed = glfwGetTime() - lastTick; diff --git a/source/engine/yugine.h b/source/engine/yugine.h index 308f83f..e5af950 100644 --- a/source/engine/yugine.h +++ b/source/engine/yugine.h @@ -11,6 +11,8 @@ int phys_stepping(); void set_timescale(float val); void print_stacktrace(); +const char *engine_info(); + int frame_fps(); extern double lastTick; diff --git a/source/scripts/components.js b/source/scripts/components.js index ee09d0f..1d7468c 100644 --- a/source/scripts/components.js +++ b/source/scripts/components.js @@ -395,6 +395,12 @@ var bucket = clone(collider2d, { looped: 3 */ type: 3, + typeid: { + open: 0, + clamped: 1, + beziers: 2, + looped: 3 + }, mirrorx: false, mirrory: false, @@ -457,7 +463,7 @@ var bucket = clone(collider2d, { assert knots%order != 0 */ - if (this.type === 3) + if (this.type === bucket.typeid.looped) return spline_cmd(0, this.degrees, this.dimensions, 0, spoints.wrapped(this.degrees), n); return spline_cmd(0, this.degrees, this.dimensions, this.type, spoints, n); diff --git a/source/scripts/engine.js b/source/scripts/engine.js index 674e52f..d4c5256 100644 --- a/source/scripts/engine.js +++ b/source/scripts/engine.js @@ -9,11 +9,50 @@ function load(file) { files[file] = modtime; } +var Cmdline = {}; + +Cmdline.cmds = []; +Cmdline.register_cmd = function(flag, fn, desc) { + Cmdline.cmds.push({ + flag: flag, + fn: fn, + desc: desc + }); +}; + +function cmd_args(cmdargs) +{ + var play = false; + var cmds = cmdargs.split(" "); + + Cmdline.play = false; + + for (var i = 0; i < cmds.length; i++) { + if (cmds[i][0] !== '-') + continue; + + var c = Cmdline.cmds.find(function(cmd) { return cmd.flag === cmds[i].slice(1); }); + if (c && c.fn) + c.fn(); + } + + if (Cmdline.play) + run("scripts/play.js"); + else + run("scripts/editor.js"); +} + +Cmdline.register_cmd("p", function() { Cmdline.play = true; }, "Launch engine in play mode."); +Cmdline.register_cmd("v", function() { Log.warn(cmd(120)); }, "Display engine info."); +Cmdline.register_cmd("c", null, "Redirect logging to console."); +Cmdline.register_cmd("l", null, "Set logging file name."); +Cmdline.register_cmd("h", function() { Log.warn("Helping."); exit();}, "Help."); + function run(file) { - var text = IO.slurp(file); - eval?.(`"use strict";${text}`); - return; +// var text = IO.slurp(file); +// eval?.(`"use strict";${text}`); +// return; var modtime = cmd(119, file); if (modtime === 0) { Log.stack(); @@ -84,6 +123,11 @@ var Log = { load("scripts/diff.js"); +var Physics = { + dynamic: 0, + kinematic: 1, + static: 2, +}; function win_icon(str) { cmd(90, str); @@ -227,7 +271,14 @@ var GUI = { var old = def; def = Object.create(def); - if (def.hovered && pointinbb(def.bb, Mouse.screenpos) || def.selected) { +/* if (pointinbb(def.bb, Mouse.screenpos)) { + Object.assign(def, def.hovered); + def.calc_bb(cursor); + GUI.selected = def; + def.selected = true; + } +*/ + if (def.selected) { Object.assign(def, def.hovered); def.calc_bb(cursor); } @@ -261,6 +312,12 @@ var GUI = { def.items.forEach(function(item,idx) { Object.setPrototypeOf(def.items[idx], def); + + if (def.items[idx-1]) + def.up = def.items[idx-1]; + + if (def.items[idx+1]) + def.down = def.items[idx+1]; }); def.draw = function(pos) { @@ -274,8 +331,37 @@ var GUI = { return def; }, + + input_lmouse_pressed() { + if (GUI.selected) + GUI.selected.action(); + }, + + input_s_pressed() { + if (GUI.selected.down) { + GUI.selected.selected = false; + GUI.selected = GUI.selected.down; + GUI.selected.selected = true; + } + }, + + input_w_pressed() { + if (GUI.selected.up) { + GUI.selected.selected = false; + GUI.selected = GUI.selected.up; + GUI.selected.selected = true; + } + }, + + input_enter_pressed() { + if (GUI.selected) { + GUI.selected.action(); + } + } }; + + GUI.defaults.debug_colors = { bounds: Color.red.slice(), margin: Color.blue.slice(), @@ -501,8 +587,6 @@ var Tween = { nval = defn.ease(nval); obj[target] = tvals[i].lerp(tvals[i+1], nval); - - Log.warn(defn.pct); }; defn.restart = function() { defn.accum = 0; }; @@ -897,7 +981,6 @@ var Register = { if (!this.inloop) fn(); else { - Log.warn("resgieted ..."); this.loopcbs.push(fn); } }, @@ -964,7 +1047,7 @@ function unset_pawn(obj, player = Player.players[0]) { player.uncontrol(obj); } - +Player.players[0].control(GUI); var Signal = { signals: [], @@ -1689,6 +1772,8 @@ var gameobject = { return q_body(7, this.body); }, + on_ground() { return !this.in_air(); }, + name: "gameobject", toString() { return this.name; }, @@ -1732,6 +1817,7 @@ var gameobject = { }, get moi() { return q_body(6, this.body); }, + set moi(x) { set_body(13, this.body, x); }, phys: 2, phys_nuke() { @@ -1968,6 +2054,9 @@ var gameobject = { if (typeof obj.draw === 'function') register_draw(obj.draw,obj); + if (typeof obj.debug === 'function') + register_debug(obj.debug, obj); + obj.components.forEach(function(x) { if (typeof x.collide === 'function') register_collide(1, x.collide, x, obj.body, x.shape); @@ -2169,6 +2258,7 @@ var camera2d = gameobject.clone("camera2d", { }); Yugine.camera = World.spawn(camera2d); +cmd(61, Yugine.camera.id); win_make(Game.title, Game.resolution[0], Game.resolution[1]); //win_icon("icon.png"); diff --git a/source/shaders/slice9_f.glsl b/source/shaders/slice9_f.glsl index d6524a2..d95da96 100644 --- a/source/shaders/slice9_f.glsl +++ b/source/shaders/slice9_f.glsl @@ -2,12 +2,12 @@ in vec2 uv; /* image uv */ in vec4 border; /* uv length of border, normalized to image dimensions; left, bottom, right, top */ -in vec2 scale; /* polygon dimensions / texture dimensions */ +in vec2 scale; /* polygon dimensions ~ texture dimensions */ in vec4 fcolor; out vec4 color; -uniform sampler2d image; +uniform sampler2D image; float map(float value, float min1, float max1, float min2, float max2) { @@ -24,7 +24,7 @@ float processAxis(float coord, float texBorder, float winBorder) return map(coord, 1 - winBorder, 1, 1 - texBorder, 1); } -uv9slice(vec2 uv, vec2 s, vec4 b) +vec2 uv9slice(vec2 uv, vec2 s, vec4 b) { vec2 t = clamp((s * uv - b.xy) / (s - b.xy - b.zw), 0.0, 1.0); return mix(uv * s, 1.0 - s * (1.0 - uv), t); diff --git a/source/shaders/slice9_v.glsl b/source/shaders/slice9_v.glsl index 0e18f8c..6215586 100644 --- a/source/shaders/slice9_v.glsl +++ b/source/shaders/slice9_v.glsl @@ -1,5 +1,7 @@ #version 330 core + + layout (location = 0) in vec2 vert; layout (location = 1) in vec2 vuv; layout (location = 2) in vec4 vborder;