Move console and time to c; consoleout and colors

This commit is contained in:
John Alanbrook 2024-03-14 14:10:06 -05:00
parent 55ab159a85
commit 188fe7526c
12 changed files with 247 additions and 293 deletions

View file

@ -62,12 +62,12 @@ convert.buf2hex = function(buffer) { // buffer is an ArrayBuffer
} }
/* Time values are always expressed in terms of real earth-seconds */ /* Time values are always expressed in terms of real earth-seconds */
var time = { Object.assign(time, {
get hour2minute() { return this.hour/this.minute; }, hour2minute() { return this.hour/this.minute; },
get day2hour() { return this.day/this.hour; }, day2hour() { return this.day/this.hour; },
get minute2second() { return this.minute/this.second; }, minute2second() { return this.minute/this.second; },
get week2day() { return this.week/this.day; }, week2day() { return this.week/this.day; },
}; });
time.strparse = { time.strparse = {
yyyy: "year", yyyy: "year",
@ -106,8 +106,6 @@ time.doc = {
text: "Return a text formatted time." text: "Return a text formatted time."
}; };
time.second = 1; time.second = 1;
time.minute = 60; time.minute = 60;
time.hour = 3_600; time.hour = 3_600;
@ -117,9 +115,6 @@ time.weekdays = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday
time.monthstr = ["January", "February", "March", 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']; time.monthstr = ["January", "February", "March", 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
time.epoch = 1970; time.epoch = 1970;
time.now = function() { return cmd(210);}
time.computer_zone = function() { return cmd(211)/this.hour; }
time.computer_dst = function() { return cmd(212); }
time.isleap = function(year) { return this.yearsize(year) === 366; } time.isleap = function(year) { return this.yearsize(year) === 366; }
time.isleap.doc = "Return true if the given year is a leapyear."; time.isleap.doc = "Return true if the given year is a leapyear.";
@ -129,6 +124,13 @@ time.yearsize = function(y) {
return 365; return 365;
} }
time.timecode = function(t, fps = 24)
{
var s = Math.trunc(t);
t -= s;
return `${s}:${Math.trunc(fps*s)}`;
}
time.monthdays = [31,28,31,30,31,30,31,31,30,31,30,31]; time.monthdays = [31,28,31,30,31,30,31,31,30,31,30,31];
time.zones = {}; time.zones = {};
time.zones['-12'] = 'IDLW'; time.zones['-12'] = 'IDLW';
@ -215,9 +217,9 @@ time.number = function(rec)
c += this.day*this.yearsize(i); c += this.day*this.yearsize(i);
c += (this.yearsize(year)-yday-1)*this.day; c += (this.yearsize(year)-yday-1)*this.day;
c += (this.day2hour-hour-1)*this.hour; c += (this.day2hour()-hour-1)*this.hour;
c += (this.hour2minute-minute-1)*this.minute; c += (this.hour2minute()-minute-1)*this.minute;
c += (this.minute2second-second); c += (this.minute2second()-second);
c += zone*this.hour; c += zone*this.hour;
c *= -1; c *= -1;
return c; return c;

View file

@ -63,7 +63,7 @@ var Debug = {
if (Debug.Options.gif.rec) { if (Debug.Options.gif.rec) {
GUI.text("REC", [0,40], 1); GUI.text("REC", [0,40], 1);
GUI.text(Time.seconds_to_timecode(Time.time - Debug.Options.gif.start_time, Debug.Options.gif.fps), [0,30], 1); GUI.text(time.timecode(time.timenow() - Debug.Options.gif.start_time, Debug.Options.gif.fps), [0,30], 1);
} }
GUI.text(Game.playing() ? "PLAYING" GUI.text(Game.playing() ? "PLAYING"
@ -98,54 +98,52 @@ var Gizmos = {
}, },
}; };
Object.assign(performance, { Object.assign(profile, {
tick_now() { return cmd(127); }, best_t(t) {
ns(ticks) { return cmd(128, ticks); },
us(ticks) { return cmd(129, ticks); },
ms(ticks) { return cmd(130, ticks); },
best_t(ns) {
var e = ns;
var qq = 'ns'; var qq = 'ns';
if (e > 1000) { if (t > 1000) {
e /= 1000; t /= 1000;
qq = 'us'; qq = 'us';
if (e > 1000) { if (t > 1000) {
e /= 1000; t /= 1000;
qq = 'ms'; qq = 'ms';
} }
} }
return { return `${t.toPrecision(4)} ${qq}`;
time: e,
unit: qq
};
}, },
cpu(fn, times, q) { cpu(fn, times, q) {
times ??= 1; times ??= 1;
q ??= "unnamed"; q ??= "unnamed";
var start = performance.tick_now(); var start = profile.now();
for (var i = 0; i < times; i++) for (var i = 0; i < times; i++)
fn(); fn();
var elapsed = performance.tick_now() - start; var elapsed = profile.now() - start;
var avgt = performance.best_t(elapsed/times); var avgt = profile.best_t(elapsed/times);
var totalt = performance.best_t(elapsed); var totalt = profile.best_t(elapsed);
say(`performance [${q}]: ${avgt.time.toFixed(3)} ${avgt.unit} average [${totalt.time.toFixed(3)} ${totalt.unit} for ${times} loops]`); say(`profile [${q}]: ${profile.best_t(avgt)} average [${profile.best_t(totalt)} for ${times} loops]`);
}, },
get fps() { return sys_cmd(8); }, time(fn) {
var start = profile.now();
fn();
return profile.lap(start);
},
lap(t) {
return profile.best_t(profile.now()-t);
},
measure(fn, str) { measure(fn, str) {
str ??= 'unnamed'; str ??= 'unnamed';
var start = performance.tick_now(); var start = profile.now();
fn(); fn();
var elapsed = performance.tick_now()-start; say(`profile [${str}]: ${profile.lap(start)}`);
elapsed = performance.best_t(elapsed);
say(`performance [${str}]: ${elapsed.time.toFixed(3)} ${elapsed.unit}`);
}, },
}); });
performance.now = performance.tick_now;
performance.test = { performance.test = {
barecall() { performance(0); }, barecall() { performance(0); },
@ -160,7 +158,7 @@ performance.test = {
performance.test.call_fn_n.doc = "Calls fn1 n times, and then fn2."; performance.test.call_fn_n.doc = "Calls fn1 n times, and then fn2.";
performance.cpu.doc = `Output the time it takes to do a given function n number of times. Provide 'q' as "ns", "us", or "ms" to output the time taken in the requested resolution.`; //performance.cpu.doc = `Output the time it takes to do a given function n number of times. Provide 'q' as "ns", "us", or "ms" to output the time taken in the requested resolution.`;
/* These controls are available during editing, and during play of debug builds */ /* These controls are available during editing, and during play of debug builds */
Debug.inputs = {}; Debug.inputs = {};
@ -200,7 +198,7 @@ Debug.Options.gif = {
cmd(131, w, h, this.cpf, this.depth); cmd(131, w, h, this.cpf, this.depth);
this.rec = true; this.rec = true;
this.fps = (1/this.cpf)*100; this.fps = (1/this.cpf)*100;
this.start_time = Time.time; this.start_time = time.now();
timer.oneshot(this.stop.bind(this), this.secs, this, true); timer.oneshot(this.stop.bind(this), this.secs, this, true);
}, },
@ -233,46 +231,6 @@ Debug.inputs['M-2'] = render.wireframe;
Debug.inputs['C-M-f'] = function() {}; Debug.inputs['C-M-f'] = function() {};
Debug.inputs['C-M-f'].doc = "Enter camera fly mode."; Debug.inputs['C-M-f'].doc = "Enter camera fly mode.";
var Time = {
set timescale(x) { cmd(3, x); },
get timescale() { return cmd(121); },
set updateMS(x) { cmd(6, x); },
set physMS(x) { cmd(7, x); },
set renderMS(x) { cmd(5, x); },
get time() { return cmd(133); },
seconds_to_timecode(secs, fps)
{
var s = Math.trunc(secs);
secs -= s;
var f = Math.trunc(fps * secs);
return `${s}:${f}`;
},
pause() {
Time.stash = Time.timescale;
Time.timescale = 0;
},
play() {
if (!Time.stash) {
console.warn("Tried to resume time without calling Time.pause first.");
return;
}
Time.timescale = Time.stash;
},
};
Time.doc = {};
Time.doc.timescale = "Get and set the timescale. 1 is normal time; 0.5 is half speed; etc.";
Time.doc.updateMS = "Set the ms per game update.";
Time.doc.physMS = "Set the ms per physics update.";
Time.doc.renderMS = "Set the ms per render update.";
Time.doc.time = "Seconds elapsed since the game started.";
Time.doc.pause = "Pause the game by setting the timescale to 0; remembers the current timescale on play.";
Time.doc.play = "Resume the game after using Time.pause.";
Debug.api = {}; Debug.api = {};
Debug.api.doc_entry = function(obj, key) Debug.api.doc_entry = function(obj, key)
{ {
@ -351,8 +309,6 @@ Debug.api.print_doc = function(name)
return { return {
Debug, Debug,
Time,
Gizmos, Gizmos,
performance,
assert assert
} }

View file

@ -1,11 +1,67 @@
"use math"; "use math";
Object.assign(console, {
say(msg) { console.print(msg + "\n"); },
pprint(msg, lvl = 0) {
if (typeof msg === 'object')
msg = JSON.stringify(msg, null, 2);
var file = "nofile";
var line = 0;
var caller = (new Error()).stack.split('\n')[2];
if (caller) {
var m = caller.match(/\((.*)\:/)[1];
if (m) file = m;
m = caller.match(/\:(\d*)\)/)[1];
if (m) line = m;
}
console.rec(lvl, msg, file, line);
},
spam(msg) { console.pprint(msg,0); },
debug(msg) { console.pprint(msg,1); },
info(msg) { console.pprint(msg, 2); },
warn(msg) { console.pprint(msg, 3); },
error(msg) { console.pprint(msg + "\n" + console.stackstr(2), 4);},
panic(msg) { console.pprint(msg + "\n" + console.stackstr(2), 5); },
stackstr(skip=0) {
var err = new Error();
var stack = err.stack.split('\n');
return stack.slice(skip,stack.length).join('\n');
},
stack(skip = 0) {
console.log(console.stackstr(skip+1));
},
});
console.log = console.say;
var say = console.say;
var print = console.print;
console.doc = {
level: "Set level to output logging to console.",
info: "Output info level message.",
warn: "Output warn level message.",
error: "Output error level message, and print stacktrace.",
critical: "Output critical level message, and exit game immediately.",
write: "Write raw text to console.",
say: "Write raw text to console, plus a newline.",
stack: "Output a stacktrace to console.",
console: "Output directly to in game console.",
clear: "Clear console."
};
globalThis.global = globalThis; globalThis.global = globalThis;
function use(file) function use(file)
{ {
if (use.files[file]) return use.files[file]; if (use.files[file]) return use.files[file];
if (globalThis.console) console.info(`running ${file}`);
console.info(`running ${file}`);
var c = io.slurp(file); var c = io.slurp(file);
@ -19,7 +75,7 @@ use.files = {};
function include(file,that) function include(file,that)
{ {
if (!that) return; if (!that) return;
if (globalThis.console) console.info(`running ${file}`); console.info(`running ${file}`);
var c = io.slurp(file); var c = io.slurp(file);
eval_env(c, that, file); eval_env(c, that, file);
} }
@ -28,7 +84,7 @@ function eval_env(script, env, file)
{ {
env ??= {}; env ??= {};
file ??= "SCRIPT"; file ??= "SCRIPT";
if (globalThis.console) console.info(`eval ${file}`); console.info(`eval ${file}`);
script = `(function() { ${script}; }).call(this);\n`; script = `(function() { ${script}; }).call(this);\n`;
return cmd(123,script,env,file); return cmd(123,script,env,file);
} }
@ -159,7 +215,6 @@ Game.doc.dt = "Current frame dt.";
Game.doc.view_camera = "Set the camera for the current view."; Game.doc.view_camera = "Set the camera for the current view.";
Game.doc.camera = "Current camera."; Game.doc.camera = "Current camera.";
global.prosperon = {};
prosperon.version = cmd(255); prosperon.version = cmd(255);
prosperon.revision = cmd(256); prosperon.revision = cmd(256);
@ -225,7 +280,6 @@ prosperon.clipboardpaste = function(str){};
global.mixin("scripts/input.js"); global.mixin("scripts/input.js");
global.mixin("scripts/std.js"); global.mixin("scripts/std.js");
console.level = 1;
global.mixin("scripts/diff.js"); global.mixin("scripts/diff.js");
global.mixin("scripts/color.js"); global.mixin("scripts/color.js");
global.mixin("scripts/gui.js"); global.mixin("scripts/gui.js");

View file

@ -120,82 +120,6 @@ Resources.replstrs = function(path)
return script; return script;
} }
var console = {
print(msg) { cmd(91, msg); },
say(msg) { console.print(msg + "\n"); },
pprint(msg, lvl) {
var lg;
if (typeof msg === 'object') {
lg = JSON.stringify(msg, null, 2);
} else {
lg = msg;
}
var stack = (new Error()).stack;
var n = stack.next('\n',0)+1;
n = stack.next('\n', n)+1;
var nnn = stack.slice(n);
var fmatch = nnn.match(/\(.*\:/);
var file = fmatch ? fmatch[0].shift(1).shift(-1) : "nofile";
var lmatch = nnn.match(/\:\d*\)/);
var line = lmatch ? lmatch[0].shift(1).shift(-1) : "0";
yughlog(lvl, lg, file, line);
},
spam(msg) {
console.pprint(msg,0);
},
/* this always prints to stdout */
debug(msg) {
console.pprint(msg,1);
},
info(msg) {
console.pprint(msg, 2);
},
warn(msg) {
console.pprint(msg, 3);
},
error(msg) {
console.pprint(msg + "\n" + console.stackstr(3), 4);
},
panic(msg) {
console.pprint(msg + "\n" + console.stackstr(1), 5);
},
stackstr(skip=0) {
var err = new Error();
var stack = err.stack.split('\n');
return stack.slice(skip,stack.length-10).join('\n');
},
stack(skip = 0) {
console.log(stackstr(skip+1));
},
};
console.log = console.say;
var say = console.say;
var print = console.print;
console.doc = {
level: "Set level to output logging to console.",
info: "Output info level message.",
warn: "Output warn level message.",
error: "Output error level message, and print stacktrace.",
critical: "Output critical level message, and exit game immediately.",
write: "Write raw text to console.",
say: "Write raw text to console, plus a newline.",
stack: "Output a stacktrace to console.",
console: "Output directly to in game console.",
clear: "Clear console."
};
/* /*
io path rules. Starts with, meaning: io path rules. Starts with, meaning:
@ -608,10 +532,7 @@ Cmdline.register_cmd("l", function(n) {
}, "Set log level."); }, "Set log level.");
return { return {
console,
Resources, Resources,
say,
print,
Cmdline, Cmdline,
cmd_args, cmd_args,
steam steam

View file

@ -3,29 +3,36 @@
var tests = []; var tests = [];
var pass = 0; var pass = 0;
var fail = 0; var fail = 0;
var failed = [];
var test = function(name, fn) var test = function(name, fn)
{ {
tests.push(function() { var func = function() {
print(`${pass+fail}/${tests.length}: ${name} ... `); print(`${pass+fail+1}/${tests.length}: ${name} ... `);
var result = fn(); var p = profile.now();
if (result) print(`pass`); var b = fn();
else print(`fail`); p = profile.lap(p);
return result; print(`${b ? "pass" : "fail"} [${p}]`);
}); return b;
};
func.testname = name;
tests.push(func);
} }
test("Pass test", _=>1);
test("Fail test", _=>0);
say(`Testing ${tests.length} tests.`); say(`Testing ${tests.length} tests.`);
for (var t of tests) { for (var t of tests) {
if (t()) if (t())
pass++; pass++;
else else {
fail++; fail++;
failed.push(t.testname);
}
print("\n"); print("\n");
} }
say(`Passed ${pass} tests and failed ${fail}`); say(`Passed ${pass} tests and failed ${fail} [${(pass*100/(pass+fail)).toPrecision(4)}%].`);
say(`Failed tests are:`);
for (var f of failed)
say(f);
Game.quit(); Game.quit();

View file

@ -592,7 +592,7 @@ int shape_get_sensor(struct phys2d_shape *shape) {
if (!shape->shape) { if (!shape->shape) {
struct phys2d_edge *edge = shape->data; struct phys2d_edge *edge = shape->data;
if (arrlen(edge->shapes) > 0) return cpShapeGetSensor(edge->shapes[0]); if (arrlen(edge->shapes) > 0) return cpShapeGetSensor(edge->shapes[0]);
YughInfo("Attempted to get the sensor of an edge with no shapes. It has %d points.", arrlen(edge->points)); YughWarn("Attempted to get the sensor of an edge with no shapes. It has %d points.", arrlen(edge->points));
return 0; return 0;
} }

View file

@ -12,12 +12,27 @@
#include "script.h" #include "script.h"
#define ESC "\033["
#define BLACK 30
#define RED 31
#define GREEN 32
#define YELLOW 33
#define BLUE 34
#define MAGENTA 35
#define CYAN 36
#define WHITE 37
#define COLOR(TXT, _C) ESC #_C "m" #TXT ESC "0m"
char *logstr[] = { "spam", "debug", "info", "warn", "error", "panic"}; char *logstr[] = { "spam", "debug", "info", "warn", "error", "panic"};
char *logcolor[] = { COLOR(spam,37), COLOR(debug,32), COLOR(info,36), COLOR(warn,33), COLOR(error,31), COLOR(panic,45) };
char *catstr[] = {"engine", "script", "render"}; char *catstr[] = {"engine", "script", "render"};
static FILE *logout; /* where logs are written to */ static FILE *logout; /* where logs are written to */
static FILE *writeout; /* where console is written to */ static FILE *writeout; /* where console is written to */
int stdout_lvl = LOG_PANIC;
void log_init() void log_init()
{ {
#ifndef NDEBUG #ifndef NDEBUG
@ -49,8 +64,8 @@ void mYughLog(int category, int priority, int line, const char *file, const char
va_end(args); va_end(args);
fprintf(logout, "\n"); fprintf(logout, "\n");
if (priority == LOG_DEBUG) { if (priority == LOG_DEBUG || priority > stdout_lvl) {
printf(logfmt, file, line, timebuf, logstr[priority], catstr[category]); printf(logfmt, file, line, timebuf, logcolor[priority], catstr[category]);
va_list args; va_list args;
va_start(args,message); va_start(args,message);
vprintf(message, args); vprintf(message, args);

View file

@ -18,6 +18,8 @@
void log_init(); void log_init();
void log_shutdown(); void log_shutdown();
extern int stdout_lvl;
#ifndef NDEBUG #ifndef NDEBUG
#define YughLog(cat, pri, msg, ...) mYughLog(cat, pri, __LINE__, __FILE__, msg, ##__VA_ARGS__) #define YughLog(cat, pri, msg, ...) mYughLog(cat, pri, __LINE__, __FILE__, msg, ##__VA_ARGS__)
#define YughSpam(msg, ...) mYughLog(0, LOG_SPAM, __LINE__, __FILE__, msg, ##__VA_ARGS__); #define YughSpam(msg, ...) mYughLog(0, LOG_SPAM, __LINE__, __FILE__, msg, ##__VA_ARGS__);

View file

@ -27,8 +27,11 @@
#include <sokol/sokol_time.h> #include <sokol/sokol_time.h>
#include <sokol/sokol_app.h> #include <sokol/sokol_app.h>
#include <time.h>
#include <sys/time.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
#include <limits.h> #include <limits.h>
@ -129,32 +132,10 @@ JS_SetClassProto(js, js_##TYPE##_id, TYPE##_proto); \
void js_setprop_str(JSValue obj, const char *prop, JSValue v) { JS_SetPropertyStr(js, obj, prop, v); } void js_setprop_str(JSValue obj, const char *prop, JSValue v) { JS_SetPropertyStr(js, obj, prop, v); }
JSValue jstzone()
{
time_t t = time(NULL);
time_t local_t = mktime(localtime(&t));
double diff = difftime(t, local_t);
return number2js(diff/3600);
}
int js2bool(JSValue v) { return JS_ToBool(js, v); } int js2bool(JSValue v) { return JS_ToBool(js, v); }
JSValue bool2js(int b) { return JS_NewBool(js,b); } JSValue bool2js(int b) { return JS_NewBool(js,b); }
JSValue jsdst()
{
time_t t = time(NULL);
return bool2js(localtime(&t)->tm_isdst);
}
JSValue jscurtime()
{
time_t t;
time(&t);
JSValue jst = number2js(t);
return jst;
}
void js_setprop_num(JSValue obj, uint32_t i, JSValue v) { JS_SetPropertyUint32(js, obj, i, v); } void js_setprop_num(JSValue obj, uint32_t i, JSValue v) { JS_SetPropertyUint32(js, obj, i, v); }
JSValue gos2ref(gameobject **go) JSValue gos2ref(gameobject **go)
@ -689,21 +670,10 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
ret = JS_NewInt64(js, script_dofile(str)); ret = JS_NewInt64(js, script_dofile(str));
break; break;
case 3:
set_timescale(js2number(argv[1]));
break;
case 4: case 4:
debug_draw_phys(JS_ToBool(js, argv[1])); debug_draw_phys(JS_ToBool(js, argv[1]));
break; break;
case 6:
updateMS = js2number(argv[1]);
break;
case 7:
physMS = js2number(argv[1]);
break;
case 15: case 15:
gameobject_draw_debug(js2gameobject(argv[1])); gameobject_draw_debug(js2gameobject(argv[1]));
@ -845,11 +815,6 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
window_set_icon(str); window_set_icon(str);
break; break;
case 91:
str = JS_ToCString(js, argv[1]);
log_print(str);
break;
case 97: case 97:
str = js2str(argv[1]); str = js2str(argv[1]);
cursor_img(str); cursor_img(str);
@ -886,10 +851,6 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
ret = JS_NewInt64(js, file_mod_secs(str)); ret = JS_NewInt64(js, file_mod_secs(str));
break; break;
case 121:
ret = number2js(get_timescale());
break;
case 122: case 122:
str = JS_ToCString(js, argv[1]); str = JS_ToCString(js, argv[1]);
ret = file_eval_env(str, argv[2]); ret = file_eval_env(str, argv[2]);
@ -906,23 +867,6 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
pack_engine(str); pack_engine(str);
break; break;
case 127:
ret = JS_NewInt64(js, stm_now());
break;
case 128:
ret = JS_NewFloat64(js, stm_ns(js2int64(argv[1])));
break;
case 129:
ret = JS_NewFloat64(js, stm_us(js2int64(argv[1])));
break;
case 130:
ret = JS_NewFloat64(js, stm_ms(js2int64(argv[1])));
break;
case 131: case 131:
gif_rec_start(js2int(argv[1]), js2int(argv[2]), js2int(argv[3]), js2int(argv[4])); gif_rec_start(js2int(argv[1]), js2int(argv[2]), js2int(argv[3]), js2int(argv[4]));
break; break;
@ -930,9 +874,6 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
str = JS_ToCString(js, argv[1]); str = JS_ToCString(js, argv[1]);
gif_rec_end(str); gif_rec_end(str);
break; break;
case 133:
ret = JS_NewFloat64(js, apptime());
break;
case 135: case 135:
ret = number2js(cam_zoom()); ret = number2js(cam_zoom());
@ -959,11 +900,6 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
text_flush(&hudproj); text_flush(&hudproj);
break; break;
case 142:
str = JS_ToCString(js, argv[1]);
log_print(str);
break;
case 149: case 149:
((struct drawmodel *)js2ptr(argv[1]))->model = GetExistingModel(js2str(argv[2])); ((struct drawmodel *)js2ptr(argv[1]))->model = GetExistingModel(js2str(argv[2]));
break; break;
@ -1057,15 +993,6 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
case 207: case 207:
ret = dsp_node2js(dsp_fwd_delay(js2number(argv[1]), js2number(argv[2]))); ret = dsp_node2js(dsp_fwd_delay(js2number(argv[1]), js2number(argv[2])));
break; break;
case 210:
ret = jscurtime();
break;
case 211:
ret = jstzone();
break;
case 212:
ret = jsdst();
break;
case 213: case 213:
free_drawmodel(js2ptr(argv[1])); free_drawmodel(js2ptr(argv[1]));
break; break;
@ -1242,9 +1169,6 @@ JSValue duk_sys_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *ar
case 6: case 6:
return JS_NewBool(js, sim_paused()); return JS_NewBool(js, sim_paused());
case 8:
return JS_NewInt64(js, frame_fps());
} }
return JS_UNDEFINED; return JS_UNDEFINED;
@ -1254,20 +1178,6 @@ JSValue duk_make_gameobject(JSContext *js, JSValueConst this, int argc, JSValueC
return gameobject2js(MakeGameobject()); return gameobject2js(MakeGameobject());
} }
JSValue duk_yughlog(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) {
int cmd = js2int(argv[0]);
const char *s = JS_ToCString(js, argv[1]);
const char *f = JS_ToCString(js, argv[2]);
int line = js2int(argv[3]);
mYughLog(LOG_SCRIPT, cmd, line, f, s);
JS_FreeCString(js, s);
JS_FreeCString(js, f);
return JS_UNDEFINED;
}
JSValue duk_set_body(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) { JSValue duk_set_body(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) {
int cmd = js2int(argv[0]); int cmd = js2int(argv[0]);
gameobject *go = js2gameobject(argv[1]); gameobject *go = js2gameobject(argv[1]);
@ -1490,10 +1400,14 @@ GETSET_PAIR(warp_gravity, planar_force, vec3)
#define MIST_CFUNC_DEF(name, length, func1) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE | JS_PROP_ENUMERABLE, JS_DEF_CFUNC, 0, .u = { .func = { length, JS_CFUNC_generic, { .generic = func1 } } } } #define MIST_CFUNC_DEF(name, length, func1) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE | JS_PROP_ENUMERABLE, 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)
#define MIST_CGETSET_DEF(name, fgetter, fsetter) { name, JS_PROP_CONFIGURABLE | JS_PROP_ENUMERABLE, JS_DEF_CGETSET, 0, .u = { .getset = { .get = { .getter = fgetter }, .set = { .setter = fsetter } } } } #define MIST_CGETSET_DEF(name, fgetter, fsetter) { name, JS_PROP_CONFIGURABLE | JS_PROP_ENUMERABLE, JS_DEF_CGETSET, 0, .u = { .getset = { .get = { .getter = fgetter }, .set = { .setter = fsetter } } } }
#define CGETSET_ADD(ID, ENTRY) MIST_CGETSET_DEF(#ENTRY, ID##_get_##ENTRY, ID##_set_##ENTRY) #define CGETSET_ADD(ID, ENTRY) MIST_CGETSET_DEF(#ENTRY, ID##_get_##ENTRY, ID##_set_##ENTRY)
#define GGETSET_ADD(ENTRY)
static const JSCFunctionListEntry js_warp_gravity_funcs [] = { static const JSCFunctionListEntry js_warp_gravity_funcs [] = {
CGETSET_ADD(warp_gravity, strength), CGETSET_ADD(warp_gravity, strength),
CGETSET_ADD(warp_gravity, decay), CGETSET_ADD(warp_gravity, decay),
@ -1582,9 +1496,92 @@ JSValue js_os_sys(JSContext *js, JSValueConst this, int argc, JSValue *argv)
} }
static const JSCFunctionListEntry js_os_funcs[] = { static const JSCFunctionListEntry js_os_funcs[] = {
MIST_CFUNC_DEF("cwd", 0, js_os_cwd), MIST_FUNC_DEF(os, cwd, 0),
MIST_CFUNC_DEF("env", 1, js_os_env), MIST_FUNC_DEF(os, env, 1),
MIST_CFUNC_DEF("sys", 0, js_os_sys), MIST_FUNC_DEF(os, sys, 0)
};
#define GETSET_GLOBAL(ENTRY, TYPE) \
JSValue global_set_##ENTRY (JSContext *js, JSValue this, JSValue val) { \
ENTRY = js2##TYPE (val); \
return JS_UNDEFINED; \
} \
\
JSValue global_get_##ENTRY (JSContext *js, JSValue this) { \
return TYPE##2js(ENTRY); \
} \
GETSET_GLOBAL(physMS, number)
GETSET_GLOBAL(timescale, number)
GETSET_GLOBAL(updateMS, number)
static const JSCFunctionListEntry js_prosperon_funcs[] = {
CGETSET_ADD(global, updateMS),
CGETSET_ADD(global, physMS),
CGETSET_ADD(global, timescale),
};
JSValue js_time_now(JSContext *js, JSValue this) {
struct timeval ct;
gettimeofday(&ct, NULL);
return number2js((double)ct.tv_sec+(double)(ct.tv_usec/1000000.0));
}
JSValue js_time_computer_dst(JSContext *js, JSValue this) {
time_t t = time(NULL);
return bool2js(localtime(&t)->tm_isdst);
}
JSValue js_time_computer_zone(JSContext *js, JSValue this) {
time_t t = time(NULL);
time_t local_t = mktime(localtime(&t));
double diff = difftime(t, local_t);
return number2js(diff/3600);
}
static const JSCFunctionListEntry js_time_funcs[] = {
MIST_FUNC_DEF(time, now, 0),
MIST_FUNC_DEF(time, computer_dst, 0),
MIST_FUNC_DEF(time, computer_zone, 0)
};
JSValue js_console_print(JSContext *js, JSValue this, int argc, JSValue *argv)
{
char *s = JS_ToCString(js,argv[0]);
log_print(s);
JS_FreeCString(js,s);
return JS_UNDEFINED;
}
JSValue js_console_rec(JSContext *js, JSValue this, int argc, JSValue *argv)
{
int level = js2int(argv[0]);
const char *msg = JS_ToCString(js, argv[1]);
const char *file = JS_ToCString(js, argv[2]);
int line = js2int(argv[3]);
mYughLog(LOG_SCRIPT, level, line, file, msg);
JS_FreeCString(js, msg);
JS_FreeCString(js, file);
return JS_UNDEFINED;
}
GETSET_GLOBAL(stdout_lvl, number)
static const JSCFunctionListEntry js_console_funcs[] = {
MIST_FUNC_DEF(console,print,1),
MIST_FUNC_DEF(console,rec,4),
CGETSET_ADD(global, stdout_lvl)
};
JSValue js_profile_now(JSContext *js, JSValue this) { return number2js(stm_now()); }
JSValue js_profile_fps(JSContext *js, JSValue this) { return number2js(frame_fps()); }
static const JSCFunctionListEntry js_profile_funcs[] = {
MIST_FUNC_DEF(profile,now,0),
MIST_FUNC_DEF(profile,fps,0)
}; };
JSValue js_io_exists(JSContext *js, JSValueConst this, int argc, JSValue *argv) JSValue js_io_exists(JSContext *js, JSValueConst this, int argc, JSValue *argv)
@ -2050,7 +2047,6 @@ void ffi_load() {
JS_SetPropertyFunctionList(js, nota, nota_funcs, countof(nota_funcs)); JS_SetPropertyFunctionList(js, nota, nota_funcs, countof(nota_funcs));
JS_SetPropertyStr(js, globalThis, "nota", nota); JS_SetPropertyStr(js, globalThis, "nota", nota);
DUK_FUNC(yughlog, 4)
DUK_FUNC(make_gameobject, 0) DUK_FUNC(make_gameobject, 0)
DUK_FUNC(set_body, 3) DUK_FUNC(set_body, 3)
DUK_FUNC(q_body, 2) DUK_FUNC(q_body, 2)
@ -2094,6 +2090,10 @@ void ffi_load() {
QJSGLOBALCLASS(os); QJSGLOBALCLASS(os);
QJSGLOBALCLASS(io); QJSGLOBALCLASS(io);
QJSGLOBALCLASS(prosperon);
QJSGLOBALCLASS(time);
QJSGLOBALCLASS(console);
QJSGLOBALCLASS(profile);
JS_SetPropertyStr(js, globalThis, "Window", window2js(&mainwin)); JS_SetPropertyStr(js, globalThis, "Window", window2js(&mainwin));

View file

@ -217,7 +217,7 @@ void trace_make_pipeline(const sg_pipeline_desc *d, sg_pipeline id, void *data)
void trace_apply_pipeline(sg_pipeline pip, void *data) void trace_apply_pipeline(sg_pipeline pip, void *data)
{ {
YughSpam("Applying pipeline %u %s.", pip, sg_query_pipeline_desc(pip).label); // YughSpam("Applying pipeline %u %s.", pip, sg_query_pipeline_desc(pip).label);
} }
void trace_fail_pipeline(sg_pipeline pip, void *data) void trace_fail_pipeline(sg_pipeline pip, void *data)
@ -232,7 +232,7 @@ void trace_make_attachments(const sg_attachment_desc *d, sg_attachments result,
void trace_begin_pass(sg_pass pass, const sg_pass_action *action, void *data) void trace_begin_pass(sg_pass pass, const sg_pass_action *action, void *data)
{ {
YughSpam("Begin pass %s", pass.label); // YughSpam("Begin pass %s", pass.label);
} }
static sg_trace_hooks hooks = { static sg_trace_hooks hooks = {

View file

@ -73,7 +73,7 @@ static int phys_step = 0;
uint64_t start_t; uint64_t start_t;
uint64_t frame_t; uint64_t frame_t;
static float timescale = 1.f; double timescale = 1.f;
#define SIM_PLAY 0 #define SIM_PLAY 0
#define SIM_PAUSE 1 #define SIM_PAUSE 1
@ -267,8 +267,6 @@ void sim_start() { sim_play = SIM_PLAY; }
void sim_pause() { sim_play = SIM_PAUSE; } void sim_pause() { sim_play = SIM_PAUSE; }
int phys_stepping() { return sim_play == SIM_STEP; } int phys_stepping() { return sim_play == SIM_STEP; }
void sim_step() { sim_play = SIM_STEP; } void sim_step() { sim_play = SIM_STEP; }
void set_timescale(float val) { timescale = val; }
double get_timescale() { return timescale; }
static sapp_desc start_desc = { static sapp_desc start_desc = {
.width = 720, .width = 720,
@ -302,7 +300,7 @@ int main(int argc, char **argv) {
#endif #endif
resources_init(); resources_init();
stm_setup(); /* time */
script_startup(); script_startup();
int argsize = 0; int argsize = 0;
@ -333,7 +331,7 @@ int main(int argc, char **argv) {
void engine_start(JSValue fn) void engine_start(JSValue fn)
{ {
c_init_fn = fn; c_init_fn = fn;
stm_setup(); /* time */
start_t = frame_t = stm_now(); start_t = frame_t = stm_now();
physlast = updatelast = start_t; physlast = updatelast = start_t;
sound_init(); sound_init();

View file

@ -10,15 +10,14 @@ void sim_pause();
void sim_stop(); void sim_stop();
void sim_step(); void sim_step();
int phys_stepping(); int phys_stepping();
void set_timescale(float val);
void print_stacktrace(); void print_stacktrace();
void engine_start(JSValue fn); /* fn runs after the engine starts */ void engine_start(JSValue fn); /* fn runs after the engine starts */
int frame_fps(); int frame_fps();
double get_timescale();
void quit(); void quit();
double apptime(); double apptime();
extern double timescale;
extern double renderMS; extern double renderMS;
extern double physMS; extern double physMS;
extern double updateMS; extern double updateMS;