From 6b3cea4ca50387bd5a65980c98c745aae03d80c2 Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Mon, 4 Mar 2024 11:15:55 -0600 Subject: [PATCH] utilize sokol_fetch for game.cdb fetching on load --- Makefile | 15 ++++++----- scripts/actor.js | 16 +++++------- scripts/entity.js | 37 ++++++++++++++------------- scripts/geometry.js | 2 ++ scripts/gui.js | 2 +- scripts/std.js | 19 +++++++++----- source/engine/jsffi.c | 32 ++++++++++++++++------- source/engine/render.c | 1 + source/engine/resources.c | 54 ++++++++++++++++++++++++++++++++++----- source/engine/resources.h | 1 + source/engine/sprite.c | 4 +-- source/engine/texture.c | 2 -- source/engine/yugine.c | 8 +++++- 13 files changed, 132 insertions(+), 61 deletions(-) diff --git a/Makefile b/Makefile index 15420f7..2279d1b 100755 --- a/Makefile +++ b/Makefile @@ -24,9 +24,6 @@ LEAK ?= 0 INFO := LD = $(CC) -#ifeq ($(CC), clang) -# AR = llvm-ar -#endif ifeq ($(CC), x86_64-w64-mingw32-gcc) AR = x86_64-w64-mingw32-ar endif @@ -53,6 +50,14 @@ endif CPPFLAGS += -ffast-math +ifeq ($(CC), emcc) + LDFLAGS += #--closure 1 + CPPFLAGS += -O0 + OPT = 0 + DBG = 0 + AR = emar +endif + ifeq ($(DBG),1) CPPFLAGS += -g INFO += _dbg @@ -123,12 +128,10 @@ ifeq ($(OS), Windows_NT) UNZIP = unzip -o -q $(DISTDIR)/$(DIST) -d $(DESTDIR) else ifeq ($(CC), emcc) OS := Web - LDFLAGS += -sMIN_WEBGL_VERSION=2 -sMAX_WEBGL_VERSION=2 -pthread -sTOTAL_MEMORY=450MB + LDFLAGS += -sMIN_WEBGL_VERSION=2 -sMAX_WEBGL_VERSION=2 -pthread -sTOTAL_MEMORY=32MB CPPFLAGS += -pthread LDLIBS += pthread quickjs GL openal c m dl - CC = emcc EXT = .html - else UNAME != uname -s ifeq ($(UNAME), Linux) diff --git a/scripts/actor.js b/scripts/actor.js index c37fa52..b5e06b4 100644 --- a/scripts/actor.js +++ b/scripts/actor.js @@ -5,7 +5,7 @@ actor.spawn = function(script, config){ if (typeof script !== 'string') return undefined; if (!a_db[script]) a_db[script] = io.slurp(script); var padawan = Object.create(actor); - eval_env(a_db[script], padawan); + eval_env(a_db[script], padawan, script); if (typeof config === 'object') Object.merge(padawan,config); @@ -20,12 +20,16 @@ actor.spawn = function(script, config){ actor.spawn.doc = `Create a new actor, using this actor as the master, initializing it with 'script' and with data (as a JSON or Nota file) from 'config'.`; +actor.rm_pawn = function(pawn) +{ + this.padawans.remove(pawn); +} + actor.timers = []; actor.kill = function(){ if (this.__dead__) return; this.timers.forEach(t => t.kill()); - if (this.master) - delete this.master[this.toString()]; + if (this.master) this.master.rm_pawn(this); this.padawans.forEach(p => p.kill()); this.padawans = []; this.__dead__ = true; @@ -56,12 +60,6 @@ actor.delay.doc = `Call 'fn' after 'seconds' with 'this' set to the actor.`; actor.padawans = []; -actor.remaster = function(to){ - delete this.master.padawans[this.toString()]; - this.master = to; - to.padawans.push(this); -}; - global.app = Object.create(actor); app.die = function() diff --git a/scripts/entity.js b/scripts/entity.js index d30dcad..02d42dc 100644 --- a/scripts/entity.js +++ b/scripts/entity.js @@ -780,7 +780,7 @@ var resani = function(ur, path) return restry; } -var ur; +global.ur = {}; if (io.exists(".prosperon/ur.json")) ur = json.decode(io.slurp(".prosperon/ur.json")); @@ -860,26 +860,27 @@ function file2fqn(file) return ur[fqn]; } -/* FIND ALL URS IN A PROJECT */ -for (var file of io.glob("**.jso")) { - if (file[0] === '.' || file[0] === '_') continue; - var topur = file2fqn(file); - topur.text = file; -} +Game.loadurs = function() { + ur = {}; + ur._list = []; + /* FIND ALL URS IN A PROJECT */ + for (var file of io.glob("**.jso")) { + if (file[0] === '.' || file[0] === '_') continue; + var topur = file2fqn(file); + topur.text = file; + } -for (var file of io.glob("**.json")) { - if (file[0] === '.' || file[0] === '_') continue; - var topur = file2fqn(file); - topur.data = file; -} + for (var file of io.glob("**.json")) { + if (file[0] === '.' || file[0] === '_') continue; + var topur = file2fqn(file); + topur.data = file; + } -io.slurpwrite(".prosperon/ur.json", json.encode(ur)); - -ur.empty = { - name: "empty" + ur.empty = { + name: "empty" + }; }; return { - gameobject, - ur + gameobject } diff --git a/scripts/geometry.js b/scripts/geometry.js index 5d01462..2d95bbd 100644 --- a/scripts/geometry.js +++ b/scripts/geometry.js @@ -65,3 +65,5 @@ shape.circle.points = function(radius, n) { if (n <= 1) return []; return shape.arc(radius, 360, n); }; + +return {shape}; diff --git a/scripts/gui.js b/scripts/gui.js index 3f99d0a..148a67c 100644 --- a/scripts/gui.js +++ b/scripts/gui.js @@ -37,7 +37,7 @@ var GUI = { image(path,pos,color) { color ??= Color.black; var wh = cmd(64,path); - gui_img(path,pos, [1.0,1.0], 0.0, 0.0, [0.0,0.0], 0.0, Color.black); + gui_img(path,pos, [1.0,1.0], 0.0, false, [0.0,0.0], Color.white); return bbox.fromcwh([0,0], wh); }, diff --git a/scripts/std.js b/scripts/std.js index 62fdf28..62f3cf3 100644 --- a/scripts/std.js +++ b/scripts/std.js @@ -72,12 +72,12 @@ Resources.replpath = function(str, path) return os.prefpath() + "/" + str.rm(0); if (!path) return str; - + var stem = path.dir(); while (stem) { var tr = stem + "/" +str; if (io.exists(tr)) return tr; - stem = steam.updir(); + stem = stem.updir(); } return str; @@ -219,6 +219,7 @@ io.slurpbytes = function(path) io.mkpath = function(dir) { + if (!dir) return; var mkstack = []; while (!io.exists(dir)) { mkstack.push(dir.fromlast('/')); @@ -266,14 +267,15 @@ io.mixin({ }, glob(pat) { - var paths = io.ls(); + var paths = io.ls('.'); pat = pat.replaceAll(/([\[\]\(\)\^\$\.\|\+])/g, "\\$1"); pat = pat.replaceAll('**', '.*'); pat = pat.replaceAll(/[^\.]\*/g, '[^\\/]*'); pat = pat.replaceAll('?', '.'); var regex = new RegExp("^"+pat+"$", ""); - return paths.filter(str => str.match(regex)); + paths = paths.filter(str => str.match(regex)).sort(); + return paths; }, }); @@ -346,7 +348,12 @@ Cmdline.register_order("debug", function() { Cmdline.orders.play(); }, "Play the game with debugging enabled."); -Cmdline.register_order("play", function() { +Cmdline.register_order("play", function(argv) { + if (argv[0]) + io.chdir(argv[0]); + + Game.loadurs(); + if (!io.exists(projectfile)) { say("No game to play. Try making one with 'prosperon init'."); return; @@ -356,7 +363,7 @@ Cmdline.register_order("play", function() { Game.title = project.title; global.mixin("config.js"); if (project.title) Window.title(project.title); - + Game.engine_start(function() { global.mixin("scripts/sound.js"); global.mixin("game.js"); diff --git a/source/engine/jsffi.c b/source/engine/jsffi.c index 4da9e43..201d1c7 100644 --- a/source/engine/jsffi.c +++ b/source/engine/jsffi.c @@ -1872,14 +1872,14 @@ GETSET_PAIR(emitter, persist, number) GETSET_PAIR(emitter, persist_var, number) GETSET_PAIR(emitter, warp_mask, bitmask) -JSValue js_emitter_start (JSContext *js, JSValue this) +JSValue js_emitter_start (JSContext *js, JSValue this, int argc, JSValue *argv) { emitter *n = js2emitter(this); start_emitter(n); return JS_UNDEFINED; } -JSValue js_emitter_stop(JSContext *js, JSValue this) +JSValue js_emitter_stop(JSContext *js, JSValue this, int argc, JSValue *argv) { emitter *n = js2emitter(this); stop_emitter(n); @@ -1893,10 +1893,15 @@ JSValue js_emitter_emit(JSContext *js, JSValueConst this, int argc, JSValue *arg return JS_UNDEFINED; } -JSValue js_os_cwd(JSContext *js, JSValueConst this) +JSValue js_os_cwd(JSContext *js, JSValueConst this, int argc, JSValue *argv) { char cwd[PATH_MAX]; + #ifndef __EMSCRIPTEN__ getcwd(cwd, sizeof(cwd)); + #else + cwd[0] = '.'; + cwd[1] = 0; + #endif return str2js(cwd); } @@ -1909,7 +1914,7 @@ JSValue js_os_env(JSContext *js, JSValueConst this, int argc, JSValue *argv) return ret; } -JSValue js_os_sys(JSContext *js, JSValueConst this) +JSValue js_os_sys(JSContext *js, JSValueConst this, int argc, JSValue *argv) { #ifdef __linux__ return str2js("linux"); @@ -1935,14 +1940,14 @@ JSValue js_io_exists(JSContext *js, JSValueConst this, int argc, JSValue *argv) return ret; } -JSValue js_io_ls(JSContext *js, JSValueConst this) +JSValue js_io_ls(JSContext *js, JSValueConst this, int argc, JSValue *argv) { - return strarr2js(ls(",")); + return strarr2js(ls(".")); } JSValue js_io_cp(JSContext *js, JSValueConst this, int argc, JSValue *argv) { - char *f1, f2; + char *f1, *f2; f1 = JS_ToCString(js, argv[0]); f2 = JS_ToCString(js, argv[1]); JSValue ret = int2js(cp(f1,f2)); @@ -1953,7 +1958,7 @@ JSValue js_io_cp(JSContext *js, JSValueConst this, int argc, JSValue *argv) JSValue js_io_mv(JSContext *js, JSValueConst this, int argc, JSValue *argv) { - char *f1, f2; + char *f1, *f2; f1 = JS_ToCString(js, argv[0]); f2 = JS_ToCString(js, argv[1]); JSValue ret = int2js(rename(f1,f2)); @@ -1962,6 +1967,14 @@ JSValue js_io_mv(JSContext *js, JSValueConst this, int argc, JSValue *argv) return ret; } +JSValue js_io_chdir(JSContext *js, JSValueConst this, int argc, JSValue *argv) +{ + char *path = JS_ToCString(js, argv[0]); + JSValue ret = int2js(chdir(path)); + JS_FreeCString(js,path); + return ret; +} + JSValue js_io_rm(JSContext *js, JSValueConst this, int argc, JSValue *argv) { char *file = JS_ToCString(js, argv[0]); @@ -2036,6 +2049,7 @@ static const JSCFunctionListEntry js_io_funcs[] = { MIST_CFUNC_DEF("cp", 2, js_io_cp), MIST_CFUNC_DEF("mv", 2, js_io_mv), MIST_CFUNC_DEF("rm", 1, js_io_rm), + MIST_CFUNC_DEF("chdir", 1, js_io_chdir), MIST_CFUNC_DEF("mkdir", 1, js_io_mkdir), MIST_CFUNC_DEF("chmod", 2, js_io_chmod), MIST_CFUNC_DEF("slurp", 1, js_io_slurp), @@ -2078,7 +2092,7 @@ JSValue js_dsp_node_plugin(JSContext *js, JSValueConst this, int argc, JSValue * return JS_UNDEFINED; } -JSValue js_dsp_node_unplug(JSContext *js, JSValueConst this) +JSValue js_dsp_node_unplug(JSContext *js, JSValueConst this, int argc, JSValue *argv) { unplug_node(js2dsp_node(this)); return JS_UNDEFINED; diff --git a/source/engine/render.c b/source/engine/render.c index 158f953..1b4e348 100644 --- a/source/engine/render.c +++ b/source/engine/render.c @@ -412,6 +412,7 @@ void full_2d_pass(struct window *window) pos.y + zoom * window->rheight / 2, -10000.f, 10000.f); hudproj = HMM_Orthographic_LH_ZO(0, window->rwidth, 0, window->rheight, -1.f, 1.f); + sprite_draw_all(); model_draw_all(); call_draw(); diff --git a/source/engine/resources.c b/source/engine/resources.c index b6a26de..494043a 100644 --- a/source/engine/resources.c +++ b/source/engine/resources.c @@ -21,6 +21,9 @@ #include #endif +#define SOKOL_FETCH_IMPL +#include "sokol/sokol_fetch.h" + #include "stb_ds.h" #include "core.cdb.h" @@ -35,9 +38,43 @@ char pathbuf[MAXPATH + 1]; static struct cdb corecdb; static struct cdb game_cdb; +extern int LOADED_GAME = 0; +uint8_t *gamebuf; + +static void response_cb(const sfetch_response_t *r) +{ + if (r->fetched) { + cdb_initf(&game_cdb, r->data.ptr, r->data.size); + LOADED_GAME = 1; + } + if (r->finished) { + LOADED_GAME = -1; + if (r->failed) { + printf("NO GAME\n"); + LOADED_GAME = -1; + + } + } +} + void resources_init() { - int fd = open("game.cdb", O_RDONLY); - cdb_init(&game_cdb, fd); + sfetch_setup(&(sfetch_desc_t){ + .max_requests = 1024, + .num_channels = 4, + .num_lanes = 8, + .logger = { .func = sg_logging }, + }); + gamebuf = malloc(64*1024*1024); + + sfetch_handle_t h = sfetch_send(&(sfetch_request_t){ + .path="game.cdb", + .callback = response_cb, + .buffer = { + .ptr = gamebuf, + .size = 64*1024*1024 + } + }); + cdb_initf(&corecdb, core_cdb, core_cdb_len); } @@ -106,7 +143,8 @@ char **ls(const char *path) arrfree(ls_paths); } - ftw(".", ls_ftw, 10); + + ftw(path, ls_ftw, 10); return ls_paths; } @@ -225,9 +263,11 @@ int mkpath(char *dir, mode_t mode) if (strlen(dir) == 1 && dir[0] == '/') return 0; -// mkpath(dirname(strdupa(dir)), mode); - - return mkdir(dir, mode); +#ifdef _WIN32 + return mkdir(dir); +#else + return mkdir(dir,mode); +#endif } int slurp_write(const char *txt, const char *filename, size_t len) { @@ -292,5 +332,5 @@ void pack_engine(const char *fname){ YughError("Cannot pack engine on a web build."); } -char **ls(char *path) { return NULL; } +char **ls(const char *path) { return NULL; } #endif diff --git a/source/engine/resources.h b/source/engine/resources.h index c7cff9f..8827a70 100644 --- a/source/engine/resources.h +++ b/source/engine/resources.h @@ -6,6 +6,7 @@ #include "string.h" extern char *DATA_PATH; +extern int LOADED_GAME; void resources_init(); char *get_filename_from_path(char *path, int extension); diff --git a/source/engine/sprite.c b/source/engine/sprite.c index 3891542..60d608a 100644 --- a/source/engine/sprite.c +++ b/source/engine/sprite.c @@ -240,7 +240,7 @@ void gui_draw_img(const char *img, transform2d t, int wrap, HMM_Vec2 wrapoffset, sg_apply_pipeline(pip_sprite); sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(hudproj)); struct Texture *tex = texture_pullfromfile(img); - tex_draw(tex, transform2d2mat(t), tex_get_rect(tex), color, wrap, wrapoffset, (HMM_Vec2){wrapscale,wrapscale}, (struct rgba){0,0,0,0}, 0); + tex_draw(tex, transform2d2mat(t), ST_UNIT, color, wrap, wrapoffset, (HMM_Vec2){wrapscale,wrapscale}, (struct rgba){0,0,0,0}, 0); } void slice9_draw(const char *img, HMM_Vec2 pos, HMM_Vec2 dimensions, struct rgba color) @@ -249,7 +249,7 @@ void slice9_draw(const char *img, HMM_Vec2 pos, HMM_Vec2 dimensions, struct rgba sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(hudproj)); struct Texture *tex = texture_pullfromfile(img); - struct glrect r = tex_get_rect(tex); + struct glrect r = ST_UNIT; struct slice9_vert verts[4]; diff --git a/source/engine/texture.c b/source/engine/texture.c index 55da3c9..3fb62af 100644 --- a/source/engine/texture.c +++ b/source/engine/texture.c @@ -285,8 +285,6 @@ struct Texture *texture_fromdata(void *raw, long size) struct Texture *texture_loadfromfile(const char *path) { return texture_pullfromfile(path); } -struct glrect tex_get_rect(struct Texture *tex) { return ST_UNIT; } - HMM_Vec2 tex_get_dimensions(struct Texture *tex) { if (!tex) return (HMM_Vec2){0,0}; HMM_Vec2 d; diff --git a/source/engine/yugine.c b/source/engine/yugine.c index e7288ca..58f3649 100644 --- a/source/engine/yugine.c +++ b/source/engine/yugine.c @@ -46,6 +46,7 @@ #include "sokol/sokol_audio.h" #include "sokol/sokol_time.h" #include "sokol/sokol_args.h" +#include "sokol/sokol_fetch.h" #include #include #include "stb_image.h" @@ -153,6 +154,7 @@ void c_frame() } void c_clean() { + sfetch_shutdown(); gif_rec_end("out.gif"); out_memusage(".prosperon/jsmem.txt"); script_stop(); @@ -319,8 +321,12 @@ dam->update_activity(dam, &da, NULL, NULL); strcat(cmdstr, argv[i]); if (argc > i+1) strcat(cmdstr, " "); } - script_evalf("cmd_args('%s');", cmdstr); + while (!LOADED_GAME) + sfetch_dowork(); + + script_evalf("cmd_args('%s');", cmdstr); + out_memusage(".prosperon/jsmem.txt"); script_stop();