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 :=
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)

View file

@ -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()

View file

@ -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
}

View file

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

View file

@ -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);
},

View file

@ -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");

View file

@ -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;

View file

@ -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();

View file

@ -21,6 +21,9 @@
#include <ftw.h>
#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

View file

@ -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);

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_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];

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 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;

View file

@ -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 <stb_ds.h>
#include <stb_truetype.h>
#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();