From f535a88453759bf7a6aac31e4bc6e895b1b88595 Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Wed, 17 Apr 2024 06:32:25 -0500 Subject: [PATCH] Add asynchronous web game loading and simple pack --- Makefile | 18 +++++++----- scripts/std.js | 16 ++++++++--- source/engine/jsffi.c | 12 ++++++++ source/engine/resources.c | 60 ++++++++++++++++++++++++++++++--------- source/engine/resources.h | 13 ++------- source/engine/window.c | 2 ++ source/engine/yugine.c | 36 ++++++++++++++++------- 7 files changed, 112 insertions(+), 45 deletions(-) diff --git a/Makefile b/Makefile index aa46658..a752b87 100755 --- a/Makefile +++ b/Makefile @@ -4,6 +4,10 @@ MAKEDIR != pwd # Options # NDEBUG --- build with debugging symbols and logging +ifeq ($(ARCH),) + ARCH != uname -m +endif + CXX:=$(CC) # Temp to strip long emcc paths to just emcc @@ -17,13 +21,13 @@ LD = $(CC) STEAM = steam/sdk STEAMAPI = - ifeq ($(CC), emcc) - LDFLAGS += --preload-file game.zip --preload-file config.js --preload-file game.js + LDFLAGS += -sUSE_WEBGPU --shell-file shell.html CPPFLAGS += -Wbad-function-cast -Wcast-function-type -sSTACK_SIZE=5MB -sALLOW_MEMORY_GROWTH OPT = 0 NDEBUG = 1 AR = emar + ARCH:= wasm endif CCC != $(CC) -v @@ -90,11 +94,7 @@ PKGCMD = tar --directory --exclude="./*.a" --exclude="./obj" -czf $(DISTDIR)/$(D ZIP = .tar.gz UNZIP = cp $(DISTDIR)/$(DIST) $(DESTDIR) && tar xzf $(DESTDIR)/$(DIST) -C $(DESTDIR) && rm $(DESTDIR)/$(DIST) -ifeq ($(ARCH),) - ARCH != uname -m -endif - -INFO :=$(INFO)_$(ARCH) +INFO := $(INFO)_$(ARCH) ifeq ($(OS), Windows_NT) # then WINDOWS PLATFORM := win64 @@ -167,6 +167,9 @@ includeflag := $(addprefix -I, $(includeflag)) WARNING_FLAGS = -Wno-incompatible-function-pointer-types -Wno-incompatible-pointer-types +ifeq ($(INFO),_) + INFO := +endif APP = prosperon NAME = $(APP)$(INFO)$(EXT) SEM != git describe --tags --abbrev=0 @@ -271,6 +274,7 @@ crossmac: Prosperon.icns crossweb: make CC=emcc + mv $(APP).html index.html clean: @echo Cleaning project diff --git a/scripts/std.js b/scripts/std.js index fbde31a..a27a51b 100644 --- a/scripts/std.js +++ b/scripts/std.js @@ -230,7 +230,7 @@ Cmdline.register_order("debug", function() { Cmdline.register_order("play", function(argv) { if (argv[0]) io.chdir(argv[0]); - + game.loadurs(); if (!io.exists(projectfile)) { @@ -267,9 +267,17 @@ Cmdline.register_order("pack", function(str) { packname = str[0]; say(`Packing into ${packname}`); - -// io.pack_engine(packname); - io.chmod(packname, 666); + + io.pack_start(packname); + var files = io.ls('.'); + files = files.filter(f => !f.startsWith('.git')); + files = files.filter(f => !f.startsWith('.nova')); + files = files.filter(f => !f.includes('.DS_Store')); + files = files.filter(f => !f.startsWith('.gitignore')); + say(files); + for (var f of files) + io.pack_add(f); + io.pack_end(); }, "Pack the game into the given name.", "NAME"); Cmdline.register_order("cdb", function(argv) { diff --git a/source/engine/jsffi.c b/source/engine/jsffi.c index c953920..636affe 100644 --- a/source/engine/jsffi.c +++ b/source/engine/jsffi.c @@ -120,6 +120,11 @@ JSValue strarr2js(char **c) return arr; } +JSValue js2strarr(JSValue v) +{ + +} + JSValue number2js(double g) { return JS_NewFloat64(js,g); } double js2number(JSValue v) { double g; @@ -868,6 +873,10 @@ JSValue js_io_chmod(JSContext *js, JSValue this, int argc, JSValue *argv) JSC_SCALL(io_save_qoa, save_qoa(str)) +JSC_SCALL(io_pack_start, pack_start(str)) +JSC_SCALL(io_pack_add, pack_add(str)) +JSC_CCALL(io_pack_end, pack_end()) + static const JSCFunctionListEntry js_io_funcs[] = { MIST_FUNC_DEF(io, exists,1), MIST_FUNC_DEF(io, ls, 0), @@ -881,6 +890,9 @@ static const JSCFunctionListEntry js_io_funcs[] = { MIST_FUNC_DEF(io, slurpbytes, 1), MIST_FUNC_DEF(io, slurpwrite, 2), MIST_FUNC_DEF(io, save_qoa,1), + MIST_FUNC_DEF(io, pack_start, 1), + MIST_FUNC_DEF(io, pack_add, 1), + MIST_FUNC_DEF(io, pack_end, 0) }; JSC_CCALL(debug_draw_gameobject, gameobject_draw_debug(js2gameobject(argv[0]));) diff --git a/source/engine/resources.c b/source/engine/resources.c index 32309e9..fedfeb6 100644 --- a/source/engine/resources.c +++ b/source/engine/resources.c @@ -45,46 +45,57 @@ static mz_zip_archive game_cdb; int LOADED_GAME = 0; uint8_t *gamebuf; +void *zipbuf; + +sfetch_handle_t game_h; static void response_cb(const sfetch_response_t *r) { if (r->fetched) { - mz_zip_reader_init_mem(&game_cdb, r->data.ptr, r->data.size,0); - LOADED_GAME = 1; + zipbuf = malloc(r->data.size); + memcpy(zipbuf, r->data.ptr, r->data.size); + mz_zip_reader_init_mem(&game_cdb, zipbuf, r->data.size,0); + } if (r->finished) { - LOADED_GAME = -1; - if (r->failed) { + LOADED_GAME = 1; + void *buf = sfetch_unbind_buffer(r->handle); + free(buf); + if (r->failed) LOADED_GAME = -1; - } } } void *gamedata; void resources_init() { - /* 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){ + mz_zip_reader_init_mem(&corecdb, core_cdb, core_cdb_len, 0); + +#ifdef __EMSCRIPTEN__ + gamebuf = malloc(8*1024*1024); + game_h = sfetch_send(&(sfetch_request_t){ .path="game.zip", .callback = response_cb, .buffer = { .ptr = gamebuf, - .size = 64*1024*1024 + .size = 8*1024*1024 } }); - */ - mz_zip_reader_init_mem(&corecdb, core_cdb, core_cdb_len, 0); +#else size_t gamesize; - gamedata = slurp_file("game.zip", &gamesize); - mz_zip_reader_init_mem(&game_cdb, gamedata, gamesize, 0); + gamebuf = slurp_file("game.zip", &gamesize); + if (gamebuf) { + mz_zip_reader_init_mem(&game_cdb, gamebuf, gamesize, 0); + free(gamebuf); + return; + } +#endif } char *get_filename_from_path(char *path, int extension) { @@ -163,10 +174,31 @@ char **ls(const char *path) return ls_paths; } +static mz_zip_archive ar; + +void pack_start(const char *name) +{ + memset(&ar, 0, sizeof(ar)); + int status = mz_zip_writer_init_file(&ar, name, 0); + +} + +void pack_add(const char *path) +{ + mz_zip_writer_add_file(&ar, path, path, NULL, 0, MZ_BEST_COMPRESSION); +} + +void pack_end() +{ + mz_zip_writer_finalize_archive(&ar); + mz_zip_writer_end(&ar); +} + #else void fill_extensions(char *paths, const char *path, const char *ext) {}; char **ls(const char *path) { return NULL; } +void pack(const char *name, const char *dir) {} #endif char *str_replace_ext(const char *s, const char *newext) { diff --git a/source/engine/resources.h b/source/engine/resources.h index a6dfba0..96a2cf1 100644 --- a/source/engine/resources.h +++ b/source/engine/resources.h @@ -18,6 +18,9 @@ char **ls(const char *path); int cp(const char *p1, const char *p2); int fexists(const char *path); time_t file_mod_secs(const char *file); +void pack_start(const char *name); +void pack_add(const char *path); +void pack_end(); char *dirname(const char *path); @@ -27,14 +30,4 @@ int slurp_write(const char *txt, const char *filename, size_t len); char *seprint(char *fmt, ...); -static inline void *stbarrdup(void *mem, size_t size, int len) { - void *out = NULL; - arrsetlen(out, len); - memcpy(out,mem,size*len); - return out; -} - -#define arrconcat(a,b) do{for (int i = 0; i < arrlen(b); i++) arrput(a,b[i]);}while(0) -#define arrdup(a) (stbarrdup(a, sizeof(*a), arrlen(a))) - #endif diff --git a/source/engine/window.c b/source/engine/window.c index dad2821..0ae64bb 100644 --- a/source/engine/window.c +++ b/source/engine/window.c @@ -20,6 +20,8 @@ struct window mainwin = { .vsync = 1, .enable_clipboard = 0, .enable_dragndrop = 0, + .size = (HMM_Vec2){640,400}, + .rendersize = (HMM_Vec2){640,400}, }; static struct window *windows = NULL; diff --git a/source/engine/yugine.c b/source/engine/yugine.c index 6dd47ed..db4f8cd 100644 --- a/source/engine/yugine.c +++ b/source/engine/yugine.c @@ -53,8 +53,10 @@ static int sim_play = SIM_PLAY; static int argc; static char **args; -static JSValue c_start; -static JSValue c_process_fn; +static JSValue c_start = JS_UNDEFINED; +static JSValue c_process_fn = JS_UNDEFINED; + +static int PLAYSTART = 0; void c_init() { mainwin.start = 1; @@ -62,13 +64,28 @@ void c_init() { phys2d_init(); render_init(); particle_init(); - script_call_sym(c_start,0,NULL); - JS_FreeValue(js, c_start); + if (!JS_IsUndefined(c_start)) { + script_call_sym(c_start,0,NULL); + JS_FreeValue(js, c_start); + } } void c_frame() { + sfetch_dowork(); +#ifdef __EMSCRIPTEN__ + if (PLAYSTART) + script_call_sym(c_process_fn,0,NULL); + else if (LOADED_GAME) { + PLAYSTART = 1; + printf("LOADED GAME\n"); + script_evalf("cmd_args('play');"); + script_call_sym(c_start,0,NULL); + JS_FreeValue(js, c_start); + window_resize(sapp_width(), sapp_height()); + } +#else script_call_sym(c_process_fn,0,NULL); - fflush(stdout); +#endif } void cleanup() @@ -216,6 +233,7 @@ sapp_desc sokol_main(int argc, char **argv) { stm_setup(); /* time */ script_startup(); +#ifndef __EMSCRIPTEN__ int argsize = 0; for (int i = 0; i < argc; i++) { argsize += strlen(argv[i]); @@ -225,15 +243,13 @@ sapp_desc sokol_main(int argc, char **argv) { char cmdstr[argsize+1]; cmdstr[0] = '\0'; - for (int i = 0; i < argc; i++) - { + for (int i = 0; i < argc; i++) { strcat(cmdstr, argv[i]); if (argc > i+1) strcat(cmdstr, " "); } - - //while (!LOADED_GAME) -// sfetch_dowork(); + script_evalf("cmd_args('%s');", cmdstr); +#endif return start_desc; }