utilize sokol_fetch for game.cdb fetching on load

This commit is contained in:
John Alanbrook 2024-03-04 11:15:55 -06:00
parent 89e3f9b849
commit 6b3cea4ca5
13 changed files with 132 additions and 61 deletions

View file

@ -24,9 +24,6 @@ LEAK ?= 0
INFO := INFO :=
LD = $(CC) LD = $(CC)
#ifeq ($(CC), clang)
# AR = llvm-ar
#endif
ifeq ($(CC), x86_64-w64-mingw32-gcc) ifeq ($(CC), x86_64-w64-mingw32-gcc)
AR = x86_64-w64-mingw32-ar AR = x86_64-w64-mingw32-ar
endif endif
@ -53,6 +50,14 @@ endif
CPPFLAGS += -ffast-math CPPFLAGS += -ffast-math
ifeq ($(CC), emcc)
LDFLAGS += #--closure 1
CPPFLAGS += -O0
OPT = 0
DBG = 0
AR = emar
endif
ifeq ($(DBG),1) ifeq ($(DBG),1)
CPPFLAGS += -g CPPFLAGS += -g
INFO += _dbg INFO += _dbg
@ -123,12 +128,10 @@ ifeq ($(OS), Windows_NT)
UNZIP = unzip -o -q $(DISTDIR)/$(DIST) -d $(DESTDIR) UNZIP = unzip -o -q $(DISTDIR)/$(DIST) -d $(DESTDIR)
else ifeq ($(CC), emcc) else ifeq ($(CC), emcc)
OS := Web 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 CPPFLAGS += -pthread
LDLIBS += pthread quickjs GL openal c m dl LDLIBS += pthread quickjs GL openal c m dl
CC = emcc
EXT = .html EXT = .html
else else
UNAME != uname -s UNAME != uname -s
ifeq ($(UNAME), Linux) ifeq ($(UNAME), Linux)

View file

@ -5,7 +5,7 @@ actor.spawn = function(script, config){
if (typeof script !== 'string') return undefined; if (typeof script !== 'string') return undefined;
if (!a_db[script]) a_db[script] = io.slurp(script); if (!a_db[script]) a_db[script] = io.slurp(script);
var padawan = Object.create(actor); var padawan = Object.create(actor);
eval_env(a_db[script], padawan); eval_env(a_db[script], padawan, script);
if (typeof config === 'object') if (typeof config === 'object')
Object.merge(padawan,config); 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.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.timers = [];
actor.kill = function(){ actor.kill = function(){
if (this.__dead__) return; if (this.__dead__) return;
this.timers.forEach(t => t.kill()); this.timers.forEach(t => t.kill());
if (this.master) if (this.master) this.master.rm_pawn(this);
delete this.master[this.toString()];
this.padawans.forEach(p => p.kill()); this.padawans.forEach(p => p.kill());
this.padawans = []; this.padawans = [];
this.__dead__ = true; this.__dead__ = true;
@ -56,12 +60,6 @@ actor.delay.doc = `Call 'fn' after 'seconds' with 'this' set to the actor.`;
actor.padawans = []; actor.padawans = [];
actor.remaster = function(to){
delete this.master.padawans[this.toString()];
this.master = to;
to.padawans.push(this);
};
global.app = Object.create(actor); global.app = Object.create(actor);
app.die = function() app.die = function()

View file

@ -780,7 +780,7 @@ var resani = function(ur, path)
return restry; return restry;
} }
var ur; global.ur = {};
if (io.exists(".prosperon/ur.json")) if (io.exists(".prosperon/ur.json"))
ur = json.decode(io.slurp(".prosperon/ur.json")); ur = json.decode(io.slurp(".prosperon/ur.json"));
@ -860,26 +860,27 @@ function file2fqn(file)
return ur[fqn]; return ur[fqn];
} }
/* FIND ALL URS IN A PROJECT */ Game.loadurs = function() {
for (var file of io.glob("**.jso")) { ur = {};
if (file[0] === '.' || file[0] === '_') continue; ur._list = [];
var topur = file2fqn(file); /* FIND ALL URS IN A PROJECT */
topur.text = file; 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")) { for (var file of io.glob("**.json")) {
if (file[0] === '.' || file[0] === '_') continue; if (file[0] === '.' || file[0] === '_') continue;
var topur = file2fqn(file); var topur = file2fqn(file);
topur.data = file; topur.data = file;
} }
io.slurpwrite(".prosperon/ur.json", json.encode(ur)); ur.empty = {
name: "empty"
ur.empty = { };
name: "empty"
}; };
return { return {
gameobject, gameobject
ur
} }

View file

@ -65,3 +65,5 @@ shape.circle.points = function(radius, n) {
if (n <= 1) return []; if (n <= 1) return [];
return shape.arc(radius, 360, n); return shape.arc(radius, 360, n);
}; };
return {shape};

View file

@ -37,7 +37,7 @@ var GUI = {
image(path,pos,color) { image(path,pos,color) {
color ??= Color.black; color ??= Color.black;
var wh = cmd(64,path); 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); return bbox.fromcwh([0,0], wh);
}, },

