add tracy as profiler

This commit is contained in:
2024-11-15 03:00:22 -06:00
parent ce8e553fec
commit 0d12002677
21 changed files with 280 additions and 354 deletions

View File

@@ -6,6 +6,7 @@ link = []
if not get_option('editor')
add_project_arguments('-DNEDITOR', language:'c')
add_project_arguments('-DTRACY_ENABLE', language:'c')
endif
add_project_arguments('-Wno-incompatible-function-pointer-types', language: 'c')
@@ -24,8 +25,6 @@ endif
cc = meson.get_compiler('c')
deps += cc.find_library('jemalloc')
if host_machine.system() == 'linux'
deps += cc.find_library('asound', required:true)
deps += [dependency('x11'), dependency('xi'), dependency('xcursor'), dependency('egl'), dependency('gl')]
@@ -47,6 +46,7 @@ deps += dependency('qjs-nota',static:true)
deps += dependency('qjs-miniz',static:true)
deps += dependency('qjs-soloud',static:true)
deps += dependency('qjs-dmon',static:true)
deps += dependency('tracy', static:true)
deps += dependency('threads')
@@ -65,7 +65,6 @@ endif
sources = []
src = ['anim.c', 'config.c', 'datastream.c','font.c','gameobject.c','HandmadeMath.c','jsffi.c','model.c','render.c','script.c','simplex.c','spline.c','texture.c', 'timer.c', 'transform.c','warp.c','yugine.c']
imsrc = ['GraphEditor.cpp','ImCurveEdit.cpp','ImGradient.cpp','imgui_draw.cpp','imgui_tables.cpp','imgui_widgets.cpp','imgui.cpp','ImGuizmo.cpp','imnodes.cpp','implot_items.cpp','implot.cpp']
srceng = 'source'
@@ -99,8 +98,6 @@ endforeach
core = custom_target('core.zip',
output:'core.zip',
command: ['zip', '-r', '-j', '@OUTPUT@'] + zip_paths,
build_by_default: true,
build_always:true
)
prosperon = executable('prosperon', sources,

View File

@@ -4,7 +4,7 @@ var actor_urs = {};
var actor_spawns = {};
globalThis.class_use = function (script, config, base, callback) {
globalThis.class_use = function class_use(script, config, base, callback) {
var file = Resources.find_script(script);
if (!file) {
@@ -27,7 +27,7 @@ globalThis.class_use = function (script, config, base, callback) {
if (callback) callback(padawan);
var script = Resources.replstrs(file);
script = `(function() { var self = this; var $ = this.__proto__; ${script}; })`;
script = `(function use_${file.name()}() { var self = this; var $ = this.__proto__; ${script}; })`;
var fn = os.eval(file, script);
fn.call(padawan);
@@ -59,7 +59,7 @@ actor.__stats = function () {
return stats;
};
actor.hotreload = function (file) {
actor.hotreload = function hotreload(file) {
var script = Resources.replstrs(file);
script = `(function() { var self = this; var $ = this.__proto__;${script};})`;
var fn = os.eval(file, script);

View File

@@ -457,7 +457,7 @@ Object.defHidden = function (obj, prop) {
Object.defineProperty(obj, prop, { enumerable: false, writable: true });
};
Object.hide = function (obj, ...props) {
Object.hide = function hide(obj, ...props) {
for (var prop of props) {
var p = Object.getOwnPropertyDescriptor(obj, prop);
if (!p) continue;
@@ -566,7 +566,7 @@ Object.defineProperty(Object.prototype, "forEach", {
},
});
Object.empty = function (obj) {
Object.empty = function empty(obj) {
return Object.keys(obj).length === 0;
};
@@ -828,10 +828,10 @@ Array.random = function(arr) {
function make_swizz() {
function setelem(n) {
return {
get: function () {
get: function get() {
return this[n];
},
set: function (x) {
set: function set(x) {
this[n] = x;
},
};
@@ -1040,7 +1040,7 @@ Object.defineProperty(Array.prototype, "mapvec", {
});
Object.defineProperty(Array.prototype, "remove", {
value: function (b) {
value: function remove(b) {
var idx = this.indexOf(b);
if (idx === -1) return false;

View File

@@ -1,6 +1,6 @@
var component = {};
var make_point_obj = function (o, p) {
function make_point_obj(o, p) {
return {
pos: p,
move(d) {
@@ -12,7 +12,7 @@ var make_point_obj = function (o, p) {
};
};
var sprite_addbucket = function (sprite) {
function sprite_addbucket(sprite) {
if (!sprite.image) return;
var layer = sprite.z_value();
sprite_buckets[layer] ??= {};
@@ -22,7 +22,7 @@ var sprite_addbucket = function (sprite) {
sprite._oldtex = sprite.image.texture;
};
var sprite_rmbucket = function (sprite) {
function sprite_rmbucket(sprite) {
if (sprite._oldlayer && sprite._oldtex) sprite_buckets[sprite._oldlayer][sprite._oldtex].remove(sprite);
else for (var layer of Object.values(sprite_buckets)) for (var path of Object.values(layer)) path.remove(sprite);
};
@@ -35,14 +35,12 @@ frog = {
...etc
}
*/
function z_value() {return 100000 + this.gameobject.drawlayer * 1000 - this.gameobject.pos.y;}
var sprite = {
image: undefined,
get diffuse() { return this.image.texture; },
set diffuse(x) {},
z_value() {
return 100000 + this.gameobject.drawlayer * 1000 - this.gameobject.pos.y;
},
z_value:z_value,
anim_speed: 1,
play(str, loop = true, reverse = false, fn) {
if (!this.animset) {
@@ -142,7 +140,7 @@ var sprite = {
get path() {
return this._p;
},
kill() {
kill: function kill() {
sprite_rmbucket(this);
this.del_anim?.();
this.anim = undefined;
@@ -150,7 +148,7 @@ var sprite = {
allsprites.remove(this);
},
anchor: [0, 0],
sync() {
sync: function sync() {
var layer = this.z_value();
if (layer === this._oldlayer && this.image.texture === this._oldtex) return;

View File

@@ -120,11 +120,11 @@ Resources.is_path = function (str) {
};
globalThis.json = {};
json.encode = function (value, replacer, space = 1) {
json.encode = function json_encode(value, replacer, space = 1) {
return JSON.stringify(value, replacer, space);
};
json.decode = function (text, reviver) {
json.decode = function json_decode(text, reviver) {
if (!text) return undefined;
return JSON.parse(text, reviver);
};
@@ -308,21 +308,17 @@ globalThis.use = function use(file) {
file = Resources.find_script(file);
if (use_cache[file]) {
profile.report(`use_${file}`);
var ret = use_cache[file]();
profile.endreport(`use_${file}`);
return ret;
}
profile.report(`compile_${file}`);
var script = Resources.replstrs(file);
script = `(function() { var self = this; ${script}; })`;
var fnname = file.replace(/[^a-zA-Z0-9_$]/g, "_");
script = `(function ${fnname}() { var self = this; ${script}; })`;
var fn = os.eval(file, script);
use_cache[file] = fn;
profile.endreport(`compile_${file}`);
profile.report(`use_${file}`);
var ret = fn();
profile.endreport(`use_${file}`);
return ret;
};
@@ -330,14 +326,14 @@ globalThis.use = function use(file) {
var allpaths = io.ls();
io.exists = function(path)
{
return allpaths.includes(path) || core_db.exists(path);
return allpaths.includes(path);// || core_db.exists(path);
}
var tmpslurp = io.slurp;
io.slurp = function(path)
io.slurp = function slurp(path)
{
var findpath = Resources.replpath(path);
var ret = tmpslurp(findpath, true) || core_db.slurp(findpath, true);
var ret = tmpslurp(findpath, true); //|| core_db.slurp(findpath, true);
if (!ret) console.info(`could not slurp path ${path} as ${findpath}`)
return ret;
}
@@ -345,7 +341,7 @@ io.slurp = function(path)
io.slurpbytes = function(path)
{
path = Resources.replpath(path);
var ret = tmpslurp(path) || core_db.slurp(path);
var ret = tmpslurp(path);// || core_db.slurp(path);
if (!ret) throw new Error(`Could not find file ${path} anywhere`);
return ret;
}
@@ -359,10 +355,10 @@ if (ignore) {
}
}
var coredata = tmpslurp("core.zip");
var core_db = miniz.read(coredata);
//var coredata = tmpslurp("core.zip");
//var core_db = miniz.read(coredata);
io.globToRegex = function (glob) {
io.globToRegex = function globToRegex(glob) {
// Escape special regex characters
// Replace glob characters with regex equivalents
let regexStr = glob
@@ -379,7 +375,7 @@ io.globToRegex = function (glob) {
return new RegExp(regexStr);
};
io.glob = function(pat) {
io.glob = function glob(pat) {
var regex = io.globToRegex(pat);
return allpaths.filter(str => str.match(regex)).sort();
}
@@ -393,7 +389,7 @@ function stripped_use(file, script) {
}
script ??= Resources.replstrs(file);
script = `(function() { var self = this; ${script}; })`;
script = `(function () { var self = this; ${script}; })`;
var fn = os.eval(file, script);
var ret = fn();
@@ -403,7 +399,8 @@ function stripped_use(file, script) {
function bare_use(file) {
var script = io.slurp(file);
if (!script) return;
script = `(function() { var self = this; ${script}; })`;
var fnname = file.replace(/[^a-zA-Z0-9_$]/g, "_");
script = `(function ${fnname}() { var self = this; ${script}; })`;
Object.assign(globalThis, os.eval(file, script)());
}
@@ -413,8 +410,8 @@ profile.enabled = true;
console.enabled = true;
debug.enabled = true;
bare_use("base.js");
bare_use("profile.js");
bare_use("core/scripts/base.js");
bare_use("core/scripts/profile.js");
prosperon.release = function () {
profile.enabled = false;
@@ -422,9 +419,9 @@ prosperon.release = function () {
debug.enabled = false;
};
bare_use("preconfig.js");
bare_use("core/scripts/preconfig.js");
if (!profile.enabled) use = stripped_use;
Object.assign(globalThis, use("prosperon.js"));
Object.assign(globalThis, use("core/scripts/prosperon.js"));

View File

@@ -124,7 +124,6 @@ var entity = {
},
spawn(text, config, callback) {
profile.report(`make_${text}`);
var ent = class_use(text, config, entity, function (ent) {
ent.transform = os.make_transform();
ent.guid = prosperon.guid();
@@ -220,8 +219,6 @@ var entity = {
ent.ur.fresh.objects = {};
// for (var i in ent.objects) ent.ur.fresh.objects[i] = ent.objects[i].instance_obj();
profile.endreport(`make_${text}`);
return ent;
},

View File

@@ -67,7 +67,7 @@ function modstr() {
return s;
}
prosperon.keydown = function (key, repeat) {
prosperon.keydown = function keydown(key, repeat) {
downkeys[key] = true;
if (key == 341 || key == 345) mod.ctrl = 1;
@@ -81,7 +81,7 @@ prosperon.keydown = function (key, repeat) {
}
};
prosperon.keyup = function (key) {
prosperon.keyup = function keyup(key) {
delete downkeys[key];
if (key == 341 || key == 345) mod.ctrl = 0;
@@ -109,43 +109,43 @@ prosperon.mousemove = function (pos, dx) {
mousepos = pos;
player[0].mouse_input("move", pos, dx);
};
prosperon.mousescroll = function (dx) {
prosperon.mousescroll = function mousescroll(dx) {
player[0].mouse_input(modstr() + "scroll", dx);
};
prosperon.mousedown = function (b) {
prosperon.mousedown = function mousedown(b) {
player[0].raw_input(modstr() + input.mouse.button[b], "pressed");
downkeys[input.mouse.button[b]] = true;
};
prosperon.mouseup = function (b) {
prosperon.mouseup = function mouseup(b) {
player[0].raw_input(input.mouse.button[b], "released");
delete downkeys[input.mouse.button[b]];
};
input.mouse = {};
input.mouse.screenpos = function () {
input.mouse.screenpos = function mouse_screenpos() {
return mousepos.slice();
};
input.mouse.worldpos = function () {
input.mouse.worldpos = function mouse_worldpos() {
return prosperon.camera.screen2world(mousepos);
};
input.mouse.viewpos = function()
input.mouse.viewpos = function mouse_viewpos()
{
var world = input.mouse.worldpos();
return mousepos.slice();
}
input.mouse.disabled = function () {
input.mouse.disabled = function mouse_disabled() {
input.mouse_mode(1);
};
input.mouse.normal = function () {
input.mouse.normal = function mouse_normal() {
input.mouse_mode(0);
};
input.mouse.mode = function (m) {
input.mouse.mode = function mouse_mode(m) {
if (input.mouse.custom[m]) input.cursor_img(input.mouse.custom[m]);
else input.mouse_cursor(m);
};
input.mouse.set_custom_cursor = function (img, mode = input.mouse.cursor.default) {
input.mouse.set_custom_cursor = function mouse_cursor(img, mode = input.mouse.cursor.default) {
if (!img) delete input.mouse.custom[mode];
else {
input.cursor_img(img);
@@ -218,7 +218,7 @@ joysticks["wasd"] = {
dx: "a",
};
input.procdown = function () {
input.procdown = function procdown() {
for (var k in downkeys) player[0].raw_input(keyname_extd(k), "down");
for (var i in joysticks) {
@@ -229,7 +229,7 @@ input.procdown = function () {
}
};
input.print_md_kbm = function (pawn) {
input.print_md_kbm = function print_md_kbm(pawn) {
if (!("inputs" in pawn)) return;
var str = "";
@@ -259,7 +259,7 @@ input.action = {
actions: [],
};
input.tabcomplete = function (val, list) {
input.tabcomplete = function tabcomplete(val, list) {
if (!val) return val;
list.dofilter(function (x) {
return x.startsWith(val);

View File

@@ -22,7 +22,7 @@ var root_config;
var boxes = [];
globalThis.clay = {};
clay.normalizeSpacing = function(spacing) {
clay.normalizeSpacing = function normalizeSpacing(spacing) {
if (typeof spacing === 'number') {
return {l: spacing, r: spacing, t: spacing, b: spacing};
} else if (Array.isArray(spacing)) {
@@ -38,7 +38,7 @@ clay.normalizeSpacing = function(spacing) {
}
}
clay.draw = function(size, fn)
clay.draw = function draw(size, fn)
{
lay_ctx.reset();
boxes = [];
@@ -118,7 +118,7 @@ function image_size(img)
return [img.rect[2]*img.texture.width, img.rect[3]*img.texture.height];
}
var add_item = function(config)
function add_item(config)
{
// Normalize the child's margin
var margin = clay.normalizeSpacing(config.margin || 0);
@@ -177,7 +177,7 @@ function rectify_configs(config_array)
return cleanobj;
}
clay.image = function(path, ...configs)
clay.image = function image(path, ...configs)
{
var config = rectify_configs(configs);
var image = game.texture(path);
@@ -186,7 +186,7 @@ clay.image = function(path, ...configs)
add_item(config);
}
clay.text = function(str, ...configs)
clay.text = function text(str, ...configs)
{
var config = rectify_configs(configs);
var tsize = render.text_size(str, config.font);
@@ -208,7 +208,7 @@ var button_base = Object.assign(Object.create(clay_base), {
hovered:{
}
});
clay.button = function(str, action, config = {})
clay.button = function button(str, action, config = {})
{
config.__proto__ = button_base;
config.size = render.text_size(str,config.font);
@@ -219,7 +219,7 @@ clay.button = function(str, action, config = {})
var hovered = undefined;
layout.newframe = function() { hovered = undefined; }
layout.draw_commands = function(cmds, pos = [0,0])
layout.draw_commands = function draw_commands(cmds, pos = [0,0])
{
var mousepos = prosperon.camera.screen2hud(input.mouse.screenpos());
for (var cmd of cmds) {
@@ -249,7 +249,7 @@ layout.draw_commands = function(cmds, pos = [0,0])
}
}
layout.draw_debug = function(cmds, pos = [0,0])
layout.draw_debug = function draw_debug(cmds, pos = [0,0])
{
for (var cmd of cmds) {
render.rectangle(cmd.content, [1,0,0,0.1]);

View File

@@ -53,7 +53,7 @@ emitter.spawn = function (t) {
this.spawn_hook(par);
};
emitter.step = function (dt) {
emitter.step = function step(dt) {
// update spawning particles
if (this.on && this.pps > 0) {
this.spawn_timer += dt;

View File

@@ -328,7 +328,7 @@ profile.report = function(path)
profile.reports[path].st = profile.now();
}
profile.endreport = function(path)
profile.endreport = function endreport(path)
{
var rep = profile.reports[path];
if (!rep || !rep.st) return;

View File

@@ -1,6 +1,6 @@
globalThis.gamestate = {};
global.check_registers = function (obj) {
global.check_registers = function check_registers(obj) {
for (var reg in Register.registries) {
if (!Register.registries[reg].register) return;
if (typeof obj[reg] === "function") {
@@ -80,7 +80,7 @@ prosperon.init = function () {
render.init();
imgui.init();
// global.mixin("sound.js");
globalThis.audio = use("sound.js");
world_start();
prosperon.camera = prosperon.make_camera();
prosperon.camera.transform.pos = [0, 0, -100];
@@ -184,7 +184,7 @@ function calc_image_size(img)
return [img.texture.width*img.rect.width, img.texture.height*img.rect.height];
}
game.tex_hotreload = function (file) {
game.tex_hotreload = function tex_hotreload(file) {
if (!(file in game.texture.cache)) return;
var data = io.slurpbytes(file);
var tex;
@@ -330,7 +330,7 @@ game.is_image = function(obj)
}
// Any request to it returns an image, which is a texture and rect. But they can
game.texture = function (path) {
game.texture = function texture(path) {
if (typeof path !== 'string') throw new Error('need a string for game.texture')
var parts = path.split(':');
path = Resources.find_image(parts[0]);
@@ -362,7 +362,7 @@ game.texture = function (path) {
if (!io.exists(path)) {
console.error(`Missing texture: ${path}`);
game.texture.cache[path] = game.texture("no_tex.gif");
game.texture.cache[path] = game.texture("core/icons/no_tex.gif");
game.texture.time_cache[path] = io.mod(path);
return game.texture.cache[path];
}
@@ -547,10 +547,7 @@ var Register = {
var guid = prosperon.guid();
var dofn = function (...args) {
profile.report(`call_${name}_${oname}`);
var st = profile.now();
fn(...args);
profile.endreport(`call_${name}_${oname}`);
};
var left = 0;
@@ -576,13 +573,12 @@ var Register = {
if (!flush) {
prosperon[name] = function (...args) {
profile.report(name);
// profile.fiber_enter(vector.fib);
fns.forEach(fn => fn(...args));
profile.endreport(name);
// profile.fiber_leave(vector.fib);
};
} else
prosperon[name] = function (...args) {
profile.report(name);
prosperon[name] = function name(...args) {
var layer = undefined;
for (var fn of fns) {
if (layer !== fn.layer) {
@@ -591,7 +587,6 @@ var Register = {
}
fn();
}
profile.endreport(name);
};
prosperon[name].fns = fns;

View File

@@ -1,7 +1,7 @@
var unit_transform = os.make_transform();
/*
Anatomy of rendering an image
Anatomy of rendpering an image
render.image(path)
Path can be a file like "toad"
If this is a gif, this would display the entire range of the animation
@@ -351,7 +351,7 @@ function strip_shader_inputs(shader) {
for (var a of shader.vs.inputs) a.name = a.name.slice(2);
}
render.hotreload = function () {
render.hotreload = function shader_hotreload() {
for (var i in shader_times) {
if (io.mod(i) <= shader_times[i]) continue;
say(`HOT RELOADING SHADER ${i}`);
@@ -490,8 +490,6 @@ function make_shader(shader, pipe) {
return obj;
}
profile.report(`shader_${file}`);
var compiled = create_shader_obj(file);
io.slurpwrite(writejson, json.encode(compiled));
var obj = compiled[os.sys()];
@@ -499,8 +497,6 @@ function make_shader(shader, pipe) {
shader_cache[file] = obj;
shader_times[file] = io.mod(file);
profile.endreport(`shader_${file}`);
return obj;
}
@@ -737,8 +733,6 @@ render.sprites = function render_sprites() {
}
*/
profile.report("sprites");
profile.report("drawing");
render.use_shader(spritessboshader);
var buckets = component.sprite_buckets();
for (var l in buckets) {
@@ -752,8 +746,6 @@ render.sprites = function render_sprites() {
render.draw(shape.quad, sprite_ssbo, sparray.length);
}
}
profile.endreport("drawing");
profile.endreport("sprites");
};
render.circle = function render_circle(pos, radius, color, inner_radius = 1) {
@@ -1069,7 +1061,7 @@ render.images = function(image, rects, rotations, colors)
var slice9_t = os.make_transform();
// pos is the lower left corner, scale is the width and height
// slice is given in pixels
render.slice9 = function (image, rect = [0,0], slice = 0, color = Color.white) {
render.slice9 = function slice9(image, rect = [0,0], slice = 0, color = Color.white) {
if (typeof image === 'string')
image = game.texture(image);
@@ -1104,7 +1096,7 @@ var textssbos = [];
var tdraw = 0;
var cur_font = undefined;
render.flush_text = function () {
render.flush_text = function flush_text() {
if (!render.textshader) return;
tdraw++;
if (textssbos.length < tdraw) textssbos.push(render.make_textssbo());
@@ -1124,7 +1116,7 @@ render.flush_text = function () {
var fontcache = {};
var datas= [];
render.get_font = function(path,size)
render.get_font = function get_font(path,size)
{
var parts = path.split('.');
if (!isNaN(parts[1])) {
@@ -1147,9 +1139,7 @@ render.rectangle.doc = "Draw a rectangle, with its corners at lowerleft and uppe
render.draw = function render_draw(mesh, ssbo, inst = 1, e_start = 0) {
sg_bind(mesh, ssbo);
profile.report("gpu_draw");
render.spdraw(e_start, cur.bind.count, inst);
profile.endreport("gpu_draw");
};
// Camera viewport is a rectangle with the bottom left corner defined as x,y. Units are pixels on the window.
@@ -1252,7 +1242,7 @@ function camextents() {
screen2cam.doc = "Convert a screen space position in pixels to a normalized viewport position in a camera.";
prosperon.gizmos = function () {
prosperon.gizmos = function gizmos() {
game.all_objects(o => {
if (o.gizmo) render.image(game.texture(o.gizmo), o.pos);
});
@@ -1266,7 +1256,7 @@ function screen2hud(pos)
return campos;
}
prosperon.make_camera = function () {
prosperon.make_camera = function make_camera() {
var cam = world.spawn();
cam.near = 1;
cam.far = -1000;
@@ -1294,7 +1284,7 @@ globalThis.imtoggle = function (name, obj, field) {
};
var replstr = "";
var imdebug = function () {
var imdebug = function imdebug() {
imtoggle("Physics", debug, "draw_phys");
imtoggle("Bouning boxes", debug, "draw_bb");
imtoggle("Gizmos", debug, "draw_gizmos");
@@ -1304,7 +1294,7 @@ var imdebug = function () {
imtoggle("Show ur names", debug, "urnames");
};
var imgui_fn = function () {
var imgui_fn = function imgui_fn() {
imgui.newframe(prosperon.size.x, prosperon.size.y, 0.01);
if (debug.console)
debug.console = imgui.window("console", _ => {
@@ -1377,7 +1367,7 @@ var imgui_fn = function () {
prosperon.window_render(basesize.scale(mult));
*/
prosperon.render = function () {
prosperon.render = function prosperon_render() {
try{
render.glue_pass();
render.set_view(prosperon.camera.transform);
@@ -1421,14 +1411,11 @@ try{
prosperon.app();
render.forceflush();
profile.report("imgui");
if (debug.show) imgui_fn();
profile.endreport("imgui");
} catch(e) {
throw e;
} finally {
render.end_pass();
profile.report_frame(profile.secs(profile.now()) - frame_t);
render.commit();
endframe();
}
@@ -1439,7 +1426,6 @@ dmon.watch('.');
function dmon_cb(e)
{
if (e.file.startsWith('.')) return;
console.info(json.encode(e))
if (e.file.endsWith('.js'))
actor.hotreload(e.file);
else if (Resources.is_image(e.file))
@@ -1453,32 +1439,17 @@ prosperon.process = function process() {
layout.newframe();
// check for hot reloading
dmon.poll(dmon_cb);
profile.report("frame");
var dt = profile.secs(profile.now()) - frame_t;
frame_t = profile.secs(profile.now());
var sst = profile.now();
/* debugging: check for gc */
profile.print_gc();
var cycles = os.check_cycles();
if (cycles) say(cycles);
profile.report("app update");
prosperon.appupdate(dt);
profile.endreport("app update");
profile.report("input");
input.procdown();
profile.endreport("input");
if (sim.mode === "play" || sim.mode === "step") {
profile.report("update");
prosperon.update(dt * game.timescale);
update_emitters(dt * game.timescale);
os.update_timers(dt * game.timescale);
profile.endreport("update");
if (sim.mode === "step") sim.pause();
}
@@ -1486,7 +1457,7 @@ prosperon.process = function process() {
sst = profile.now();
if (sim.mode === "play" || sim.mode === "step") {
/* profile.report("physics");
/*
physlag += dt;
while (physlag > physics.delta) {
@@ -1495,19 +1466,12 @@ prosperon.process = function process() {
prosperon.physupdate(physics.delta * game.timescale);
}
profile.endreport("physics");
profile.pushdata(profile.data.cpu.physics, profile.now() - sst);
sst = profile.now();
*/
}
profile.report("render");
prosperon.render();
profile.endreport("render");
profile.pushdata(profile.data.cpu.render, profile.now() - sst);
profile.endreport('frame');
profile.capture_data();
};
return { render };

View File

@@ -1,93 +1,34 @@
/* This file runs after the audio system is initiated */
Object.readonly(audio, "samplerate");
Object.readonly(audio, "channels");
Object.readonly(audio, "buffer_frames");
var sources = [];
var audio = {};
soloud.init();
var pcms = {};
audio.pcm = function(file)
{
file = Resources.find_sound(file);
if (!file) return;
if (!file) throw new Error(`Could not findfile ${file}`);
if (pcms[file]) return pcms[file];
var newpcm = os.make_pcm(file);
if (!newpcm) return;
var newpcm = soloud.load_wav_mem(io.slurpbytes(file));
pcms[file] = newpcm;
newpcm.format(audio.samplerate, audio.channels);
return newpcm;
}
audio.play = function (file, bus = audio.bus.master) {
audio.play = function (file) {
var pcm = audio.pcm(file);
if (!pcm) return;
var src = audio.dsp.source(pcm);
src.plugin(bus);
src.guid = prosperon.guid();
src.name = file;
src._pcm = pcm;
src.type = "source";
sources.push(src);
return src;
};
audio.bus = {};
audio.bus.master = dspsound.master();
audio.dsp = {};
audio.dsp = dspsound;
audio.bus.master.__proto__.type = "bus";
audio.bus.master.name = "master";
var plugin_node = audio.bus.master.plugin;
audio.bus.master.__proto__.plugin = function (to) {
this.tos ??= [];
this.tos.push(to);
to.ins ??= [];
to.ins.push(this);
plugin_node.call(this, to);
return soloud.play(pcm);
};
var unplug_node = audio.bus.master.unplug;
audio.bus.master.__proto__.unplug = function () {
if (this.tos) {
for (var node of this.tos) node.ins.remove(this);
this.tos = [];
audio.cry = function (file) {
var voice = audio.play(file);
if (!voice) return;
return function() {
voice.stop();
voice = undefined;
}
unplug_node.call(this);
};
audio.dsp.mix().__proto__.imgui = function () {
imgui.pushid(this.memid());
this.volume = imgui.slider("Volume", this.volume);
this.off = imgui.checkbox("Mute", this.off);
imgui.popid();
};
audio.cry = function (file, bus = audio.bus.sfx) {
var player = audio.play(file, bus);
if (!player) return;
player.ended = function () {
player?.unplug();
player = undefined;
};
return player.ended;
};
// This function is called when every audio source is finished
var killer = Register.appupdate.register(function () {
for (var src of sources) {
if (!src.loop && (src.frame < src.lastframe || src.frame === src.frames())) {
src.unplug();
src.ended?.();
}
src.lastframe = src.frame;
}
});
var song;
// Play 'file' for new song, cross fade for seconds
@@ -98,19 +39,19 @@ audio.music = function (file, fade = 0.5) {
}
if (!fade) {
song = audio.play(file, audio.bus.music);
song = audio.play(file);
song.loop = true;
return;
}
if (!song) {
song = audio.play(file, audio.bus.music);
song = audio.play(file);
song.volume = 1;
// tween(song,'volume', 1, fade);
return;
}
var temp = audio.play(file, audio.bus.music);
var temp = audio.play(file);
if (!temp) return;
temp.volume = 1;
@@ -121,78 +62,4 @@ audio.music = function (file, fade = 0.5) {
song.loop = true;
};
audio.music.playing = function()
{
return song;
}
audio.bus.music = audio.dsp.mix();
audio.bus.music.plugin(audio.bus.master);
audio.bus.music.name = "music";
audio.bus.sfx = audio.dsp.mix();
audio.bus.sfx.plugin(audio.bus.master);
audio.bus.sfx.name = "sfx";
audio.dsp.allpass = function (secs, decay) {
var composite = {};
var fwd = audio.dsp.fwd_delay(secs, -decay);
var fbk = audio.dsp.delay(secs, decay);
composite.id = fwd.id;
composite.plugin = composite.plugin.bind(fbk);
composite.unplug = dsp_node.unplug.bind(fbk);
fwd.plugin(fbk);
return composite;
};
audio.dsp.doc = {
delay: "Delays the input by secs, multiplied by decay",
fwd_delay: "Forward feedback delays the input by secs, multiplied by decay",
allpass: "Composite node of a delay and fwd_delay",
lpf: "Low pass filter at a given frequency",
hpf: "High pass filter at a given frequency",
midi: "A source node for a midi file with a given soundfont file",
crush: "Bitcrush the input to a given rate and bit depth",
limiter: "Limit audio to ceil with pleasent rolloff",
noise_gate: "Do not pass audio below the given floor",
pitchshift: "Shift sound by octaves",
noise: "Plain randon noise",
pink: "Pink noise",
red: "Red noise",
};
audio.dsp.obscure("doc");
Object.mixin(audio.bus.master.__proto__, {
get db() {
return 20 * Math.log10(Math.abs(this.volume));
},
set db(x) {
x = Math.clamp(x, -100, 0);
this.volume = Math.pow(10, x / 20);
},
get volume() {
return this.gain;
},
set volume(x) {
this.gain = x;
},
});
audio.bus.master.__proto__.toJSON = function () {
return {
volume: this.volume,
off: this.off,
pan: this.pan,
pass: this.pass,
};
};
/*Object.mixin(audio.dsp.source().__proto__, {
length() { return this.frames()/audio.samplerate(); },
time() { return this.frame/sound.samplerate(); },
pct() { return this.time()/this.length(); },
});
*/
return { audio };
return audio;

View File

@@ -288,7 +288,7 @@ Cmdline.register_order(
}
prosperon.frame = prosperon.process;
prosperon.icon = os.make_texture(io.slurpbytes('moon.gif'));
prosperon.icon = os.make_texture(io.slurpbytes('core/icons/moon.gif'));
prosperon.high_dpi = 0;
prosperon.alpha = 1;
prosperon.fullscreen = 0;

View File

@@ -114,8 +114,7 @@ Ease.elastic.c5 = (2 * Math.PI) / 4.5;
var tween = function (from, to, time, fn, endfn) {
var start = profile.secs(profile.now());
var update = function (dt) {
profile.report("tween");
var update = function tween_update(dt) {
var elapsed = profile.secs(profile.now()) - start;
fn(from.lerp(to, elapsed / time));
if (elapsed >= time) {
@@ -124,7 +123,6 @@ var tween = function (from, to, time, fn, endfn) {
stop();
endfn?.();
}
profile.endreport("tween");
};
var stop = Register.update.register(update);
return stop;

View File

@@ -30,11 +30,10 @@
#include "timer.h"
#include <signal.h>
#include <dirent.h>
#include <fts.h>
#include "cute_aseprite.h"
#include <tracy/TracyC.h>
JSValue number2js(JSContext *js, double g) { return JS_NewFloat64(js,g); }
double js2number(JSContext *js, JSValue v) {
double g;
@@ -611,7 +610,10 @@ JSC_CCALL(render_viewport,
sg_apply_viewportf(view.x, view.y,view.w,view.h, JS_ToBool(js,argv[1]));
)
JSC_CCALL(render_commit, sg_commit())
JSC_CCALL(render_commit,
sg_commit();
TracyCFrameMark
)
JSC_CCALL(render_end_pass, sg_end_pass())
HMM_Mat4 transform2view(transform *t)
@@ -1403,6 +1405,17 @@ JSC_CCALL(vector_median,
return number2js(js,arr[len/2]);
)
int fibonacci(int n) {
if (n <= 1) return n;
return fibonacci(n-1) + fibonacci(n-2);
}
JSC_CCALL(vector_fib,
int n = js2number(js,argv[0]);
int fib = fibonacci(n);
printf("ANSWER IS %d\n", fib);
)
static const JSCFunctionListEntry js_vector_funcs[] = {
MIST_FUNC_DEF(vector, dot,2),
MIST_FUNC_DEF(vector, project,2),
@@ -1426,7 +1439,8 @@ static const JSCFunctionListEntry js_vector_funcs[] = {
MIST_FUNC_DEF(vector, sum, 1),
MIST_FUNC_DEF(vector, sigma, 1),
MIST_FUNC_DEF(vector, median, 1),
MIST_FUNC_DEF(vector, length, 1)
MIST_FUNC_DEF(vector, length, 1),
MIST_FUNC_DEF(vector, fib, 1),
};
#define JS_HMM_FN(OP, HMM, SIGN) \
@@ -1649,6 +1663,18 @@ JSC_CCALL(profile_gather_stop,
JS_SetInterruptHandler(JS_GetRuntime(js),NULL,NULL);
)
JSC_CCALL(profile_trace_start,
#ifdef TRACY_MANUAL_LIFETIME
___tracy_startup_profiler();
#endif
)
JSC_CCALL(profile_trace_stop,
#ifdef TRACY_MANUAL_LIFETIME
___tracy_shutdown_profiler();
#endif
)
JSC_CCALL(profile_best_t,
char* result[50];
double seconds = stm_sec(js2number(js,argv[0]));
@@ -1664,15 +1690,50 @@ JSC_CCALL(profile_best_t,
ret = JS_NewString(js,result);
)
JSC_CCALL(profile_message,
size_t len;
const char *str = JS_ToCStringLen(js, &len, argv[0]);
TracyCMessage(str,len);
JS_FreeCString(js,str);
)
JSC_CCALL(profile_secs, return number2js(js,stm_sec(js2number(js,argv[0]))); )
JSC_SCALL(profile_plot,
TracyCPlot(str, js2number(js,argv[1]));
)
JSC_SCALL(profile_plot_config,
TracyCPlotConfig(str, js2number(js,argv[1]), JS_ToBool(js,argv[2]), JS_ToBool(js,argv[3]), js2number(js,argv[4]))
)
JSC_CCALL(profile_fiber_enter,
JSAtom atom = JS_ValueToAtom(js,argv[0]);
const char *str = JS_AtomToCString(js, atom);
TracyCFiberEnter(str);
JS_FreeAtom(js,atom);
)
JSC_CCALL(profile_fiber_leave,
JSAtom atom = JS_ValueToAtom(js,argv[0]);
const char *str = JS_AtomToCString(js, atom);
TracyCFiberLeave(str);
JS_FreeAtom(js,atom);
)
static const JSCFunctionListEntry js_profile_funcs[] = {
MIST_FUNC_DEF(profile,now,0),
MIST_FUNC_DEF(profile,best_t, 1),
MIST_FUNC_DEF(profile,gather,2),
MIST_FUNC_DEF(profile,gather_rate,1),
MIST_FUNC_DEF(profile,gather_stop,0),
MIST_FUNC_DEF(profile,trace_start,0),
MIST_FUNC_DEF(profile,secs,1),
MIST_FUNC_DEF(profile, message, 1),
MIST_FUNC_DEF(profile, plot, 2),
MIST_FUNC_DEF(profile, plot_config, 5),
MIST_FUNC_DEF(profile, fiber_enter, 1),
MIST_FUNC_DEF(profile, fiber_leave, 1),
};
static void list_files(const char *path, JSContext *js, JSValue v, int *n)
@@ -1790,7 +1851,10 @@ static const JSCFunctionListEntry js_io_funcs[] = {
JSC_GETSET(transform, pos, vec3)
JSC_GETSET(transform, scale, vec3f)
JSC_GETSET(transform, rotation, quat)
JSC_CCALL(transform_move, transform_move(js2transform(js,self), js2vec3(js,argv[0])); )
JSC_CCALL(transform_move,
transform *t = js2transform(js,self);
transform_move(t, js2vec3(js,argv[0]));
)
JSC_CCALL(transform_lookat,
HMM_Vec3 point = js2vec3(js,argv[0]);
@@ -2099,6 +2163,7 @@ JSC_CCALL(os_gc, JS_RunGC(JS_GetRuntime(js)))
JSC_CCALL(os_mem_limit, JS_SetMemoryLimit(JS_GetRuntime(js), js2number(js,argv[0])))
JSC_CCALL(os_gc_threshold, JS_SetGCThreshold(JS_GetRuntime(js), js2number(js,argv[0])))
JSC_CCALL(os_max_stacksize, JS_SetMaxStackSize(JS_GetRuntime(js), js2number(js,argv[0])))
JSC_CCALL(os_rt_info, return JS_GetRTInfo(JS_GetRuntime(js),js))
static JSValue tmp2js(JSContext *js,FILE *tmp)
{
@@ -2711,6 +2776,7 @@ static const JSCFunctionListEntry js_os_funcs[] = {
MIST_FUNC_DEF(os, mem_limit, 1),
MIST_FUNC_DEF(os, gc_threshold, 1),
MIST_FUNC_DEF(os, max_stacksize, 1),
MIST_FUNC_DEF(os, rt_info, 0),
MIST_FUNC_DEF(os, dump_value, 1),
MIST_FUNC_DEF(os, dump_mem, 0),
MIST_FUNC_DEF(os, dump_shapes, 0),
@@ -2824,15 +2890,15 @@ void ffi_load(JSContext *js) {
signal(SIGINT, signal_handler);
signal(SIGTERM, signal_handler);
signal(SIGHUP, signal_handler);
signal(SIGSEGV, signal_handler);
signal(SIGQUIT, signal_handler);
signal(SIGABRT, signal_handler);
atexit(exit_handler);
#ifndef NEDITOR
JS_SetPropertyStr(js, globalThis, "imgui", js_imgui(js));
#endif
TracyCSetThreadName("MAIN_QUICKJS")
JS_FreeValue(js,globalThis);
}

View File

@@ -1,3 +1,5 @@
#include <tracy/TracyC.h>
#define MIST_CFUNC_DEF(name, length, func1, props) { name, props, JS_DEF_CFUNC, 0, .u = { .func = { length, JS_CFUNC_generic, { .generic = func1 } } } }
#define MIST_FUNC_DEF(TYPE, FN, LEN) MIST_CFUNC_DEF(#FN, LEN, js_##TYPE##_##FN, JS_PROP_C_W_E)

View File

@@ -4,6 +4,9 @@
#include "sokol/sokol_glue.h"
#include "sokol/util/sokol_gl.h"
#include "HandmadeMath.h"
#include <stdio.h>
#include <tracy/TracyC.h>
sg_sampler std_sampler;
sg_sampler tex_sampler;
@@ -27,11 +30,6 @@ void trace_apply_uniforms(sg_shader_stage stage, int ub_index, const sg_range *d
rfd.size_uniforms += data->size;
}
void trace_draw(int base_e, int num_e, int num_inst, void *data)
{
}
void trace_apply_pipeline(sg_pipeline pip, void *data)
{
// YughSpam("Applying pipeline %u %s.", pip, sg_query_pipeline_desc(pip).label);
@@ -42,46 +40,83 @@ void trace_begin_pass(sg_pass pass, const sg_pass_action *action, void *data)
// YughSpam("Begin pass %s", pass.label);
}
#define SG_TRACE_SET(NAME) \
void trace_alloc_##NAME (sg_##NAME id, void *data) \
{ \
sg_##NAME##_desc desc = sg_query_##NAME##_desc(id); \
} \
\
void trace_dealloc_##NAME(sg_##NAME id, void *data) \
{ \
sg_##NAME##_desc desc = sg_query_##NAME##_desc(id); \
} \
\
void trace_make_##NAME(sg_##NAME##_desc *desc, void *data) \
{ \
} \
\
void trace_destroy_##NAME(sg_##NAME id, void *data) \
{ \
sg_##NAME##_desc desc = sg_query_##NAME##_desc(id); \
} \
\
void trace_init_##NAME(sg_##NAME id, sg_##NAME##_desc *desc, void *data) \
{ \
} \
\
void trace_uninit_##NAME(sg_##NAME id, void *data) \
{ \
sg_##NAME##_desc desc = sg_query_##NAME##_desc(id); \
} \
\
void trace_fail_##NAME(sg_##NAME id, void *data) \
{ \
sg_##NAME##_desc desc = sg_query_##NAME##_desc(id); \
} \
void trace_apply_viewport(int x, int y, int width, int height, bool origin_top_left, void *user_data)
{
}
void trace_draw(int base_element, int num_elements, int num_instances, void *user_data)
{
TracyCPlotI("draw", num_elements);
}
void trace_alloc_buffer(sg_buffer result, void *data) {
TracyCMessageL("BUFFER ALLOC");
}
void trace_init_buffer(sg_buffer id, const sg_buffer_desc *desc, void *data){
TracyCMessageL("BUFFER INIT");
}
void trace_make_buffer(const sg_buffer_desc *desc, sg_buffer id, void *data){
TracyCAllocN((void*)id.id, desc->data.size, "buffer");
}
void trace_append_buffer(sg_buffer id, const sg_range *data, int result, void *user_data) {
sg_buffer_desc desc = sg_query_buffer_desc(id);
}
void trace_update_buffer(sg_buffer buf, const sg_range *data, void *user_data){
TracyCMessageL("BUFFER UPDATED");
}
void trace_uninit_buffer(sg_buffer id, void *data){
TracyCMessageL("BUFFER UNINIT");
}
void trace_dealloc_buffer(sg_buffer id, void *data){
TracyCMessageL("BUFFER DEALLOC");
}
void trace_destroy_buffer(sg_buffer id, void *data){
TracyCFreeN((void*)id.id, "buffer");
}
void trace_fail_buffer(sg_buffer id, void *data){}
void trace_alloc_image(sg_image result, void *data) {
TracyCMessageL("IMAGE ALLOC");
}
void trace_init_image(sg_image id, const sg_image_desc *desc, void *data){
TracyCMessageL("IMAGE INIT");
}
int image_data_size(sg_image_data *data)
{
int total_size = 0;
for (int i = 0; i < SG_CUBEFACE_NUM; i++)
for (int j = 0; j < SG_MAX_MIPMAPS; j++)
total_size += data->subimage[i][j].size;
return total_size;
}
void trace_make_image(const sg_image_desc *desc, sg_image id, void *data){
int total_size = 0;
for (int i = 0; i < desc->num_mipmaps; i++)
total_size += desc->data.subimage[i]->size;
TracyCAllocN((void*)id.id, image_data_size(&desc->data), "tex_gpu");
}
void trace_update_image(sg_image id, const sg_image_data *data, void *user_data){
TracyCFreeN((void*)id.id, "tex_gpu");
TracyCAllocN((void*)id.id, image_data_size(data), "tex_gpu");
}
void trace_uninit_image(sg_image id, void *data){
TracyCMessageL("IMAGE UNINIT");
}
void trace_dealloc_image(sg_image id, void *data){
TracyCMessageL("IMAGE DEALLOC");
}
void trace_destroy_image(sg_image id, void *data){
TracyCFreeN((void*)id.id, "tex_gpu");
}
void trace_fail_image(sg_image id, void *data){}
SG_TRACE_SET(buffer)
SG_TRACE_SET(image)
SG_TRACE_SET(sampler)
SG_TRACE_SET(shader)
SG_TRACE_SET(pipeline)
SG_TRACE_SET(attachments)
#define SG_HOOK_SET(NAME) \
.alloc_##NAME = trace_alloc_##NAME, \
@@ -92,22 +127,18 @@ SG_TRACE_SET(attachments)
.destroy_##NAME = trace_destroy_##NAME, \
.make_##NAME = trace_make_##NAME \
void trace_append_buffer(sg_buffer id, sg_range *data, void *user)
{
sg_buffer_desc desc = sg_query_buffer_desc(id);
// YughSpam("Appending buffer %d [%s]", id, desc.label);
}
static sg_trace_hooks hooks = {
.apply_pipeline = trace_apply_pipeline,
.begin_pass = trace_begin_pass,
SG_HOOK_SET(buffer),
.append_buffer = trace_append_buffer,
SG_HOOK_SET(image),
SG_HOOK_SET(shader),
SG_HOOK_SET(sampler),
SG_HOOK_SET(pipeline),
SG_HOOK_SET(attachments),
.append_buffer = trace_append_buffer
// SG_HOOK_SET(shader),
// SG_HOOK_SET(sampler),
// SG_HOOK_SET(pipeline),
// SG_HOOK_SET(attachments),
.draw = trace_draw,
};
void render_init() {

View File

@@ -8,6 +8,10 @@
#include <errno.h>
#include <stdarg.h>
#include "jsffi.h"
#include <malloc.h>
#include <assert.h>
#include <tracy/TracyC.h>
static JSContext *js = NULL;
static JSRuntime *rt = NULL;
@@ -69,8 +73,8 @@ void script_startup() {
ffi_load(js);
char *eng = read_file("engine.js");
JSValue v = script_eval("engine.js", eng);
char *eng = read_file("core/scripts/engine.js");
JSValue v = script_eval("core/scripts/engine.js", eng);
JS_FreeValue(js, v);
free(eng);
}

View File

@@ -11,6 +11,8 @@
#include <stdio.h>
#include <tracy/TracyC.h>
#include "qoi.h"
#ifndef NSVG
@@ -152,6 +154,7 @@ int mip_wh(int w, int h, int *mw, int *mh, int lvl)
void texture_offload(texture *tex)
{
if (tex->data) {
TracyCFreeN(tex->data, "texture");
free(tex->data);
tex->data = NULL;
}
@@ -160,9 +163,7 @@ void texture_offload(texture *tex)
void texture_free(JSRuntime *rt, texture *tex)
{
if (!tex) return;
if (tex->data)
free(tex->data);
texture_offload(tex);
free(tex);
}
@@ -173,6 +174,7 @@ struct texture *texture_empty(int w, int h)
tex->data = calloc(w*h*n, sizeof(unsigned char));
tex->width = w;
tex->height = h;
TracyCAllocN(tex->data, tex->height*tex->width*4, "texture");
return tex;
}
@@ -189,6 +191,7 @@ struct texture *texture_fromdata(void *raw, long size)
}
tex->data = data;
TracyCAllocN(tex->data, tex->height*tex->width*4, "texture");
return tex;
}

7
subprojects/tracy.wrap Normal file
View File

@@ -0,0 +1,7 @@
[wrap-git]
url = https://github.com/wolfpld/tracy.git
revision = v0.11.1
depth = 1
[provide]
tracy = tracy_dep