From 612111067b13c3579f5e6e8e236e43974e99bd10 Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Fri, 24 Jan 2025 00:04:55 -0600 Subject: [PATCH] fix emitter --- scripts/{particle.js => emitter.js} | 135 +++++++++++++------------ scripts/engine.js | 12 ++- scripts/io.js | 44 +++++++++ scripts/render.js | 44 +++++++-- scripts/std.js | 147 +--------------------------- scripts/stdprofile.js | 8 +- source/jsffi.c | 21 ++-- 7 files changed, 167 insertions(+), 244 deletions(-) rename scripts/{particle.js => emitter.js} (57%) diff --git a/scripts/particle.js b/scripts/emitter.js similarity index 57% rename from scripts/particle.js rename to scripts/emitter.js index b765f8f5..3aa30f1c 100644 --- a/scripts/particle.js +++ b/scripts/emitter.js @@ -2,19 +2,21 @@ var Color = use('color') var ex = {} -var emitter = {}; -emitter.life = 10; -emitter.scale = 1; -emitter.grow_for = 0; -emitter.spawn_timer = 0; -emitter.pps = 0; -emitter.color = Color.white; +ex.emitters = new Set() -emitter.kill = function () { - emitters.remove(this); -}; +ex.garbage = function() +{ + ex.emitters.delete(this) +} -var std_step = function (p) { +ex.update = function(dt) +{ + for (var e of ex.emitters) + try { e.step(dt) } catch(e) { console.error(e) } +} + +ex.step_hook = function(p) +{ if (p.time < this.grow_for) { var s = Math.lerp(0, this.scale, p.time / this.grow_for); p.transform.scale = s; @@ -22,40 +24,10 @@ var std_step = function (p) { var s = Math.lerp(0, this.scale, (p.life - p.time) / this.shrink_for); p.transform.scale = s; } else p.transform.scale = [this.scale, this.scale, this.scale]; -}; +} -emitter.step_hook = std_step; - -emitter.spawn = function (t) { - t ??= this.transform; - - var par = this.dead.shift(); - if (par) { - par.transform.unit(); - par.transform.pos = t.pos; - par.transform.scale = this.scale; - this.particles.push(par); - par.time = 0; - this.spawn_hook?.(par); - par.life = this.life; - return; - } - - par = { - transform: os.make_transform(), - life: this.life, - time: 0, - color: this.color, - body:{}, - }; - - par.transform.scale = this.scale; - this.particles.push(par); - - this.spawn_hook(par); -}; - -emitter.step = function step(dt) { +ex.step = function(dt) +{ // update spawning particles if (this.on && this.pps > 0) { this.spawn_timer += dt; @@ -75,33 +47,46 @@ emitter.step = function step(dt) { if (this.kill_hook?.(p) || p.time >= p.life) { this.die_hook?.(p); this.dead.push(p); - this.particles.remove(p); + this.particles.delete(p); } } - -// for (var p of this.particles) -// p.transform.clean(); -}; - -emitter.burst = function (count, t) { - for (var i = 0; i < count; i++) this.spawn(t); -}; - -var emitters = []; - -ex.make = function make_emitter() { - var e = Object.create(emitter); - e.particles = []; - e.dead = []; - emitters.push(e); - return e; -}; - -ex.update = function update_emitters(dt) { - for (var e of emitters) e.step(dt); } -ex.stat = function stat_emitters() +ex.burst = function(count,t) +{ + for (var i = 0; i < count; i++) this.spawn(t) +} + +ex.spawn = function(t) +{ + t ??= this.transform + + var par = this.dead.shift() + if (par) { + par.transform.unit() + par.transform.pos = t.pos; + par.transform.scale = this.scale; + this.particles.push(par); + par.time = 0; + this.spawn_hook?.(par); + par.life = this.life; + return; + } + + par = { + transform: os.make_transform(), + life: this.life, + time: 0, + color: this.color, + body:{}, + } + + par.transform.scale = this.scale + this.particles.push(par) + this.spawn_hook(par) +} + +ex.stat = function() { var stat = {}; stat.emitters = emitters.length; @@ -111,6 +96,20 @@ ex.stat = function stat_emitters() return stat; } -ex.all = function all_emitters() { return emitters; } +ex.life = 10 +ex.scale = 1 +ex.grow_for = 0 +ex.spawn_timer = 0 +ex.pps = 0 +ex.color = Color.white return ex + +--- + +this.particles = [] +this.dead = [] + +this.transform = this.overling.transform + +$.emitters.add(this) diff --git a/scripts/engine.js b/scripts/engine.js index f7dae30e..f08fbf3f 100644 --- a/scripts/engine.js +++ b/scripts/engine.js @@ -1,5 +1,4 @@ -globalThis.console = os.use('console') -globalThis.prosperon = os.use('prosperon') +globalThis.prosperon = {} var io = os.use('io') os.mem_limit.doc = "Set the memory limit of the runtime in bytes."; @@ -8,6 +7,10 @@ os.max_stacksize.doc = "Set the max stack size in bytes."; globalThis.Resources = {}; +prosperon.SIGINT = function() { + os.exit(); +} + Resources.rm_fn = function rm_fn(fn, text) { var reg = new RegExp(fn.source + "\\s*\\("); var match; @@ -31,8 +34,6 @@ Resources.replpath = function replpath(str, path) { if (!str) return str; if (str[0] === "/") return str.rm(0); - if (str[0] === "@") return os.prefpath() + "/" + str.rm(0); - if (!path) return str; var stem = path.dir(); @@ -53,7 +54,7 @@ Resources.replstrs = function replstrs(path) { var stem = path.dir(); - if (!console.enabled) script = Resources.rm_fn(/console\.(spam|info|warn|error)/, script); +// if (!console.enabled) script = Resources.rm_fn(/console\.(spam|info|warn|error)/, script); /* if (!profile.enabled) script = Resources.rm_fn(/profile\.(cache|frame|endcache|endframe)/, script); if (!debug.enabled) { @@ -284,6 +285,7 @@ console.log = function(msg) } console.error = function(e) { + console.print(e.message) if (!e) e = new Error(); diff --git a/scripts/io.js b/scripts/io.js index 0f63d68b..3886b24f 100644 --- a/scripts/io.js +++ b/scripts/io.js @@ -1,3 +1,10 @@ +/* + io path rules. Starts with, meaning: + "@": user path + "/": root game path + "" : relative game path +*/ + var io = os.use('io') var tmpslurp = io.slurp; @@ -26,10 +33,47 @@ io.glob = function glob(pat) { return allpaths.filter(str => game.glob(pat,str)).sort(); } +/*var ignore; +if (ignore = io.slurp('.prosperonignore')) { + ignore = ignore.split('\n'); + for (var ig of ignore) { + if (!ig) continue; + allpaths = allpaths.filter(x => !x.startsWith(ig)); + } +} +*/ + io.invalidate = function() { allpaths = undefined; } +io.mkpath = function (dir) { + if (!dir) return; + var mkstack = []; + while (!io.exists(dir)) { + mkstack.push(dir.fromlast("/")); + dir = dir.dir(); + } + for (var d of mkstack) { + dir = dir + "/" + d; + say(`making ${dir}`); + io.mkdir(dir); + } +}; + +io.doc = { + doc: "Functions for filesystem input/output commands.", + exists: "Returns true if a file exists.", + slurp: "Returns the contents of given file as a string.", + slurpbytes: "Return the contents of a file as a byte array.", + slurpwrite: "Write a given string to a given file.", + cp: "Copy file f1 to f2.", + mv: "Rename file f1 to f2.", + rm: "Remove file f.", + mkdir: "Make dir.", + ls: "List contents of the game directory.", + glob: "Glob files in game directory.", +}; return io diff --git a/scripts/render.js b/scripts/render.js index 65b5dfb7..2610a25f 100644 --- a/scripts/render.js +++ b/scripts/render.js @@ -5,6 +5,32 @@ var gizmo = use('gizmos') var vector = use('vector') var search = use('search') +var input = use('input') + +var appy = {}; +appy.inputs = {}; +if (os.sys() === "macos") { + appy.inputs["S-q"] = os.exit; +} + +appy.inputs.f7 = function () { + debug.meta = !debug.meta; +}; +appy.inputs.f8 = function () { + debug.cheat = !debug.cheat; +}; +appy.inputs.f9 = function () { + debug.console = !debug.console; +}; +appy.inputs.f10 = function () { + debug.show = !debug.show; +}; + +appy.inputs["M-f4"] = os.exit; + +input.player[0].control(appy); + + prosperon.window = os.engine_start(config); var driver = "vulkan" @@ -870,14 +896,15 @@ render.rectangle = function render_rectangle(rect, color = Color.white, pipeline render.particles = function render_particles(emitter, pipeline = sprite_pipeline) { - if (!emitter.diffuse) throw new Error("emitter does not have a proper diffuse"); + var diff = graphics.texture(emitter.diffuse) + if (!diff) throw new Error("emitter does not have a proper diffuse"); var mesh = render._main.make_sprite_mesh(emitter.particles); if (mesh.num_indices === 0) return; current_queue.push({ type:'geometry', mesh, - image:emitter.diffuse, + image:diff, pipeline, first_index:0, num_indices:mesh.num_indices @@ -1157,7 +1184,7 @@ function screen2hud(pos) * Cameras have a position and rotation. They are not affected by scale. */ -prosperon.make_camera = function make_camera() { +prosperon.make_camera = function (make_camera) { return; /* var cam = world.spawn(); cam.near = 1; @@ -1281,14 +1308,14 @@ var imgui_fn = function imgui_fn() { }; var dmon -try { +/*try { dmon = use('dmon') } catch (e) { console.log(`could not use dmon`) console.error(e) } if (dmon) dmon.watch('.'); - +*/ function dmon_cb(e) { io.invalidate(); @@ -1302,7 +1329,7 @@ function dmon_cb(e) } var sim = use('sim') -var emitters = use('particle') +var emitter = use('emitter') var waittime = 1/240; var last_frame_time = 0; @@ -1331,7 +1358,7 @@ render.process = function process() { prosperon.appupdate(dt) input.procdown() - emitters.update(dt * timescale) + emitter.update(dt * timescale) os.update_timers(dt * timescale) prosperon.update(dt*timescale) @@ -1350,8 +1377,7 @@ render.process = function process() { current_queue = render_queue; prosperon.draw() - for (var e of emitters.all()) - render.particles(e); + emitter.emitters.forEach(e => render.particles(e)) current_queue = hud_queue; prosperon.hud() imgui_fn() diff --git a/scripts/std.js b/scripts/std.js index 07eb5f7e..74ccd451 100644 --- a/scripts/std.js +++ b/scripts/std.js @@ -1,148 +1,6 @@ -os.cwd.doc = "Get the absolute path of the current working directory."; -os.env.doc = "Return the value of the environment variable v."; -if (os.sys() === "windows") os.user = os.env("USERNAME"); -else os.user = os.env("USER"); - -var sim = use('sim') var io = use('io') -var util = use('util') -/*var ignore; -if (ignore = io.slurp('.prosperonignore')) { - ignore = ignore.split('\n'); - for (var ig of ignore) { - if (!ig) continue; - allpaths = allpaths.filter(x => !x.startsWith(ig)); - } -} -*/ - -var appy = {}; -appy.inputs = {}; -if (os.sys() === "macos") { - appy.inputs["S-q"] = os.exit; -} - -appy.inputs.f7 = function () { - debug.meta = !debug.meta; -}; -appy.inputs.f8 = function () { - debug.cheat = !debug.cheat; -}; -appy.inputs.f9 = function () { - debug.console = !debug.console; -}; -appy.inputs.f10 = function () { - debug.show = !debug.show; -}; - -prosperon.toggle_fullscreen = function() -{ - prosperon.fullscreen = !prosperon.fullscreen; - game.fullscreen(); - console.log(`fullscreen is now ${prosperon.fullscreen}`) -} - -appy.inputs.f11 = prosperon.toggle_fullscreen; -appy.inputs.f11.doc = "Toggle window fullscreen."; -appy.inputs.f11.title = "Toggle Fullscreen"; -appy.inputs["M-f4"] = os.exit; - -var input = use('input') - -input.player[0].control(appy); - -os.home = os.env("HOME"); - -/*steam.path = { - windows: `C:/Program Files (x86)/Steam/userdata/${steam.userid}/${steam.appid}`, - macos: `${os.home}/Library/Application Support/Steam/userdata/${steam.userid}/${steam.appid}`, - linux: `${os.home}/.local/share/Steam/userdata/${steam.userid}/${steam.appid}` -}; -*/ - -var otherpath = { - windows: `C:/Users/${os.user}/Saved Games`, - macos: `${os.home}/Library/Application Support`, - linux: `${os.home}/.local/share`, -}; - -os.prefpath = function () { - return otherpath[os.sys()] + "/" + (game.title ? game.title : "Untitled Prosperon Game"); -}; - -os.openurl = function (url) { - if (os.sys() === "windows") os.system(`start ${url}`); - else os.system(`open ${url}`); -}; - -io.dumpfolder = ".prosperon"; - -Resources.texture = {}; -Resources.texture.dimensions = function (path) { - texture.dimensions(path); -}; - -Resources.gif = {}; -Resources.gif.frames = function (path) { - return render.gif_frames(path); -}; - -prosperon.SIGINT = function() { - os.exit(); -} - -/* - io path rules. Starts with, meaning: - "@": user path - "/": root game path - "" : relative game path -*/ - -var tmpchm = io.chmod; -io.chmod = function (file, mode) { - return tmpchm(file, parseInt(mode, 8)); -}; - -io.mkpath = function (dir) { - if (!dir) return; - var mkstack = []; - while (!io.exists(dir)) { - mkstack.push(dir.fromlast("/")); - dir = dir.dir(); - } - for (var d of mkstack) { - dir = dir + "/" + d; - say(`making ${dir}`); - io.mkdir(dir); - } -}; - -var tmpslurpw = io.slurpwrite; -io.slurpwrite = function (path, c) { - path = Resources.replpath(path); -// io.mkpath(path.dir()); - return tmpslurpw(path, c); -}; - -var tmprm = io.rm; -io.rm = function (f) { - tmprm(Resources.replpath(f)); -}; - -io.doc = { - doc: "Functions for filesystem input/output commands.", - exists: "Returns true if a file exists.", - slurp: "Returns the contents of given file as a string.", - slurpbytes: "Return the contents of a file as a byte array.", - slurpwrite: "Write a given string to a given file.", - cp: "Copy file f1 to f2.", - mv: "Rename file f1 to f2.", - rm: "Remove file f.", - mkdir: "Make dir.", - ls: "List contents of the game directory.", - glob: "Glob files in game directory.", -}; +var dumpfolder = ".prosperon"; var Cmdline = {}; @@ -169,7 +27,6 @@ Cmdline.register_order( say("No game to edit. Try making one with 'prosperon init'."); return; } - sim.pause(); }, "Edit the project in this folder. Give it the name of an UR to edit that specific object.", "?UR?", @@ -183,7 +40,7 @@ Cmdline.register_order( return; } - io.mkdir(io.dumpfolder); + io.mkdir(dumpfolder); var project = {}; project.version = prosperon.version; project.revision = prosperon.revision; diff --git a/scripts/stdprofile.js b/scripts/stdprofile.js index 577e059a..0054277e 100644 --- a/scripts/stdprofile.js +++ b/scripts/stdprofile.js @@ -24,17 +24,17 @@ function test_arrays(ta, tb) // test_arrays(ta.slice(0,i), ta.slice(0,i)); //} /* -say(prosperon.guid()); -say(prosperon.guid()); +say(os.guid()); +say(os.guid()); var aa = []; var ao = {}; var amt = 10000; -profile.cpu(_ => prosperon.guid(), 10000, "guid generation"); +profile.cpu(_ => os.guid(), 10000, "guid generation"); profile.cpu(_ => aa.push(1), amt, "add one to array"); -profile.cpu(_ => ao[prosperon.guid()] = 1, amt, "add one via guid"); +profile.cpu(_ => ao[os.guid()] = 1, amt, "add one via guid"); var aos = Object.keys(ao); diff --git a/source/jsffi.c b/source/jsffi.c index 981cdd7d..6a832b6b 100644 --- a/source/jsffi.c +++ b/source/jsffi.c @@ -5449,7 +5449,7 @@ static const JSCFunctionListEntry js_input_funcs[] = { MIST_FUNC_DEF(input, keymod, 0), }; -JSC_CCALL(prosperon_guid, +JSC_CCALL(os_guid, char guid[33]; for (int i = 0; i < 4; i++) { int r = rand(); @@ -5463,12 +5463,12 @@ JSC_CCALL(prosperon_guid, return JS_NewString(js,guid); ) -JSC_SCALL(prosperon_openurl, +JSC_SCALL(os_openurl, if (!SDL_OpenURL(str)) ret = JS_ThrowReferenceError(js, "unable to open url %s: %s\n", str, SDL_GetError()); ) -JSC_CCALL(prosperon_push_event, +JSC_CCALL(os_push_event, SDL_UserEvent e; SDL_zero(e); e.type = SDL_EVENT_USER; @@ -5480,12 +5480,6 @@ JSC_CCALL(prosperon_push_event, SDL_PushEvent(&e); ) -static const JSCFunctionListEntry js_prosperon_funcs[] = { - MIST_FUNC_DEF(prosperon, guid, 0), - MIST_FUNC_DEF(prosperon, openurl, 1), - MIST_FUNC_DEF(prosperon, push_event, 1), -}; - JSC_CCALL(time_now, struct timeval ct; gettimeofday(&ct, NULL); @@ -5571,8 +5565,7 @@ JSC_SCALL(io_rm, if (!PHYSFS_delete(str)) ret = JS_ThrowReferenceError(js,"%s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode())); ) JSC_SCALL(io_mkdir, - if (!PHYSFS_mkdir(str)) ret = JS_ThrowReferenceError(js,"%s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode())); -) + if (!PHYSFS_mkdir(str)) ret = JS_ThrowReferenceError(js,"%s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));) JSC_SCALL(io_exists, ret = JS_NewBool(js,PHYSFS_exists(str)); ) @@ -7194,9 +7187,7 @@ typedef struct { static ModuleEntry module_registry[] = { MISTLINE(io), MISTLINE(input), - MISTLINE(prosperon), MISTLINE(time), - MISTLINE(console), MISTLINE(profile), MISTLINE(debug), MISTLINE(vector), @@ -7263,6 +7254,9 @@ static const JSCFunctionListEntry js_os_funcs[] = { MIST_FUNC_DEF(os, system, 1), MIST_FUNC_DEF(os, exit, 1), MIST_FUNC_DEF(os, gc, 0), + MIST_FUNC_DEF(os, guid, 0), + MIST_FUNC_DEF(os, openurl, 1), + MIST_FUNC_DEF(os, push_event, 1), MIST_FUNC_DEF(os, eval, 2), MIST_FUNC_DEF(os, make_quadtree, 1), MIST_FUNC_DEF(os, make_rtree, 0), @@ -7635,6 +7629,7 @@ void ffi_load(JSContext *js) { QJSCLASSPREP_FUNCS(timer); QJSGLOBALCLASS(os); + QJSGLOBALCLASS(console); JSValue jsarray = JS_GetPropertyStr(js,globalThis, "Array"); JSValue array_proto = JS_GetPropertyStr(js,jsarray, "prototype");