View file

@ -77,7 +77,7 @@ Resources.replpath = function(str, path)
while (stem) { while (stem) {
var tr = stem + "/" +str; var tr = stem + "/" +str;
if (io.exists(tr)) return tr; if (io.exists(tr)) return tr;
stem = steam.updir(); stem = stem.updir();
} }
return str; return str;
@ -219,6 +219,7 @@ io.slurpbytes = function(path)
io.mkpath = function(dir) io.mkpath = function(dir)
{ {
if (!dir) return;
var mkstack = []; var mkstack = [];
while (!io.exists(dir)) { while (!io.exists(dir)) {
mkstack.push(dir.fromlast('/')); mkstack.push(dir.fromlast('/'));
@ -266,14 +267,15 @@ io.mixin({
}, },
glob(pat) { glob(pat) {
var paths = io.ls(); var paths = io.ls('.');
pat = pat.replaceAll(/([\[\]\(\)\^\$\.\|\+])/g, "\\$1"); pat = pat.replaceAll(/([\[\]\(\)\^\$\.\|\+])/g, "\\$1");
pat = pat.replaceAll('**', '.*'); pat = pat.replaceAll('**', '.*');
pat = pat.replaceAll(/[^\.]\*/g, '[^\\/]*'); pat = pat.replaceAll(/[^\.]\*/g, '[^\\/]*');
pat = pat.replaceAll('?', '.'); pat = pat.replaceAll('?', '.');
var regex = new RegExp("^"+pat+"$", ""); 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(); Cmdline.orders.play();
}, "Play the game with debugging enabled."); }, "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)) { if (!io.exists(projectfile)) {
say("No game to play. Try making one with 'prosperon init'."); say("No game to play. Try making one with 'prosperon init'.");
return; return;

View file

@ -1872,14 +1872,14 @@ GETSET_PAIR(emitter, persist, number)
GETSET_PAIR(emitter, persist_var, number) GETSET_PAIR(emitter, persist_var, number)
GETSET_PAIR(emitter, warp_mask, bitmask) 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); emitter *n = js2emitter(this);
start_emitter(n); start_emitter(n);
return JS_UNDEFINED; 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); emitter *n = js2emitter(this);
stop_emitter(n); stop_emitter(n);
@ -1893,10 +1893,15 @@ JSValue js_emitter_emit(JSContext *js, JSValueConst this, int argc, JSValue *arg
return JS_UNDEFINED; 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]; char cwd[PATH_MAX];
#ifndef __EMSCRIPTEN__
getcwd(cwd, sizeof(cwd)); getcwd(cwd, sizeof(cwd));
#else
cwd[0] = '.';
cwd[1] = 0;
#endif
return str2js(cwd); return str2js(cwd);
} }
@ -1909,7 +1914,7 @@ JSValue js_os_env(JSContext *js, JSValueConst this, int argc, JSValue *argv)
return ret; return ret;
} }
JSValue js_os_sys(JSContext *js, JSValueConst this) JSValue js_os_sys(JSContext *js, JSValueConst this, int argc, JSValue *argv)
{ {
#ifdef __linux__ #ifdef __linux__
return str2js("linux"); return str2js("linux");
@ -1935,14 +1940,14 @@ JSValue js_io_exists(JSContext *js, JSValueConst this, int argc, JSValue *argv)
return ret; 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) JSValue js_io_cp(JSContext *js, JSValueConst this, int argc, JSValue *argv)
{ {
char *f1, f2; char *f1, *f2;
f1 = JS_ToCString(js, argv[0]); f1 = JS_ToCString(js, argv[0]);
f2 = JS_ToCString(js, argv[1]); f2 = JS_ToCString(js, argv[1]);
JSValue ret = int2js(cp(f1,f2)); 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) JSValue js_io_mv(JSContext *js, JSValueConst this, int argc, JSValue *argv)
{ {
char *f1, f2; char *f1, *f2;
f1 = JS_ToCString(js, argv[0]); f1 = JS_ToCString(js, argv[0]);
f2 = JS_ToCString(js, argv[1]); f2 = JS_ToCString(js, argv[1]);
JSValue ret = int2js(rename(f1,f2)); JSValue ret = int2js(rename(f1,f2));
@ -1962,6 +1967,14 @@ JSValue js_io_mv(JSContext *js, JSValueConst this, int argc, JSValue *argv)
return ret; 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) JSValue js_io_rm(JSContext *js, JSValueConst this, int argc, JSValue *argv)
{ {
char *file = JS_ToCString(js, argv[0]); 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("cp", 2, js_io_cp),
MIST_CFUNC_DEF("mv", 2, js_io_mv), MIST_CFUNC_DEF("mv", 2, js_io_mv),
MIST_CFUNC_DEF("rm", 1, js_io_rm), 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("mkdir", 1, js_io_mkdir),
MIST_CFUNC_DEF("chmod", 2, js_io_chmod), MIST_CFUNC_DEF("chmod", 2, js_io_chmod),
MIST_CFUNC_DEF("slurp", 1, js_io_slurp), 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; 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)); unplug_node(js2dsp_node(this));
return JS_UNDEFINED; return JS_UNDEFINED;

View file

@ -412,6 +412,7 @@ void full_2d_pass(struct window *window)
pos.y + zoom * window->rheight / 2, -10000.f, 10000.f); 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); hudproj = HMM_Orthographic_LH_ZO(0, window->rwidth, 0, window->rheight, -1.f, 1.f);
sprite_draw_all(); sprite_draw_all();
model_draw_all(); model_draw_all();
call_draw(); call_draw();

View file

@ -21,6 +21,9 @@
#include <ftw.h> #include <ftw.h>
#endif #endif
#define SOKOL_FETCH_IMPL
#include "sokol/sokol_fetch.h"
#include "stb_ds.h" #include "stb_ds.h"
#include "core.cdb.h" #include "core.cdb.h"
@ -35,9 +38,43 @@ char pathbuf[MAXPATH + 1];
static struct cdb corecdb; static struct cdb corecdb;
static struct cdb game_cdb; 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() { void resources_init() {
int fd = open("game.cdb", O_RDONLY); sfetch_setup(&(sfetch_desc_t){
cdb_init(&game_cdb, fd); .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); cdb_initf(&corecdb, core_cdb, core_cdb_len);
} }
@ -106,7 +143,8 @@ char **ls(const char *path)
arrfree(ls_paths); arrfree(ls_paths);
} }
ftw(".", ls_ftw, 10);
ftw(path, ls_ftw, 10);
return ls_paths; return ls_paths;
} }
@ -225,9 +263,11 @@ int mkpath(char *dir, mode_t mode)
if (strlen(dir) == 1 && dir[0] == '/') if (strlen(dir) == 1 && dir[0] == '/')
return 0; return 0;
// mkpath(dirname(strdupa(dir)), mode); #ifdef _WIN32
return mkdir(dir);
return mkdir(dir, mode); #else
return mkdir(dir,mode);
#endif
} }
int slurp_write(const char *txt, const char *filename, size_t len) { 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."); YughError("Cannot pack engine on a web build.");
} }
char **ls(char *path) { return NULL; } char **ls(const char *path) { return NULL; }
#endif #endif

