From 92ccb72c0431f52193c899133f8ef0b702de3d84 Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Mon, 30 Oct 2023 22:41:32 +0000 Subject: [PATCH] Add update and physics timings; add instance reversion on save urtype --- scripts/editor.js | 32 ++++++++++++-------- scripts/engine.js | 3 +- scripts/entity.js | 22 +++++++++----- scripts/sound.js | 4 +++ source/engine/debug/debugdraw.c | 2 +- source/engine/debug/log.c | 2 -- source/engine/ffi.c | 4 +-- source/engine/render.c | 6 ++-- source/engine/yugine.c | 52 +++++++++++++++++++++------------ source/engine/yugine.h | 2 +- 10 files changed, 80 insertions(+), 49 deletions(-) diff --git a/scripts/editor.js b/scripts/editor.js index 20ce506..534dc2a 100644 --- a/scripts/editor.js +++ b/scripts/editor.js @@ -629,7 +629,7 @@ var editor = { }, /* Checking to save an entity as a subtype. */ - /* sub is the name of the type; obj is the object to save it as */ + /* sub is the name of the (sub)type; obj is the object to save it as */ saveas_check(sub, obj) { if (!sub) return; obj ??= editor.selectlist[0]; @@ -644,18 +644,20 @@ var editor = { var saveobj = obj.json_obj(); IO.slurpwrite(JSON.stringify(saveobj,null,1), path); - if (obj === editor.edit_level) { - obj.clear(); - var nobj = editor.edit_level.spawn(sub); - editor.selectlist = [nobj]; - return; + if (obj === editor.desktop) { + obj.clear(); + var nobj = editor.edit_level.spawn(sub); + editor.selectlist = [nobj]; + return; + } + editor.edit_level = editor.edit_level.level; } - - var t = obj.transform(); - obj.kill(); + + var t = obj.transform(); editor.unselect(); - obj = editor.load(sub); + obj.kill(); + obj = editor.edit_level.spawn(sub); obj.pos = t.pos; obj.angle = t.angle; } @@ -874,12 +876,18 @@ editor.inputs['C-s'] = function() { Log.warn(`Wrote to file ${path}`); Object.values(saveobj.objects).forEach(function(x) { x._ed.check_dirty(); }); + + Game.objects.forEach(function(x) { + if (x._ed.dirty) return; + x.revert(); + x._ed.check_dirty(); + }); }; editor.inputs['C-s'].doc = "Save selected."; editor.inputs['C-S'] = function() { if (editor.selectlist.length !== 1) return; - saveaspanel.stem = this.selectlist[0].toString(); + saveaspanel.stem = this.selectlist[0].ur; editor.openpanel(saveaspanel); }; editor.inputs['C-S'].doc = "Save selected as."; @@ -1077,7 +1085,7 @@ editor.inputs.mm = function() { var o = editor.try_pick(); if (!o) return; - editor.selectlist = [o]; +// editor.selectlist = [o]; editor.grabselect = [o]; }; editor.inputs['C-mm'] = editor.inputs.mm; diff --git a/scripts/engine.js b/scripts/engine.js index 1500995..8cf1bf1 100644 --- a/scripts/engine.js +++ b/scripts/engine.js @@ -790,7 +790,6 @@ preprimum.gscale = function() { return 1; }; preprimum.pos = [0,0]; preprimum.angle = 0; preprimum.remove_obj = function() {}; -preprimum.instances = []; preprimum.toString = function() { return "preprimum"; }; globalThis.World = preprimum.make(preprimum); globalThis.Primum = World; @@ -800,6 +799,8 @@ Primum.toString = function() { return "Primum"; }; Primum._ed.selectable = false; Primum._ed.check_dirty = function() { }; Primum._ed.dirty = false; +Primum.revert = function(){}; +Primum.ur = undefined; globalThis.World.reparent = function(parent) { Log.warn("Cannot reparent the Primum."); } Game.view_camera(Primum.spawn(ur.camera2d)); } diff --git a/scripts/entity.js b/scripts/entity.js index 3e1651b..4644e25 100644 --- a/scripts/entity.js +++ b/scripts/entity.js @@ -238,7 +238,11 @@ var gameobject = { /* Make a unique object the same as its prototype */ revert() { - Object.merge(this,this.__proto__); + var jobj = this.json_obj(); + delete jobj.objects; + Object.keys(jobj).forEach(function(x) { + this[x] = this.__proto__[x]; + }, this); this.sync(); }, @@ -416,7 +420,10 @@ var gameobject = { Player.do_uncontrol(this); Register.unregister_obj(this); -// ur[this.ur].instances.remove(this); + + if (this.__proto__.instances) + this.__proto__.instances.remove(this); + this.body = -1; for (var key in this.components) { @@ -446,7 +453,8 @@ var gameobject = { obj.make = undefined; obj.level = level; // obj.toJSON = obj.transform_obj; -// this.instances.push(obj); + if (this.instances) + this.instances.push(obj); // Log.warn(`Made an object from ${this.toString()}`); // Log.warn(this.instances.length); obj.body = make_gameobject(); @@ -509,12 +517,10 @@ var gameobject = { obj.sync(); gameobject.check_registers(obj); + if (data) + Object.dainty_assign(obj,data); + if (Game.playing() && typeof obj.start === 'function') obj.start(); -/* obj.objects.forEach(function(obj) { - if (Game.playing() && typeof obj.start === 'function') obj.start(); - }); -*/ - return obj; }, diff --git a/scripts/sound.js b/scripts/sound.js index ee1d9ce..9464637 100644 --- a/scripts/sound.js +++ b/scripts/sound.js @@ -1,3 +1,7 @@ +var Audio = { + +}; + var Music = { play(path) { Log.info("Playing " + path); diff --git a/source/engine/debug/debugdraw.c b/source/engine/debug/debugdraw.c index 5004253..9f94229 100644 --- a/source/engine/debug/debugdraw.c +++ b/source/engine/debug/debugdraw.c @@ -102,7 +102,7 @@ void debug_flush(HMM_Mat4 *view) sg_apply_bindings(&line_bind); sg_apply_uniforms(SG_SHADERSTAGE_VS,0,SG_RANGE_REF(*view)); lfs_params_t lt; - lt.time = appTime; + lt.time = apptime(); sg_apply_uniforms(SG_SHADERSTAGE_FS,0,SG_RANGE_REF(lt)); sg_draw(line_sc,line_c,1); } diff --git a/source/engine/debug/log.c b/source/engine/debug/log.c index 9abd0b3..493881e 100644 --- a/source/engine/debug/log.c +++ b/source/engine/debug/log.c @@ -29,14 +29,12 @@ FILE *logfile = NULL; #define CONSOLE_BUF 1024*1024 /* 5MB */ char *consolelog; -FILE *consolefp; static FILE *sout; void log_init() { consolelog = malloc(CONSOLE_BUF+1); - consolefp = fmemopen(consolelog, CONSOLE_BUF+1,"w"); sout = fdopen(dup(stdout),"w"); sout = stdout; } diff --git a/source/engine/ffi.c b/source/engine/ffi.c index 68d3545..0e1da85 100644 --- a/source/engine/ffi.c +++ b/source/engine/ffi.c @@ -514,7 +514,7 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) break; case 6: -// updateMS = js2number(argv[1]); + updateMS = js2number(argv[1]); break; case 7: @@ -1047,7 +1047,7 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) gif_rec_end(str); break; case 133: - ret = JS_NewFloat64(js, appTime); + ret = JS_NewFloat64(js, apptime()); break; case 134: diff --git a/source/engine/render.c b/source/engine/render.c index deba60b..16235bc 100644 --- a/source/engine/render.c +++ b/source/engine/render.c @@ -56,7 +56,7 @@ void gif_rec_start(int w, int h, int cpf, int bitdepth) gif.cpf = cpf; gif.spf = cpf/100.0; gif.rec = 1; - gif.timer = appTime; + gif.timer = apptime(); if (gif.buffer) free(gif.buffer); gif.buffer = malloc(gif.w*gif.h*4); @@ -548,14 +548,14 @@ void openglRender(struct window *window) { full_2d_pass(window); sg_end_pass(); - if (gif.rec && (appTime - gif.timer) > gif.spf) { + if (gif.rec && (apptime() - gif.timer) > gif.spf) { sg_begin_pass(sg_gif.pass, &pass_action); sg_apply_pipeline(sg_gif.pipe); sg_apply_bindings(&sg_gif.bind); sg_draw(0,6,1); sg_end_pass(); - gif.timer = appTime; + gif.timer = apptime(); sg_query_image_pixels(sg_gif.img, crt_post.bind.fs.samplers[0], gif.buffer, gif.w*gif.h*4); msf_gif_frame(&gif_state, gif.buffer, gif.cpf, gif.depth, gif.w * -4); } diff --git a/source/engine/yugine.c b/source/engine/yugine.c index 3452913..91ce461 100644 --- a/source/engine/yugine.c +++ b/source/engine/yugine.c @@ -54,12 +54,16 @@ static struct d_prof prof_input; static struct d_prof prof_physics; double physlag = 0; - double physMS = 1 / 60.f; +uint64_t physlast = 0; + +double updateMS = 1/60.f; +uint64_t updatelast = 0; static int phys_step = 0; -double appTime = 0; +uint64_t start_t; +uint64_t frame_t; static float timescale = 1.f; @@ -139,6 +143,8 @@ void c_init() { window_set_icon("icons/moon.gif"); window_resize(sapp_width(), sapp_height()); script_evalf("Game.init();"); + + } int frame_fps() { @@ -147,34 +153,34 @@ int frame_fps() { static void process_frame() { - double elapsed = sapp_frame_duration(); - appTime += elapsed; + double elapsed = stm_sec(stm_laptime(&frame_t)); + physlag += elapsed; input_poll(0); + /* Timers all update every frame - once per monitor refresh */ timer_update(elapsed, timescale); - if (sim_play == SIM_PLAY || sim_play == SIM_STEP) { + if (sim_play == SIM_PLAY || sim_play == SIM_STEP && stm_sec(stm_diff(frame_t, updatelast)) > updateMS) { + double dt = stm_sec(stm_diff(frame_t, updatelast)); + updatelast = frame_t; prof_start(&prof_update); - - call_updates(elapsed * timescale); + call_updates(dt * timescale); prof(&prof_update); - physlag += elapsed; - while (physlag >= physMS) { - prof_start(&prof_physics); - phys_step = 1; - physlag -= physMS; - phys2d_update(physMS * timescale); - call_physics(physMS * timescale); - if (sim_play == SIM_STEP) sim_pause(); - phys_step = 0; - prof(&prof_physics); - } - if (sim_play == SIM_STEP) sim_pause(); } + while ((sim_play == SIM_PLAY || sim_play == SIM_STEP) && physlag > physMS) { + physlag -= physMS; + prof_start(&prof_physics); + phys_step = 1; + phys2d_update(physMS * timescale); + call_physics(physMS * timescale); + phys_step = 0; + prof(&prof_physics); + } + prof_start(&prof_draw); window_render(&mainwin); prof(&prof_draw); @@ -338,6 +344,9 @@ int main(int argc, char **argv) { #endif stm_setup(); /* time */ + start_t = frame_t = stm_now(); + physlast = updatelast = start_t; + resources_init(); phys2d_init(); script_startup(); @@ -366,3 +375,8 @@ int main(int argc, char **argv) { return 0; } + +double apptime() +{ + return stm_sec(stm_diff(start_t, stm_now())); +} diff --git a/source/engine/yugine.h b/source/engine/yugine.h index 0d79e27..ba13a36 100644 --- a/source/engine/yugine.h +++ b/source/engine/yugine.h @@ -18,7 +18,7 @@ void app_name(char *name); int frame_fps(); double get_timescale(); -extern double appTime; +double apptime(); extern double renderMS; extern double physMS; extern double updateMS;