Clean up render; fix delay kills

This commit is contained in:
John Alanbrook 2024-03-22 09:02:10 -05:00
parent 1540da8392
commit 845fc5d4b8
10 changed files with 94 additions and 140 deletions

View file

@ -1402,6 +1402,21 @@ Math.randomint = function(max) { return Math.clamp(Math.floor(Math.random() * ma
/* BOUNDINGBOXES */
var bbox = {};
bbox.overlap = function(box1, box2) {
return (
box1.l > box2.l &&
box1.r < box2.r &&
box1.t < box2.t &&
box1.b > box2.b
);
return (
box1.l > box2.r ||
box1.r < box2.l ||
box1.t > box2.b ||
box1.b < box2.t
);
}
bbox.fromcwh = function(c, wh) {
return {
t: c.y+(wh.y/2),

View file

@ -93,11 +93,14 @@ Object.mixin(os.sprite(true), {
this.del_anim = function() {
sp = undefined;
advance = undefined;
this.del_anim = undefined;
stop();
}
str ??= 0;
var playing = this.anim[str];
if (!playing) return;
var f = 0;
var stop;
function advance() {
if (!sp) this.del_anim();
@ -106,17 +109,23 @@ Object.mixin(os.sprite(true), {
sp.frame = playing.frames[f].rect;
f = (f+1)%playing.frames.length;
if (f === 0) sp.anim_done?.();
sp.gameobject.delay(advance, playing.frames[f].time);
stop = sp.gameobject.delay(advance, playing.frames[f].time);
}
advance();
},
stop() {
this.del_anim?.();
},
set path(p) {
p = Resources.find_image(p);
if (!p) return;
if (p === this.path) return;
this._p = p;
this.del_anime?.();
this.tex(game.texture(p));
this.texture = game.texture(p);
this.tex(this.texture);
var anim = SpriteAnim.make(p);
if (!anim) return;
@ -148,7 +157,7 @@ Object.mixin(os.sprite(true), {
},
dimensions() {
var dim = [this.tex.width(), this.tex.height()];
var dim = [this.texture.width, this.texture.height];
dim.x *= this.frame.w;
dim.y *= this.frame.h;
return dim;
@ -167,8 +176,6 @@ os.sprite(true).make = function(go)
component.sprite = os.sprite(true);
Object.freeze(sprite);
var sprite = component.sprite;
sprite.doc = {
@ -177,16 +184,33 @@ sprite.doc = {
pos: "The offset position of the sprite, relative to its entity."
};
sprite.anchor = function(anch) {
var off = [0,0];
switch(anch) {
case "ll": break;
case "lm": off = [-0.5,0]; break;
case "lr": off = [-1,0]; break;
case "ml": off = [0,-0.5]; break;
case "mm": off = [-0.5,-0.5]; break;
case "mr": off = [-1,-0.5]; break;
case "ul": off = [0,-1]; break;
case "um": off = [-0.5,-1]; break;
case "ur": off = [-1,-1]; break;
}
this.pos = this.dimensions().scale(off);
}
sprite.inputs = {};
sprite.inputs.kp9 = function() { this.pos = this.dimensions().scale([0,0]); };
sprite.inputs.kp8 = function() { this.pos = this.dimensions().scale([-0.5, 0]); };
sprite.inputs.kp7 = function() { this.pos = this.dimensions().scale([-1,0]); };
sprite.inputs.kp6 = function() { this.pos = this.dimensions().scale([0,-0.5]); };
sprite.inputs.kp5 = function() { this.pos = this.dimensions().scale([-0.5,-0.5]); };
sprite.inputs.kp4 = function() { this.pos = this.dimensions().scale([-1,-0.5]); };
sprite.inputs.kp3 = function() { this.pos = this.dimensions().scale([0, -1]); };
sprite.inputs.kp2 = function() { this.pos = this.dimensions().scale([-0.5,-1]); };
sprite.inputs.kp1 = function() { this.pos = this.dimensions().scale([-1,-1]); };
sprite.inputs.kp9 = function() { this.anchor("ll"); }
sprite.inputs.kp8 = function() { this.anchor("lm"); }
sprite.inputs.kp7 = function() { this.anchor("lr"); }
sprite.inputs.kp6 = function() { this.anchor("ml"); }
sprite.inputs.kp5 = function() { this.anchor("mm"); }
sprite.inputs.kp4 = function() { this.anchor("mr"); }
sprite.inputs.kp3 = function() { this.anchor("ur"); }
sprite.inputs.kp2 = function() { this.anchor("um"); }
sprite.inputs.kp1 = function() { this.anchor("ul"); }
Object.seal(sprite);
/* sprite anim returns a data structure for the given file path
@ -796,7 +820,7 @@ component.circle2d = Object.copy(collider2d, {
toString() { return "circle2d"; },
boundingbox() {
return bbox.fromcwh(this.offset.scale(this.gameobject.scale), [this.radius,this.radius]);
return bbox.fromcwh([0,0], [this.radius,this.radius]);
},
hides: ['gameobject', 'id', 'shape', 'scale'],

View file

@ -462,3 +462,8 @@ global.mixin("scripts/physics");
window.title = `Prosperon v${prosperon.version}`;
window.size = [500,500];
window.boundingbox = function() {
var pos = game.camera.pos;
var wh = window.rendersize.scale(game.camera.zoom);
return bbox.fromcwh(pos,wh);
}

View file

@ -641,17 +641,22 @@ JSValue arb2js(cpArbiter *arb)
void phys_run_post(cpSpace *space, JSValue *fn, JSValue *hit)
{
script_call_sym(*fn, 1, hit);
JS_FreeValue(js, *hit);
YughInfo("Run post for %p", fn);
JSValue hh = *hit;
script_call_sym(*fn, 1, &hh);
JS_FreeValue(js, hh);
}
/* TODO: Limitation, cannot handle multiple collision same frame */
int script_phys_cb_begin(cpArbiter *arb, cpSpace *space, gameobject *go)
{
if (!arb_valid(arb)) return 1;
YughInfo("Adding begin callbacks for go %p", go);
if (!JS_IsUndefined(go->cbs.begin) && cpSpaceAddPostStepCallback(space, phys_run_post, &go->cbs.begin, &go->cbs.bhit))
if (!JS_IsUndefined(go->cbs.begin) && cpSpaceAddPostStepCallback(space, phys_run_post, &go->cbs.begin, &go->cbs.bhit)) {
YughInfo("Added begin for %p", &go->cbs.begin);
go->cbs.bhit = arb2js(arb);
}
cpShape *shape1;
cpShape *shape2;

View file

@ -805,6 +805,7 @@ JSC_CCALL(os_make_edge2d,
JSC_SCALL(os_make_texture,
ret = texture2js(texture_from_file(str));
YughInfo("MADE TEXTURE");
JS_SetPropertyStr(js, ret, "path", JS_DupValue(js,argv[0]));
)
@ -1608,8 +1609,13 @@ void ffi_load() {
JS_SetPropertyStr(js, globalThis, "texture", JS_DupValue(js,texture_proto));
sound_proto = JS_NewObject(js);
JS_SetPropertyStr(js,globalThis, "sound_proto", sound_proto);
JS_SetPropertyFunctionList(js, sound_proto, js_sound_funcs, countof(js_sound_funcs));
JS_SetPrototype(js, sound_proto, dsp_node_proto);
JS_FreeValue(js,globalThis);
JS_FreeValue(js,globalThis);
}
void ffi_stop()
{
}

View file

@ -6,6 +6,7 @@
#include "dsp.h"
void ffi_load();
void ffi_stop();
JSValue vec22js(HMM_Vec2 v);
HMM_Vec2 js2vec2(JSValue v);

View file

@ -115,56 +115,12 @@ void capture_screen(int x, int y, int w, int h, const char *path)
int renderMode = LIT;
struct shader *spriteShader = NULL;
struct shader *wireframeShader = NULL;
struct shader *animSpriteShader = NULL;
static struct shader *textShader;
struct rgba editorClearColor = {35,60,92,255};
float shadowLookahead = 8.5f;
struct rgba gridSmallColor = {
.r = 255 * 0.35f,
.g = 255,
.b = 255 * 0.9f
};
struct rgba gridBigColor = {
.r = 255 * 0.92f,
.g = 255 * 0.92f,
.b = 255 * 0.68f
};
float gridScale = 500.f;
float smallGridUnit = 1.f;
float bigGridUnit = 10.f;
float gridSmallThickness = 2.f;
float gridBigThickness = 7.f;
float gridOpacity = 0.3f;
// Debug render modes
bool renderGizmos = false;
bool showGrid = true;
bool renderNav = false;
// Lighting effect flags
bool renderAO = true;
bool renderDynamicShadows = true;
bool renderRefraction = true;
bool renderReflection = true;
///// for editing
struct gameobject *selectedobject = NULL;
char objectName[200] = {'\0'}; // object name buffer
sg_image ddimg;
void opengl_rendermode(enum RenderMode r) {
renderMode = r;
}
sg_pipeline mainpip;
sg_pass_action pass_action = {0};
static struct {
@ -309,47 +265,6 @@ void render_init() {
.data = gif_quad,
});
sg_gif.bind.fs.samplers[0] = sg_make_sampler(&(sg_sampler_desc){});
/*
sg_image_desc shadow_desc = {
.render_target = true,
.width = 1024,
.height = 1024,
.pixel_format = SG_PIXELFORMAT_R32F,
};
sg_image depth_img = sg_make_image(&shadow_desc);
shadow_desc.pixel_format = sapp_depth_format();
ddimg = sg_make_image(&shadow_desc);
sg_shadow.pass = sg_make_pass(&(sg_pass_desc){
.color_attachments[0].image = depth_img,
.depth_stencil_attachment.image = ddimg,
});
sg_shadow.pass_action = (sg_pass_action) {
.colors[0] = { .action=SG_ACTION_CLEAR, .value = {1,1,1,1} } };
sg_shadow.shader = sg_make_shader(shadow_shader_desc(sg_query_backend()));
sg_shadow.pipe = sg_make_pipeline(&(sg_pipeline_desc){
.shader = sg_shadow.shader,
.layout = {
.attrs = {
[0].format = SG_VERTEXFORMAT_FLOAT3,
}
},
.depth = {
.compare = SG_COMPAREFUNC_LESS_EQUAL,
.write_enabled = true,
.pixel_format = sapp_depth_format()
},
.colors[0].pixel_format = SG_PIXELFORMAT_R32F,
.index_type = SG_INDEXTYPE_UINT16,
.cull_mode = SG_CULLMODE_BACK,
});
*/
}
HMM_Vec2 world2screen(HMM_Vec2 pos)
@ -381,28 +296,6 @@ HMM_Vec3 dirl_pos = {4, 100, 20};
#define MODE_EXPAND 4
#define MODE_FULL 5
void full_3d_pass(struct window *window)
{
HMM_Mat4 model = HMM_M4D(1.f);
float scale = 0.08;
model = HMM_MulM4(model, HMM_Scale((HMM_Vec3){scale,scale,scale}));
// Shadow pass
// sg_begin_pass(sg_shadow.pass, &sg_shadow.pass_action);
// sg_apply_pipeline(sg_shadow.pipe);
HMM_Mat4 light_proj = HMM_Orthographic_RH_ZO(-100.f, 100.f, -100.f, 100.f, 1.f, 100.f);
HMM_Mat4 light_view = HMM_LookAt_RH(dirl_pos, (HMM_Vec3){0,0,0}, (HMM_Vec3){0,1,0});
HMM_Mat4 lsm = HMM_MulM4(light_proj, light_view);
HMM_Mat4 subo[2];
subo[0] = lsm;
subo[1] = model;
sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(subo));
}
void openglRender(struct window *window, gameobject *cam, float zoom) {
sg_swapchain sch = sglue_swapchain();
sg_begin_pass(&(sg_pass){
@ -448,7 +341,7 @@ void openglRender(struct window *window, gameobject *cam, float zoom) {
campos.y + camzoom * usesize.y / 2, -10000.f, 10000.f);
hudproj = HMM_Orthographic_LH_ZO(0, usesize.x, 0, usesize.y, -1.f, 1.f);
return;
/* if (gif.rec && (apptime() - gif.timer) > gif.spf) {
sg_begin_pass(&(sg_pass){

View file

@ -20,21 +20,27 @@ void script_startup() {
js = JS_NewContext(rt);
ffi_load();
size_t len;
char *eng = slurp_text("scripts/engine.js", &len);
script_eval("scripts/engine.js", eng);
JSValue v = script_eval("scripts/engine.js", eng);
JS_FreeValue(js,v);
free(eng);
}
static int stopped = 0;
void script_stop()
{
script_evalf("prosperon.quit();");
#if LEAK
JS_FreeContext(js);
JS_FreeRuntime(rt);
#ifndef LEAK
return;
#endif
printf("FREEING CONTEXT\n");
ffi_stop();
JS_FreeContext(js);
script_gc();
JS_FreeRuntime(rt);
js = NULL;
rt = NULL;
}
void script_gc() { JS_RunGC(rt); }
@ -60,16 +66,18 @@ void script_evalf(const char *format, ...)
JSValue script_eval(const char *file, const char *script)
{
JSValue v = JS_Eval(js, script, strlen(script), file, JS_EVAL_FLAGS | JS_EVAL_FLAG_COMPILE_ONLY);
JSValue v = JS_Eval(js, script, strlen(script), file, JS_EVAL_FLAGS);
js_print_exception(v);
return JS_EvalFunction(js, v);
return v;
}
void script_call_sym(JSValue sym, int argc, JSValue *argv) {
if (!JS_IsFunction(js, sym)) return;
JSValue g = JS_GetGlobalObject(js);
JSValue ret = JS_Call(js, sym, JS_GetGlobalObject(js), argc, argv);
js_print_exception(ret);
JS_FreeValue(js, ret);
JS_FreeValue(js,g);
}
void out_memusage(const char *file)

View file

@ -112,6 +112,7 @@ void quickjs_set_dumpout(FILE *f)
//#define DUMP_READ_OBJECT
#ifdef DUMP
#define DUMP_FREE
#define DUMP_MEM
#define DUMP_CLOSURE
#define DUMP_GC

View file

@ -202,7 +202,6 @@ int main(int argc, char **argv) {
signal(SIGFPE, seghandle);
#endif
resources_init();
stm_setup(); /* time */
script_startup();
@ -226,9 +225,6 @@ int main(int argc, char **argv) {
script_evalf("cmd_args('%s');", cmdstr);
out_memusage(".prosperon/jsmem.txt");
script_stop();
return 0;
}