View file

@ -6,6 +6,7 @@
#include "string.h" #include "string.h"
extern char *DATA_PATH; extern char *DATA_PATH;
extern int LOADED_GAME;
void resources_init(); void resources_init();
char *get_filename_from_path(char *path, int extension); char *get_filename_from_path(char *path, int extension);

View file

@ -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_pipeline(pip_sprite);
sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(hudproj)); sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(hudproj));
struct Texture *tex = texture_pullfromfile(img); 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) 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)); sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(hudproj));
struct Texture *tex = texture_pullfromfile(img); struct Texture *tex = texture_pullfromfile(img);
struct glrect r = tex_get_rect(tex); struct glrect r = ST_UNIT;
struct slice9_vert verts[4]; struct slice9_vert verts[4];

View file

@ -285,8 +285,6 @@ struct Texture *texture_fromdata(void *raw, long size)
struct Texture *texture_loadfromfile(const char *path) { return texture_pullfromfile(path); } 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) { HMM_Vec2 tex_get_dimensions(struct Texture *tex) {
if (!tex) return (HMM_Vec2){0,0}; if (!tex) return (HMM_Vec2){0,0};
HMM_Vec2 d; HMM_Vec2 d;

View file

@ -46,6 +46,7 @@
#include "sokol/sokol_audio.h" #include "sokol/sokol_audio.h"
#include "sokol/sokol_time.h" #include "sokol/sokol_time.h"
#include "sokol/sokol_args.h" #include "sokol/sokol_args.h"
#include "sokol/sokol_fetch.h"
#include <stb_ds.h> #include <stb_ds.h>
#include <stb_truetype.h> #include <stb_truetype.h>
#include "stb_image.h" #include "stb_image.h"
@ -153,6 +154,7 @@ void c_frame()
} }
void c_clean() { void c_clean() {
sfetch_shutdown();
gif_rec_end("out.gif"); gif_rec_end("out.gif");
out_memusage(".prosperon/jsmem.txt"); out_memusage(".prosperon/jsmem.txt");
script_stop(); script_stop();
@ -319,6 +321,10 @@ dam->update_activity(dam, &da, NULL, NULL);
strcat(cmdstr, argv[i]); strcat(cmdstr, argv[i]);
if (argc > i+1) strcat(cmdstr, " "); if (argc > i+1) strcat(cmdstr, " ");
} }
while (!LOADED_GAME)
sfetch_dowork();
script_evalf("cmd_args('%s');", cmdstr); script_evalf("cmd_args('%s');", cmdstr);
out_memusage(".prosperon/jsmem.txt"); out_memusage(".prosperon/jsmem.txt");