Fix render bug

This commit is contained in:
John Alanbrook 2024-04-10 16:21:46 -05:00
parent 941106ced5
commit 33ac36ae5c
20 changed files with 224 additions and 144 deletions

View file

@ -344,6 +344,20 @@ Object.rkeys = function(o)
return keys;
}
Object.readonly = function(o, name, msg)
{
var tmp = {};
var prop = Object.getOwnPropertyDescriptor(o, name);
if (!prop) {
console.error(`Attempted to make property ${name} readonly, but it doesn't exist on ${o}.`);
return;
}
Object.defineProperty(tmp, name, prop);
prop.get = function() { return tmp[name]; }
prop.set = function() { console.warn(`Attempted to set readonly property ${name}`); }
Object.defineProperty(o, name, prop);
}
Object.extend = function(from)
{
var n = {};

View file

@ -232,23 +232,25 @@ Object.seal(sprite);
loop: true if it should be looped
*/
var animcache = {};
var SpriteAnim = {
make(path) {
var SpriteAnim = {};
SpriteAnim.make = function(path) {
if (animcache[path]) return animcache[path];
var anim;
if (io.exists(path.set_ext(".json")))
if (io.exists(path.set_ext(".ase")))
anim = SpriteAnim.aseprite(path.set_ext(".ase"));
else if (io.exists(path.set_ext(".json")))
anim = SpriteAnim.aseprite(path.set_ext(".json"));
else if (path.ext() === 'gif')
anim = SpriteAnim.gif(path);
else if (path.ext() === 'ase')
anim = SpriteAnim.aseprite(path);
else if (path.ext() === 'gif')
anim = SpriteAnim.gif(path);
else
return undefined;
animcache[path] = anim;
return animcache[path];
},
gif(path) {
};
SpriteAnim.gif = function(path) {
console.info(`making an anim from ${path}`);
var anim = {};
anim.frames = [];
@ -278,9 +280,9 @@ var SpriteAnim = {
dim.y /= frames;
anim.dim = dim;
return {0:anim};
},
};
strip(path, frames, time=0.05) {
SpriteAnim.strip = function(path, frames, time=0.05) {
var anim = {};
anim.frames = [];
anim.path = path;
@ -294,9 +296,9 @@ var SpriteAnim = {
anim.dim = Resources.texture.dimensions(path);
anim.dim.x /= frames;
return anim;
},
};
aseprite(path) {
SpriteAnim.aseprite = function(path) {
function aseframeset2anim(frameset, meta) {
var anim = {};
anim.frames = [];
@ -334,20 +336,18 @@ var SpriteAnim = {
}
return anims;
},
};
validate(anim)
{
SpriteAnim.validate = function(anim) {
if (!Object.isObject(anim)) return false;
if (typeof anim.path !== 'string') return false;
if (typeof anim.dim !== 'object') return false;
return true;
},
};
find(path) {
SpriteAnim.find = function(path) {
if (!io.exists(path + ".asset")) return;
var asset = JSON.parse(io.slurp(path + ".asset"));
},
};
SpriteAnim.doc = 'Functions to create Primum animations from varying sources.';

View file

@ -8,7 +8,6 @@ game.loadurs();
console.info(`window size: ${window.size}, render size: ${window.rendersize}`);
player[0].control(debug);
Register.gui.register(debug.draw, debug);
var show_frame = true;
@ -423,7 +422,7 @@ var editor = {
var depth = 0;
var alldirty = false;
for (var lvl of lvlchain) {
if (!lvl._ed) continue;
if (!lvl._ed?.selectable) continue;
if (alldirty)
lvl._ed.dirty = true;
else {
@ -461,7 +460,7 @@ var editor = {
var mg = physics.pos_query(input.mouse.worldpos(),10);
if (mg) {
if (mg && mg._ed?.selectable) {
var p = mg.path_from(thiso);
render.text(p, input.mouse.screenpos(),1,Color.teal);
}

View file

@ -250,9 +250,15 @@ var gggstart = game.engine_start;
game.engine_start = function(s) {
game.startengine = 1;
gggstart(function() {
global.mixin("scripts/sound.js");
world_start();
go_init();
window.set_icon(os.make_texture("icons/moon.gif"))
Object.readonly(window.__proto__, 'vsync');
Object.readonly(window.__proto__, 'enable_dragndrop');
Object.readonly(window.__proto__, 'enable_clipboard');
Object.readonly(window.__proto__, 'high_dpi');
Object.readonly(window.__proto__, 'sample_count');
s();
}, process);
}
@ -307,9 +313,14 @@ game.timescale = 1;
var eachobj = function(obj,fn)
{
fn(obj);
for (var o in obj.objects)
for (var o in obj.objects) {
if (obj.objects[o] === obj) {
//console.error(`Object ${obj.toString()} is referenced by itself.`);
continue;
}
eachobj(obj.objects[o],fn);
}
}
game.all_objects = function(fn, startobj = world) { eachobj(startobj,fn); };
@ -552,6 +563,7 @@ function world_start() {
world.kill = function() { this.clear(); };
world.phys = 2;
world.zoom = 1;
world._ed = { selectable: false };
game.cam = world;
}

View file

@ -279,6 +279,7 @@ var gameobject = {
var o = ent.objects;
delete ent.objects;
for (var i in o) {
console.info(`creating ${i} on ${ent.toString()}`);
var newur = o[i].ur;
delete o[i].ur;
var n = ent.spawn(ur[newur], o[i]);

View file

@ -1,20 +1,20 @@
input.keycodes = {
259: "backspace",
258: "tab",
257: "enter",
256: "escape",
32: "space",
45: "minus",
256: "escape",
257: "enter",
258: "tab",
259: "backspace",
260: "insert",
261: "delete",
262: "right",
263: "left",
264: "down",
265: "up",
266: "pgup",
267: "pgdown",
268: "home",
269: "end",
263: "left",
265: "up",
262: "right",
265: "down",
260: "insert",
261: "delete",
45: "minus",
};
input.codekeys = {};
@ -117,7 +117,7 @@ prosperon.textinput = function(c){
};
prosperon.mousemove = function(pos, dx){
mousepos = pos;
player[0].mouse_input(modstr() + "move", pos, dx);
player[0].mouse_input("move", pos, dx);
};
prosperon.mousescroll = function(dx){
player[0].mouse_input(modstr() + "scroll", dx);
@ -126,7 +126,7 @@ prosperon.mousedown = function(b){
player[0].raw_input(modstr() + input.mouse.button[b], "pressed");
};
prosperon.mouseup = function(b){
player[0].raw_input(modstr() + input.mouse.button[b], "released");
player[0].raw_input(input.mouse.button[b], "released");
};
input.mouse = {};

View file

@ -1,7 +1,11 @@
var audio = {};
/* This file runs after the audio system is initiated */
var cries = {};
audio.samplerate = dspsound.samplerate();
Object.readonly(audio, 'samplerate');
Object.readonly(audio, 'channels');
Object.readonly(audio, 'buffer_frames');
audio.play = function(file,bus = audio.bus.master) {
file = Resources.find_sound(file);
if (!file) {

View file

@ -250,9 +250,9 @@ Cmdline.register_order("play", function(argv) {
console.info(`Starting game with window size ${window.size} and render ${window.rendersize}.`);
game.engine_start(function() {
global.mixin("scripts/sound.js");
global.app = actor.spawn("game.js");
if (project.icon) window.set_icon(game.texture(project.icon));
render.set_font("fonts/c64.ttf", 8);
game.camera = world.spawn("scripts/camera2d");
});
}, "Play the game present in this folder.");

View file

@ -20,7 +20,7 @@
#include "font.h"
#define v_amt 5000
#define v_amt 500000
struct flush {
sg_shader shader;
@ -372,6 +372,7 @@ void draw_line(HMM_Vec2 *points, int n, struct rgba color, float seg_len, float
.size = sizeof(uint16_t)*i_c
};
if (sg_query_buffer_will_overflow(line_bind.vertex_buffers[0], vr.size) || sg_query_buffer_will_overflow(line_bind.index_buffer, ir.size)) return;
sg_append_buffer(line_bind.vertex_buffers[0], &vr);
sg_append_buffer(line_bind.index_buffer, &ir);

View file

@ -20,7 +20,6 @@ void draw_grid(float width, float span, struct rgba color);
void debug_flush(HMM_Mat4 *view);
void debug_newframe();
void debug_nextpass();
HMM_Vec2 *inflatepoints(HMM_Vec2 *p, float d, int n);

View file

@ -89,9 +89,15 @@ void mYughLog(int category, int priority, int line, const char *file, const char
printf("\n");
}
//if (priority >= LOG_ERROR)
//js_stacktrace();
//raise(SIGINT);
if (priority >= LOG_PANIC) {
js_stacktrace();
#ifdef __WIN32
DebugBreak();
#else
raise(SIGTRAP);
#endif
}
#endif
}

View file

@ -625,7 +625,7 @@ JSC_CCALL(render_line,
JSC_CCALL(render_sprites, sprite_draw_all())
JSC_CCALL(render_models, model_draw_all())
JSC_CCALL(render_emitters, emitters_draw(&useproj))
JSC_CCALL(render_flush, debug_flush(&useproj); text_flush(&useproj))
JSC_CCALL(render_flush, debug_flush(&useproj); text_flush(&useproj); )
JSC_CCALL(render_end_pass,
sg_end_pass();
sg_commit();
@ -823,6 +823,16 @@ static const JSCFunctionListEntry js_console_funcs[] = {
CGETSET_ADD(global, stdout_lvl)
};
JSC_GETSET_GLOBAL(CHANNELS, number)
JSC_GETSET_GLOBAL(BUF_FRAMES, number)
JSC_GETSET_GLOBAL(SAMPLERATE, number)
static const JSCFunctionListEntry js_audio_funcs[] = {
CGETSET_ADD_NAME(global, CHANNELS, channels),
CGETSET_ADD_NAME(global, BUF_FRAMES, buffer_frames),
CGETSET_ADD_NAME(global, SAMPLERATE, samplerate),
};
JSC_CCALL(profile_now, return number2js(stm_now()))
static const JSCFunctionListEntry js_profile_funcs[] = {
@ -1110,6 +1120,11 @@ static JSValue js_window_set_title(JSContext *js, JSValue this, JSValue v)
}
JSC_CCALL(window_get_title, return str2js(js2window(this)->title))
JSC_CCALL(window_set_icon, window_seticon(&mainwin, js2texture(argv[0])))
JSC_GETSET(window, vsync, boolean)
JSC_GETSET(window, enable_clipboard, boolean)
JSC_GETSET(window, enable_dragndrop, boolean)
JSC_GETSET(window, high_dpi, boolean)
JSC_GETSET(window, sample_count, number)
static const JSCFunctionListEntry js_window_funcs[] = {
CGETSET_ADD(window, size),
@ -1117,6 +1132,11 @@ static const JSCFunctionListEntry js_window_funcs[] = {
CGETSET_ADD(window, mode),
CGETSET_ADD(window, fullscreen),
CGETSET_ADD(window, title),
CGETSET_ADD(window, vsync),
CGETSET_ADD(window, enable_clipboard),
CGETSET_ADD(window, enable_dragndrop),
CGETSET_ADD(window, high_dpi),
CGETSET_ADD(window, sample_count),
MIST_FUNC_DEF(window, set_icon, 1)
};
@ -1229,7 +1249,6 @@ JSC_SCALL(dspsound_source,
JSC_CCALL(dspsound_mix, return dsp_node2js(make_node(NULL,NULL,NULL)))
JSC_CCALL(dspsound_master, return dsp_node2js(masterbus))
JSC_CCALL(dspsound_plugin_node, plugin_node(js2dsp_node(argv[0]), js2dsp_node(argv[1]));)
JSC_CCALL(dspsound_samplerate, return number2js(SAMPLERATE))
JSC_SCALL(dspsound_mod, ret = dsp_node2js(dsp_mod(str)))
JSC_SSCALL(dspsound_midi, ret = dsp_node2js(dsp_midi(str, make_soundfont(str2))))
@ -1250,7 +1269,6 @@ static const JSCFunctionListEntry js_dspsound_funcs[] = {
MIST_FUNC_DEF(dspsound, mix, 0),
MIST_FUNC_DEF(dspsound, master, 0),
MIST_FUNC_DEF(dspsound, plugin_node, 2),
MIST_FUNC_DEF(dspsound, samplerate, 0),
MIST_FUNC_DEF(dspsound, midi, 2),
MIST_FUNC_DEF(dspsound, mod, 1)
};
@ -1548,6 +1566,7 @@ void ffi_load() {
QJSGLOBALCLASS(prosperon);
QJSGLOBALCLASS(time);
QJSGLOBALCLASS(console);
QJSGLOBALCLASS(audio);
QJSGLOBALCLASS(profile);
QJSGLOBALCLASS(game);
QJSGLOBALCLASS(gui);

View file

@ -30,6 +30,7 @@
#define MIST_CGETET_HID(name, fgetter, fsetter) MIST_CGETSET_BASE(name, fgetter, fsetter, JS_PROP_CONFIGURABLE)
#define MIST_GET(name, fgetter) { #fgetter , JS_PROP_CONFIGURABLE | JS_PROP_ENUMERABLE, JS_DEF_CGETSET, 0, .u = { .getset = { .get = { .getter = js_##name##_get_##fgetter } } } }
#define CGETSET_ADD_NAME(ID, ENTRY, NAME) MIST_CGETSET_DEF(#NAME, js_##ID##_get_##ENTRY, js_##ID##_set_##ENTRY)
#define CGETSET_ADD(ID, ENTRY) MIST_CGETSET_DEF(#ENTRY, js_##ID##_get_##ENTRY, js_##ID##_set_##ENTRY)
#define CGETSET_ADD_HID(ID, ENTRY) MIST_CGETSET_BASE(#ENTRY, js_##ID##_get_##ENTRY, js_##ID##_set_##ENTRY, JS_PROP_CONFIGURABLE)

View file

@ -295,6 +295,8 @@ void render_init() {
.size = sizeof(crt_quad),
.type = SG_BUFFERTYPE_VERTEXBUFFER,
.usage = SG_USAGE_IMMUTABLE,
.data = SG_RANGE(crt_quad),
.label = "crt vert buffer",
});
}

View file

@ -13,6 +13,10 @@
#define PI 3.14159265
int SAMPLERATE = 44100;
int BUF_FRAMES = 2048;
int CHANNELS = 2;
dsp_node *masterbus = NULL;
void iir_free(struct dsp_iir *iir)
@ -143,10 +147,10 @@ dsp_node *make_node(void *data, void (*proc)(void *data, soundbyte *out, int sam
dsp_node *self = malloc(sizeof(dsp_node));
memset(self, 0, sizeof(*self));
self->data = data;
self->cache = calloc(BUF_FRAMES*CHANNELS*sizeof(soundbyte),1);
self->proc = proc;
self->pass = 0;
self->gain = 1;
self->id = node_count++;
return self;
}

View file

@ -1,9 +1,9 @@
#ifndef DSP_H
#define DSP_H
#define SAMPLERATE 44100
#define BUF_FRAMES 2048 /* At 48k, 128 needed for 240fps consistency */
#define CHANNELS 2
extern int SAMPLERATE;
extern int BUF_FRAMES;
extern int CHANNELS;
#include "sound.h"
#include "cbuf.h"
@ -15,14 +15,13 @@ typedef struct dsp_node {
void (*proc)(void *dsp, soundbyte *buf, int samples); /* processor */
void *data; /* Node specific data to use in the proc function, passed in as dsp */
void (*data_free)(void *data);
soundbyte cache[BUF_FRAMES*CHANNELS]; /* Cached process */
soundbyte *cache;
struct dsp_node **ins; /* Array of in nodes */
struct dsp_node *out; /* node this one is connected to */
int pass; /* True if the filter should be bypassed */
int off; /* True if the filter shouldn't output */
float gain; /* Between 0 and 1, to attenuate this output */
float pan; /* Between -100 and +100, panning left to right in the speakers */
int id;
} dsp_node;
void dsp_init();

View file

@ -137,6 +137,10 @@ void sound_init() {
.buffer_frames = BUF_FRAMES,
.logger.func = sg_logging,
});
SAMPLERATE = saudio_sample_rate();
CHANNELS = saudio_channels();
BUF_FRAMES = saudio_buffer_frames();
}
typedef struct {

View file

@ -15,7 +15,12 @@
#include "sokol/sokol_app.h"
#include "stb_image_resize2.h"
struct window mainwin = {0};
struct window mainwin = {
.sample_count = 1,
.vsync = 1,
.enable_clipboard = 0,
.enable_dragndrop = 0,
};
static struct window *windows = NULL;

View file

@ -23,6 +23,11 @@ struct window {
float aspect;
float raspect;
char *title;
int vsync;
int enable_clipboard;
int enable_dragndrop;
int high_dpi;
int sample_count;
int start;
};
typedef struct window window;

View file

@ -246,6 +246,11 @@ void engine_start(JSValue start, JSValue procfn)
start_desc.height = mainwin.size.y;
start_desc.window_title = mainwin.title;
start_desc.fullscreen = mainwin.fullscreen;
start_desc.swap_interval = mainwin.vsync;
start_desc.enable_dragndrop = mainwin.enable_dragndrop;
start_desc.enable_clipboard = mainwin.enable_clipboard;
start_desc.high_dpi = mainwin.high_dpi;
start_desc.sample_count = mainwin.sample_count;
}
double apptime() { return stm_sec(stm_now()); }