fix makefile; prettify javascript
This commit is contained in:
parent
f95249f147
commit
f35c77c4a9
4
.prettierignore
Normal file
4
.prettierignore
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
**/*.html
|
||||||
|
**/*.json
|
||||||
|
**/*.css
|
||||||
|
**/*.md
|
21
.prettierrc
Normal file
21
.prettierrc
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"arrowParens": "avoid",
|
||||||
|
"bracketSameLine": false,
|
||||||
|
"bracketSpacing": true,
|
||||||
|
"semi": true,
|
||||||
|
"experimentalTernaries": false,
|
||||||
|
"singleQuote": false,
|
||||||
|
"jsxSingleQuote": false,
|
||||||
|
"quoteProps": "as-needed",
|
||||||
|
"trailingComma": "all",
|
||||||
|
"singleAttributePerLine": false,
|
||||||
|
"htmlWhitespaceSensitivity": "css",
|
||||||
|
"vueIndentScriptAndStyle": false,
|
||||||
|
"proseWrap": "preserve",
|
||||||
|
"insertPragma": false,
|
||||||
|
"printWidth": 1000,
|
||||||
|
"requirePragma": false,
|
||||||
|
"tabWidth": 2,
|
||||||
|
"useTabs": false,
|
||||||
|
"embeddedLanguageFormatting": "auto"
|
||||||
|
}
|
10
Makefile
10
Makefile
|
@ -27,19 +27,19 @@ ifeq ($(CROSS)$(CC), emcc)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifdef NEDITOR
|
ifdef NEDITOR
|
||||||
CPPFLAGS += -DNO_EDITOR
|
CPPFLAGS += -DNO_EDITOR
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifdef NFLAC
|
ifdef NFLAC
|
||||||
CPPFLAGS += -DNFLAC
|
CPPFLAGS += -DNFLAC
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifdef NMP3
|
ifdef NMP3
|
||||||
CPPFLAGS += -DNMP3
|
CPPFLAGS += -DNMP3
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifdef NSVG
|
ifdef NSVG
|
||||||
CPPFLAGS += -DNSVG
|
CPPFLAGS += -DNSVG
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifdef NQOA
|
ifdef NQOA
|
||||||
|
@ -297,4 +297,4 @@ tags: $(TAGINC)
|
||||||
|
|
||||||
MYFILES != (ls scripts/*.js* source/engine/*.[ch] source/engine/sound/*.[ch])
|
MYFILES != (ls scripts/*.js* source/engine/*.[ch] source/engine/sound/*.[ch])
|
||||||
pretty:
|
pretty:
|
||||||
clang-format -i $(MYFILES)
|
clang-format -i $(MYFILES)
|
||||||
|
|
|
@ -16,5 +16,5 @@ achievement.doc = {
|
||||||
hidden: "True if the player shouldn't see this achievement.",
|
hidden: "True if the player shouldn't see this achievement.",
|
||||||
icon: "Path to an unlocked icon.",
|
icon: "Path to an unlocked icon.",
|
||||||
licon: "Path to icon for not achieved.",
|
licon: "Path to icon for not achieved.",
|
||||||
max: "Value needed to reach to unlock the achievement."
|
max: "Value needed to reach to unlock the achievement.",
|
||||||
};
|
};
|
||||||
|
|
108
scripts/actor.js
108
scripts/actor.js
|
@ -5,8 +5,7 @@ var script_times = {};
|
||||||
|
|
||||||
var actor_spawns = {};
|
var actor_spawns = {};
|
||||||
|
|
||||||
globalThis.class_use = function(script, config, base, callback)
|
globalThis.class_use = function (script, config, base, callback) {
|
||||||
{
|
|
||||||
var file = Resources.find_script(script);
|
var file = Resources.find_script(script);
|
||||||
|
|
||||||
if (!file) {
|
if (!file) {
|
||||||
|
@ -31,24 +30,21 @@ globalThis.class_use = function(script, config, base, callback)
|
||||||
|
|
||||||
var script = Resources.replstrs(file);
|
var script = Resources.replstrs(file);
|
||||||
script = `(function() { var self = this; var $ = this.__proto__; ${script}; })`;
|
script = `(function() { var self = this; var $ = this.__proto__; ${script}; })`;
|
||||||
|
|
||||||
var fn = os.eval(file,script);
|
var fn = os.eval(file, script);
|
||||||
fn.call(padawan);
|
fn.call(padawan);
|
||||||
|
|
||||||
if (typeof config === 'object')
|
if (typeof config === "object") Object.merge(padawan, config);
|
||||||
Object.merge(padawan,config);
|
|
||||||
|
|
||||||
return padawan;
|
return padawan;
|
||||||
}
|
};
|
||||||
|
|
||||||
globalThis.rmactor = function(e)
|
globalThis.rmactor = function (e) {
|
||||||
{
|
|
||||||
if (!actor_spawns[e._file]) return;
|
if (!actor_spawns[e._file]) return;
|
||||||
actor_spawns[e._file].remove(e);
|
actor_spawns[e._file].remove(e);
|
||||||
}
|
};
|
||||||
|
|
||||||
actor.__stats = function()
|
actor.__stats = function () {
|
||||||
{
|
|
||||||
var total = 0;
|
var total = 0;
|
||||||
var stats = {};
|
var stats = {};
|
||||||
for (var i in actor_spawns) {
|
for (var i in actor_spawns) {
|
||||||
|
@ -57,10 +53,9 @@ actor.__stats = function()
|
||||||
}
|
}
|
||||||
stats.total = total;
|
stats.total = total;
|
||||||
return stats;
|
return stats;
|
||||||
}
|
};
|
||||||
|
|
||||||
actor.hotreload = function()
|
actor.hotreload = function () {
|
||||||
{
|
|
||||||
profile.cache("hotreload", "check");
|
profile.cache("hotreload", "check");
|
||||||
for (var i in script_times) {
|
for (var i in script_times) {
|
||||||
if (io.mod(i) > script_times[i]) {
|
if (io.mod(i) > script_times[i]) {
|
||||||
|
@ -72,54 +67,54 @@ actor.hotreload = function()
|
||||||
var $ = this.__proto__;
|
var $ = this.__proto__;
|
||||||
${script};
|
${script};
|
||||||
})`;
|
})`;
|
||||||
var fn = os.eval(i,script);
|
var fn = os.eval(i, script);
|
||||||
|
|
||||||
for (var obj of actor_spawns[i]) {
|
for (var obj of actor_spawns[i]) {
|
||||||
var a = obj;
|
var a = obj;
|
||||||
for (var t of a.timers)
|
for (var t of a.timers) t();
|
||||||
t();
|
a.timers = [];
|
||||||
a.timers = [];
|
var save = json.decode(json.encode(a));
|
||||||
var save = json.decode(json.encode(a));
|
|
||||||
fn.call(a);
|
fn.call(a);
|
||||||
Object.merge(a,save);
|
Object.merge(a, save);
|
||||||
check_registers(a);
|
check_registers(a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
profile.endcache();
|
profile.endcache();
|
||||||
}
|
};
|
||||||
|
|
||||||
actor.spawn = function(script, config){
|
actor.spawn = function (script, config) {
|
||||||
if (typeof script !== 'string') return undefined;
|
if (typeof script !== "string") return undefined;
|
||||||
|
|
||||||
var padawan = class_use(script, config, actor);
|
var padawan = class_use(script, config, actor);
|
||||||
|
|
||||||
padawan.padawans = [];
|
padawan.padawans = [];
|
||||||
padawan.timers = [];
|
padawan.timers = [];
|
||||||
padawan.master = this;
|
padawan.master = this;
|
||||||
Object.hide(padawan, "master","padawans");
|
Object.hide(padawan, "master", "padawans");
|
||||||
padawan.toString = function() { return script; }
|
padawan.toString = function () {
|
||||||
|
return script;
|
||||||
|
};
|
||||||
check_registers(padawan);
|
check_registers(padawan);
|
||||||
this.padawans.push(padawan);
|
this.padawans.push(padawan);
|
||||||
if (padawan.awake) padawan.awake();
|
if (padawan.awake) padawan.awake();
|
||||||
return padawan;
|
return padawan;
|
||||||
};
|
};
|
||||||
|
|
||||||
actor.tween = function(from,to,time,fn) {
|
actor.tween = function (from, to, time, fn) {
|
||||||
var stop = tween(from,to,time,fn);
|
var stop = tween(from, to, time, fn);
|
||||||
this.timers.push(stop);
|
this.timers.push(stop);
|
||||||
return stop;
|
return stop;
|
||||||
}
|
};
|
||||||
|
|
||||||
actor.spawn.doc = `Create a new actor, using this actor as the master, initializing it with 'script' and with data (as a JSON or Nota file) from 'config'.`;
|
actor.spawn.doc = `Create a new actor, using this actor as the master, initializing it with 'script' and with data (as a JSON or Nota file) from 'config'.`;
|
||||||
|
|
||||||
actor.rm_pawn = function(pawn)
|
actor.rm_pawn = function (pawn) {
|
||||||
{
|
|
||||||
this.padawans.remove(pawn);
|
this.padawans.remove(pawn);
|
||||||
}
|
};
|
||||||
|
|
||||||
actor.timers = [];
|
actor.timers = [];
|
||||||
actor.kill = function(){
|
actor.kill = function () {
|
||||||
if (this.__dead__) return;
|
if (this.__dead__) return;
|
||||||
this.timers.forEach(t => t());
|
this.timers.forEach(t => t());
|
||||||
input.do_uncontrol(this);
|
input.do_uncontrol(this);
|
||||||
|
@ -129,62 +124,65 @@ actor.kill = function(){
|
||||||
this.padawans = [];
|
this.padawans = [];
|
||||||
this.__dead__ = true;
|
this.__dead__ = true;
|
||||||
actor_spawns[this._file].remove(this);
|
actor_spawns[this._file].remove(this);
|
||||||
if (typeof this.die === 'function') this.die();
|
if (typeof this.die === "function") this.die();
|
||||||
if (typeof this.stop === 'function') this.stop();
|
if (typeof this.stop === "function") this.stop();
|
||||||
if (typeof this.garbage === 'function') this.garbage();
|
if (typeof this.garbage === "function") this.garbage();
|
||||||
if (typeof this.then === 'function') this.then();
|
if (typeof this.then === "function") this.then();
|
||||||
};
|
};
|
||||||
|
|
||||||
actor.kill.doc = `Remove this actor and all its padawans from existence.`;
|
actor.kill.doc = `Remove this actor and all its padawans from existence.`;
|
||||||
|
|
||||||
actor.delay = function(fn, seconds) {
|
actor.delay = function (fn, seconds) {
|
||||||
var timers = this.timers;
|
var timers = this.timers;
|
||||||
var stop = function() {
|
var stop = function () {
|
||||||
timers.remove(stop);
|
timers.remove(stop);
|
||||||
stop = undefined;
|
stop = undefined;
|
||||||
rm();
|
rm();
|
||||||
}
|
};
|
||||||
|
|
||||||
function execute() {
|
function execute() {
|
||||||
if (fn) fn();
|
if (fn) fn();
|
||||||
if (stop && stop.then) stop.then();
|
if (stop && stop.then) stop.then();
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
stop.remain = seconds;
|
stop.remain = seconds;
|
||||||
stop.seconds = seconds;
|
stop.seconds = seconds;
|
||||||
stop.pct = function() { return 1-(stop.remain / stop.seconds); };
|
stop.pct = function () {
|
||||||
|
return 1 - stop.remain / stop.seconds;
|
||||||
|
};
|
||||||
|
|
||||||
function update(dt) {
|
function update(dt) {
|
||||||
profile.frame("timer");
|
profile.frame("timer");
|
||||||
stop.remain -= dt;
|
stop.remain -= dt;
|
||||||
if (stop.remain <= 0) execute();
|
if (stop.remain <= 0) execute();
|
||||||
profile.endframe();
|
profile.endframe();
|
||||||
}
|
}
|
||||||
|
|
||||||
var rm = Register.appupdate.register(update);
|
var rm = Register.appupdate.register(update);
|
||||||
|
|
||||||
timers.push(stop);
|
timers.push(stop);
|
||||||
return stop;
|
return stop;
|
||||||
};
|
};
|
||||||
actor.delay.doc = `Call 'fn' after 'seconds' with 'this' set to the actor.`;
|
actor.delay.doc = `Call 'fn' after 'seconds' with 'this' set to the actor.`;
|
||||||
|
|
||||||
actor.interval = function(fn, seconds)
|
actor.interval = function (fn, seconds) {
|
||||||
{
|
|
||||||
var self = this;
|
var self = this;
|
||||||
var stop;
|
var stop;
|
||||||
var usefn = function() {
|
var usefn = function () {
|
||||||
fn();
|
fn();
|
||||||
stop = self.delay(usefn, seconds);
|
stop = self.delay(usefn, seconds);
|
||||||
}
|
};
|
||||||
stop = self.delay(usefn, seconds);
|
stop = self.delay(usefn, seconds);
|
||||||
|
|
||||||
return stop;
|
return stop;
|
||||||
}
|
};
|
||||||
|
|
||||||
actor.padawans = [];
|
actor.padawans = [];
|
||||||
|
|
||||||
global.app = Object.create(actor);
|
global.app = Object.create(actor);
|
||||||
app.die = function() { os.quit(); }
|
app.die = function () {
|
||||||
|
os.quit();
|
||||||
|
};
|
||||||
|
|
||||||
return {actor, app};
|
return { actor, app };
|
||||||
|
|
|
@ -1,58 +1,55 @@
|
||||||
var ai = {
|
var ai = {
|
||||||
race(list) {
|
race(list) {
|
||||||
return function(dt) {
|
return function (dt) {
|
||||||
var good = false;
|
var good = false;
|
||||||
for (var i = 0; i < list.length; i++)
|
for (var i = 0; i < list.length; i++) if (list[i].call(this, dt)) good = true;
|
||||||
if (list[i].call(this,dt)) good=true;
|
|
||||||
|
|
||||||
return good;
|
return good;
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
sequence(list) {
|
sequence(list) {
|
||||||
var i = 0;
|
var i = 0;
|
||||||
var fn = function(dt) {
|
var fn = function (dt) {
|
||||||
while (i !== list.length) {
|
while (i !== list.length) {
|
||||||
if (list[i].call(this,dt))
|
if (list[i].call(this, dt)) i++;
|
||||||
i++;
|
else return false;
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
if (fn.done) fn.done();
|
if (fn.done) fn.done();
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
fn.restart = function() { i = 0; };
|
fn.restart = function () {
|
||||||
|
i = 0;
|
||||||
|
};
|
||||||
return fn;
|
return fn;
|
||||||
},
|
},
|
||||||
|
|
||||||
parallel(list) {
|
parallel(list) {
|
||||||
return function(dt) {
|
return function (dt) {
|
||||||
var good = true;
|
var good = true;
|
||||||
list.forEach(function(x){ if (!x.call(this,dt)) good = false; },this);
|
list.forEach(function (x) {
|
||||||
|
if (!x.call(this, dt)) good = false;
|
||||||
|
}, this);
|
||||||
return good;
|
return good;
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
dofor(secs, fn) {
|
dofor(secs, fn) {
|
||||||
return ai.race([
|
return ai.race([ai.wait(secs), fn]);
|
||||||
ai.wait(secs),
|
|
||||||
fn
|
|
||||||
]);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
wait(secs = 1) {
|
wait(secs = 1) {
|
||||||
var accum = 0;
|
var accum = 0;
|
||||||
return function(dt) {
|
return function (dt) {
|
||||||
accum += dt;
|
accum += dt;
|
||||||
if (accum >= secs) {
|
if (accum >= secs) {
|
||||||
accum = 0;
|
accum = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
return {ai};
|
return { ai };
|
||||||
|
|
1638
scripts/base.js
1638
scripts/base.js
File diff suppressed because it is too large
Load diff
|
@ -1,43 +1,48 @@
|
||||||
this.phys = physics.kinematic;
|
this.phys = physics.kinematic;
|
||||||
this.dir_view2world = function(dir) { return dir.scale(this.zoom); };
|
this.dir_view2world = function (dir) {
|
||||||
this.view2world = function(pos) {
|
return dir.scale(this.zoom);
|
||||||
|
};
|
||||||
|
this.view2world = function (pos) {
|
||||||
var useren = window.rendersize.scale(this.zoom);
|
var useren = window.rendersize.scale(this.zoom);
|
||||||
if (window.mode === window.modetypes.stretch) {
|
if (window.mode === window.modetypes.stretch) {
|
||||||
pos = pos.scale([window.rendersize.x/window.size.x, window.rendersize.y/window.size.y]);
|
pos = pos.scale([window.rendersize.x / window.size.x, window.rendersize.y / window.size.y]);
|
||||||
pos = pos.sub(window.rendersize.scale(0.5));
|
pos = pos.sub(window.rendersize.scale(0.5));
|
||||||
pos = pos.scale(this.zoom);
|
pos = pos.scale(this.zoom);
|
||||||
pos = pos.add(this.pos);
|
pos = pos.add(this.pos);
|
||||||
}
|
}
|
||||||
if (window.mode === window.modetypes.full) {
|
if (window.mode === window.modetypes.full) {
|
||||||
pos = pos.sub(window.size.scale(0.5));
|
pos = pos.sub(window.size.scale(0.5));
|
||||||
pos = pos.scale(this.zoom);
|
pos = pos.scale(this.zoom);
|
||||||
pos = pos.add(this.pos);
|
pos = pos.add(this.pos);
|
||||||
}
|
}
|
||||||
if (window.mode === window.modetypes.expand) {
|
if (window.mode === window.modetypes.expand) {
|
||||||
pos = pos.sub(window.size.scale(0.5));
|
pos = pos.sub(window.size.scale(0.5));
|
||||||
pos = pos.scale([window.rendersize.x/window.size.x, window.rendersize.y/window.size.y]);
|
pos = pos.scale([window.rendersize.x / window.size.x, window.rendersize.y / window.size.y]);
|
||||||
}
|
}
|
||||||
return pos;
|
return pos;
|
||||||
};
|
};
|
||||||
this.world2view = function(pos) {
|
this.world2view = function (pos) {
|
||||||
if (window.mode === window.modetypes.stretch) {
|
if (window.mode === window.modetypes.stretch) {
|
||||||
pos = pos.sub(this.pos);
|
pos = pos.sub(this.pos);
|
||||||
pos = pos.scale(1.0/this.zoom);
|
pos = pos.scale(1.0 / this.zoom);
|
||||||
pos = pos.add(window.rendersize.scale(0.5));
|
pos = pos.add(window.rendersize.scale(0.5));
|
||||||
}
|
}
|
||||||
if (window.mode === window.modetypes.full) {
|
if (window.mode === window.modetypes.full) {
|
||||||
pos = pos.sub(this.pos);
|
pos = pos.sub(this.pos);
|
||||||
pos = pos.scale(1/this.zoom);
|
pos = pos.scale(1 / this.zoom);
|
||||||
pos = pos.add(window.size.scale(0.5));
|
pos = pos.add(window.size.scale(0.5));
|
||||||
}
|
}
|
||||||
if (window.mode === window.modetypes.expand) {
|
if (window.mode === window.modetypes.expand) {
|
||||||
|
|
||||||
}
|
}
|
||||||
return pos;
|
return pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.screenright = function() { return this.view2world(window.size).x; }
|
this.screenright = function () {
|
||||||
this.screenleft = function() { return this.view2world([0,0]).x; }
|
return this.view2world(window.size).x;
|
||||||
|
};
|
||||||
|
this.screenleft = function () {
|
||||||
|
return this.view2world([0, 0]).x;
|
||||||
|
};
|
||||||
|
|
||||||
var zoom = 1;
|
var zoom = 1;
|
||||||
|
|
||||||
|
@ -46,6 +51,7 @@ Object.mixin(self, {
|
||||||
zoom = x;
|
zoom = x;
|
||||||
if (zoom <= 0.1) zoom = 0.1;
|
if (zoom <= 0.1) zoom = 0.1;
|
||||||
},
|
},
|
||||||
get zoom() { return zoom; }
|
get zoom() {
|
||||||
}
|
return zoom;
|
||||||
);
|
},
|
||||||
|
});
|
||||||
|
|
207
scripts/color.js
207
scripts/color.js
|
@ -1,113 +1,118 @@
|
||||||
var Color = {
|
var Color = {
|
||||||
white: [255,255,255],
|
white: [255, 255, 255],
|
||||||
black: [0,0,0],
|
black: [0, 0, 0],
|
||||||
blue: [0,0,255],
|
blue: [0, 0, 255],
|
||||||
green: [0,255,0],
|
green: [0, 255, 0],
|
||||||
yellow: [255,255,0],
|
yellow: [255, 255, 0],
|
||||||
red: [255,0,0],
|
red: [255, 0, 0],
|
||||||
gray: [181,181,181],
|
gray: [181, 181, 181],
|
||||||
cyan: [0,255,255],
|
cyan: [0, 255, 255],
|
||||||
purple: [162,93,227],
|
purple: [162, 93, 227],
|
||||||
orange: [255,144,64],
|
orange: [255, 144, 64],
|
||||||
magenta: [255,0,255],
|
magenta: [255, 0, 255],
|
||||||
};
|
};
|
||||||
|
|
||||||
Color.editor = {};
|
Color.editor = {};
|
||||||
Color.editor.ur = Color.green;
|
Color.editor.ur = Color.green;
|
||||||
|
|
||||||
Color.tohtml = function(v)
|
Color.tohtml = function (v) {
|
||||||
{
|
var html = v.map(function (n) {
|
||||||
var html = v.map(function(n) { return Number.hex(n*255); });
|
return Number.hex(n * 255);
|
||||||
return "#" + html.join('');
|
});
|
||||||
}
|
return "#" + html.join("");
|
||||||
|
};
|
||||||
|
|
||||||
var esc = {};
|
var esc = {};
|
||||||
esc.reset = "\x1b[0";
|
esc.reset = "\x1b[0";
|
||||||
esc.color = function(v) {
|
esc.color = function (v) {
|
||||||
var c = v.map(function(n) { return Math.floor(n*255); });
|
var c = v.map(function (n) {
|
||||||
var truecolor = "\x1b[38;2;" + c.join(';') + ';';
|
return Math.floor(n * 255);
|
||||||
|
});
|
||||||
|
var truecolor = "\x1b[38;2;" + c.join(";") + ";";
|
||||||
return truecolor;
|
return truecolor;
|
||||||
}
|
};
|
||||||
|
|
||||||
esc.doc = "Functions and constants for ANSI escape sequences.";
|
esc.doc = "Functions and constants for ANSI escape sequences.";
|
||||||
|
|
||||||
Color.Arkanoid = {
|
Color.Arkanoid = {
|
||||||
orange: [255,143,0],
|
orange: [255, 143, 0],
|
||||||
teal: [0,255,255],
|
teal: [0, 255, 255],
|
||||||
green: [0,255,0],
|
green: [0, 255, 0],
|
||||||
red: [255,0,0],
|
red: [255, 0, 0],
|
||||||
blue: [0,112,255],
|
blue: [0, 112, 255],
|
||||||
purple: [255,0,255],
|
purple: [255, 0, 255],
|
||||||
yellow: [255,255,0],
|
yellow: [255, 255, 0],
|
||||||
silver: [157,157,157],
|
silver: [157, 157, 157],
|
||||||
gold: [188,174,0],
|
gold: [188, 174, 0],
|
||||||
};
|
};
|
||||||
|
|
||||||
Color.Arkanoid.Powerups = {
|
Color.Arkanoid.Powerups = {
|
||||||
red: [174,0,0], /* laser */
|
red: [174, 0, 0] /* laser */,
|
||||||
blue: [0,0,174], /* enlarge */
|
blue: [0, 0, 174] /* enlarge */,
|
||||||
green: [0,174,0], /* catch */
|
green: [0, 174, 0] /* catch */,
|
||||||
orange: [224,143,0], /* slow */
|
orange: [224, 143, 0] /* slow */,
|
||||||
purple: [210,0,210], /* break */
|
purple: [210, 0, 210] /* break */,
|
||||||
cyan: [0,174,255], /* disruption */
|
cyan: [0, 174, 255] /* disruption */,
|
||||||
gray: [143,143,143] /* 1up */
|
gray: [143, 143, 143] /* 1up */,
|
||||||
};
|
};
|
||||||
|
|
||||||
Color.Gameboy = {
|
Color.Gameboy = {
|
||||||
darkest: [229,107,26],
|
darkest: [229, 107, 26],
|
||||||
dark: [229,189,26],
|
dark: [229, 189, 26],
|
||||||
light: [189,229,26],
|
light: [189, 229, 26],
|
||||||
lightest: [107,229,26],
|
lightest: [107, 229, 26],
|
||||||
};
|
};
|
||||||
|
|
||||||
Color.Apple = {
|
Color.Apple = {
|
||||||
green: [94,189,62],
|
green: [94, 189, 62],
|
||||||
yellow: [255,185,0],
|
yellow: [255, 185, 0],
|
||||||
orange: [247,130,0],
|
orange: [247, 130, 0],
|
||||||
red: [226,56,56],
|
red: [226, 56, 56],
|
||||||
purple: [151,57,153],
|
purple: [151, 57, 153],
|
||||||
blue: [0,156,223]
|
blue: [0, 156, 223],
|
||||||
};
|
};
|
||||||
|
|
||||||
Color.Debug = {
|
Color.Debug = {
|
||||||
boundingbox: Color.white,
|
boundingbox: Color.white,
|
||||||
names: [84,110,255],
|
names: [84, 110, 255],
|
||||||
};
|
};
|
||||||
|
|
||||||
Color.Editor = {
|
Color.Editor = {
|
||||||
grid: [99,255,128],
|
grid: [99, 255, 128],
|
||||||
select: [255,255,55],
|
select: [255, 255, 55],
|
||||||
newgroup: [120,255,10],
|
newgroup: [120, 255, 10],
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Detects the format of all colors and munges them into a floating point format */
|
/* Detects the format of all colors and munges them into a floating point format */
|
||||||
Color.normalize = function(c) {
|
Color.normalize = function (c) {
|
||||||
var add_a = function(a) {
|
var add_a = function (a) {
|
||||||
var n = this.slice();
|
var n = this.slice();
|
||||||
n.a = a;
|
n.a = a;
|
||||||
return n;
|
return n;
|
||||||
};
|
};
|
||||||
|
|
||||||
for (var p of Object.keys(c)) {
|
for (var p of Object.keys(c)) {
|
||||||
var fmt = "nrm";
|
var fmt = "nrm";
|
||||||
if (typeof c[p] !== 'object') continue;
|
if (typeof c[p] !== "object") continue;
|
||||||
if (!Array.isArray(c[p])) {
|
if (!Array.isArray(c[p])) {
|
||||||
Color.normalize(c[p]);
|
Color.normalize(c[p]);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
c[p][3] = 255;
|
c[p][3] = 255;
|
||||||
|
|
||||||
for (var color of c[p]) {
|
for (var color of c[p]) {
|
||||||
if (color > 1) {
|
if (color > 1) {
|
||||||
fmt = "8b";
|
fmt = "8b";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(fmt) {
|
switch (fmt) {
|
||||||
case "8b":
|
case "8b":
|
||||||
c[p] = c[p].map(function(x) { return x/255; });
|
c[p] = c[p].map(function (x) {
|
||||||
|
return x / 255;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
c[p].alpha = add_a;
|
c[p].alpha = add_a;
|
||||||
}
|
}
|
||||||
|
@ -118,66 +123,64 @@ Color.normalize(Color);
|
||||||
Object.deepfreeze(Color);
|
Object.deepfreeze(Color);
|
||||||
|
|
||||||
var ColorMap = {};
|
var ColorMap = {};
|
||||||
ColorMap.makemap = function(map)
|
ColorMap.makemap = function (map) {
|
||||||
{
|
|
||||||
var newmap = Object.create(ColorMap);
|
var newmap = Object.create(ColorMap);
|
||||||
Object.assign(newmap, map);
|
Object.assign(newmap, map);
|
||||||
return newmap;
|
return newmap;
|
||||||
}
|
};
|
||||||
ColorMap.Jet = ColorMap.makemap({
|
ColorMap.Jet = ColorMap.makemap({
|
||||||
0: [0,0,131],
|
0: [0, 0, 131],
|
||||||
0.125: [0,60,170],
|
0.125: [0, 60, 170],
|
||||||
0.375: [5,255,255],
|
0.375: [5, 255, 255],
|
||||||
0.625: [255,255,0],
|
0.625: [255, 255, 0],
|
||||||
0.875: [250,0,0],
|
0.875: [250, 0, 0],
|
||||||
1: [128,0,0]
|
1: [128, 0, 0],
|
||||||
});
|
});
|
||||||
|
|
||||||
ColorMap.BlueRed = ColorMap.makemap({
|
ColorMap.BlueRed = ColorMap.makemap({
|
||||||
0: [0,0,255],
|
0: [0, 0, 255],
|
||||||
1: [255,0,0]
|
1: [255, 0, 0],
|
||||||
});
|
});
|
||||||
|
|
||||||
ColorMap.Inferno = ColorMap.makemap({
|
ColorMap.Inferno = ColorMap.makemap({
|
||||||
0:[0,0,4],
|
0: [0, 0, 4],
|
||||||
0.13: [31,12,72],
|
0.13: [31, 12, 72],
|
||||||
0.25: [85,15,109],
|
0.25: [85, 15, 109],
|
||||||
0.38: [136,34,106],
|
0.38: [136, 34, 106],
|
||||||
0.5: [186,54,85],
|
0.5: [186, 54, 85],
|
||||||
0.63: [227,89,51],
|
0.63: [227, 89, 51],
|
||||||
0.75: [249,140,10],
|
0.75: [249, 140, 10],
|
||||||
0.88: [249,201,50],
|
0.88: [249, 201, 50],
|
||||||
1: [252,255,164]
|
1: [252, 255, 164],
|
||||||
});
|
});
|
||||||
|
|
||||||
ColorMap.Bathymetry = ColorMap.makemap({
|
ColorMap.Bathymetry = ColorMap.makemap({
|
||||||
0: [40,26,44],
|
0: [40, 26, 44],
|
||||||
0.13: [59.49,90],
|
0.13: [59.49, 90],
|
||||||
0.25: [64,76,139],
|
0.25: [64, 76, 139],
|
||||||
0.38: [63,110,151],
|
0.38: [63, 110, 151],
|
||||||
0.5: [72,142,158],
|
0.5: [72, 142, 158],
|
||||||
0.63: [85,174,163],
|
0.63: [85, 174, 163],
|
||||||
0.75: [120,206,163],
|
0.75: [120, 206, 163],
|
||||||
0.88: [187,230,172],
|
0.88: [187, 230, 172],
|
||||||
1: [253,254,204]
|
1: [253, 254, 204],
|
||||||
});
|
});
|
||||||
|
|
||||||
ColorMap.Viridis = ColorMap.makemap({
|
ColorMap.Viridis = ColorMap.makemap({
|
||||||
0: [68,1,84],
|
0: [68, 1, 84],
|
||||||
0.13: [71,44,122],
|
0.13: [71, 44, 122],
|
||||||
0.25: [59,81,139],
|
0.25: [59, 81, 139],
|
||||||
0.38: [44,113,142],
|
0.38: [44, 113, 142],
|
||||||
0.5: [33,144,141],
|
0.5: [33, 144, 141],
|
||||||
0.63: [39,173,129],
|
0.63: [39, 173, 129],
|
||||||
0.75: [92,200,99],
|
0.75: [92, 200, 99],
|
||||||
0.88: [170,220,50],
|
0.88: [170, 220, 50],
|
||||||
1: [253,231,37]
|
1: [253, 231, 37],
|
||||||
});
|
});
|
||||||
|
|
||||||
Color.normalize(ColorMap);
|
Color.normalize(ColorMap);
|
||||||
|
|
||||||
ColorMap.sample = function(t, map = this)
|
ColorMap.sample = function (t, map = this) {
|
||||||
{
|
|
||||||
if (t < 0) return map[0];
|
if (t < 0) return map[0];
|
||||||
if (t > 1) return map[1];
|
if (t > 1) return map[1];
|
||||||
|
|
||||||
|
@ -192,7 +195,7 @@ ColorMap.sample = function(t, map = this)
|
||||||
lastkey = key;
|
lastkey = key;
|
||||||
}
|
}
|
||||||
return map[1];
|
return map[1];
|
||||||
}
|
};
|
||||||
|
|
||||||
ColorMap.doc = {
|
ColorMap.doc = {
|
||||||
sample: "Sample a given colormap at the given percentage (0 to 1).",
|
sample: "Sample a given colormap at the given percentage (0 to 1).",
|
||||||
|
@ -203,5 +206,5 @@ Object.freeze(ColorMap);
|
||||||
return {
|
return {
|
||||||
Color,
|
Color,
|
||||||
esc,
|
esc,
|
||||||
ColorMap
|
ColorMap,
|
||||||
}
|
};
|
||||||
|
|
File diff suppressed because it is too large
Load diff
169
scripts/debug.js
169
scripts/debug.js
|
@ -1,4 +1,7 @@
|
||||||
debug.build = function(fn) { if (!debug.show) return; fn(); }
|
debug.build = function (fn) {
|
||||||
|
if (!debug.show) return;
|
||||||
|
fn();
|
||||||
|
};
|
||||||
debug.show = true;
|
debug.show = true;
|
||||||
debug.urnames = false;
|
debug.urnames = false;
|
||||||
debug.termout = true;
|
debug.termout = true;
|
||||||
|
@ -7,64 +10,62 @@ debug.cheat = false;
|
||||||
debug.meta = false;
|
debug.meta = false;
|
||||||
debug.showprofiler = false;
|
debug.showprofiler = false;
|
||||||
|
|
||||||
debug.fn_break = function(fn,obj = globalThis) {
|
debug.fn_break = function (fn, obj = globalThis) {
|
||||||
if (typeof fn !== 'function') return;
|
if (typeof fn !== "function") return;
|
||||||
|
|
||||||
var newfn = function() {
|
var newfn = function () {
|
||||||
console.log("broke");
|
console.log("broke");
|
||||||
fn();
|
fn();
|
||||||
};
|
};
|
||||||
obj[fn.name] = newfn;
|
obj[fn.name] = newfn;
|
||||||
}
|
};
|
||||||
|
|
||||||
debug.draw_phys = false;
|
debug.draw_phys = false;
|
||||||
debug.draw_bb = false;
|
debug.draw_bb = false;
|
||||||
debug.draw_gizmos = false;
|
debug.draw_gizmos = false;
|
||||||
debug.draw_names = false;
|
debug.draw_names = false;
|
||||||
debug.sprite_nums = false;
|
debug.sprite_nums = false;
|
||||||
debug.draw = function() {
|
debug.draw = function () {
|
||||||
if (this.draw_phys) game.all_objects(function(x) { debug.draw_gameobject(x); });
|
if (this.draw_phys)
|
||||||
|
game.all_objects(function (x) {
|
||||||
|
debug.draw_gameobject(x);
|
||||||
|
});
|
||||||
|
|
||||||
if (this.draw_bb)
|
if (this.draw_bb)
|
||||||
game.all_objects(function(x) { debug.boundingbox(x.boundingbox(), Color.debug.boundingbox.alpha(0.05)); });
|
game.all_objects(function (x) {
|
||||||
|
debug.boundingbox(x.boundingbox(), Color.debug.boundingbox.alpha(0.05));
|
||||||
|
});
|
||||||
|
|
||||||
if (this.draw_gizmos)
|
if (this.draw_gizmos)
|
||||||
game.all_objects(function(x) {
|
game.all_objects(function (x) {
|
||||||
if (!x.icon) return;
|
if (!x.icon) return;
|
||||||
gui.image(x.icon, game.camera.world2view(x.pos));
|
gui.image(x.icon, game.camera.world2view(x.pos));
|
||||||
});
|
});
|
||||||
|
|
||||||
if (this.draw_names)
|
if (this.draw_names)
|
||||||
game.all_objects(function(x) {
|
game.all_objects(function (x) {
|
||||||
render.text(x, game.camera.view2screen(x.pos).add([0,32]), 1, Color.debug.names);
|
render.text(x, game.camera.view2screen(x.pos).add([0, 32]), 1, Color.debug.names);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (debug.gif.rec) {
|
if (debug.gif.rec) {
|
||||||
render.text("REC", [0,40], 1);
|
render.text("REC", [0, 40], 1);
|
||||||
render.text(time.timecode(time.timenow() - debug.gif.start_time, debug.gif.fps), [0,30], 1);
|
render.text(time.timecode(time.timenow() - debug.gif.start_time, debug.gif.fps), [0, 30], 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (sim.paused()) render.text("PAUSED", [0,0],1);
|
|
||||||
|
|
||||||
render.text(sim.playing() ? "PLAYING"
|
if (sim.paused()) render.text("PAUSED", [0, 0], 1);
|
||||||
: sim.stepping() ?
|
|
||||||
"STEP" :
|
|
||||||
sim.paused() ?
|
|
||||||
"PAUSED; EDITING" :
|
|
||||||
"EDIT", [0, 0], 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
var assert = function(op, str = `assertion failed [value '${op}']`)
|
render.text(sim.playing() ? "PLAYING" : sim.stepping() ? "STEP" : sim.paused() ? "PAUSED; EDITING" : "EDIT", [0, 0], 1);
|
||||||
{
|
};
|
||||||
if (!op)
|
|
||||||
console.panic(str);
|
var assert = function (op, str = `assertion failed [value '${op}']`) {
|
||||||
}
|
if (!op) console.panic(str);
|
||||||
|
};
|
||||||
|
|
||||||
var Gizmos = {
|
var Gizmos = {
|
||||||
pick_gameobject_points(worldpos, gameobject, points) {
|
pick_gameobject_points(worldpos, gameobject, points) {
|
||||||
var idx = Math.grab_from_points(worldpos, points.map(gameobject.this2world,gameobject), 25);
|
var idx = Math.grab_from_points(worldpos, points.map(gameobject.this2world, gameobject), 25);
|
||||||
if (idx === -1) return undefined;
|
if (idx === -1) return undefined;
|
||||||
return idx;
|
return idx;
|
||||||
},
|
},
|
||||||
|
@ -72,20 +73,24 @@ var Gizmos = {
|
||||||
|
|
||||||
/* 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 = {};
|
||||||
debug.inputs.f1 = function () { debug.draw_phys = !debug.draw_phys; };
|
debug.inputs.f1 = function () {
|
||||||
|
debug.draw_phys = !debug.draw_phys;
|
||||||
|
};
|
||||||
debug.inputs.f1.doc = "Draw physics debugging aids.";
|
debug.inputs.f1.doc = "Draw physics debugging aids.";
|
||||||
debug.inputs.f3 = function() { debug.draw_bb = !debug.draw_bb; };
|
debug.inputs.f3 = function () {
|
||||||
|
debug.draw_bb = !debug.draw_bb;
|
||||||
|
};
|
||||||
debug.inputs.f3.doc = "Toggle drawing bounding boxes.";
|
debug.inputs.f3.doc = "Toggle drawing bounding boxes.";
|
||||||
debug.inputs.f4 = function() {
|
debug.inputs.f4 = function () {
|
||||||
debug.draw_names = !debug.draw_names;
|
debug.draw_names = !debug.draw_names;
|
||||||
debug.draw_gizmos = !debug.draw_gizmos;
|
debug.draw_gizmos = !debug.draw_gizmos;
|
||||||
};
|
};
|
||||||
debug.inputs.f4.doc = "Toggle drawing gizmos and names of objects.";
|
debug.inputs.f4.doc = "Toggle drawing gizmos and names of objects.";
|
||||||
|
|
||||||
var gif = {
|
var gif = {
|
||||||
w: 640, /* Max width */
|
w: 640 /* Max width */,
|
||||||
h: 480, /* Max height */
|
h: 480 /* Max height */,
|
||||||
stretch: false, /* True if you want to stretch */
|
stretch: false /* True if you want to stretch */,
|
||||||
cpf: 4,
|
cpf: 4,
|
||||||
depth: 16,
|
depth: 16,
|
||||||
file: "out.gif",
|
file: "out.gif",
|
||||||
|
@ -97,17 +102,15 @@ var gif = {
|
||||||
var w = this.w;
|
var w = this.w;
|
||||||
var h = this.h;
|
var h = this.h;
|
||||||
if (!this.stretch) {
|
if (!this.stretch) {
|
||||||
var win = window.height / window.width;
|
var win = window.height / window.width;
|
||||||
var gif = h/w;
|
var gif = h / w;
|
||||||
if (gif > win)
|
if (gif > win) h = w * win;
|
||||||
h = w * win;
|
else w = h / win;
|
||||||
else
|
|
||||||
w = h / win;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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.now();
|
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);
|
||||||
|
@ -115,54 +118,59 @@ var gif = {
|
||||||
|
|
||||||
stop() {
|
stop() {
|
||||||
if (!this.rec) return;
|
if (!this.rec) return;
|
||||||
// cmd(132, this.file);
|
// cmd(132, this.file);
|
||||||
this.rec = false;
|
this.rec = false;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
debug.inputs.f8 = function() {
|
debug.inputs.f8 = function () {
|
||||||
var now = new Date();
|
var now = new Date();
|
||||||
debug.gif.file = now.toISOString() + ".gif";
|
debug.gif.file = now.toISOString() + ".gif";
|
||||||
debug.gif.start();
|
debug.gif.start();
|
||||||
};
|
};
|
||||||
debug.inputs.f9 = function() {
|
debug.inputs.f9 = function () {
|
||||||
debug.gif.stop();
|
debug.gif.stop();
|
||||||
}
|
};
|
||||||
|
|
||||||
debug.inputs.f10 = function() { time.timescale = 0.1; };
|
debug.inputs.f10 = function () {
|
||||||
|
time.timescale = 0.1;
|
||||||
|
};
|
||||||
debug.inputs.f10.doc = "Toggle timescale to 1/10.";
|
debug.inputs.f10.doc = "Toggle timescale to 1/10.";
|
||||||
debug.inputs.f10.released = function () { time.timescale = 1.0; };
|
debug.inputs.f10.released = function () {
|
||||||
debug.inputs.f12 = function() { gui.defaults.debug = !gui.defaults.debug; console.warn("gui toggle debug");};
|
time.timescale = 1.0;
|
||||||
|
};
|
||||||
|
debug.inputs.f12 = function () {
|
||||||
|
gui.defaults.debug = !gui.defaults.debug;
|
||||||
|
console.warn("gui toggle debug");
|
||||||
|
};
|
||||||
debug.inputs.f12.doc = "Toggle drawing gui debugging aids.";
|
debug.inputs.f12.doc = "Toggle drawing gui debugging aids.";
|
||||||
|
|
||||||
debug.inputs['M-1'] = render.normal;
|
debug.inputs["M-1"] = render.normal;
|
||||||
debug.inputs['M-2'] = render.wireframe;
|
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.";
|
||||||
|
|
||||||
debug.api = {};
|
debug.api = {};
|
||||||
debug.api.doc_entry = function(obj, key)
|
debug.api.doc_entry = function (obj, key) {
|
||||||
{
|
if (typeof key !== "string") {
|
||||||
if (typeof key !== 'string') {
|
|
||||||
console.warn("Cannot print a key that isn't a string.");
|
console.warn("Cannot print a key that isn't a string.");
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
var title = key;
|
var title = key;
|
||||||
|
|
||||||
var o = obj[key];
|
var o = obj[key];
|
||||||
if (typeof o === 'undefined' && obj.impl && typeof obj.impl[key] !== 'undefined')
|
if (typeof o === "undefined" && obj.impl && typeof obj.impl[key] !== "undefined") o = obj.impl[key];
|
||||||
o = obj.impl[key];
|
|
||||||
|
|
||||||
var t = typeof o;
|
var t = typeof o;
|
||||||
if (Array.isArray(o)) t = "array";
|
if (Array.isArray(o)) t = "array";
|
||||||
else if (t === 'function') {
|
else if (t === "function") {
|
||||||
title = o.toString().tofirst(')') + ")";
|
title = o.toString().tofirst(")") + ")";
|
||||||
title = title.fromfirst('(');
|
title = title.fromfirst("(");
|
||||||
title = key + "(" + title;
|
title = key + "(" + title;
|
||||||
if (o.doc) doc = o.doc;
|
if (o.doc) doc = o.doc;
|
||||||
t = "";
|
t = "";
|
||||||
} else if (t === 'undefined') t = "";
|
} else if (t === "undefined") t = "";
|
||||||
|
|
||||||
if (t) t = "**" + t + "**\n";
|
if (t) t = "**" + t + "**\n";
|
||||||
|
|
||||||
|
@ -175,12 +183,11 @@ debug.api.doc_entry = function(obj, key)
|
||||||
${t}
|
${t}
|
||||||
${doc}
|
${doc}
|
||||||
`;
|
`;
|
||||||
}
|
};
|
||||||
|
|
||||||
debug.api.print_doc = function(name)
|
debug.api.print_doc = function (name) {
|
||||||
{
|
|
||||||
var obj = name;
|
var obj = name;
|
||||||
if (typeof name === 'string') {
|
if (typeof name === "string") {
|
||||||
obj = eval(name);
|
obj = eval(name);
|
||||||
if (!obj) {
|
if (!obj) {
|
||||||
console.warn(`Cannot print the API of '${name}', as it was not found.`);
|
console.warn(`Cannot print the API of '${name}', as it was not found.`);
|
||||||
|
@ -189,8 +196,8 @@ debug.api.print_doc = function(name)
|
||||||
|
|
||||||
obj = globalThis[name];
|
obj = globalThis[name];
|
||||||
}
|
}
|
||||||
|
|
||||||
obj = eval(name);
|
obj = eval(name);
|
||||||
|
|
||||||
if (!Object.isObject(obj)) {
|
if (!Object.isObject(obj)) {
|
||||||
console.warn("Cannot print the API of something that isn't an object.");
|
console.warn("Cannot print the API of something that isn't an object.");
|
||||||
|
@ -201,24 +208,24 @@ debug.api.print_doc = function(name)
|
||||||
console.warn(`Object '${name}' does not exist.`);
|
console.warn(`Object '${name}' does not exist.`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var mdoc = "# " + name + "\n";
|
var mdoc = "# " + name + "\n";
|
||||||
if (obj.doc?.doc) mdoc += obj.doc.doc + "\n";
|
if (obj.doc?.doc) mdoc += obj.doc.doc + "\n";
|
||||||
else if (typeof obj.doc === 'string') mdoc += obj.doc + "\n";
|
else if (typeof obj.doc === "string") mdoc += obj.doc + "\n";
|
||||||
|
|
||||||
var keys = Object.keys(obj);
|
var keys = Object.keys(obj);
|
||||||
for (var key of keys) {
|
for (var key of keys) {
|
||||||
if (key === 'doc') continue;
|
if (key === "doc") continue;
|
||||||
if (key === 'toString') continue;
|
if (key === "toString") continue;
|
||||||
|
|
||||||
mdoc += debug.api.doc_entry(obj, key) + "\n";
|
mdoc += debug.api.doc_entry(obj, key) + "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return mdoc;
|
return mdoc;
|
||||||
}
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
debug,
|
debug,
|
||||||
Gizmos,
|
Gizmos,
|
||||||
assert
|
assert,
|
||||||
}
|
};
|
||||||
|
|
|
@ -1,98 +1,90 @@
|
||||||
function deep_copy(from) { return json.decode(json.encode(from)); }
|
function deep_copy(from) {
|
||||||
|
return json.decode(json.encode(from));
|
||||||
|
}
|
||||||
|
|
||||||
function valdiff(from,to)
|
function valdiff(from, to) {
|
||||||
{
|
|
||||||
if (typeof from !== typeof to) return from;
|
if (typeof from !== typeof to) return from;
|
||||||
if (typeof from === 'function') return undefined;
|
if (typeof from === "function") return undefined;
|
||||||
if (typeof from === 'undefined') return undefined;
|
if (typeof from === "undefined") return undefined;
|
||||||
|
|
||||||
|
if (typeof from === "number") {
|
||||||
|
return to;
|
||||||
|
|
||||||
if (typeof from === 'number') {
|
|
||||||
return to;
|
|
||||||
|
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof from === 'object')
|
if (typeof from === "object") return ediff(from, to);
|
||||||
return ediff(from,to);
|
|
||||||
|
|
||||||
if (from !== to) return to;
|
if (from !== to) return to;
|
||||||
|
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
function ediff(from,to)
|
function ediff(from, to) {
|
||||||
{
|
|
||||||
var ret = {};
|
var ret = {};
|
||||||
|
|
||||||
if (!to)
|
|
||||||
// return ediff(from, {});
|
|
||||||
return deep_copy(from);
|
|
||||||
|
|
||||||
Object.entries(from).forEach(function([key,v]) {
|
|
||||||
if (typeof v === 'function') return;
|
|
||||||
if (typeof v === 'undefined') return;
|
|
||||||
|
|
||||||
|
if (!to)
|
||||||
|
// return ediff(from, {});
|
||||||
|
return deep_copy(from);
|
||||||
|
|
||||||
|
Object.entries(from).forEach(function ([key, v]) {
|
||||||
|
if (typeof v === "function") return;
|
||||||
|
if (typeof v === "undefined") return;
|
||||||
|
|
||||||
if (Array.isArray(v)) {
|
if (Array.isArray(v)) {
|
||||||
if (!Array.isArray(to[key]) || v.length !== to[key].length) {
|
if (!Array.isArray(to[key]) || v.length !== to[key].length) {
|
||||||
var r = ediff(v,[]);
|
var r = ediff(v, []);
|
||||||
if (r) ret[key] = Object.values(r);
|
if (r) ret[key] = Object.values(r);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var diff = ediff(from[key], to[key]);
|
var diff = ediff(from[key], to[key]);
|
||||||
if (diff && !Object.empty(diff))
|
if (diff && !Object.empty(diff)) ret[key] = Object.values(ediff(v, []));
|
||||||
ret[key] = Object.values(ediff(v,[]));
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof v === 'object' && v !== null) {
|
if (typeof v === "object" && v !== null) {
|
||||||
var diff = ediff(v, to[key]);
|
var diff = ediff(v, to[key]);
|
||||||
if (diff && !Object.empty(diff))
|
if (diff && !Object.empty(diff)) ret[key] = diff;
|
||||||
ret[key] = diff;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof v === 'number' || v === null) {
|
if (typeof v === "number" || v === null) {
|
||||||
if (!isFinite(v)) v = null; // Squash infinity to null
|
if (!isFinite(v)) v = null; // Squash infinity to null
|
||||||
if (v !== to[key])
|
if (v !== to[key]) ret[key] = v;
|
||||||
ret[key] = v;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!to || v !== to[key])
|
if (!to || v !== to[key]) ret[key] = v;
|
||||||
ret[key] = v;
|
|
||||||
});
|
});
|
||||||
if (Object.empty(ret)) return undefined;
|
if (Object.empty(ret)) return undefined;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ediff.doc = "Given a from and to object, returns an object that, if applied to from, will make it the same as to. Does not include deletion; it is only additive. If one element in an array is different, the entire array is copied. Squashes infinite numbers to null for use in JSON.";
|
ediff.doc = "Given a from and to object, returns an object that, if applied to from, will make it the same as to. Does not include deletion; it is only additive. If one element in an array is different, the entire array is copied. Squashes infinite numbers to null for use in JSON.";
|
||||||
|
|
||||||
function samediff(from, to)
|
function samediff(from, to) {
|
||||||
{
|
|
||||||
var same = [];
|
var same = [];
|
||||||
if (!to) return same;
|
if (!to) return same;
|
||||||
if (typeof to !== 'object') {
|
if (typeof to !== "object") {
|
||||||
console.warn("'To' must be an object. Got " + to);
|
console.warn("'To' must be an object. Got " + to);
|
||||||
return same;
|
return same;
|
||||||
}
|
}
|
||||||
Object.keys(from).forEach(function(k) {
|
Object.keys(from).forEach(function (k) {
|
||||||
if (Object.isObject(from[k])) {
|
if (Object.isObject(from[k])) {
|
||||||
samediff(from[k], to[k]);
|
samediff(from[k], to[k]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (Array.isArray(from[k])) {
|
// if (Array.isArray(from[k])) {
|
||||||
// var d = valdiff(from[k], to[k]);
|
// var d = valdiff(from[k], to[k]);
|
||||||
// if (!d)
|
// if (!d)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
var d = valdiff(from[k], to[k]);
|
var d = valdiff(from[k], to[k]);
|
||||||
if (!d)
|
if (!d) delete from[k];
|
||||||
delete from[k];
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return same;
|
return same;
|
||||||
|
@ -104,4 +96,4 @@ return {
|
||||||
deep_copy,
|
deep_copy,
|
||||||
ediff,
|
ediff,
|
||||||
samediff,
|
samediff,
|
||||||
}
|
};
|
||||||
|
|
1355
scripts/editor.js
1355
scripts/editor.js
File diff suppressed because it is too large
Load diff
|
@ -4,8 +4,10 @@ os.mem_limit.doc = "Set the memory limit of the runtime in bytes.";
|
||||||
os.gc_threshold.doc = "Set the threshold before a GC pass is triggered in bytes. This is set to malloc_size + malloc_size>>1 after a GC pass.";
|
os.gc_threshold.doc = "Set the threshold before a GC pass is triggered in bytes. This is set to malloc_size + malloc_size>>1 after a GC pass.";
|
||||||
os.max_stacksize.doc = "Set the max stack size in bytes.";
|
os.max_stacksize.doc = "Set the max stack size in bytes.";
|
||||||
|
|
||||||
Object.defineProperty(String.prototype, 'rm', {
|
Object.defineProperty(String.prototype, "rm", {
|
||||||
value: function(index, endidx = index+1) { return this.slice(0,index) + this.slice(endidx); }
|
value: function (index, endidx = index + 1) {
|
||||||
|
return this.slice(0, index) + this.slice(endidx);
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Object.defineProperty(String.prototype, "tolast", {
|
Object.defineProperty(String.prototype, "tolast", {
|
||||||
|
@ -33,23 +35,22 @@ Object.defineProperty(String.prototype, "folder", {
|
||||||
|
|
||||||
globalThis.Resources = {};
|
globalThis.Resources = {};
|
||||||
|
|
||||||
Resources.rm_fn = function rm_fn(fn, text)
|
Resources.rm_fn = function rm_fn(fn, text) {
|
||||||
{
|
|
||||||
var reg = new RegExp(fn.source + "\\s*\\(");
|
var reg = new RegExp(fn.source + "\\s*\\(");
|
||||||
var match;
|
var match;
|
||||||
while (match = text.match(reg)) {
|
while ((match = text.match(reg))) {
|
||||||
var last = match.index+match[0].length;
|
var last = match.index + match[0].length;
|
||||||
var par = 1;
|
var par = 1;
|
||||||
while (par !== 0) {
|
while (par !== 0) {
|
||||||
if (text[last] === '(') par++;
|
if (text[last] === "(") par++;
|
||||||
if (text[last] === ')') par--;
|
if (text[last] === ")") par--;
|
||||||
last++;
|
last++;
|
||||||
}
|
}
|
||||||
text = text.rm(match.index, last);
|
text = text.rm(match.index, last);
|
||||||
}
|
}
|
||||||
|
|
||||||
return text;
|
return text;
|
||||||
}
|
};
|
||||||
Resources.rm_fn.doc = "Remove calls to a given function from a given text script.";
|
Resources.rm_fn.doc = "Remove calls to a given function from a given text script.";
|
||||||
|
|
||||||
Resources.replpath = function replpath(str, path) {
|
Resources.replpath = function replpath(str, path) {
|
||||||
|
@ -76,17 +77,15 @@ Resources.replstrs = function replstrs(path) {
|
||||||
|
|
||||||
var stem = path.dir();
|
var stem = path.dir();
|
||||||
|
|
||||||
if (!console.enabled)
|
if (!console.enabled) script = Resources.rm_fn(/console\.(spam|info|warn|error)/, script);
|
||||||
script = Resources.rm_fn(/console\.(spam|info|warn|error)/, script);
|
|
||||||
|
if (!profile.enabled) script = Resources.rm_fn(/profile\.(cache|frame|endcache|endframe)/, script);
|
||||||
if (!profile.enabled)
|
|
||||||
script = Resources.rm_fn(/profile\.(cache|frame|endcache|endframe)/, script);
|
|
||||||
|
|
||||||
if (!debug.enabled) {
|
if (!debug.enabled) {
|
||||||
script = Resources.rm_fn(/assert/, script);
|
script = Resources.rm_fn(/assert/, script);
|
||||||
script = Resources.rm_fn(/debug\.(build|fn_break)/, script);
|
script = Resources.rm_fn(/debug\.(build|fn_break)/, script);
|
||||||
}
|
}
|
||||||
|
|
||||||
script = script.replace(regexp, function (str) {
|
script = script.replace(regexp, function (str) {
|
||||||
var newstr = Resources.replpath(str.trimchr('"'), path);
|
var newstr = Resources.replpath(str.trimchr('"'), path);
|
||||||
return `"${newstr}"`;
|
return `"${newstr}"`;
|
||||||
|
@ -95,23 +94,21 @@ Resources.replstrs = function replstrs(path) {
|
||||||
return script;
|
return script;
|
||||||
};
|
};
|
||||||
|
|
||||||
Resources.is_sound = function(path) {
|
Resources.is_sound = function (path) {
|
||||||
var ext = path.ext();
|
var ext = path.ext();
|
||||||
return Resources.sounds.any(x => x === ext);
|
return Resources.sounds.any(x => x === ext);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
Resources.is_animation = function (path) {
|
||||||
|
if (path.ext() === "gif" && Resources.gif.frames(path) > 1) return true;
|
||||||
|
if (path.ext() === "ase") return true;
|
||||||
|
|
||||||
Resources.is_animation = function(path)
|
|
||||||
{
|
|
||||||
if (path.ext() === 'gif' && Resources.gif.frames(path) > 1) return true;
|
|
||||||
if (path.ext() === 'ase') return true;
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
};
|
||||||
|
|
||||||
Resources.is_path = function(str)
|
Resources.is_path = function (str) {
|
||||||
{
|
|
||||||
return !/[\\\/:*?"<>|]/.test(str);
|
return !/[\\\/:*?"<>|]/.test(str);
|
||||||
}
|
};
|
||||||
|
|
||||||
globalThis.json = {};
|
globalThis.json = {};
|
||||||
json.encode = function (value, replacer, space = 1) {
|
json.encode = function (value, replacer, space = 1) {
|
||||||
|
@ -154,16 +151,14 @@ function find_ext(file, ext, root = "") {
|
||||||
if (ext.some(x => x === file_ext)) return file;
|
if (ext.some(x => x === file_ext)) return file;
|
||||||
for (var e of ext) {
|
for (var e of ext) {
|
||||||
var nf = `${file}.${e}`;
|
var nf = `${file}.${e}`;
|
||||||
if (io.exists(nf))
|
if (io.exists(nf)) return nf;
|
||||||
return nf;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var all_files = io.glob(`**/${file}.*`);
|
var all_files = io.glob(`**/${file}.*`);
|
||||||
var find = undefined;
|
var find = undefined;
|
||||||
for (var e of ext) {
|
for (var e of ext) {
|
||||||
var finds = all_files.filter(x => x.ext() === e);
|
var finds = all_files.filter(x => x.ext() === e);
|
||||||
if (finds.length > 1)
|
if (finds.length > 1) console.warn(`Found conflicting files when searching for '${file}': ${json.encode(finds)}. Returning the first one.`);
|
||||||
console.warn(`Found conflicting files when searching for '${file}': ${json.encode(finds)}. Returning the first one.`);
|
|
||||||
if (finds.length > 0) {
|
if (finds.length > 0) {
|
||||||
find = finds[0];
|
find = finds[0];
|
||||||
break;
|
break;
|
||||||
|
@ -176,18 +171,17 @@ function find_ext(file, ext, root = "") {
|
||||||
var hashhit = 0;
|
var hashhit = 0;
|
||||||
var hashmiss = 0;
|
var hashmiss = 0;
|
||||||
|
|
||||||
Object.defineProperty(Function.prototype, 'hashify', {
|
Object.defineProperty(Function.prototype, "hashify", {
|
||||||
value: function() {
|
value: function () {
|
||||||
var hash = new Map();
|
var hash = new Map();
|
||||||
var fn = this;
|
var fn = this;
|
||||||
function ret() {
|
function ret() {
|
||||||
if (!hash.has(arguments[0]))
|
if (!hash.has(arguments[0])) hash.set(arguments[0], fn(...arguments));
|
||||||
hash.set(arguments[0], fn(...arguments));
|
|
||||||
|
|
||||||
return hash.get(arguments[0]);
|
return hash.get(arguments[0]);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Resources.find_image = function (file, root = "") {
|
Resources.find_image = function (file, root = "") {
|
||||||
|
@ -258,7 +252,7 @@ console.stackstr = function (skip = 0) {
|
||||||
};
|
};
|
||||||
|
|
||||||
console.stack = function (skip = 0) {
|
console.stack = function (skip = 0) {
|
||||||
var stack = console.stackstr(skip+1);
|
var stack = console.stackstr(skip + 1);
|
||||||
console.log(stack);
|
console.log(stack);
|
||||||
return stack;
|
return stack;
|
||||||
};
|
};
|
||||||
|
@ -301,9 +295,9 @@ globalThis.use = function use(file) {
|
||||||
profile.endcache();
|
profile.endcache();
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
};
|
||||||
|
|
||||||
function stripped_use (file, script) {
|
function stripped_use(file, script) {
|
||||||
file = Resources.find_script(file);
|
file = Resources.find_script(file);
|
||||||
|
|
||||||
if (use_cache[file]) {
|
if (use_cache[file]) {
|
||||||
|
@ -316,12 +310,11 @@ function stripped_use (file, script) {
|
||||||
var fn = os.eval(file, script);
|
var fn = os.eval(file, script);
|
||||||
var ret = fn();
|
var ret = fn();
|
||||||
profile.endcache();
|
profile.endcache();
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
function bare_use(file)
|
function bare_use(file) {
|
||||||
{
|
|
||||||
var script = io.slurp(file);
|
var script = io.slurp(file);
|
||||||
if (!script) return;
|
if (!script) return;
|
||||||
script = `(function() { var self = this; ${script}; })`;
|
script = `(function() { var self = this; ${script}; })`;
|
||||||
|
@ -337,17 +330,15 @@ debug.enabled = true;
|
||||||
bare_use("scripts/base.js");
|
bare_use("scripts/base.js");
|
||||||
bare_use("scripts/profile.js");
|
bare_use("scripts/profile.js");
|
||||||
|
|
||||||
prosperon.release = function()
|
prosperon.release = function () {
|
||||||
{
|
|
||||||
profile.enabled = false;
|
profile.enabled = false;
|
||||||
console.enabled = false;
|
console.enabled = false;
|
||||||
debug.enabled = false;
|
debug.enabled = false;
|
||||||
}
|
};
|
||||||
|
|
||||||
bare_use("preconfig.js");
|
bare_use("preconfig.js");
|
||||||
|
|
||||||
if (!profile.enabled)
|
if (!profile.enabled) use = stripped_use;
|
||||||
use = stripped_use;
|
|
||||||
|
|
||||||
Object.assign(globalThis, use("scripts/prosperon.js"));
|
Object.assign(globalThis, use("scripts/prosperon.js"));
|
||||||
|
|
||||||
|
@ -359,4 +350,3 @@ app.interval(_ => {
|
||||||
repl.hotreload();
|
repl.hotreload();
|
||||||
profile.endframe();
|
profile.endframe();
|
||||||
}, 1);
|
}, 1);
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
globalThis.entityreport = {};
|
globalThis.entityreport = {};
|
||||||
|
|
||||||
var timer_update = function(dt)
|
var timer_update = function (dt) {
|
||||||
{
|
|
||||||
this.fn();
|
this.fn();
|
||||||
}
|
};
|
||||||
|
|
||||||
function obj_unique_name(name, obj) {
|
function obj_unique_name(name, obj) {
|
||||||
name = name.replaceAll('.', '_');
|
name = name.replaceAll(".", "_");
|
||||||
if (!(name in obj)) return name;
|
if (!(name in obj)) return name;
|
||||||
var t = 1;
|
var t = 1;
|
||||||
var n = name + t;
|
var n = name + t;
|
||||||
|
@ -18,7 +17,7 @@ function obj_unique_name(name, obj) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function unique_name(list, name = "new_object") {
|
function unique_name(list, name = "new_object") {
|
||||||
var str = name.replaceAll('.', '_');
|
var str = name.replaceAll(".", "_");
|
||||||
var n = 1;
|
var n = 1;
|
||||||
var t = str;
|
var t = str;
|
||||||
while (list.indexOf(t) !== -1) {
|
while (list.indexOf(t) !== -1) {
|
||||||
|
@ -26,23 +25,22 @@ function unique_name(list, name = "new_object") {
|
||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
return t;
|
return t;
|
||||||
};
|
}
|
||||||
|
|
||||||
var entity = {
|
var entity = {
|
||||||
drawlayer: -1,
|
drawlayer: -1,
|
||||||
get_comp_by_name(name) {
|
get_comp_by_name(name) {
|
||||||
var comps = [];
|
var comps = [];
|
||||||
for (var c of Object.values(this.components))
|
for (var c of Object.values(this.components)) if (c.comp === name) comps.push(c);
|
||||||
if (c.comp === name) comps.push(c);
|
|
||||||
|
|
||||||
if (comps.length) return comps;
|
if (comps.length) return comps;
|
||||||
return undefined;
|
return undefined;
|
||||||
},
|
},
|
||||||
|
|
||||||
rigidify() {
|
rigidify() {
|
||||||
this.body = os.make_body(this.transform);
|
this.body = os.make_body(this.transform);
|
||||||
},
|
},
|
||||||
|
|
||||||
path_from(o) {
|
path_from(o) {
|
||||||
var p = this.toString();
|
var p = this.toString();
|
||||||
var c = this.master;
|
var c = this.master;
|
||||||
|
@ -53,15 +51,17 @@ var entity = {
|
||||||
if (c === world) p = "world." + p;
|
if (c === world) p = "world." + p;
|
||||||
return p;
|
return p;
|
||||||
},
|
},
|
||||||
|
|
||||||
drawlayer: 0,
|
drawlayer: 0,
|
||||||
|
|
||||||
full_path() { return this.path_from(world); },
|
full_path() {
|
||||||
|
return this.path_from(world);
|
||||||
|
},
|
||||||
|
|
||||||
clear() {
|
clear() {
|
||||||
for (var k in this.objects) {
|
for (var k in this.objects) {
|
||||||
this.objects[k].kill();
|
this.objects[k].kill();
|
||||||
};
|
}
|
||||||
this.objects = {};
|
this.objects = {};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -72,54 +72,75 @@ var entity = {
|
||||||
|
|
||||||
delay(fn, seconds) {
|
delay(fn, seconds) {
|
||||||
var timers = this.timers;
|
var timers = this.timers;
|
||||||
var stop = function() {
|
var stop = function () {
|
||||||
timers.remove(stop);
|
timers.remove(stop);
|
||||||
execute = undefined;
|
execute = undefined;
|
||||||
stop = undefined;
|
stop = undefined;
|
||||||
rm?.();
|
rm?.();
|
||||||
rm = undefined;
|
rm = undefined;
|
||||||
update = undefined;
|
update = undefined;
|
||||||
}
|
};
|
||||||
|
|
||||||
function execute() {
|
function execute() {
|
||||||
fn();
|
fn();
|
||||||
stop?.();
|
stop?.();
|
||||||
}
|
}
|
||||||
|
|
||||||
stop.remain = seconds;
|
stop.remain = seconds;
|
||||||
stop.seconds = seconds;
|
stop.seconds = seconds;
|
||||||
stop.pct = function() { return 1 - (stop.remain/stop.seconds); };
|
stop.pct = function () {
|
||||||
|
return 1 - stop.remain / stop.seconds;
|
||||||
|
};
|
||||||
|
|
||||||
function update(dt) {
|
function update(dt) {
|
||||||
profile.frame("timer");
|
profile.frame("timer");
|
||||||
if (stop) { // TODO: This seems broken
|
if (stop) {
|
||||||
stop.remain -= dt;
|
// TODO: This seems broken
|
||||||
if (stop.remain <= 0) execute();
|
stop.remain -= dt;
|
||||||
|
if (stop.remain <= 0) execute();
|
||||||
}
|
}
|
||||||
profile.endframe();
|
profile.endframe();
|
||||||
}
|
}
|
||||||
|
|
||||||
var rm = Register.update.register(update);
|
var rm = Register.update.register(update);
|
||||||
timers.push(stop);
|
timers.push(stop);
|
||||||
return stop;
|
return stop;
|
||||||
},
|
},
|
||||||
|
|
||||||
cry(file) { return audio.cry(file); },
|
cry(file) {
|
||||||
|
return audio.cry(file);
|
||||||
get pos() { return this.transform.pos; },
|
|
||||||
set pos(x) { this.transform.pos = x; },
|
|
||||||
get angle() { return this.transform.angle; },
|
|
||||||
set angle(x) { this.transform.angle = x; },
|
|
||||||
get scale() { return this.transform.scale; },
|
|
||||||
set scale(x) { this.transform.scale = x; },
|
|
||||||
|
|
||||||
move(vec) { this.pos = this.pos.add(vec); },
|
|
||||||
rotate(x) { this.transform.rotate(x, [0,0,-1]); },
|
|
||||||
grow(vec) {
|
|
||||||
if (typeof vec === 'number') vec = [vec,vec];
|
|
||||||
this.scale = this.scale.map((x,i) => x*vec[i]);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
get pos() {
|
||||||
|
return this.transform.pos;
|
||||||
|
},
|
||||||
|
set pos(x) {
|
||||||
|
this.transform.pos = x;
|
||||||
|
},
|
||||||
|
get angle() {
|
||||||
|
return this.transform.angle;
|
||||||
|
},
|
||||||
|
set angle(x) {
|
||||||
|
this.transform.angle = x;
|
||||||
|
},
|
||||||
|
get scale() {
|
||||||
|
return this.transform.scale;
|
||||||
|
},
|
||||||
|
set scale(x) {
|
||||||
|
this.transform.scale = x;
|
||||||
|
},
|
||||||
|
|
||||||
|
move(vec) {
|
||||||
|
this.pos = this.pos.add(vec);
|
||||||
|
},
|
||||||
|
rotate(x) {
|
||||||
|
this.transform.rotate(x, [0, 0, -1]);
|
||||||
|
},
|
||||||
|
grow(vec) {
|
||||||
|
if (typeof vec === "number") vec = [vec, vec];
|
||||||
|
this.scale = this.scale.map((x, i) => x * vec[i]);
|
||||||
|
},
|
||||||
|
|
||||||
/* Reparent 'this' to be 'parent's child */
|
/* Reparent 'this' to be 'parent's child */
|
||||||
reparent(parent) {
|
reparent(parent) {
|
||||||
assert(parent, `Tried to reparent ${this.toString()} to nothing.`);
|
assert(parent, `Tried to reparent ${this.toString()} to nothing.`);
|
||||||
|
@ -127,28 +148,26 @@ var entity = {
|
||||||
console.warn(`not reparenting ... ${this.master} is the same as ${parent}`);
|
console.warn(`not reparenting ... ${this.master} is the same as ${parent}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var name = unique_name(Object.keys(parent), this.name);
|
var name = unique_name(Object.keys(parent), this.name);
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
|
||||||
this.master?.remove_obj(this);
|
this.master?.remove_obj(this);
|
||||||
this.master = parent;
|
this.master = parent;
|
||||||
parent.objects[this.guid] = this;
|
parent.objects[this.guid] = this;
|
||||||
parent[name] = this;
|
parent[name] = this;
|
||||||
Object.hide(parent, name);
|
Object.hide(parent, name);
|
||||||
},
|
},
|
||||||
|
|
||||||
remove_obj(obj) {
|
remove_obj(obj) {
|
||||||
if (this.objects)
|
if (this.objects) delete this.objects[obj.guid];
|
||||||
delete this.objects[obj.guid];
|
else console.warn(`Object ${this.guid} has no objects file.`);
|
||||||
else
|
|
||||||
console.warn(`Object ${this.guid} has no objects file.`);
|
|
||||||
delete this[obj.name];
|
delete this[obj.name];
|
||||||
Object.unhide(this, obj.name);
|
Object.unhide(this, obj.name);
|
||||||
},
|
},
|
||||||
|
|
||||||
spawn(text, config, callback) {
|
spawn(text, config, callback) {
|
||||||
var ent = class_use(text, config, entity, function(ent) {
|
var ent = class_use(text, config, entity, function (ent) {
|
||||||
ent.transform = os.make_transform();
|
ent.transform = os.make_transform();
|
||||||
ent.guid = prosperon.guid();
|
ent.guid = prosperon.guid();
|
||||||
ent.components = {};
|
ent.components = {};
|
||||||
|
@ -157,7 +176,7 @@ var entity = {
|
||||||
ent.ur = {};
|
ent.ur = {};
|
||||||
ent.urname = text;
|
ent.urname = text;
|
||||||
});
|
});
|
||||||
/*
|
/*
|
||||||
if (!text)
|
if (!text)
|
||||||
ent.ur = emptyur;
|
ent.ur = emptyur;
|
||||||
else if (text instanceof Object) {// assume it's an ur
|
else if (text instanceof Object) {// assume it's an ur
|
||||||
|
@ -192,15 +211,15 @@ var entity = {
|
||||||
profile.cache("ENTITY TIME", ent.ur.name);
|
profile.cache("ENTITY TIME", ent.ur.name);
|
||||||
*/
|
*/
|
||||||
ent.reparent(this);
|
ent.reparent(this);
|
||||||
|
|
||||||
for (var [prop, p] of Object.entries(ent)) {
|
for (var [prop, p] of Object.entries(ent)) {
|
||||||
if (!p) continue;
|
if (!p) continue;
|
||||||
if (typeof p !== 'object') continue;
|
if (typeof p !== "object") continue;
|
||||||
if (!p.comp) continue;
|
if (!p.comp) continue;
|
||||||
ent[prop] = component[p.comp](ent);
|
ent[prop] = component[p.comp](ent);
|
||||||
Object.merge(ent[prop], p);
|
Object.merge(ent[prop], p);
|
||||||
ent.components[prop] = ent[prop];
|
ent.components[prop] = ent[prop];
|
||||||
};
|
}
|
||||||
|
|
||||||
check_registers(ent);
|
check_registers(ent);
|
||||||
|
|
||||||
|
@ -209,20 +228,20 @@ var entity = {
|
||||||
ent._started = true;
|
ent._started = true;
|
||||||
if (ent.start instanceof Function) ent.start();
|
if (ent.start instanceof Function) ent.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
Object.hide(ent, 'ur', 'components', 'objects', 'timers', 'guid', 'master', 'guid');
|
Object.hide(ent, "ur", "components", "objects", "timers", "guid", "master", "guid");
|
||||||
|
|
||||||
ent._ed = {
|
ent._ed = {
|
||||||
selectable: true,
|
selectable: true,
|
||||||
dirty: false,
|
dirty: false,
|
||||||
inst: false,
|
inst: false,
|
||||||
urdiff: {}
|
urdiff: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
Object.hide(ent, '_ed');
|
Object.hide(ent, "_ed");
|
||||||
|
|
||||||
ent.sync();
|
ent.sync();
|
||||||
|
|
||||||
if (!Object.empty(ent.objects)) {
|
if (!Object.empty(ent.objects)) {
|
||||||
var o = ent.objects;
|
var o = ent.objects;
|
||||||
delete ent.objects;
|
delete ent.objects;
|
||||||
|
@ -235,46 +254,63 @@ var entity = {
|
||||||
ent.rename_obj(n.toString(), i);
|
ent.rename_obj(n.toString(), i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ent.tag) game.tag_add(ent.tag, ent);
|
if (ent.tag) game.tag_add(ent.tag, ent);
|
||||||
|
|
||||||
if (callback) callback(ent);
|
if (callback) callback(ent);
|
||||||
|
|
||||||
ent.ur.fresh ??= json.decode(json.encode(ent));
|
ent.ur.fresh ??= json.decode(json.encode(ent));
|
||||||
ent.ur.fresh.objects = {};
|
ent.ur.fresh.objects = {};
|
||||||
for (var i in ent.objects)
|
for (var i in ent.objects) ent.ur.fresh.objects[i] = ent.objects[i].instance_obj();
|
||||||
ent.ur.fresh.objects[i] = ent.objects[i].instance_obj();
|
|
||||||
|
|
||||||
profile.endcache();
|
profile.endcache();
|
||||||
|
|
||||||
return ent;
|
return ent;
|
||||||
},
|
},
|
||||||
|
|
||||||
disable() { for (var x of this.components) x.disable(); },
|
disable() {
|
||||||
enable() { for (var x of this.components) x.enable(); },
|
for (var x of this.components) x.disable();
|
||||||
|
},
|
||||||
this2screen(pos) { return game.camera.world2view(this.this2world(pos)); },
|
enable() {
|
||||||
screen2this(pos) { return this.world2this(game.camera.view2world(pos)); },
|
for (var x of this.components) x.enable();
|
||||||
|
},
|
||||||
|
|
||||||
|
this2screen(pos) {
|
||||||
|
return game.camera.world2view(this.this2world(pos));
|
||||||
|
},
|
||||||
|
screen2this(pos) {
|
||||||
|
return this.world2this(game.camera.view2world(pos));
|
||||||
|
},
|
||||||
|
|
||||||
/* Make a unique object the same as its prototype */
|
/* Make a unique object the same as its prototype */
|
||||||
revert() { Object.merge(this, this.ur.fresh); },
|
revert() {
|
||||||
|
Object.merge(this, this.ur.fresh);
|
||||||
|
},
|
||||||
|
|
||||||
name: "new_object",
|
name: "new_object",
|
||||||
toString() { return this.name; },
|
toString() {
|
||||||
|
return this.name;
|
||||||
|
},
|
||||||
width() {
|
width() {
|
||||||
var bb = this.boundingbox();
|
var bb = this.boundingbox();
|
||||||
return bb.r - bb.l;
|
return bb.r - bb.l;
|
||||||
},
|
},
|
||||||
|
|
||||||
height() {
|
height() {
|
||||||
var bb = this.boundingbox();
|
var bb = this.boundingbox();
|
||||||
return bb.t - bb.b;
|
return bb.t - bb.b;
|
||||||
},
|
},
|
||||||
|
|
||||||
flipx() { return this.scale.x < 0; },
|
flipx() {
|
||||||
flipy() { return this.scale.y < 0; },
|
return this.scale.x < 0;
|
||||||
|
},
|
||||||
mirror(plane) { this.scale = Vector.reflect(this.scale, plane); },
|
flipy() {
|
||||||
|
return this.scale.y < 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
mirror(plane) {
|
||||||
|
this.scale = Vector.reflect(this.scale, plane);
|
||||||
|
},
|
||||||
|
|
||||||
/* Bounding box of the object in world dimensions */
|
/* Bounding box of the object in world dimensions */
|
||||||
boundingbox() {
|
boundingbox() {
|
||||||
|
@ -283,46 +319,42 @@ var entity = {
|
||||||
t: 0,
|
t: 0,
|
||||||
r: 0,
|
r: 0,
|
||||||
b: 0,
|
b: 0,
|
||||||
l: 0
|
l: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
for (var key in this.components) {
|
for (var key in this.components) {
|
||||||
if ('boundingbox' in this.components[key])
|
if ("boundingbox" in this.components[key]) boxes.push(this.components[key].boundingbox());
|
||||||
boxes.push(this.components[key].boundingbox());
|
|
||||||
}
|
}
|
||||||
for (var key in this.objects)
|
for (var key in this.objects) boxes.push(this.objects[key].boundingbox());
|
||||||
boxes.push(this.objects[key].boundingbox());
|
|
||||||
|
|
||||||
var bb = boxes.shift();
|
var bb = boxes.shift();
|
||||||
|
|
||||||
for (var x of boxes) bb = bbox.expand(bb, x);
|
for (var x of boxes) bb = bbox.expand(bb, x);
|
||||||
|
|
||||||
bb = bbox.move(bb, this.pos);
|
bb = bbox.move(bb, this.pos);
|
||||||
|
|
||||||
return bb ? bb : bbox.fromcwh([0, 0], [0, 0]);
|
return bb ? bb : bbox.fromcwh([0, 0], [0, 0]);
|
||||||
},
|
},
|
||||||
|
|
||||||
toJSON() {
|
toJSON() {
|
||||||
return {guid:this.guid};
|
return { guid: this.guid };
|
||||||
},
|
},
|
||||||
|
|
||||||
/* The unique components of this object. Its diff. */
|
/* The unique components of this object. Its diff. */
|
||||||
json_obj(depth=0) {
|
json_obj(depth = 0) {
|
||||||
var fresh = this.ur.fresh;
|
var fresh = this.ur.fresh;
|
||||||
var thiso = json.decode(json.encode(this)); // TODO: SLOW. Used to ignore properties in toJSON of components.
|
var thiso = json.decode(json.encode(this)); // TODO: SLOW. Used to ignore properties in toJSON of components.
|
||||||
var d = ediff(thiso, fresh);
|
var d = ediff(thiso, fresh);
|
||||||
|
|
||||||
d ??= {};
|
d ??= {};
|
||||||
|
|
||||||
fresh.objects ??= {};
|
fresh.objects ??= {};
|
||||||
var curobjs = {};
|
var curobjs = {};
|
||||||
for (var o in this.objects)
|
for (var o in this.objects) curobjs[o] = this.objects[o].instance_obj();
|
||||||
curobjs[o] = this.objects[o].instance_obj();
|
|
||||||
|
|
||||||
var odiff = ediff(curobjs, fresh.objects);
|
var odiff = ediff(curobjs, fresh.objects);
|
||||||
if (odiff)
|
if (odiff) d.objects = curobjs;
|
||||||
d.objects = curobjs;
|
|
||||||
|
|
||||||
delete d.pos;
|
delete d.pos;
|
||||||
delete d.angle;
|
delete d.angle;
|
||||||
delete d.scale;
|
delete d.scale;
|
||||||
|
@ -330,7 +362,7 @@ var entity = {
|
||||||
delete d.angularvelocity;
|
delete d.angularvelocity;
|
||||||
return d;
|
return d;
|
||||||
},
|
},
|
||||||
|
|
||||||
/* The object needed to store an object as an instance of a master */
|
/* The object needed to store an object as an instance of a master */
|
||||||
instance_obj() {
|
instance_obj() {
|
||||||
var t = os.make_transform();
|
var t = os.make_transform();
|
||||||
|
@ -338,65 +370,65 @@ var entity = {
|
||||||
t.ur = this.ur.name;
|
t.ur = this.ur.name;
|
||||||
return t;
|
return t;
|
||||||
},
|
},
|
||||||
|
|
||||||
transform() {
|
transform() {
|
||||||
var t = {};
|
var t = {};
|
||||||
t.pos = this.get_pos(this.master).map(x => Math.places(x, 0));
|
t.pos = this.get_pos(this.master).map(x => Math.places(x, 0));
|
||||||
t.angle = Math.places(this.get_angle(this.master), 4);
|
t.angle = Math.places(this.get_angle(this.master), 4);
|
||||||
t.scale = this.get_scale(this.master).map(x => Math.places(x, 2));;
|
t.scale = this.get_scale(this.master).map(x => Math.places(x, 2));
|
||||||
return t;
|
return t;
|
||||||
},
|
},
|
||||||
|
|
||||||
dup(diff) {
|
dup(diff) {
|
||||||
var n = this.master.spawn(this.ur);
|
var n = this.master.spawn(this.ur);
|
||||||
Object.totalmerge(n, this.transform());
|
Object.totalmerge(n, this.transform());
|
||||||
return n;
|
return n;
|
||||||
},
|
},
|
||||||
|
|
||||||
kill() {
|
kill() {
|
||||||
if (this.__kill) return;
|
if (this.__kill) return;
|
||||||
this.__kill = true;
|
this.__kill = true;
|
||||||
|
|
||||||
this.timers.forEach(x => x());
|
this.timers.forEach(x => x());
|
||||||
delete this.timers;
|
delete this.timers;
|
||||||
Event.rm_obj(this);
|
Event.rm_obj(this);
|
||||||
input.do_uncontrol(this);
|
input.do_uncontrol(this);
|
||||||
|
|
||||||
if (this.master) {
|
if (this.master) {
|
||||||
this.master.remove_obj(this);
|
this.master.remove_obj(this);
|
||||||
this.master = undefined;
|
this.master = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var key in this.components) {
|
for (var key in this.components) {
|
||||||
this.components[key].kill?.();
|
this.components[key].kill?.();
|
||||||
this.components[key].gameobject = undefined;
|
this.components[key].gameobject = undefined;
|
||||||
this.components[key].enabled = false;
|
this.components[key].enabled = false;
|
||||||
delete this.components[key];
|
delete this.components[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
delete this.components;
|
delete this.components;
|
||||||
|
|
||||||
this.clear();
|
this.clear();
|
||||||
if (this.stop instanceof Function) this.stop();
|
if (this.stop instanceof Function) this.stop();
|
||||||
if (typeof this.garbage === 'function') this.garbage();
|
if (typeof this.garbage === "function") this.garbage();
|
||||||
if (typeof this.then === 'function') this.then();
|
if (typeof this.then === "function") this.then();
|
||||||
|
|
||||||
game.tag_clear_guid(this.guid);
|
game.tag_clear_guid(this.guid);
|
||||||
|
|
||||||
rmactor(this);
|
rmactor(this);
|
||||||
|
|
||||||
for (var i in this) {
|
for (var i in this) {
|
||||||
if (this[i] instanceof Object || this[i] instanceof Function) delete this[i];
|
if (this[i] instanceof Object || this[i] instanceof Function) delete this[i];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
make_objs(objs) {
|
make_objs(objs) {
|
||||||
for (var prop in objs) {
|
for (var prop in objs) {
|
||||||
say(`spawning ${json.encode(objs[prop])}`);
|
say(`spawning ${json.encode(objs[prop])}`);
|
||||||
var newobj = this.spawn(objs[prop]);
|
var newobj = this.spawn(objs[prop]);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
rename_obj(name, newname) {
|
rename_obj(name, newname) {
|
||||||
if (!this.objects[name]) {
|
if (!this.objects[name]) {
|
||||||
console.warn(`No object with name ${name}. Could not rename to ${newname}.`);
|
console.warn(`No object with name ${name}. Could not rename to ${newname}.`);
|
||||||
|
@ -406,18 +438,19 @@ dup(diff) {
|
||||||
Object.hide(this, name);
|
Object.hide(this, name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (this.objects[newname])
|
if (this.objects[newname]) return;
|
||||||
return;
|
|
||||||
|
|
||||||
this.objects[newname] = this.objects[name];
|
this.objects[newname] = this.objects[name];
|
||||||
this[newname] = this[name];
|
this[newname] = this[name];
|
||||||
this[newname].toString = function() { return newname; };
|
this[newname].toString = function () {
|
||||||
|
return newname;
|
||||||
|
};
|
||||||
Object.hide(this, newname);
|
Object.hide(this, newname);
|
||||||
delete this.objects[name];
|
delete this.objects[name];
|
||||||
delete this[name];
|
delete this[name];
|
||||||
return this.objects[newname];
|
return this.objects[newname];
|
||||||
},
|
},
|
||||||
|
|
||||||
add_component(comp, data) {
|
add_component(comp, data) {
|
||||||
var name = prosperon.guid();
|
var name = prosperon.guid();
|
||||||
this.components[name] = comp(this);
|
this.components[name] = comp(this);
|
||||||
|
@ -438,10 +471,8 @@ var gameobject = {
|
||||||
if (!lur) return;
|
if (!lur) return;
|
||||||
var lur = lur.objects[this.toString()];
|
var lur = lur.objects[this.toString()];
|
||||||
var d = ediff(this._ed.urdiff, lur);
|
var d = ediff(this._ed.urdiff, lur);
|
||||||
if (!d || Object.empty(d))
|
if (!d || Object.empty(d)) this._ed.inst = true;
|
||||||
this._ed.inst = true;
|
else this._ed.inst = false;
|
||||||
else
|
|
||||||
this._ed.inst = false;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
namestr() {
|
namestr() {
|
||||||
|
@ -460,9 +491,9 @@ var gameobject = {
|
||||||
|
|
||||||
/* pin this object to the to object */
|
/* pin this object to the to object */
|
||||||
pin(to) {
|
pin(to) {
|
||||||
var p = joint.pin(this,to);
|
var p = joint.pin(this, to);
|
||||||
},
|
},
|
||||||
slide(to, a = [0,0], b = [0,0], min = 0, max = 50) {
|
slide(to, a = [0, 0], b = [0, 0], min = 0, max = 50) {
|
||||||
var p = joint.slide(this, to, a, b, min, max);
|
var p = joint.slide(this, to, a, b, min, max);
|
||||||
p.max_force = 500;
|
p.max_force = 500;
|
||||||
p.break();
|
p.break();
|
||||||
|
@ -471,10 +502,10 @@ var gameobject = {
|
||||||
var p = joint.pivot(this, to, piv);
|
var p = joint.pivot(this, to, piv);
|
||||||
},
|
},
|
||||||
/* groove is on to, from local points a and b, anchored to this at local anchor */
|
/* groove is on to, from local points a and b, anchored to this at local anchor */
|
||||||
groove(to, a, b, anchor = [0,0]) {
|
groove(to, a, b, anchor = [0, 0]) {
|
||||||
var p = joint.groove(to, this, a, b, anchor);
|
var p = joint.groove(to, this, a, b, anchor);
|
||||||
},
|
},
|
||||||
damped_spring(to, length = Vector.length(this.pos,to.pos), stiffness = 1, damping = 1) {
|
damped_spring(to, length = Vector.length(this.pos, to.pos), stiffness = 1, damping = 1) {
|
||||||
var dc = 2 * Math.sqrt(stiffness * this.mass);
|
var dc = 2 * Math.sqrt(stiffness * this.mass);
|
||||||
var p = joint.damped_spring(this, to, [0, 0], [0, 0], stiffness, damping * dc);
|
var p = joint.damped_spring(this, to, [0, 0], [0, 0], stiffness, damping * dc);
|
||||||
},
|
},
|
||||||
|
@ -506,7 +537,7 @@ var gameobject = {
|
||||||
this.rpos = newpos;
|
this.rpos = newpos;
|
||||||
for (var o of this.objects) o.move(move);
|
for (var o of this.objects) o.move(move);
|
||||||
},
|
},
|
||||||
|
|
||||||
set_angle(x, relative = world) {
|
set_angle(x, relative = world) {
|
||||||
var newangle = relative.angle + x;
|
var newangle = relative.angle + x;
|
||||||
var diff = newangle - this.angle;
|
var diff = newangle - this.angle;
|
||||||
|
@ -516,37 +547,42 @@ var gameobject = {
|
||||||
obj.set_pos(Vector.rotate(obj.get_pos(obj.master), diff), obj.master);
|
obj.set_pos(Vector.rotate(obj.get_pos(obj.master), diff), obj.master);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
set_scale(x, relative = world) {
|
set_scale(x, relative = world) {
|
||||||
if (typeof x === 'number') x = [x,x,x];
|
if (typeof x === "number") x = [x, x, x];
|
||||||
var newscale = relative.scale.map((s,i) => x[i]*s);
|
var newscale = relative.scale.map((s, i) => x[i] * s);
|
||||||
var pct = this.scale.map((s,i) => newscale[i]/s);
|
var pct = this.scale.map((s, i) => newscale[i] / s);
|
||||||
this.rscale = newscale;
|
this.rscale = newscale;
|
||||||
for (var obj of this.objects) {
|
for (var obj of this.objects) {
|
||||||
obj.grow(pct);
|
obj.grow(pct);
|
||||||
obj.set_pos(obj.get_pos(obj.master).map((x,i) => x*pct[i]), obj.master);
|
obj.set_pos(
|
||||||
};
|
obj.get_pos(obj.master).map((x, i) => x * pct[i]),
|
||||||
|
obj.master,
|
||||||
|
);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
get_pos(relative = world) {
|
get_pos(relative = world) {
|
||||||
if (relative === world) return this.pos;
|
if (relative === world) return this.pos;
|
||||||
return relative.world2this(this.pos);
|
return relative.world2this(this.pos);
|
||||||
//return this.pos.sub(relative.pos);
|
//return this.pos.sub(relative.pos);
|
||||||
},
|
},
|
||||||
|
|
||||||
get_angle(relative = world) {
|
get_angle(relative = world) {
|
||||||
if (relative === world) return this.angle;
|
if (relative === world) return this.angle;
|
||||||
return this.angle - relative.angle;
|
return this.angle - relative.angle;
|
||||||
},
|
},
|
||||||
|
|
||||||
get_scale(relative = world) {
|
get_scale(relative = world) {
|
||||||
if (relative === world) return this.scale;
|
if (relative === world) return this.scale;
|
||||||
var masterscale = relative.scale;
|
var masterscale = relative.scale;
|
||||||
return this.scale.map((x,i) => x/masterscale[i]);
|
return this.scale.map((x, i) => x / masterscale[i]);
|
||||||
},
|
},
|
||||||
|
|
||||||
in_air() { return this.in_air(); },
|
in_air() {
|
||||||
|
return this.in_air();
|
||||||
|
},
|
||||||
|
|
||||||
/* Velocity and angular velocity of the object */
|
/* Velocity and angular velocity of the object */
|
||||||
phys_obj() {
|
phys_obj() {
|
||||||
var phys = {};
|
var phys = {};
|
||||||
|
@ -554,13 +590,13 @@ var gameobject = {
|
||||||
phys.angularvelocity = this.angularvelocity;
|
phys.angularvelocity = this.angularvelocity;
|
||||||
return phys;
|
return phys;
|
||||||
},
|
},
|
||||||
|
|
||||||
set category(n) {
|
set category(n) {
|
||||||
if (n === 0) {
|
if (n === 0) {
|
||||||
this.categories = n;
|
this.categories = n;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var cat = (1 << (n-1));
|
var cat = 1 << (n - 1);
|
||||||
this.categories = cat;
|
this.categories = cat;
|
||||||
},
|
},
|
||||||
get category() {
|
get category() {
|
||||||
|
@ -568,16 +604,16 @@ var gameobject = {
|
||||||
var pos = 0;
|
var pos = 0;
|
||||||
var num = this.categories;
|
var num = this.categories;
|
||||||
while (num > 0) {
|
while (num > 0) {
|
||||||
if (num & 1) {
|
if (num & 1) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
pos++;
|
pos++;
|
||||||
num >>>= 1;
|
num >>>= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return pos+1;
|
return pos + 1;
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
entity.spawn.doc = `Spawn an entity of type 'ur' on this entity. Returns the spawned entity.`;
|
entity.spawn.doc = `Spawn an entity of type 'ur' on this entity. Returns the spawned entity.`;
|
||||||
|
|
||||||
|
@ -598,12 +634,12 @@ gameobject.doc = {
|
||||||
set_pos: `Function to set the position of the object in world coordinates.`,
|
set_pos: `Function to set the position of the object in world coordinates.`,
|
||||||
worldangle: `Function to get the angle of the entity in the world.`,
|
worldangle: `Function to get the angle of the entity in the world.`,
|
||||||
rotate: `Function to rotate this object by x degrees.`,
|
rotate: `Function to rotate this object by x degrees.`,
|
||||||
move: 'Move an object by x,y,z. If the first parameter is an array, uses up to the first three array values.',
|
move: "Move an object by x,y,z. If the first parameter is an array, uses up to the first three array values.",
|
||||||
pulse: `Apply an impulse to this body in world coordinates. Impulse is a short force.`,
|
pulse: `Apply an impulse to this body in world coordinates. Impulse is a short force.`,
|
||||||
shove: `Apply a force to this body in world coordinates. Should be used over many frames.`,
|
shove: `Apply a force to this body in world coordinates. Should be used over many frames.`,
|
||||||
shove_at: 'Apply a force to this body, at a position relative to itself.',
|
shove_at: "Apply a force to this body, at a position relative to itself.",
|
||||||
max_velocity: 'The max linear velocity this object can travel.',
|
max_velocity: "The max linear velocity this object can travel.",
|
||||||
max_angularvelocity: 'The max angular velocity this object can rotate.',
|
max_angularvelocity: "The max angular velocity this object can rotate.",
|
||||||
on_ground: `Return true if the object is on the ground.`,
|
on_ground: `Return true if the object is on the ground.`,
|
||||||
spawn: `Create an instance of a supplied ur-type on this object. Optionally provide a data object to modify the created entity.`,
|
spawn: `Create an instance of a supplied ur-type on this object. Optionally provide a data object to modify the created entity.`,
|
||||||
hide: `Make this object invisible.`,
|
hide: `Make this object invisible.`,
|
||||||
|
@ -616,28 +652,27 @@ gameobject.doc = {
|
||||||
transform: `Return an object representing the transform state of this object.`,
|
transform: `Return an object representing the transform state of this object.`,
|
||||||
kill: `Remove this object from the world.`,
|
kill: `Remove this object from the world.`,
|
||||||
master: "The entity this entity belongs to.",
|
master: "The entity this entity belongs to.",
|
||||||
delay: 'Run the given function after the given number of seconds has elapsed.',
|
delay: "Run the given function after the given number of seconds has elapsed.",
|
||||||
cry: 'Make a sound. Can only make one at a time.',
|
cry: "Make a sound. Can only make one at a time.",
|
||||||
add_component: 'Add a component to the object by name.',
|
add_component: "Add a component to the object by name.",
|
||||||
pin: 'Pin joint to another object. Acts as if a rigid rod is between the two objects.',
|
pin: "Pin joint to another object. Acts as if a rigid rod is between the two objects.",
|
||||||
slide: 'Slide joint, similar to a pin but with min and max allowed distances.',
|
slide: "Slide joint, similar to a pin but with min and max allowed distances.",
|
||||||
pivot: 'Pivot joint to an object, with the pivot given in world coordinates.',
|
pivot: "Pivot joint to an object, with the pivot given in world coordinates.",
|
||||||
groove: 'Groove joint. The groove is on to, from to local coordinates a and b, with this object anchored at anchor.',
|
groove: "Groove joint. The groove is on to, from to local coordinates a and b, with this object anchored at anchor.",
|
||||||
damped_spring: 'Damped spring to another object. Length is the distance it wants to be, stiffness is the spring constant, and damping is the damping ratio. 1 is critical, < 1 is underdamped, > 1 is overdamped.',
|
damped_spring: "Damped spring to another object. Length is the distance it wants to be, stiffness is the spring constant, and damping is the damping ratio. 1 is critical, < 1 is underdamped, > 1 is overdamped.",
|
||||||
damped_rotary_spring: 'Similar to damped spring but for rotation. Rest angle is the attempted angle.',
|
damped_rotary_spring: "Similar to damped spring but for rotation. Rest angle is the attempted angle.",
|
||||||
rotary_limit: 'Limit the angle relative to the to body between min and max.',
|
rotary_limit: "Limit the angle relative to the to body between min and max.",
|
||||||
ratchet: 'Like a socket wrench, relative to to. ratch is the distance between clicks.',
|
ratchet: "Like a socket wrench, relative to to. ratch is the distance between clicks.",
|
||||||
gear: 'Keeps the angular velocity ratio of this body and to constant. Ratio is the gear ratio.',
|
gear: "Keeps the angular velocity ratio of this body and to constant. Ratio is the gear ratio.",
|
||||||
motor: 'Keeps the relative angular velocity of this body to to at a constant rate. The most simple idea is for one of the bodies to be static, to the other is kept at rate.',
|
motor: "Keeps the relative angular velocity of this body to to at a constant rate. The most simple idea is for one of the bodies to be static, to the other is kept at rate.",
|
||||||
layer: 'Bitmask for collision layers.',
|
layer: "Bitmask for collision layers.",
|
||||||
drawlayer: 'Layer for drawing. Higher numbers draw above lower ones.',
|
drawlayer: "Layer for drawing. Higher numbers draw above lower ones.",
|
||||||
warp_filter: 'Bitmask for selecting what warps should affect this entity.',
|
warp_filter: "Bitmask for selecting what warps should affect this entity.",
|
||||||
};
|
};
|
||||||
|
|
||||||
global.ur = {};
|
global.ur = {};
|
||||||
|
|
||||||
if (io.exists(`${io.dumpfolder}/ur.json`))
|
if (io.exists(`${io.dumpfolder}/ur.json`)) ur = json.decode(io.slurp(`${io.dumpfolder}/ur.json`));
|
||||||
ur = json.decode(io.slurp(`${io.dumpfolder}/ur.json`));
|
|
||||||
else {
|
else {
|
||||||
ur = {};
|
ur = {};
|
||||||
ur._list = [];
|
ur._list = [];
|
||||||
|
@ -655,79 +690,72 @@ ur {
|
||||||
/* Apply an ur u to an entity e */
|
/* Apply an ur u to an entity e */
|
||||||
/* u is given as */
|
/* u is given as */
|
||||||
function apply_ur(u, ent) {
|
function apply_ur(u, ent) {
|
||||||
if (typeof u !== 'string') {
|
if (typeof u !== "string") {
|
||||||
console.warn("Must give u as a string.");
|
console.warn("Must give u as a string.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var urs = u.split('.');
|
var urs = u.split(".");
|
||||||
if (!urs.every(u => ur[u])) {
|
if (!urs.every(u => ur[u])) {
|
||||||
console.error(`Attempted to make ur combo ${u} but not every ur in the chain exists.`);
|
console.error(`Attempted to make ur combo ${u} but not every ur in the chain exists.`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var u of urs) {
|
for (var u of urs) {
|
||||||
var text = u.text;
|
var text = u.text;
|
||||||
var data = u.data;
|
var data = u.data;
|
||||||
if (typeof text === 'string')
|
if (typeof text === "string") use(text, ent);
|
||||||
use(text, ent);
|
else if (Array.isArray(text)) for (var path of text) use(path, ent);
|
||||||
else if (Array.isArray(text))
|
|
||||||
for (var path of text) use(path,ent);
|
if (typeof data === "string") Object.merge(ent, json.decode(Resources.replstrs(data)));
|
||||||
|
|
||||||
if (typeof data === 'string')
|
|
||||||
Object.merge(ent, json.decode(Resources.replstrs(data)));
|
|
||||||
else if (Array.isArray(data)) {
|
else if (Array.isArray(data)) {
|
||||||
for (var path of data) {
|
for (var path of data) {
|
||||||
if (typeof path === 'string')
|
if (typeof path === "string") Object.merge(ent, json.decode(Resources.replstrs(data)));
|
||||||
Object.merge(ent, json.decode(Resources.replstrs(data)));
|
else if (path instanceof Object) Object.merge(ent, path);
|
||||||
else if (path instanceof Object)
|
}
|
||||||
Object.merge(ent,path);
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var emptyur = {
|
var emptyur = {
|
||||||
name: "empty"
|
name: "empty",
|
||||||
}
|
};
|
||||||
|
|
||||||
var getur = function(text, data)
|
var getur = function (text, data) {
|
||||||
{
|
|
||||||
if (!text && !data) {
|
if (!text && !data) {
|
||||||
console.info('empty ur');
|
console.info("empty ur");
|
||||||
return {
|
return {
|
||||||
name: "empty"
|
name: "empty",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
var urstr = text;
|
var urstr = text;
|
||||||
if (data)
|
if (data) urstr += "+" + data;
|
||||||
urstr += "+" + data;
|
|
||||||
|
|
||||||
if (!ur[urstr]) {
|
if (!ur[urstr]) {
|
||||||
ur[urstr] = {
|
ur[urstr] = {
|
||||||
name: urstr,
|
name: urstr,
|
||||||
text: text,
|
text: text,
|
||||||
data: data
|
data: data,
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
return ur[urstr];
|
return ur[urstr];
|
||||||
}
|
};
|
||||||
|
|
||||||
var ur_from_file = function(file) {
|
var ur_from_file = function (file) {
|
||||||
var urname = file.name();
|
var urname = file.name();
|
||||||
if (ur[urname]) {
|
if (ur[urname]) {
|
||||||
console.warn(`Tried to make another ur with the name ${urname} from ${file}, but it already exists.`);
|
console.warn(`Tried to make another ur with the name ${urname} from ${file}, but it already exists.`);
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
var newur = {
|
var newur = {
|
||||||
name: urname
|
name: urname,
|
||||||
};
|
};
|
||||||
ur[urname] = newur;
|
ur[urname] = newur;
|
||||||
ur._list.push(urname);
|
ur._list.push(urname);
|
||||||
return newur;
|
return newur;
|
||||||
}
|
};
|
||||||
|
|
||||||
game.loadurs = function() {
|
game.loadurs = function () {
|
||||||
return;
|
return;
|
||||||
ur = {};
|
ur = {};
|
||||||
ur._list = [];
|
ur._list = [];
|
||||||
|
@ -739,12 +767,12 @@ game.loadurs = function() {
|
||||||
var urjson = json.decode(uur);
|
var urjson = json.decode(uur);
|
||||||
Object.assign(newur, urjson);
|
Object.assign(newur, urjson);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var file of io.glob("**.jso").filter(f => !ur[f.name()])) {
|
for (var file of io.glob("**.jso").filter(f => !ur[f.name()])) {
|
||||||
if (file[0] === '.' || file[0] === '_') continue;
|
if (file[0] === "." || file[0] === "_") continue;
|
||||||
var newur = ur_from_file(file);
|
var newur = ur_from_file(file);
|
||||||
if (!newur) continue;
|
if (!newur) continue;
|
||||||
newur.text = file;
|
newur.text = file;
|
||||||
|
|
||||||
var data = file.set_ext(".json");
|
var data = file.set_ext(".json");
|
||||||
if (io.exists(data)) {
|
if (io.exists(data)) {
|
||||||
|
@ -755,9 +783,8 @@ game.loadurs = function() {
|
||||||
};
|
};
|
||||||
|
|
||||||
game.ur = {};
|
game.ur = {};
|
||||||
game.ur.load = function(str) {}
|
game.ur.load = function (str) {};
|
||||||
game.ur.add_data = function(str, data)
|
game.ur.add_data = function (str, data) {
|
||||||
{
|
|
||||||
var nur = ur[str];
|
var nur = ur[str];
|
||||||
if (!nur) {
|
if (!nur) {
|
||||||
console.warn(`Cannot add data to the ur ${str}.`);
|
console.warn(`Cannot add data to the ur ${str}.`);
|
||||||
|
@ -768,17 +795,16 @@ game.ur.add_data = function(str, data)
|
||||||
if (ur.data) arr.push(ur.data);
|
if (ur.data) arr.push(ur.data);
|
||||||
ur.data = arr;
|
ur.data = arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
ur.data.push(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
game.ur.save = function(str)
|
ur.data.push(data);
|
||||||
{
|
};
|
||||||
|
|
||||||
|
game.ur.save = function (str) {
|
||||||
var nur = ur[str];
|
var nur = ur[str];
|
||||||
if (!nur) {
|
if (!nur) {
|
||||||
console.warn(`Cannot save ur ${str}.`);
|
console.warn(`Cannot save ur ${str}.`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
return { entity }
|
return { entity };
|
||||||
|
|
|
@ -1,81 +1,70 @@
|
||||||
var shape = {};
|
var shape = {};
|
||||||
shape.box = {};
|
shape.box = {};
|
||||||
shape.box.points = function(ll, ur)
|
shape.box.points = function (ll, ur) {
|
||||||
{
|
return [ll, ll.add([ur.x - ll.x, 0]), ur, ll.add([0, ur.y - ll.y])];
|
||||||
return [ll, ll.add([ur.x-ll.x,0]), ur, ll.add([0,ur.y-ll.y])];
|
};
|
||||||
}
|
|
||||||
shape.sphere = {};
|
shape.sphere = {};
|
||||||
shape.circle = {};
|
shape.circle = {};
|
||||||
shape.sphere.volume = function(r) { return Math.pi*r*r*r*4/3; };
|
shape.sphere.volume = function (r) {
|
||||||
shape.sphere.random = function(r,theta = [0,1], phi = [-0.5,0.5])
|
return (Math.pi * r * r * r * 4) / 3;
|
||||||
{
|
};
|
||||||
if (typeof r === 'number') r = [r,r];
|
shape.sphere.random = function (r, theta = [0, 1], phi = [-0.5, 0.5]) {
|
||||||
if (typeof theta === 'number') theta = [theta,theta];
|
if (typeof r === "number") r = [r, r];
|
||||||
if (typeof phi === 'number') phi = [phi,phi];
|
if (typeof theta === "number") theta = [theta, theta];
|
||||||
|
if (typeof phi === "number") phi = [phi, phi];
|
||||||
var ra = Math.random_range(r[0],r[1]);
|
|
||||||
var ta = Math.turn2rad(Math.random_range(theta[0],theta[1]));
|
|
||||||
var pa = Math.turn2rad(Math.random_range(phi[0],phi[1]));
|
|
||||||
return [
|
|
||||||
ra*Math.sin(ta)*Math.cos(pa),
|
|
||||||
ra*Math.sin(ta)*Math.sin(pa),
|
|
||||||
ra*Math.cos(ta)
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
shape.circle.area = function(r) { return Math.pi*r*r; };
|
var ra = Math.random_range(r[0], r[1]);
|
||||||
shape.circle.random = function(r,theta)
|
var ta = Math.turn2rad(Math.random_range(theta[0], theta[1]));
|
||||||
{
|
var pa = Math.turn2rad(Math.random_range(phi[0], phi[1]));
|
||||||
return shape.sphere.random(r,theta).xz;
|
return [ra * Math.sin(ta) * Math.cos(pa), ra * Math.sin(ta) * Math.sin(pa), ra * Math.cos(ta)];
|
||||||
}
|
};
|
||||||
|
|
||||||
shape.box = function(w,h) {
|
shape.circle.area = function (r) {
|
||||||
|
return Math.pi * r * r;
|
||||||
|
};
|
||||||
|
shape.circle.random = function (r, theta) {
|
||||||
|
return shape.sphere.random(r, theta).xz;
|
||||||
|
};
|
||||||
|
|
||||||
|
shape.box = function (w, h) {
|
||||||
w /= 2;
|
w /= 2;
|
||||||
h /= 2;
|
h /= 2;
|
||||||
|
|
||||||
var points = [
|
var points = [
|
||||||
[w,h],
|
[w, h],
|
||||||
[-w,h],
|
[-w, h],
|
||||||
[-w,-h],
|
[-w, -h],
|
||||||
[w,-h]
|
[w, -h],
|
||||||
];
|
];
|
||||||
|
|
||||||
return points;
|
return points;
|
||||||
};
|
};
|
||||||
|
|
||||||
shape.ngon = function(radius, n) {
|
shape.ngon = function (radius, n) {
|
||||||
return shape.arc(radius,360,n);
|
return shape.arc(radius, 360, n);
|
||||||
};
|
};
|
||||||
|
|
||||||
shape.arc = function(radius, angle, n, start = 0) {
|
shape.arc = function (radius, angle, n, start = 0) {
|
||||||
start = Math.deg2rad(start);
|
start = Math.deg2rad(start);
|
||||||
if (angle >= 360)
|
if (angle >= 360) angle = 360;
|
||||||
angle = 360;
|
|
||||||
|
|
||||||
if (n <= 1) return [];
|
if (n <= 1) return [];
|
||||||
var points = [];
|
var points = [];
|
||||||
|
|
||||||
angle = Math.deg2rad(angle);
|
angle = Math.deg2rad(angle);
|
||||||
var arclen = angle/n;
|
var arclen = angle / n;
|
||||||
for (var i = 0; i < n; i++)
|
for (var i = 0; i < n; i++) points.push(Vector.rotate([radius, 0], start + arclen * i));
|
||||||
points.push(Vector.rotate([radius,0], start + (arclen*i)));
|
|
||||||
|
|
||||||
return points;
|
return points;
|
||||||
};
|
};
|
||||||
|
|
||||||
shape.circle.points = function(radius, n) {
|
shape.circle.points = function (radius, n) {
|
||||||
if (n <= 1) return [];
|
if (n <= 1) return [];
|
||||||
return shape.arc(radius, 360, n);
|
return shape.arc(radius, 360, n);
|
||||||
};
|
};
|
||||||
|
|
||||||
shape.corners2points = function(ll, ur)
|
shape.corners2points = function (ll, ur) {
|
||||||
{
|
return [ll, ll.add([ur.x, 0]), ur, ll.add([0, ur.y])];
|
||||||
return [
|
};
|
||||||
ll,
|
|
||||||
ll.add([ur.x,0]),
|
|
||||||
ur,
|
|
||||||
ll.add([0,ur.y]),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
return {shape};
|
return { shape };
|
||||||
|
|
307
scripts/input.js
307
scripts/input.js
|
@ -1,31 +1,30 @@
|
||||||
input.keycodes = {
|
input.keycodes = {
|
||||||
32: "space",
|
32: "space",
|
||||||
45: "minus",
|
45: "minus",
|
||||||
256: "escape",
|
256: "escape",
|
||||||
257: "enter",
|
257: "enter",
|
||||||
258: "tab",
|
258: "tab",
|
||||||
259: "backspace",
|
259: "backspace",
|
||||||
260: "insert",
|
260: "insert",
|
||||||
261: "delete",
|
261: "delete",
|
||||||
262: "right",
|
262: "right",
|
||||||
263: "left",
|
263: "left",
|
||||||
264: "down",
|
264: "down",
|
||||||
265: "up",
|
265: "up",
|
||||||
266: "pgup",
|
266: "pgup",
|
||||||
267: "pgdown",
|
267: "pgdown",
|
||||||
268: "home",
|
268: "home",
|
||||||
269: "end",
|
269: "end",
|
||||||
};
|
};
|
||||||
|
|
||||||
input.codekeys = {};
|
input.codekeys = {};
|
||||||
for (var code in input.keycodes)
|
for (var code in input.keycodes) input.codekeys[input.keycodes[code]] = code;
|
||||||
input.codekeys[input.keycodes[code]] = code;
|
|
||||||
|
|
||||||
var mod = {
|
var mod = {
|
||||||
shift: 0,
|
shift: 0,
|
||||||
ctrl: 0,
|
ctrl: 0,
|
||||||
alt: 0,
|
alt: 0,
|
||||||
super: 0
|
super: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -35,32 +34,32 @@ pressed
|
||||||
down
|
down
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function keycode(name) { return charCodeAt(name); }
|
function keycode(name) {
|
||||||
|
return charCodeAt(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
function keyname_extd(key) {
|
||||||
|
if (!parseInt(key)) return key;
|
||||||
|
|
||||||
function keyname_extd(key)
|
|
||||||
{
|
|
||||||
if (!parseInt(key)) return key;
|
|
||||||
|
|
||||||
if (key > 289 && key < 302) {
|
if (key > 289 && key < 302) {
|
||||||
var num = key-289;
|
var num = key - 289;
|
||||||
return `f${num}`;
|
return `f${num}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key >= 320 && key <= 329) {
|
if (key >= 320 && key <= 329) {
|
||||||
var num = key-320;
|
var num = key - 320;
|
||||||
return `kp${num}`;
|
return `kp${num}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input.keycodes[key]) return input.keycodes[key];
|
if (input.keycodes[key]) return input.keycodes[key];
|
||||||
if (key >= 32 && key <= 126) return String.fromCharCode(key).lc();
|
if (key >= 32 && key <= 126) return String.fromCharCode(key).lc();
|
||||||
|
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
var downkeys = {};
|
var downkeys = {};
|
||||||
|
|
||||||
function modstr()
|
function modstr() {
|
||||||
{
|
|
||||||
var s = "";
|
var s = "";
|
||||||
if (mod.ctrl) s += "C-";
|
if (mod.ctrl) s += "C-";
|
||||||
if (mod.alt) s += "M-";
|
if (mod.alt) s += "M-";
|
||||||
|
@ -68,98 +67,89 @@ function modstr()
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
prosperon.keydown = function(key, repeat)
|
prosperon.keydown = function (key, repeat) {
|
||||||
{
|
|
||||||
downkeys[key] = true;
|
downkeys[key] = true;
|
||||||
|
|
||||||
if (key == 341 || key == 345)
|
if (key == 341 || key == 345) mod.ctrl = 1;
|
||||||
mod.ctrl = 1;
|
else if (key == 342 || key == 346) mod.alt = 1;
|
||||||
else if (key == 342 || key == 346)
|
else if (key == 343 || key == 347) mod.super = 1;
|
||||||
mod.alt = 1;
|
else if (key == 340 || key == 344) mod.shift = 1;
|
||||||
else if (key == 343 || key == 347)
|
|
||||||
mod.super = 1;
|
|
||||||
else if (key == 340 || key == 344)
|
|
||||||
mod.shift = 1;
|
|
||||||
else {
|
else {
|
||||||
var emacs = modstr() + keyname_extd(key);
|
var emacs = modstr() + keyname_extd(key);
|
||||||
if (repeat)
|
if (repeat) player[0].raw_input(emacs, "rep");
|
||||||
player[0].raw_input(emacs, "rep");
|
else player[0].raw_input(emacs, "pressed");
|
||||||
else
|
|
||||||
player[0].raw_input(emacs, "pressed");
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
prosperon.keyup = function(key)
|
prosperon.keyup = function (key) {
|
||||||
{
|
|
||||||
delete downkeys[key];
|
delete downkeys[key];
|
||||||
|
|
||||||
if (key == 341 || key == 345)
|
|
||||||
mod.ctrl = 0;
|
|
||||||
|
|
||||||
else if (key == 342 || key == 346)
|
if (key == 341 || key == 345) mod.ctrl = 0;
|
||||||
mod.alt = 0;
|
else if (key == 342 || key == 346) mod.alt = 0;
|
||||||
else if (key == 343 || key == 347)
|
else if (key == 343 || key == 347) mod.super = 0;
|
||||||
mod.super = 0;
|
else if (key == 340 || key == 344) mod.shift = 0;
|
||||||
else if (key == 340 || key == 344)
|
|
||||||
mod.shift = 0;
|
|
||||||
else {
|
else {
|
||||||
var emacs = modstr() + keyname_extd(key);
|
var emacs = modstr() + keyname_extd(key);
|
||||||
player[0].raw_input(emacs, "released");
|
player[0].raw_input(emacs, "released");
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
prosperon.droppedfile = function(path)
|
prosperon.droppedfile = function (path) {
|
||||||
{
|
|
||||||
player[0].raw_input("drop", "pressed", path);
|
player[0].raw_input("drop", "pressed", path);
|
||||||
}
|
};
|
||||||
|
|
||||||
var mousepos = [0,0];
|
var mousepos = [0, 0];
|
||||||
|
|
||||||
prosperon.textinput = function(c){
|
prosperon.textinput = function (c) {
|
||||||
player[0].raw_input("char", "pressed", c);
|
player[0].raw_input("char", "pressed", c);
|
||||||
};
|
};
|
||||||
prosperon.mousemove = function(pos, dx){
|
prosperon.mousemove = function (pos, dx) {
|
||||||
mousepos = pos;
|
mousepos = pos;
|
||||||
mousepos.y = window.size.y - mousepos.y;
|
mousepos.y = window.size.y - mousepos.y;
|
||||||
player[0].mouse_input("move", pos, dx);
|
player[0].mouse_input("move", pos, dx);
|
||||||
};
|
};
|
||||||
prosperon.mousescroll = function(dx){
|
prosperon.mousescroll = function (dx) {
|
||||||
player[0].mouse_input(modstr() + "scroll", dx);
|
player[0].mouse_input(modstr() + "scroll", dx);
|
||||||
};
|
};
|
||||||
prosperon.mousedown = function(b){
|
prosperon.mousedown = function (b) {
|
||||||
player[0].raw_input(modstr() + input.mouse.button[b], "pressed");
|
player[0].raw_input(modstr() + input.mouse.button[b], "pressed");
|
||||||
downkeys[input.mouse.button[b]] = true;
|
downkeys[input.mouse.button[b]] = true;
|
||||||
};
|
};
|
||||||
prosperon.mouseup = function(b){
|
prosperon.mouseup = function (b) {
|
||||||
player[0].raw_input(input.mouse.button[b], "released");
|
player[0].raw_input(input.mouse.button[b], "released");
|
||||||
delete downkeys[input.mouse.button[b]];
|
delete downkeys[input.mouse.button[b]];
|
||||||
};
|
};
|
||||||
|
|
||||||
input.mouse = {};
|
input.mouse = {};
|
||||||
input.mouse.screenpos = function() { return mousepos.slice(); };
|
input.mouse.screenpos = function () {
|
||||||
input.mouse.worldpos = function() { return game.camera.view2world(mousepos); };
|
return mousepos.slice();
|
||||||
input.mouse.disabled = function() { input.mouse_mode(1); };
|
|
||||||
input.mouse.normal = function() { input.mouse_mode(0); };
|
|
||||||
input.mouse.mode = function(m) {
|
|
||||||
if (input.mouse.custom[m])
|
|
||||||
input.cursor_img(input.mouse.custom[m]);
|
|
||||||
else
|
|
||||||
input.mouse_cursor(m);
|
|
||||||
};
|
};
|
||||||
|
input.mouse.worldpos = function () {
|
||||||
input.mouse.set_custom_cursor = function(img, mode = input.mouse.cursor.default) {
|
return game.camera.view2world(mousepos);
|
||||||
if (!img)
|
};
|
||||||
delete input.mouse.custom[mode];
|
input.mouse.disabled = function () {
|
||||||
|
input.mouse_mode(1);
|
||||||
|
};
|
||||||
|
input.mouse.normal = function () {
|
||||||
|
input.mouse_mode(0);
|
||||||
|
};
|
||||||
|
input.mouse.mode = function (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) {
|
||||||
|
if (!img) delete input.mouse.custom[mode];
|
||||||
else {
|
else {
|
||||||
input.cursor_img(img);
|
input.cursor_img(img);
|
||||||
input.mouse.custom[mode] = img;
|
input.mouse.custom[mode] = img;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
input.mouse.button = { /* left, right, middle mouse */
|
input.mouse.button = {
|
||||||
0: "lm",
|
/* left, right, middle mouse */ 0: "lm",
|
||||||
1: "rm",
|
1: "rm",
|
||||||
2: "mm"
|
2: "mm",
|
||||||
};
|
};
|
||||||
input.mouse.custom = [];
|
input.mouse.custom = [];
|
||||||
input.mouse.cursor = {
|
input.mouse.cursor = {
|
||||||
|
@ -173,7 +163,7 @@ input.mouse.cursor = {
|
||||||
nwse: 7,
|
nwse: 7,
|
||||||
nesw: 8,
|
nesw: 8,
|
||||||
resize: 9,
|
resize: 9,
|
||||||
no: 10
|
no: 10,
|
||||||
};
|
};
|
||||||
|
|
||||||
input.mouse.doc = {};
|
input.mouse.doc = {};
|
||||||
|
@ -183,14 +173,14 @@ input.mouse.disabled.doc = "Set the mouse to hidden. This locks it to the game a
|
||||||
input.mouse.normal.doc = "Set the mouse to show again after hiding.";
|
input.mouse.normal.doc = "Set the mouse to show again after hiding.";
|
||||||
|
|
||||||
input.keyboard = {};
|
input.keyboard = {};
|
||||||
input.keyboard.down = function(code) {
|
input.keyboard.down = function (code) {
|
||||||
if (typeof code === 'number') return downkeys[code];
|
if (typeof code === "number") return downkeys[code];
|
||||||
if (typeof code === 'string') return (downkeys[code.uc().charCodeAt()] || downkeys[code.lc().charCodeAt()]);
|
if (typeof code === "string") return downkeys[code.uc().charCodeAt()] || downkeys[code.lc().charCodeAt()];
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
};
|
||||||
|
|
||||||
input.state2str = function(state) {
|
input.state2str = function (state) {
|
||||||
if (typeof state === 'string') return state;
|
if (typeof state === "string") return state;
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case 0:
|
case 0:
|
||||||
return "down";
|
return "down";
|
||||||
|
@ -199,10 +189,10 @@ input.state2str = function(state) {
|
||||||
case 2:
|
case 2:
|
||||||
return "released";
|
return "released";
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
input.print_pawn_kbm = function(pawn) {
|
input.print_pawn_kbm = function (pawn) {
|
||||||
if (!('inputs' in pawn)) return;
|
if (!("inputs" in pawn)) return;
|
||||||
var str = "";
|
var str = "";
|
||||||
for (var key in pawn.inputs) {
|
for (var key in pawn.inputs) {
|
||||||
if (!pawn.inputs[key].doc) continue;
|
if (!pawn.inputs[key].doc) continue;
|
||||||
|
@ -217,13 +207,11 @@ joysticks["wasd"] = {
|
||||||
uy: "w",
|
uy: "w",
|
||||||
dy: "s",
|
dy: "s",
|
||||||
ux: "d",
|
ux: "d",
|
||||||
dx: "a"
|
dx: "a",
|
||||||
};
|
};
|
||||||
|
|
||||||
input.procdown = function()
|
input.procdown = function () {
|
||||||
{
|
for (var k in downkeys) player[0].raw_input(keyname_extd(k), "down");
|
||||||
for (var k in downkeys)
|
|
||||||
player[0].raw_input(keyname_extd(k), "down");
|
|
||||||
|
|
||||||
for (var i in joysticks) {
|
for (var i in joysticks) {
|
||||||
var joy = joysticks[i];
|
var joy = joysticks[i];
|
||||||
|
@ -231,10 +219,10 @@ input.procdown = function()
|
||||||
var y = joy.uy - joy.dy;
|
var y = joy.uy - joy.dy;
|
||||||
player[0].joy_input(i, joysticks[i]);
|
player[0].joy_input(i, joysticks[i]);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
input.print_md_kbm = function(pawn) {
|
input.print_md_kbm = function (pawn) {
|
||||||
if (!('inputs' in pawn)) return;
|
if (!("inputs" in pawn)) return;
|
||||||
|
|
||||||
var str = "";
|
var str = "";
|
||||||
str += "|control|description|\n|---|---|\n";
|
str += "|control|description|\n|---|---|\n";
|
||||||
|
@ -247,8 +235,8 @@ input.print_md_kbm = function(pawn) {
|
||||||
return str;
|
return str;
|
||||||
};
|
};
|
||||||
|
|
||||||
input.has_bind = function(pawn, bind) {
|
input.has_bind = function (pawn, bind) {
|
||||||
return (typeof pawn.inputs?.[bind] === 'function');
|
return typeof pawn.inputs?.[bind] === "function";
|
||||||
};
|
};
|
||||||
|
|
||||||
input.action = {
|
input.action = {
|
||||||
|
@ -263,28 +251,36 @@ input.action = {
|
||||||
actions: [],
|
actions: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
input.tabcomplete = function(val, list) {
|
input.tabcomplete = function (val, list) {
|
||||||
if (!val) return val;
|
if (!val) return val;
|
||||||
list.dofilter(function(x) { return x.startsWith(val); });
|
list.dofilter(function (x) {
|
||||||
|
return x.startsWith(val);
|
||||||
|
});
|
||||||
|
|
||||||
if (list.length === 1) {
|
if (list.length === 1) {
|
||||||
return list[0];
|
return list[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
var ret = undefined;
|
|
||||||
var i = val.length;
|
|
||||||
while (!ret && !Object.empty(list)) {
|
|
||||||
var char = list[0][i];
|
|
||||||
if (!list.every(function(x) { return x[i] === char; }))
|
|
||||||
ret = list[0].slice(0, i);
|
|
||||||
else {
|
|
||||||
i++;
|
|
||||||
list.dofilter(function(x) { return x.length-1 > i; });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret ? ret : val;
|
var ret = undefined;
|
||||||
}
|
var i = val.length;
|
||||||
|
while (!ret && !Object.empty(list)) {
|
||||||
|
var char = list[0][i];
|
||||||
|
if (
|
||||||
|
!list.every(function (x) {
|
||||||
|
return x[i] === char;
|
||||||
|
})
|
||||||
|
)
|
||||||
|
ret = list[0].slice(0, i);
|
||||||
|
else {
|
||||||
|
i++;
|
||||||
|
list.dofilter(function (x) {
|
||||||
|
return x.length - 1 > i;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret ? ret : val;
|
||||||
|
};
|
||||||
|
|
||||||
/* May be a human player; may be an AI player */
|
/* May be a human player; may be an AI player */
|
||||||
|
|
||||||
|
@ -300,24 +296,22 @@ var Player = {
|
||||||
|
|
||||||
mouse_input(type, ...args) {
|
mouse_input(type, ...args) {
|
||||||
for (var pawn of this.pawns.reversed()) {
|
for (var pawn of this.pawns.reversed()) {
|
||||||
if (typeof pawn.inputs?.mouse?.[type] === 'function') {
|
if (typeof pawn.inputs?.mouse?.[type] === "function") {
|
||||||
pawn.inputs.mouse[type].call(pawn,...args);
|
pawn.inputs.mouse[type].call(pawn, ...args);
|
||||||
pawn.inputs.post?.call(pawn);
|
pawn.inputs.post?.call(pawn);
|
||||||
if (!pawn.inputs.fallthru)
|
if (!pawn.inputs.fallthru) return;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
char_input(c) {
|
char_input(c) {
|
||||||
for (var pawn of this.pawns.reversed()) {
|
for (var pawn of this.pawns.reversed()) {
|
||||||
if (typeof pawn.inputs?.char === 'function') {
|
if (typeof pawn.inputs?.char === "function") {
|
||||||
pawn.inputs.char.call(pawn, c);
|
pawn.inputs.char.call(pawn, c);
|
||||||
pawn.inputs.post?.call(pawn);
|
pawn.inputs.post?.call(pawn);
|
||||||
if (!pawn.inputs.fallthru)
|
if (!pawn.inputs.fallthru) return;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
joy_input(name, joystick) {
|
joy_input(name, joystick) {
|
||||||
|
@ -329,11 +323,11 @@ var Player = {
|
||||||
var x = 0;
|
var x = 0;
|
||||||
if (input.keyboard.down(joystick.ux)) x++;
|
if (input.keyboard.down(joystick.ux)) x++;
|
||||||
if (input.keyboard.down(joystick.dx)) x--;
|
if (input.keyboard.down(joystick.dx)) x--;
|
||||||
var y = 0;
|
var y = 0;
|
||||||
if (input.keyboard.down(joystick.uy)) y++;
|
if (input.keyboard.down(joystick.uy)) y++;
|
||||||
if (input.keyboard.down(joystick.dy)) y--;
|
if (input.keyboard.down(joystick.dy)) y--;
|
||||||
|
|
||||||
pawn.inputs.joystick[name](x,y);
|
pawn.inputs.joystick[name](x, y);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -341,62 +335,56 @@ var Player = {
|
||||||
for (var pawn of this.pawns.reversed()) {
|
for (var pawn of this.pawns.reversed()) {
|
||||||
if (!pawn.inputs) {
|
if (!pawn.inputs) {
|
||||||
console.error(`pawn no longer has inputs object.`);
|
console.error(`pawn no longer has inputs object.`);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var block = pawn.inputs.block;
|
var block = pawn.inputs.block;
|
||||||
|
|
||||||
if (!pawn.inputs[cmd]) {
|
if (!pawn.inputs[cmd]) {
|
||||||
if (pawn.inputs.block) return;
|
if (pawn.inputs.block) return;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var fn = null;
|
var fn = null;
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case 'pressed':
|
case "pressed":
|
||||||
fn = pawn.inputs[cmd];
|
fn = pawn.inputs[cmd];
|
||||||
break;
|
break;
|
||||||
case 'rep':
|
case "rep":
|
||||||
fn = pawn.inputs[cmd].rep ? pawn.inputs[cmd] : null;
|
fn = pawn.inputs[cmd].rep ? pawn.inputs[cmd] : null;
|
||||||
break;
|
break;
|
||||||
case 'released':
|
case "released":
|
||||||
fn = pawn.inputs[cmd].released;
|
fn = pawn.inputs[cmd].released;
|
||||||
break;
|
break;
|
||||||
case 'down':
|
case "down":
|
||||||
if (typeof pawn.inputs[cmd].down === 'function')
|
if (typeof pawn.inputs[cmd].down === "function") fn = pawn.inputs[cmd].down;
|
||||||
fn = pawn.inputs[cmd].down;
|
else if (pawn.inputs[cmd].down) fn = pawn.inputs[cmd];
|
||||||
else if (pawn.inputs[cmd].down)
|
|
||||||
fn = pawn.inputs[cmd];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof fn === 'function')
|
if (typeof fn === "function") fn.call(pawn, ...args);
|
||||||
fn.call(pawn, ... args);
|
|
||||||
|
|
||||||
if (!pawn.inputs)
|
if (!pawn.inputs)
|
||||||
if (block) return;
|
if (block) return;
|
||||||
else continue;
|
else continue;
|
||||||
|
|
||||||
if (state === 'released')
|
if (state === "released") pawn.inputs.release_post?.call(pawn);
|
||||||
pawn.inputs.release_post?.call(pawn);
|
|
||||||
|
|
||||||
if (!pawn.inputs.fallthru) return;
|
if (!pawn.inputs.fallthru) return;
|
||||||
if (pawn.inputs.block) return;
|
if (pawn.inputs.block) return;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
obj_controlled(obj) {
|
obj_controlled(obj) {
|
||||||
for (var p in Player.players) {
|
for (var p in Player.players) {
|
||||||
if (p.pawns.contains(obj))
|
if (p.pawns.contains(obj)) return true;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
print_pawns() {
|
print_pawns() {
|
||||||
for (var pawn of this.pawns.reversed())
|
for (var pawn of this.pawns.reversed()) say(pawn.toString());
|
||||||
say(pawn.toString());
|
|
||||||
},
|
},
|
||||||
|
|
||||||
create() {
|
create() {
|
||||||
|
@ -404,7 +392,7 @@ var Player = {
|
||||||
n.pawns = [];
|
n.pawns = [];
|
||||||
n.gamepads = [];
|
n.gamepads = [];
|
||||||
this.players.push(n);
|
this.players.push(n);
|
||||||
this[this.players.length-1] = n;
|
this[this.players.length - 1] = n;
|
||||||
return n;
|
return n;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -423,12 +411,11 @@ var Player = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
input.do_uncontrol = function(pawn)
|
input.do_uncontrol = function (pawn) {
|
||||||
{
|
Player.players.forEach(function (p) {
|
||||||
Player.players.forEach(function(p) {
|
|
||||||
p.pawns = p.pawns.filter(x => x !== pawn);
|
p.pawns = p.pawns.filter(x => x !== pawn);
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
for (var i = 0; i < 4; i++) {
|
for (var i = 0; i < 4; i++) {
|
||||||
Player.create();
|
Player.create();
|
||||||
|
@ -443,5 +430,5 @@ Player.doc.players = "A list of current players.";
|
||||||
var player = Player;
|
var player = Player;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
player
|
player,
|
||||||
};
|
};
|
||||||
|
|
249
scripts/mum.js
249
scripts/mum.js
|
@ -5,17 +5,16 @@ var panel;
|
||||||
var selected = undefined;
|
var selected = undefined;
|
||||||
|
|
||||||
mum.inputs = {};
|
mum.inputs = {};
|
||||||
mum.inputs.lm = function()
|
mum.inputs.lm = function () {
|
||||||
{
|
|
||||||
if (!selected) return;
|
if (!selected) return;
|
||||||
if (!selected.action) return;
|
if (!selected.action) return;
|
||||||
selected.action();
|
selected.action();
|
||||||
}
|
};
|
||||||
|
|
||||||
mum.base = {
|
mum.base = {
|
||||||
pos: null, // If set, puts the cursor to this position before drawing the element
|
pos: null, // If set, puts the cursor to this position before drawing the element
|
||||||
offset:[0,0], // Move x,y to the right and down before drawing
|
offset: [0, 0], // Move x,y to the right and down before drawing
|
||||||
padding:[0,0], // Pad inwards after drawing, to prepare for the next element
|
padding: [0, 0], // Pad inwards after drawing, to prepare for the next element
|
||||||
font: "fonts/c64.ttf",
|
font: "fonts/c64.ttf",
|
||||||
selectable: false,
|
selectable: false,
|
||||||
selected: false,
|
selected: false,
|
||||||
|
@ -23,33 +22,33 @@ mum.base = {
|
||||||
scale: 1,
|
scale: 1,
|
||||||
angle: 0,
|
angle: 0,
|
||||||
inset: null,
|
inset: null,
|
||||||
anchor: [0,1], // where to draw the item from, relative to the cursor. [0,1] is from the top left corner. [1,0] is from the bottom right
|
anchor: [0, 1], // where to draw the item from, relative to the cursor. [0,1] is from the top left corner. [1,0] is from the bottom right
|
||||||
background_image: null,
|
background_image: null,
|
||||||
slice: null, // pass to slice an image as a 9 slice. see render.slice9 for its format
|
slice: null, // pass to slice an image as a 9 slice. see render.slice9 for its format
|
||||||
hover: {
|
hover: {
|
||||||
color: Color.red,
|
color: Color.red,
|
||||||
},
|
},
|
||||||
text_shadow: {
|
text_shadow: {
|
||||||
pos: [0,0],
|
pos: [0, 0],
|
||||||
color: Color.white,
|
color: Color.white,
|
||||||
},
|
},
|
||||||
border: 0, // Draw a border around the element. For text, an outline.
|
border: 0, // Draw a border around the element. For text, an outline.
|
||||||
overflow: "wrap", // how to deal with overflow from parent element
|
overflow: "wrap", // how to deal with overflow from parent element
|
||||||
wrap: -1,
|
wrap: -1,
|
||||||
text_align: "left", /* left, center, right */
|
text_align: "left" /* left, center, right */,
|
||||||
shader: null, // Use this shader, instead of the engine provided one
|
shader: null, // Use this shader, instead of the engine provided one
|
||||||
color: Color.white,
|
color: Color.white,
|
||||||
opacity:1,
|
opacity: 1,
|
||||||
width:0,
|
width: 0,
|
||||||
height:0,
|
height: 0,
|
||||||
max_width: Infinity,
|
max_width: Infinity,
|
||||||
max_height: Infinity,
|
max_height: Infinity,
|
||||||
image_repeat: false,
|
image_repeat: false,
|
||||||
image_repeat_offset: [0,0],
|
image_repeat_offset: [0, 0],
|
||||||
debug: false, /* set to true to draw debug boxes */
|
debug: false /* set to true to draw debug boxes */,
|
||||||
hide: false,
|
hide: false,
|
||||||
tooltip: null,
|
tooltip: null,
|
||||||
}
|
};
|
||||||
|
|
||||||
// data is passed into each function, and various stats are generated
|
// data is passed into each function, and various stats are generated
|
||||||
// drawpos: the point to start the drawing from
|
// drawpos: the point to start the drawing from
|
||||||
|
@ -57,22 +56,23 @@ mum.base = {
|
||||||
// bound: a boundingbox around the drawn UI element
|
// bound: a boundingbox around the drawn UI element
|
||||||
// extent: a boundingbox around the total extents of the element (ie before padding)
|
// extent: a boundingbox around the total extents of the element (ie before padding)
|
||||||
|
|
||||||
function show_debug() { return prosperon.debug && mum.debug; }
|
function show_debug() {
|
||||||
|
return prosperon.debug && mum.debug;
|
||||||
|
}
|
||||||
|
|
||||||
mum.debug = false;
|
mum.debug = false;
|
||||||
|
|
||||||
var post = function() {};
|
var post = function () {};
|
||||||
var posts = [];
|
var posts = [];
|
||||||
|
|
||||||
mum.style = mum.base;
|
mum.style = mum.base;
|
||||||
|
|
||||||
var cursor = [0,0];
|
var cursor = [0, 0];
|
||||||
|
|
||||||
var pre = function(data)
|
var pre = function (data) {
|
||||||
{
|
|
||||||
if (data.hide) return true;
|
if (data.hide) return true;
|
||||||
data.__proto__ = mum.style;
|
data.__proto__ = mum.style;
|
||||||
|
|
||||||
if (data.pos) cursor = data.pos.slice();
|
if (data.pos) cursor = data.pos.slice();
|
||||||
data.drawpos = cursor.slice().add(data.offset);
|
data.drawpos = cursor.slice().add(data.offset);
|
||||||
|
|
||||||
|
@ -81,87 +81,77 @@ var pre = function(data)
|
||||||
data.color[3] = data.opacity;
|
data.color[3] = data.opacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
data.wh = [data.width,data.height];
|
data.wh = [data.width, data.height];
|
||||||
}
|
};
|
||||||
|
|
||||||
var anchor_calc = function(data)
|
var anchor_calc = function (data) {
|
||||||
{
|
var aa = [0, 1].sub(data.anchor);
|
||||||
var aa = [0,1].sub(data.anchor);
|
data.drawpos = data.drawpos.add([data.width, data.height]).scale(aa);
|
||||||
data.drawpos = data.drawpos.add([data.width,data.height]).scale(aa);
|
};
|
||||||
}
|
|
||||||
|
|
||||||
var end = function(data)
|
var end = function (data) {
|
||||||
{
|
|
||||||
cursor = cursor.add(data.padding);
|
cursor = cursor.add(data.padding);
|
||||||
post(data);
|
post(data);
|
||||||
}
|
};
|
||||||
|
|
||||||
mum.list = function(fn, data = {})
|
mum.list = function (fn, data = {}) {
|
||||||
{
|
|
||||||
if (pre(data)) return;
|
if (pre(data)) return;
|
||||||
var aa = [0,1].sub(data.anchor);
|
var aa = [0, 1].sub(data.anchor);
|
||||||
cursor = cursor.add([data.width,data.height].scale(aa)).add(data.offset).add(data.padding);
|
cursor = cursor.add([data.width, data.height].scale(aa)).add(data.offset).add(data.padding);
|
||||||
|
|
||||||
posts.push(post);
|
posts.push(post);
|
||||||
post = mum.list.post.bind(data);
|
post = mum.list.post.bind(data);
|
||||||
|
|
||||||
if (show_debug())
|
if (show_debug())
|
||||||
render.boundingbox({
|
render.boundingbox({
|
||||||
t:cursor.y,
|
t: cursor.y,
|
||||||
b:cursor.y-data.height,
|
b: cursor.y - data.height,
|
||||||
l:cursor.x,
|
l: cursor.x,
|
||||||
r:cursor.x+data.width
|
r: cursor.x + data.width,
|
||||||
});
|
});
|
||||||
|
|
||||||
//if (data.background_image) mum.image(null, Object.create(data))
|
//if (data.background_image) mum.image(null, Object.create(data))
|
||||||
if (data.background_image) {
|
if (data.background_image) {
|
||||||
var imgpos = data.pos.slice();
|
var imgpos = data.pos.slice();
|
||||||
imgpos.y -= data.height/2;
|
imgpos.y -= data.height / 2;
|
||||||
imgpos.x -= data.width/2;
|
imgpos.x -= data.width / 2;
|
||||||
var imgscale = [data.width,data.height];
|
var imgscale = [data.width, data.height];
|
||||||
if (data.slice)
|
if (data.slice) render.slice9(game.texture(data.background_image), imgpos, data.slice, imgscale);
|
||||||
render.slice9(game.texture(data.background_image), imgpos, data.slice, imgscale);
|
else render.image(game.texture(data.background_image), imgpos, [data.width, data.height]);
|
||||||
else
|
|
||||||
render.image(game.texture(data.background_image), imgpos, [data.width,data.height]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn();
|
fn();
|
||||||
|
|
||||||
data.bb.l -= data.padding.x;
|
data.bb.l -= data.padding.x;
|
||||||
data.bb.r += data.padding.x;
|
data.bb.r += data.padding.x;
|
||||||
data.bb.t += data.padding.y;
|
data.bb.t += data.padding.y;
|
||||||
data.bb.b -= data.padding.y;
|
data.bb.b -= data.padding.y;
|
||||||
|
|
||||||
if (show_debug())
|
if (show_debug()) render.boundingbox(data.bb);
|
||||||
render.boundingbox(data.bb);
|
|
||||||
|
|
||||||
post = posts.pop();
|
post = posts.pop();
|
||||||
end(data);
|
end(data);
|
||||||
}
|
};
|
||||||
|
|
||||||
mum.list.post = function(e)
|
mum.list.post = function (e) {
|
||||||
{
|
cursor.y -= e.bb.t - e.bb.b;
|
||||||
cursor.y -= (e.bb.t - e.bb.b);
|
|
||||||
cursor.y -= e.padding.y;
|
cursor.y -= e.padding.y;
|
||||||
|
|
||||||
if (this.bb)
|
|
||||||
this.bb = bbox.expand(this.bb,e.bb)
|
|
||||||
else
|
|
||||||
this.bb = e.bb;
|
|
||||||
}
|
|
||||||
|
|
||||||
mum.label = function(str, data = {})
|
if (this.bb) this.bb = bbox.expand(this.bb, e.bb);
|
||||||
{
|
else this.bb = e.bb;
|
||||||
|
};
|
||||||
|
|
||||||
|
mum.label = function (str, data = {}) {
|
||||||
if (pre(data)) return;
|
if (pre(data)) return;
|
||||||
|
|
||||||
render.set_font(data.font, data.font_size);
|
render.set_font(data.font, data.font_size);
|
||||||
|
|
||||||
data.bb = render.text_bb(str, data.scale, -1, cursor);
|
data.bb = render.text_bb(str, data.scale, -1, cursor);
|
||||||
data.wh = bbox.towh(data.bb);
|
data.wh = bbox.towh(data.bb);
|
||||||
|
|
||||||
var aa = [0,1].sub(data.anchor);
|
var aa = [0, 1].sub(data.anchor);
|
||||||
|
|
||||||
data.drawpos.y -= (data.bb.t-cursor.y);
|
data.drawpos.y -= data.bb.t - cursor.y;
|
||||||
data.drawpos = data.drawpos.add(data.wh.scale(aa)).add(data.offset);
|
data.drawpos = data.drawpos.add(data.wh.scale(aa)).add(data.offset);
|
||||||
|
|
||||||
data.bb = render.text_bb(str, data.scale, data.wrap, data.drawpos);
|
data.bb = render.text_bb(str, data.scale, data.wrap, data.drawpos);
|
||||||
|
@ -175,87 +165,72 @@ mum.label = function(str, data = {})
|
||||||
}
|
}
|
||||||
|
|
||||||
data.bb = render.text(str, data.drawpos, data.scale, data.color, data.wrap);
|
data.bb = render.text(str, data.drawpos, data.scale, data.color, data.wrap);
|
||||||
|
|
||||||
if (show_debug())
|
|
||||||
render.boundingbox(data.bb);
|
|
||||||
|
|
||||||
end(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
mum.image = function(path, data = {})
|
if (show_debug()) render.boundingbox(data.bb);
|
||||||
{
|
|
||||||
|
end(data);
|
||||||
|
};
|
||||||
|
|
||||||
|
mum.image = function (path, data = {}) {
|
||||||
if (pre(data)) return;
|
if (pre(data)) return;
|
||||||
path ??= data.background_image;
|
path ??= data.background_image;
|
||||||
var tex = path;
|
var tex = path;
|
||||||
if (typeof path === 'string')
|
if (typeof path === "string") tex = game.texture(path);
|
||||||
tex = game.texture(path);
|
|
||||||
|
|
||||||
if (!data.height)
|
if (!data.height)
|
||||||
if (data.width)
|
if (data.width) data.height = tex.height * (data.width / tex.width);
|
||||||
data.height = tex.height * (data.width/tex.width);
|
else data.height = tex.height;
|
||||||
else
|
|
||||||
data.height = tex.height;
|
|
||||||
|
|
||||||
if (!data.width)
|
if (!data.width)
|
||||||
if (data.height)
|
if (data.height) data.width = tex.width * (data.height / tex.height);
|
||||||
data.width = tex.width * (data.height/tex.height);
|
else data.height = tex.height;
|
||||||
else
|
|
||||||
data.height = tex.height;
|
|
||||||
|
|
||||||
if (!data.width) data.width = tex.width;
|
if (!data.width) data.width = tex.width;
|
||||||
if (!data.height) data.height = tex.height;
|
if (!data.height) data.height = tex.height;
|
||||||
|
|
||||||
var aa = [0,1].sub(data.anchor);
|
var aa = [0, 1].sub(data.anchor);
|
||||||
data.drawpos = data.drawpos.add(aa.scale([data.width,data.height]));
|
data.drawpos = data.drawpos.add(aa.scale([data.width, data.height]));
|
||||||
|
|
||||||
if (data.slice)
|
|
||||||
render.slice9(tex, data.drawpos, data.slice, [data.width,data.height]);
|
|
||||||
else
|
|
||||||
data.bb = render.image(tex, data.drawpos, [data.width, data.height]);
|
|
||||||
|
|
||||||
end(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
mum.rectangle = function(data = {})
|
if (data.slice) render.slice9(tex, data.drawpos, data.slice, [data.width, data.height]);
|
||||||
{
|
else data.bb = render.image(tex, data.drawpos, [data.width, data.height]);
|
||||||
|
|
||||||
|
end(data);
|
||||||
|
};
|
||||||
|
|
||||||
|
mum.rectangle = function (data = {}) {
|
||||||
if (pre(data)) return;
|
if (pre(data)) return;
|
||||||
var aa = [0,0].sub(data.anchor);
|
var aa = [0, 0].sub(data.anchor);
|
||||||
data.drawpos = data.drawpos.add(aa.scale([data.width,data.height]));
|
data.drawpos = data.drawpos.add(aa.scale([data.width, data.height]));
|
||||||
|
|
||||||
render.rectangle(data.drawpos, data.drawpos.add([data.width,data.height]), data.color);
|
render.rectangle(data.drawpos, data.drawpos.add([data.width, data.height]), data.color);
|
||||||
|
|
||||||
end(data);
|
end(data);
|
||||||
}
|
};
|
||||||
|
|
||||||
var btnbb;
|
var btnbb;
|
||||||
var btnpost = function()
|
var btnpost = function () {
|
||||||
{
|
|
||||||
btnbb = data.bb;
|
btnbb = data.bb;
|
||||||
}
|
};
|
||||||
|
|
||||||
mum.button = function(str, data = {padding:[4,4], color:Color.black})
|
mum.button = function (str, data = { padding: [4, 4], color: Color.black }) {
|
||||||
{
|
|
||||||
if (pre(data)) return;
|
if (pre(data)) return;
|
||||||
posts.push(post);
|
posts.push(post);
|
||||||
post = btnpost;
|
post = btnpost;
|
||||||
if (typeof str === 'string')
|
if (typeof str === "string") render.text(str, cursor.add(data.padding), data.scale, data.color);
|
||||||
render.text(str, cursor.add(data.padding), data.scale, data.color);
|
else str();
|
||||||
else
|
|
||||||
str();
|
|
||||||
|
|
||||||
if (data.action && data.hover && bbox.pointin(btnbb, input.mouse.screenpos())) {
|
if (data.action && data.hover && bbox.pointin(btnbb, input.mouse.screenpos())) {
|
||||||
data.hover.__proto__ = data;
|
data.hover.__proto__ = data;
|
||||||
data = data.hover;
|
data = data.hover;
|
||||||
}
|
}
|
||||||
render.rectangle([btnbb.l-data.padding.x, btnbb.b-data.padding.y], [btnbb.r+data.padding.y, btnbb.t+data.padding.y], data.color);
|
render.rectangle([btnbb.l - data.padding.x, btnbb.b - data.padding.y], [btnbb.r + data.padding.y, btnbb.t + data.padding.y], data.color);
|
||||||
data.bb = btnbb;
|
data.bb = btnbb;
|
||||||
|
|
||||||
post = posts.pop();
|
post = posts.pop();
|
||||||
end(data);
|
end(data);
|
||||||
}
|
};
|
||||||
|
|
||||||
mum.window = function(fn, data = {})
|
mum.window = function (fn, data = {}) {
|
||||||
{
|
|
||||||
if (pre(data)) return;
|
if (pre(data)) return;
|
||||||
|
|
||||||
render.rectangle(cursor, cursor.add(data.size), data.color);
|
render.rectangle(cursor, cursor.add(data.size), data.color);
|
||||||
|
@ -263,28 +238,34 @@ mum.window = function(fn, data = {})
|
||||||
cursor = cursor.add(data.padding);
|
cursor = cursor.add(data.padding);
|
||||||
fn();
|
fn();
|
||||||
end(data);
|
end(data);
|
||||||
}
|
};
|
||||||
|
|
||||||
mum.ex_hud = function()
|
mum.ex_hud = function () {
|
||||||
{
|
mum.label("TOP LEFT", { pos: [0, game.size.y], anchor: [0, 1] });
|
||||||
mum.label("TOP LEFT", {pos:[0,game.size.y], anchor:[0,1]});
|
mum.label("BOTTOM LEFT", { pos: [0, 0], anchor: [0, 0] });
|
||||||
mum.label("BOTTOM LEFT", {pos:[0,0], anchor:[0,0]});
|
mum.label("TOP RIGHT", { pos: game.size, anchor: [1, 1] });
|
||||||
mum.label("TOP RIGHT", {pos:game.size, anchor:[1,1]});
|
mum.label("BOTTOM RIGHT", { pos: [game.size.x, 0], anchor: [1, 0] });
|
||||||
mum.label("BOTTOM RIGHT", {pos:[game.size.x, 0], anchor:[1,0]});
|
};
|
||||||
}
|
|
||||||
|
|
||||||
mum.drawinput = undefined;
|
mum.drawinput = undefined;
|
||||||
var ptext = "";
|
var ptext = "";
|
||||||
var panpan = {
|
var panpan = {
|
||||||
draw() {
|
draw() {
|
||||||
mum.rectangle({pos:[0,0], anchor:[0,0], height:20, width: window.size.x, padding:[10,16], color:Color.black});
|
mum.rectangle({
|
||||||
|
pos: [0, 0],
|
||||||
|
anchor: [0, 0],
|
||||||
|
height: 20,
|
||||||
|
width: window.size.x,
|
||||||
|
padding: [10, 16],
|
||||||
|
color: Color.black,
|
||||||
|
});
|
||||||
mum.label("input level: ");
|
mum.label("input level: ");
|
||||||
mum.label(ptext, {offset:[50,0], color:Color.red});
|
mum.label(ptext, { offset: [50, 0], color: Color.red });
|
||||||
},
|
},
|
||||||
inputs: {
|
inputs: {
|
||||||
block: true,
|
block: true,
|
||||||
char(c) {
|
char(c) {
|
||||||
ptext += c
|
ptext += c;
|
||||||
},
|
},
|
||||||
enter() {
|
enter() {
|
||||||
delete mum.drawinput;
|
delete mum.drawinput;
|
||||||
|
@ -295,18 +276,18 @@ var panpan = {
|
||||||
player[0].uncontrol(panpan);
|
player[0].uncontrol(panpan);
|
||||||
},
|
},
|
||||||
backspace() {
|
backspace() {
|
||||||
ptext = ptext.slice(0,ptext.length-1);
|
ptext = ptext.slice(0, ptext.length - 1);
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
mum.textinput = function (fn, str = "") {
|
mum.textinput = function (fn, str = "") {
|
||||||
mum.drawinput = panpan.draw;
|
mum.drawinput = panpan.draw;
|
||||||
ptext = str;
|
ptext = str;
|
||||||
player[0].control(panpan);
|
player[0].control(panpan);
|
||||||
panpan.inputs.enter = function() {
|
panpan.inputs.enter = function () {
|
||||||
fn(ptext);
|
fn(ptext);
|
||||||
delete mum.drawinput;
|
delete mum.drawinput;
|
||||||
player[0].uncontrol(panpan);
|
player[0].uncontrol(panpan);
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
this.hud = function()
|
this.hud = function () {
|
||||||
{
|
mum.label("No game yet! Make game.js to get started!", {
|
||||||
mum.label("No game yet! Make game.js to get started!", {pos:game.size.scale(0.5), anchor:[0.5,0.5]});
|
pos: game.size.scale(0.5),
|
||||||
}
|
anchor: [0.5, 0.5],
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
|
@ -7,44 +7,38 @@ emitter.spawn_timer = 0;
|
||||||
emitter.pps = 0;
|
emitter.pps = 0;
|
||||||
emitter.color = Color.white;
|
emitter.color = Color.white;
|
||||||
|
|
||||||
emitter.draw = function()
|
emitter.draw = function () {
|
||||||
{
|
|
||||||
var pars = Object.values(this.particles);
|
var pars = Object.values(this.particles);
|
||||||
if (pars.length === 0) return;
|
if (pars.length === 0) return;
|
||||||
render.use_shader(this.shader);
|
render.use_shader(this.shader);
|
||||||
render.use_mat(this);
|
render.use_mat(this);
|
||||||
render.make_particle_ssbo(pars, this.ssbo);
|
render.make_particle_ssbo(pars, this.ssbo);
|
||||||
render.draw(this.shape, this.ssbo, pars.length);
|
render.draw(this.shape, this.ssbo, pars.length);
|
||||||
}
|
};
|
||||||
|
|
||||||
emitter.kill = function()
|
emitter.kill = function () {
|
||||||
{
|
|
||||||
emitters.remove(this);
|
emitters.remove(this);
|
||||||
}
|
};
|
||||||
|
|
||||||
var std_step = function(p)
|
var std_step = function (p) {
|
||||||
{
|
|
||||||
if (p.time < this.grow_for) {
|
if (p.time < this.grow_for) {
|
||||||
var s = Math.lerp(0, this.scale, p.time/this.grow_for);
|
var s = Math.lerp(0, this.scale, p.time / this.grow_for);
|
||||||
p.transform.scale = [s,s,s];
|
p.transform.scale = [s, s, s];
|
||||||
}
|
} else if (p.time > p.life - this.shrink_for) {
|
||||||
else if (p.time > (p.life - this.shrink_for)) {
|
var s = Math.lerp(0, this.scale, (p.life - p.time) / this.shrink_for);
|
||||||
var s = Math.lerp(0,this.scale,(p.life-p.time)/this.shrink_for);
|
p.transform.scale = [s, s, s];
|
||||||
p.transform.scale=[s,s,s];
|
} else p.transform.scale = [this.scale, this.scale, this.scale];
|
||||||
} else
|
};
|
||||||
p.transform.scale = [this.scale,this.scale,this.scale];
|
|
||||||
}
|
|
||||||
|
|
||||||
emitter.step_hook = std_step;
|
emitter.step_hook = std_step;
|
||||||
|
|
||||||
emitter.spawn = function(t)
|
emitter.spawn = function (t) {
|
||||||
{
|
|
||||||
t ??= this.transform;
|
t ??= this.transform;
|
||||||
|
|
||||||
var par = this.dead.shift();
|
var par = this.dead.shift();
|
||||||
if (par) {
|
if (par) {
|
||||||
par.body.pos = t.pos;
|
par.body.pos = t.pos;
|
||||||
par.transform.scale = [this.scale,this.scale,this.scale];
|
par.transform.scale = [this.scale, this.scale, this.scale];
|
||||||
this.particles[par.id] = par;
|
this.particles[par.id] = par;
|
||||||
par.time = 0;
|
par.time = 0;
|
||||||
this.spawn_hook?.(par);
|
this.spawn_hook?.(par);
|
||||||
|
@ -56,25 +50,24 @@ emitter.spawn = function(t)
|
||||||
transform: os.make_transform(),
|
transform: os.make_transform(),
|
||||||
life: this.life,
|
life: this.life,
|
||||||
time: 0,
|
time: 0,
|
||||||
color: this.color
|
color: this.color,
|
||||||
};
|
};
|
||||||
|
|
||||||
par.body = os.make_body(par.transform);
|
par.body = os.make_body(par.transform);
|
||||||
|
|
||||||
par.body.pos = t.pos;
|
par.body.pos = t.pos;
|
||||||
par.transform.scale = [this.scale,this.scale,this.scale];
|
par.transform.scale = [this.scale, this.scale, this.scale];
|
||||||
par.id = prosperon.guid();
|
par.id = prosperon.guid();
|
||||||
this.particles[par.id] = par;
|
this.particles[par.id] = par;
|
||||||
|
|
||||||
this.spawn_hook(par);
|
this.spawn_hook(par);
|
||||||
}
|
};
|
||||||
|
|
||||||
emitter.step = function(dt)
|
emitter.step = function (dt) {
|
||||||
{
|
|
||||||
// update spawning particles
|
// update spawning particles
|
||||||
if (this.on && this.pps > 0) {
|
if (this.on && this.pps > 0) {
|
||||||
this.spawn_timer += dt;
|
this.spawn_timer += dt;
|
||||||
var pp = 1/this.pps;
|
var pp = 1 / this.pps;
|
||||||
while (this.spawn_timer > pp) {
|
while (this.spawn_timer > pp) {
|
||||||
this.spawn_timer -= pp;
|
this.spawn_timer -= pp;
|
||||||
this.spawn();
|
this.spawn();
|
||||||
|
@ -92,16 +85,15 @@ emitter.step = function(dt)
|
||||||
delete this.particles[p.id];
|
delete this.particles[p.id];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
emitter.burst = function(count, t) {
|
emitter.burst = function (count, t) {
|
||||||
for (var i = 0; i < count; i++) this.spawn(t);
|
for (var i = 0; i < count; i++) this.spawn(t);
|
||||||
}
|
};
|
||||||
|
|
||||||
var emitters = [];
|
var emitters = [];
|
||||||
|
|
||||||
var make_emitter = function()
|
var make_emitter = function () {
|
||||||
{
|
|
||||||
var e = Object.create(emitter);
|
var e = Object.create(emitter);
|
||||||
e.ssbo = render.make_textssbo();
|
e.ssbo = render.make_textssbo();
|
||||||
e.shape = shape.centered_quad;
|
e.shape = shape.centered_quad;
|
||||||
|
@ -109,17 +101,14 @@ var make_emitter = function()
|
||||||
e.dead = [];
|
e.dead = [];
|
||||||
emitters.push(e);
|
emitters.push(e);
|
||||||
return e;
|
return e;
|
||||||
|
};
|
||||||
|
|
||||||
|
function update_emitters(dt) {
|
||||||
|
for (var e of emitters) e.step(dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
function update_emitters(dt)
|
function draw_emitters() {
|
||||||
{
|
|
||||||
for (var e of emitters)
|
|
||||||
e.step(dt);
|
|
||||||
}
|
|
||||||
|
|
||||||
function draw_emitters()
|
|
||||||
{
|
|
||||||
for (var e of emitters) e.draw();
|
for (var e of emitters) e.draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
return {make_emitter, update_emitters, draw_emitters};
|
return { make_emitter, update_emitters, draw_emitters };
|
||||||
|
|
|
@ -9,27 +9,25 @@ var HIT = {
|
||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
|
|
||||||
physics.pos_query = function(pos, start = world, give = 10) {
|
physics.pos_query = function (pos, start = world, give = 10) {
|
||||||
var ret;
|
var ret;
|
||||||
ret = physics.point_query_nearest(pos, 0);
|
ret = physics.point_query_nearest(pos, 0);
|
||||||
|
|
||||||
if (ret)
|
if (ret) return ret.entity;
|
||||||
return ret.entity;
|
|
||||||
|
|
||||||
return game.all_objects(function(o) {
|
return game.all_objects(function (o) {
|
||||||
var dist = Vector.length(o.pos.sub(pos));
|
var dist = Vector.length(o.pos.sub(pos));
|
||||||
if (dist <= give) return o;
|
if (dist <= give) return o;
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
physics.box_point_query = function(box,points) {
|
physics.box_point_query = function (box, points) {
|
||||||
if (!box || !points) return [];
|
if (!box || !points) return [];
|
||||||
var bbox = bbox.fromcwh(box.pos,box.wh);
|
var bbox = bbox.fromcwh(box.pos, box.wh);
|
||||||
var inside = [];
|
var inside = [];
|
||||||
for (var i in points)
|
for (var i in points) if (bbox.pointin(bbox, points[i])) inside.push[i];
|
||||||
if (bbox.pointin(bbox,points[i])) inside.push[i];
|
|
||||||
return inside;
|
return inside;
|
||||||
}
|
};
|
||||||
|
|
||||||
Object.assign(physics, {
|
Object.assign(physics, {
|
||||||
dynamic: 0,
|
dynamic: 0,
|
||||||
|
@ -37,8 +35,8 @@ Object.assign(physics, {
|
||||||
static: 2,
|
static: 2,
|
||||||
|
|
||||||
com(pos) {
|
com(pos) {
|
||||||
if (!Array.isArray(pos)) return [0,0];
|
if (!Array.isArray(pos)) return [0, 0];
|
||||||
return pos.reduce((a,i) => a.add(i)).map(g => g/pos.length);
|
return pos.reduce((a, i) => a.add(i)).map(g => g / pos.length);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -53,8 +51,8 @@ physics.gravity.strength = 500;
|
||||||
physics.damp = physics.make_damp();
|
physics.damp = physics.make_damp();
|
||||||
physics.damp.mask = ~1;
|
physics.damp.mask = ~1;
|
||||||
|
|
||||||
physics.delta = 1/240;
|
physics.delta = 1 / 240;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
physics
|
physics,
|
||||||
}
|
};
|
||||||
|
|
|
@ -10,47 +10,48 @@
|
||||||
memory - can see how much memory is allocated and from where
|
memory - can see how much memory is allocated and from where
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var t_units = [ "ns", "us", "ms", "s", "ks", "Ms" ];
|
var t_units = ["ns", "us", "ms", "s", "ks", "Ms"];
|
||||||
|
|
||||||
function calc_cpu (fn, times, diff = 0) {
|
function calc_cpu(fn, times, diff = 0) {
|
||||||
var series = [];
|
var series = [];
|
||||||
|
|
||||||
for (var i = 0; i < times; i++) {
|
for (var i = 0; i < times; i++) {
|
||||||
var st = profile.now();
|
var st = profile.now();
|
||||||
fn (i);
|
fn(i);
|
||||||
series.push(profile.now() - st - diff);
|
series.push(profile.now() - st - diff);
|
||||||
}
|
}
|
||||||
|
|
||||||
return series;
|
return series;
|
||||||
}
|
}
|
||||||
|
|
||||||
function empty_fn () {}
|
function empty_fn() {}
|
||||||
|
|
||||||
profile.cpu = function profile_cpu(fn, times = 1, q = "unnamed") {
|
profile.cpu = function profile_cpu(fn, times = 1, q = "unnamed") {
|
||||||
var retgather = gathering_cpu;
|
var retgather = gathering_cpu;
|
||||||
profile.gather_stop();
|
profile.gather_stop();
|
||||||
var empty = calc_cpu(empty_fn, 100000);
|
var empty = calc_cpu(empty_fn, 100000);
|
||||||
var mean = Math.mean(empty);
|
var mean = Math.mean(empty);
|
||||||
var series = calc_cpu(fn,times, mean);
|
var series = calc_cpu(fn, times, mean);
|
||||||
|
|
||||||
var elapsed = Math.sum(series);
|
var elapsed = Math.sum(series);
|
||||||
var avgt = profile.best_t(elapsed/series.length);
|
var avgt = profile.best_t(elapsed / series.length);
|
||||||
var totalt = profile.best_t(elapsed);
|
var totalt = profile.best_t(elapsed);
|
||||||
|
|
||||||
say(`profile [${q}]: ${avgt} ± ${profile.best_t(Math.ci(series))} [${totalt} for ${times} loops]`);
|
say(`profile [${q}]: ${avgt} ± ${profile.best_t(Math.ci(series))} [${totalt} for ${times} loops]`);
|
||||||
say(`result of function is ${fn()}`);
|
say(`result of function is ${fn()}`);
|
||||||
|
|
||||||
if (retgather)
|
|
||||||
profile.start_prof_gather();
|
|
||||||
}
|
|
||||||
|
|
||||||
profile.ms = function(t) { return profile.secs(t)*1000; }
|
if (retgather) profile.start_prof_gather();
|
||||||
|
};
|
||||||
|
|
||||||
|
profile.ms = function (t) {
|
||||||
|
return profile.secs(t) * 1000;
|
||||||
|
};
|
||||||
|
|
||||||
var callgraph = {};
|
var callgraph = {};
|
||||||
profile.rawstacks = {};
|
profile.rawstacks = {};
|
||||||
profile.cpu_cg = callgraph;
|
profile.cpu_cg = callgraph;
|
||||||
|
|
||||||
function add_callgraph (fn, line, time) {
|
function add_callgraph(fn, line, time) {
|
||||||
var cc = callgraph[line];
|
var cc = callgraph[line];
|
||||||
if (!cc) {
|
if (!cc) {
|
||||||
var cc = {};
|
var cc = {};
|
||||||
|
@ -70,87 +71,82 @@ var start_gather = profile.now();
|
||||||
|
|
||||||
profile.cpu_start = undefined;
|
profile.cpu_start = undefined;
|
||||||
|
|
||||||
profile.clear_cpu = function()
|
profile.clear_cpu = function () {
|
||||||
{
|
|
||||||
callgraph = {};
|
callgraph = {};
|
||||||
}
|
};
|
||||||
|
|
||||||
profile.start_cpu_gather = function(gathertime = 5) // gather cpu frames for 'time' seconds
|
profile.start_cpu_gather = function (gathertime = 5) {
|
||||||
{
|
// gather cpu frames for 'time' seconds
|
||||||
if (profile.cpu_start) return;
|
if (profile.cpu_start) return;
|
||||||
profile.cpu_start = profile.now();
|
profile.cpu_start = profile.now();
|
||||||
var st = profile.cpu_start;
|
var st = profile.cpu_start;
|
||||||
|
|
||||||
profile.gather(hittar, function() {
|
profile.gather(hittar, function () {
|
||||||
var time = profile.now()-st;
|
var time = profile.now() - st;
|
||||||
|
|
||||||
var err = new Error();
|
var err = new Error();
|
||||||
var stack = err.stack.split("\n").slice(1);
|
var stack = err.stack.split("\n").slice(1);
|
||||||
var rawstack = stack.join('\n');
|
var rawstack = stack.join("\n");
|
||||||
profile.rawstacks[rawstack] ??= {
|
profile.rawstacks[rawstack] ??= {
|
||||||
time: 0,
|
time: 0,
|
||||||
hits: 0
|
hits: 0,
|
||||||
};
|
};
|
||||||
profile.rawstacks[rawstack].hits++;
|
profile.rawstacks[rawstack].hits++;
|
||||||
profile.rawstacks[rawstack].time += time;
|
profile.rawstacks[rawstack].time += time;
|
||||||
|
|
||||||
stack = stack.map(x => x.slice(7).split(' '));
|
stack = stack.map(x => x.slice(7).split(" "));
|
||||||
|
|
||||||
var fns = stack.map(x => x[0]).filter(x=>x);
|
var fns = stack.map(x => x[0]).filter(x => x);
|
||||||
var lines = stack.map(x => x[1]).filter(x => x);
|
var lines = stack.map(x => x[1]).filter(x => x);
|
||||||
lines = lines.map(x => x.slice(1,x.length-1));
|
lines = lines.map(x => x.slice(1, x.length - 1));
|
||||||
|
|
||||||
for (var i = 0; i < fns.length; i++)
|
for (var i = 0; i < fns.length; i++) add_callgraph(fns[i], lines[i], time);
|
||||||
add_callgraph(fns[i], lines[i], time);
|
|
||||||
|
|
||||||
st = profile.now();
|
st = profile.now();
|
||||||
if (profile.secs(st-profile.cpu_start) < gathertime)
|
if (profile.secs(st - profile.cpu_start) < gathertime) profile.gather_rate(Math.variate(hittar, hitpct));
|
||||||
profile.gather_rate(Math.variate(hittar,hitpct));
|
|
||||||
else {
|
else {
|
||||||
profile.gather_stop();
|
profile.gather_stop();
|
||||||
profile.cpu_start = undefined;
|
profile.cpu_start = undefined;
|
||||||
var e = Object.values(callgraph);
|
var e = Object.values(callgraph);
|
||||||
e = e.sort((a,b) => {
|
e = e.sort((a, b) => {
|
||||||
if (a.time > b.time) return -1;
|
if (a.time > b.time) return -1;
|
||||||
return 1;
|
return 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
for (var x of e) {
|
for (var x of e) {
|
||||||
var ffs = x.line.split(':');
|
var ffs = x.line.split(":");
|
||||||
x.timestr = profile.best_t(x.time);
|
x.timestr = profile.best_t(x.time);
|
||||||
var pct = profile.secs(x.time)/gathertime*100;
|
var pct = (profile.secs(x.time) / gathertime) * 100;
|
||||||
x.timeper = x.time / x.hits;
|
x.timeper = x.time / x.hits;
|
||||||
x.timeperstr = profile.best_t(x.timeper);
|
x.timeperstr = profile.best_t(x.timeper);
|
||||||
x.fncall = get_line(ffs[0], ffs[1]);
|
x.fncall = get_line(ffs[0], ffs[1]);
|
||||||
x.log =`${x.line}::${x.fn}:: ${x.timestr} (${pct.toPrecision(3)}%) (${x.hits} hits) --> ${get_line(ffs[0], ffs[1])}`;
|
x.log = `${x.line}::${x.fn}:: ${x.timestr} (${pct.toPrecision(3)}%) (${x.hits} hits) --> ${get_line(ffs[0], ffs[1])}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
profile.cpu_instr = e;
|
profile.cpu_instr = e;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
function push_time(arr, ob, max)
|
function push_time(arr, ob, max) {
|
||||||
{
|
|
||||||
arr.push({
|
arr.push({
|
||||||
time:profile.now(),
|
time: profile.now(),
|
||||||
ob
|
ob,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
profile.cpu_frames = [];
|
profile.cpu_frames = [];
|
||||||
profile.last_cpu_frame = undefined;
|
profile.last_cpu_frame = undefined;
|
||||||
profile.cpu_frame = function()
|
profile.cpu_frame = function () {
|
||||||
{
|
profile.gather(Math.random_range(300, 600), function () {
|
||||||
profile.gather(Math.random_range(300,600), function() {
|
|
||||||
var err = new Error();
|
var err = new Error();
|
||||||
profile.last_cpu_frame = err.stack;//.split('\n').slicconsole.stack(2);
|
profile.last_cpu_frame = err.stack; //.split('\n').slicconsole.stack(2);
|
||||||
profile.gather_stop();
|
profile.gather_stop();
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
var filecache = {};
|
var filecache = {};
|
||||||
function get_line (file, line) {
|
function get_line(file, line) {
|
||||||
var text = filecache[file];
|
var text = filecache[file];
|
||||||
if (!text) {
|
if (!text) {
|
||||||
var f = io.slurp(file);
|
var f = io.slurp(file);
|
||||||
|
@ -158,17 +154,19 @@ function get_line (file, line) {
|
||||||
filecache[file] = "undefined";
|
filecache[file] = "undefined";
|
||||||
return filecache[file];
|
return filecache[file];
|
||||||
}
|
}
|
||||||
filecache[file] = io.slurp(file).split('\n');
|
filecache[file] = io.slurp(file).split("\n");
|
||||||
text = filecache[file];
|
text = filecache[file];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof text === 'string') return text;
|
if (typeof text === "string") return text;
|
||||||
text = text[Number (line) - 1];
|
text = text[Number(line) - 1];
|
||||||
if (!text) return "NULL";
|
if (!text) return "NULL";
|
||||||
return text.trim();
|
return text.trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
profile.stop_cpu_instr = function () { return; }
|
profile.stop_cpu_instr = function () {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
profile.best_t = function (t) {
|
profile.best_t = function (t) {
|
||||||
var qq = 0;
|
var qq = 0;
|
||||||
|
@ -193,26 +191,23 @@ profile.report = function (start, msg = "[undefined report]") {
|
||||||
var frame_avg = false;
|
var frame_avg = false;
|
||||||
profile.frame_avg_t = 72000;
|
profile.frame_avg_t = 72000;
|
||||||
|
|
||||||
profile.start_frame_avg = function()
|
profile.start_frame_avg = function () {
|
||||||
{
|
|
||||||
if (frame_avg) return;
|
if (frame_avg) return;
|
||||||
profile_frames = {};
|
profile_frames = {};
|
||||||
profile_frame_ts = [];
|
profile_frame_ts = [];
|
||||||
profile_cframe = profile_frames;
|
profile_cframe = profile_frames;
|
||||||
pframe = 0;
|
pframe = 0;
|
||||||
frame_avg = true;
|
frame_avg = true;
|
||||||
}
|
};
|
||||||
|
|
||||||
profile.stop_frame_avg = function()
|
profile.stop_frame_avg = function () {
|
||||||
{
|
|
||||||
frame_avg = false;
|
frame_avg = false;
|
||||||
}
|
};
|
||||||
|
|
||||||
profile.toggle_frame_avg = function()
|
profile.toggle_frame_avg = function () {
|
||||||
{
|
|
||||||
if (frame_avg) profile.stop_frame_avg();
|
if (frame_avg) profile.stop_frame_avg();
|
||||||
else profile.start_frame_avg();
|
else profile.start_frame_avg();
|
||||||
}
|
};
|
||||||
|
|
||||||
var profile_framer = {
|
var profile_framer = {
|
||||||
series: [],
|
series: [],
|
||||||
|
@ -223,52 +218,46 @@ var profile_cframe = undefined;
|
||||||
var pframe = 0;
|
var pframe = 0;
|
||||||
var profile_stack = [];
|
var profile_stack = [];
|
||||||
|
|
||||||
profile.frame = function profile_frame(title)
|
profile.frame = function profile_frame(title) {
|
||||||
{
|
|
||||||
if (profile.cpu_start) return;
|
if (profile.cpu_start) return;
|
||||||
if (!frame_avg) return;
|
if (!frame_avg) return;
|
||||||
|
|
||||||
if (!profile_cframe) {
|
if (!profile_cframe) {
|
||||||
profile_cframe = {};
|
profile_cframe = {};
|
||||||
profile_framer.series.push({
|
profile_framer.series.push({
|
||||||
time:profile.now(),
|
time: profile.now(),
|
||||||
data:profile_cframe
|
data: profile_cframe,
|
||||||
});
|
});
|
||||||
} else
|
} else profile_stack.push(profile_cframe);
|
||||||
profile_stack.push(profile_cframe);
|
|
||||||
|
|
||||||
profile_cframe[title] ??= {};
|
profile_cframe[title] ??= {};
|
||||||
profile_cframe = profile_cframe[title];
|
profile_cframe = profile_cframe[title];
|
||||||
profile_cframe.time = profile.now();
|
profile_cframe.time = profile.now();
|
||||||
}
|
};
|
||||||
|
|
||||||
profile.endframe = function profile_endframe()
|
profile.endframe = function profile_endframe() {
|
||||||
{
|
|
||||||
if (!frame_avg) return;
|
if (!frame_avg) return;
|
||||||
profile_cframe.time = profile.now() - profile_cframe.time;
|
profile_cframe.time = profile.now() - profile_cframe.time;
|
||||||
profile_cframe = profile_frame_ts.pop();
|
profile_cframe = profile_frame_ts.pop();
|
||||||
}
|
};
|
||||||
|
|
||||||
var print_frame = function(frame, indent, title)
|
var print_frame = function (frame, indent, title) {
|
||||||
{
|
|
||||||
say(indent + `${title} ::::: ${profile.best_t(Math.mean(frame._times))} ± ${profile.best_t(Math.ci(frame._times))} (${frame._times.length} hits)`);
|
say(indent + `${title} ::::: ${profile.best_t(Math.mean(frame._times))} ± ${profile.best_t(Math.ci(frame._times))} (${frame._times.length} hits)`);
|
||||||
|
|
||||||
for (var i in frame) {
|
for (var i in frame) {
|
||||||
if (i === '_times') continue;
|
if (i === "_times") continue;
|
||||||
print_frame(frame[i], indent + " ", i);
|
print_frame(frame[i], indent + " ", i);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
profile.print_frame_avg = function()
|
profile.print_frame_avg = function () {
|
||||||
{
|
|
||||||
say("===FRAME AVERAGES===\n");
|
say("===FRAME AVERAGES===\n");
|
||||||
|
|
||||||
var indent = "";
|
var indent = "";
|
||||||
for (var i in profile_frames)
|
for (var i in profile_frames) print_frame(profile_frames[i], "", "frame");
|
||||||
print_frame(profile_frames[i], "", 'frame');
|
|
||||||
|
|
||||||
say("\n");
|
say("\n");
|
||||||
}
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Cache reporting is to measure how long specific events take, that are NOT every frame
|
Cache reporting is to measure how long specific events take, that are NOT every frame
|
||||||
|
@ -283,47 +272,48 @@ var cachest = 0;
|
||||||
var cachegroup;
|
var cachegroup;
|
||||||
var cachetitle;
|
var cachetitle;
|
||||||
|
|
||||||
profile.cache_reporting = function() { return cache_reporting; }
|
profile.cache_reporting = function () {
|
||||||
profile.cache_toggle = function() { cache_reporting = !cache_reporting; }
|
return cache_reporting;
|
||||||
profile.cache_dump = function() {
|
};
|
||||||
|
profile.cache_toggle = function () {
|
||||||
|
cache_reporting = !cache_reporting;
|
||||||
|
};
|
||||||
|
profile.cache_dump = function () {
|
||||||
report_cache = {};
|
report_cache = {};
|
||||||
}
|
};
|
||||||
|
|
||||||
profile.cache = function profile_cache(group, title)
|
profile.cache = function profile_cache(group, title) {
|
||||||
{
|
|
||||||
if (!cache_reporting) return;
|
if (!cache_reporting) return;
|
||||||
cachest = profile.now();
|
cachest = profile.now();
|
||||||
cachegroup = group;
|
cachegroup = group;
|
||||||
cachetitle = title;
|
cachetitle = title;
|
||||||
}
|
};
|
||||||
|
|
||||||
profile.endcache = function profile_endcache(tag = "")
|
profile.endcache = function profile_endcache(tag = "") {
|
||||||
{
|
|
||||||
addreport(cachegroup, cachetitle + tag, cachest);
|
addreport(cachegroup, cachetitle + tag, cachest);
|
||||||
}
|
};
|
||||||
|
|
||||||
function addreport(group, line, start) {
|
function addreport(group, line, start) {
|
||||||
if (typeof group !== 'string') group = 'UNGROUPED';
|
if (typeof group !== "string") group = "UNGROUPED";
|
||||||
report_cache[group] ??= {};
|
report_cache[group] ??= {};
|
||||||
var cache = report_cache[group];
|
var cache = report_cache[group];
|
||||||
cache[line] ??= [];
|
cache[line] ??= [];
|
||||||
var t = profile.now();
|
var t = profile.now();
|
||||||
cache[line].push(t - start);
|
cache[line].push(t - start);
|
||||||
return t;
|
return t;
|
||||||
};
|
}
|
||||||
|
|
||||||
function printreport (cache, name) {
|
function printreport(cache, name) {
|
||||||
var report = `==${name}==` +
|
var report = `==${name}==` + "\n";
|
||||||
"\n";
|
|
||||||
|
|
||||||
var reports = [];
|
var reports = [];
|
||||||
for (var i in cache) {
|
for (var i in cache) {
|
||||||
var time = cache[i].reduce((a, b) => a + b);
|
var time = cache[i].reduce((a, b) => a + b);
|
||||||
reports.push({
|
reports.push({
|
||||||
time : time,
|
time: time,
|
||||||
name : i,
|
name: i,
|
||||||
hits : cache[i].length,
|
hits: cache[i].length,
|
||||||
avg : time / cache[i].length
|
avg: time / cache[i].length,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
reports = reports.sort((a, b) => {
|
reports = reports.sort((a, b) => {
|
||||||
|
@ -331,47 +321,40 @@ function printreport (cache, name) {
|
||||||
return -1;
|
return -1;
|
||||||
});
|
});
|
||||||
|
|
||||||
for (var rep of reports)
|
for (var rep of reports) report += `${rep.name} ${profile.best_t(rep.avg)} (${rep.hits} hits) (total ${profile.best_t(rep.time)})\n`;
|
||||||
report += `${rep.name} ${profile.best_t(rep.avg)} (${
|
|
||||||
rep.hits} hits) (total ${profile.best_t(rep.time)})\n`;
|
|
||||||
|
|
||||||
return report;
|
return report;
|
||||||
};
|
}
|
||||||
|
|
||||||
profile.data = {};
|
profile.data = {};
|
||||||
profile.curframe = 0;
|
profile.curframe = 0;
|
||||||
|
|
||||||
function prof_add_stats (obj, stat) {
|
function prof_add_stats(obj, stat) {
|
||||||
for (var i in stat) {
|
for (var i in stat) {
|
||||||
obj[i] ??= [];
|
obj[i] ??= [];
|
||||||
if (obj[i].last() !== stat[i]) obj[i][profile.curframe] = stat[i];
|
if (obj[i].last() !== stat[i]) obj[i][profile.curframe] = stat[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
profile.pushdata = function(arr, val)
|
profile.pushdata = function (arr, val) {
|
||||||
{
|
if (arr.last() !== val) arr[profile.curframe] = val;
|
||||||
if (arr.last() !== val)
|
};
|
||||||
arr[profile.curframe] = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
profile.capture_data = function()
|
profile.capture_data = function () {
|
||||||
{
|
|
||||||
prof_add_stats(profile.data.memory, os.mem());
|
prof_add_stats(profile.data.memory, os.mem());
|
||||||
prof_add_stats(profile.data.gfx, imgui.framestats());
|
prof_add_stats(profile.data.gfx, imgui.framestats());
|
||||||
prof_add_stats(profile.data.actors, actor.__stats());
|
prof_add_stats(profile.data.actors, actor.__stats());
|
||||||
profile.curframe++;
|
profile.curframe++;
|
||||||
}
|
};
|
||||||
|
|
||||||
profile.best_mem = function(bytes)
|
profile.best_mem = function (bytes) {
|
||||||
{
|
var sizes = ["Bytes", "KB", "MB", "GB", "TB"];
|
||||||
var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
|
if (bytes == 0) return "0 Bytes";
|
||||||
if (bytes == 0) return '0 Bytes';
|
|
||||||
var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
|
var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
|
||||||
return (bytes / Math.pow(1024, i)).toPrecision(3) + ' ' + sizes[i];
|
return (bytes / Math.pow(1024, i)).toPrecision(3) + " " + sizes[i];
|
||||||
}
|
};
|
||||||
|
|
||||||
profile.cleardata = function()
|
profile.cleardata = function () {
|
||||||
{
|
|
||||||
profile.data.gpu = {};
|
profile.data.gpu = {};
|
||||||
profile.data.physics = {};
|
profile.data.physics = {};
|
||||||
profile.data.script = {};
|
profile.data.script = {};
|
||||||
|
@ -383,19 +366,18 @@ profile.cleardata = function()
|
||||||
render: [],
|
render: [],
|
||||||
physics: [],
|
physics: [],
|
||||||
};
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
profile.cleardata();
|
profile.cleardata();
|
||||||
|
|
||||||
profile.last_mem = undefined;
|
profile.last_mem = undefined;
|
||||||
profile.mems = [];
|
profile.mems = [];
|
||||||
profile.gcs = [];
|
profile.gcs = [];
|
||||||
profile.print_gc = function()
|
profile.print_gc = function () {
|
||||||
{
|
|
||||||
var gc = os.check_gc();
|
var gc = os.check_gc();
|
||||||
if (!gc) return;
|
if (!gc) return;
|
||||||
profile.data.gc ??= [];
|
profile.data.gc ??= [];
|
||||||
profile.data.gc[profile.curframe] = gc;
|
profile.data.gc[profile.curframe] = gc;
|
||||||
}
|
};
|
||||||
|
|
||||||
return {profile};
|
return { profile };
|
||||||
|
|
|
@ -2,14 +2,14 @@ globalThis.gamestate = {};
|
||||||
|
|
||||||
global.check_registers = function (obj) {
|
global.check_registers = function (obj) {
|
||||||
for (var reg in Register.registries) {
|
for (var reg in Register.registries) {
|
||||||
if (typeof obj[reg] === 'function') {
|
if (typeof obj[reg] === "function") {
|
||||||
var fn = obj[reg].bind(obj);
|
var fn = obj[reg].bind(obj);
|
||||||
fn.layer = obj[reg].layer;
|
fn.layer = obj[reg].layer;
|
||||||
var name = obj.ur ? obj.ur.name : obj.toString();
|
var name = obj.ur ? obj.ur.name : obj.toString();
|
||||||
obj.timers.push(Register.registries[reg].register(fn, name));
|
obj.timers.push(Register.registries[reg].register(fn, name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var k in obj) {
|
for (var k in obj) {
|
||||||
if (!k.startsWith("on_")) continue;
|
if (!k.startsWith("on_")) continue;
|
||||||
var signal = k.fromfirst("on_");
|
var signal = k.fromfirst("on_");
|
||||||
|
@ -70,7 +70,7 @@ game.engine_start = function (s) {
|
||||||
|
|
||||||
prosperon.camera = prosperon.make_camera();
|
prosperon.camera = prosperon.make_camera();
|
||||||
var camera = prosperon.camera;
|
var camera = prosperon.camera;
|
||||||
camera.transform.pos = [0,0,-100];
|
camera.transform.pos = [0, 0, -100];
|
||||||
camera.mode = "keep";
|
camera.mode = "keep";
|
||||||
camera.break = "fit";
|
camera.break = "fit";
|
||||||
camera.size = game.size;
|
camera.size = game.size;
|
||||||
|
@ -87,11 +87,11 @@ game.engine_start = function (s) {
|
||||||
var appcam = prosperon.appcam;
|
var appcam = prosperon.appcam;
|
||||||
appcam.near = 0;
|
appcam.near = 0;
|
||||||
appcam.size = window.size;
|
appcam.size = window.size;
|
||||||
appcam.transform.pos = [window.size.x,window.size.y,-100];
|
appcam.transform.pos = [window.size.x, window.size.y, -100];
|
||||||
prosperon.screencolor = render.screencolor();
|
prosperon.screencolor = render.screencolor();
|
||||||
|
|
||||||
globalThis.imgui = render.imgui_init();
|
globalThis.imgui = render.imgui_init();
|
||||||
|
|
||||||
s();
|
s();
|
||||||
|
|
||||||
shape.quad = {
|
shape.quad = {
|
||||||
|
@ -109,13 +109,13 @@ game.engine_start = function (s) {
|
||||||
count: 3,
|
count: 3,
|
||||||
index: os.make_buffer([0, 2, 1], 1),
|
index: os.make_buffer([0, 2, 1], 1),
|
||||||
};
|
};
|
||||||
|
|
||||||
shape.centered_quad = {
|
shape.centered_quad = {
|
||||||
pos: os.make_buffer([-0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5], 0),
|
pos: os.make_buffer([-0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5], 0),
|
||||||
verts: 4,
|
verts: 4,
|
||||||
uv: os.make_buffer([0,1,1,1,0,0,1,0],2),
|
uv: os.make_buffer([0, 1, 1, 1, 0, 0, 1, 0], 2),
|
||||||
index: os.make_buffer([0,1,2,2,1,3],1),
|
index: os.make_buffer([0, 1, 2, 2, 1, 3], 1),
|
||||||
count: 6
|
count: 6,
|
||||||
};
|
};
|
||||||
|
|
||||||
render.init();
|
render.init();
|
||||||
|
@ -128,12 +128,11 @@ game.engine_start = function (s) {
|
||||||
|
|
||||||
game.startengine = 0;
|
game.startengine = 0;
|
||||||
|
|
||||||
prosperon.release_mode = function()
|
prosperon.release_mode = function () {
|
||||||
{
|
|
||||||
prosperon.debug = false;
|
prosperon.debug = false;
|
||||||
mum.debug = false;
|
mum.debug = false;
|
||||||
debug.kill();
|
debug.kill();
|
||||||
}
|
};
|
||||||
prosperon.debug = true;
|
prosperon.debug = true;
|
||||||
|
|
||||||
game.timescale = 1;
|
game.timescale = 1;
|
||||||
|
@ -142,8 +141,7 @@ var eachobj = function (obj, fn) {
|
||||||
var val = fn(obj);
|
var val = fn(obj);
|
||||||
if (val) return val;
|
if (val) return val;
|
||||||
for (var o in obj.objects) {
|
for (var o in obj.objects) {
|
||||||
if (obj.objects[o] === obj)
|
if (obj.objects[o] === obj) console.error(`Object ${obj.toString()} is referenced by itself.`);
|
||||||
console.error(`Object ${obj.toString()} is referenced by itself.`);
|
|
||||||
val = eachobj(obj.objects[o], fn);
|
val = eachobj(obj.objects[o], fn);
|
||||||
if (val) return val;
|
if (val) return val;
|
||||||
}
|
}
|
||||||
|
@ -179,8 +177,7 @@ game.doc.pause = "Pause game simulation.";
|
||||||
game.doc.play = "Resume or start game simulation.";
|
game.doc.play = "Resume or start game simulation.";
|
||||||
game.doc.camera = "Current camera.";
|
game.doc.camera = "Current camera.";
|
||||||
|
|
||||||
game.tex_hotreload = function()
|
game.tex_hotreload = function () {
|
||||||
{
|
|
||||||
for (var path in game.texture.cache) {
|
for (var path in game.texture.cache) {
|
||||||
if (io.mod(path) > game.texture.time_cache[path]) {
|
if (io.mod(path) > game.texture.time_cache[path]) {
|
||||||
var tex = game.texture.cache[path];
|
var tex = game.texture.cache[path];
|
||||||
|
@ -188,17 +185,17 @@ game.tex_hotreload = function()
|
||||||
os.texture_swap(path, game.texture.cache[path]);
|
os.texture_swap(path, game.texture.cache[path]);
|
||||||
for (var sprite of Object.values(allsprites)) {
|
for (var sprite of Object.values(allsprites)) {
|
||||||
if (sprite.texture == tex) {
|
if (sprite.texture == tex) {
|
||||||
sprite.tex_sync();
|
sprite.tex_sync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
game.texture = function (path) {
|
game.texture = function (path) {
|
||||||
if (!path) return game.texture("icons/no_text.gif");
|
if (!path) return game.texture("icons/no_text.gif");
|
||||||
path = Resources.find_image(path);
|
path = Resources.find_image(path);
|
||||||
|
|
||||||
if (!io.exists(path)) {
|
if (!io.exists(path)) {
|
||||||
console.error(`Missing texture: ${path}`);
|
console.error(`Missing texture: ${path}`);
|
||||||
game.texture.cache[path] = game.texture("icons/no_tex.gif");
|
game.texture.cache[path] = game.texture("icons/no_tex.gif");
|
||||||
|
@ -229,8 +226,7 @@ prosperon.semver.valid = function (v, range) {
|
||||||
|
|
||||||
if (range[0] === "~") {
|
if (range[0] === "~") {
|
||||||
range[0] = range[0].slice(1);
|
range[0] = range[0].slice(1);
|
||||||
for (var i = 0; i < 2; i++)
|
for (var i = 0; i < 2; i++) if (parseInt(v[i]) < parseInt(range[i])) return false;
|
||||||
if (parseInt(v[i]) < parseInt(range[i])) return false;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,8 +247,7 @@ prosperon.semver.cmp = function (v1, v2) {
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
prosperon.semver.cmp.doc =
|
prosperon.semver.cmp.doc = "Compare two semantic version numbers, given like X.X.X.";
|
||||||
"Compare two semantic version numbers, given like X.X.X.";
|
|
||||||
prosperon.semver.valid.doc = `Test if semantic version v is valid, given a range.
|
prosperon.semver.valid.doc = `Test if semantic version v is valid, given a range.
|
||||||
Range is given by a semantic versioning number, prefixed with nothing, a ~, or a ^.
|
Range is given by a semantic versioning number, prefixed with nothing, a ~, or a ^.
|
||||||
~ means that MAJOR and MINOR must match exactly, but any PATCH greater or equal is valid.
|
~ means that MAJOR and MINOR must match exactly, but any PATCH greater or equal is valid.
|
||||||
|
@ -277,7 +272,9 @@ prosperon.quit = function () {
|
||||||
|
|
||||||
window.size = [640, 480];
|
window.size = [640, 480];
|
||||||
window.mode = "keep";
|
window.mode = "keep";
|
||||||
window.toggle_fullscreen = function() { window.fullscreen = !window.fullscreen; }
|
window.toggle_fullscreen = function () {
|
||||||
|
window.fullscreen = !window.fullscreen;
|
||||||
|
};
|
||||||
|
|
||||||
window.set_icon.doc = "Set the icon of the window using the PNG image at path.";
|
window.set_icon.doc = "Set the icon of the window using the PNG image at path.";
|
||||||
|
|
||||||
|
@ -285,14 +282,13 @@ window.doc = {};
|
||||||
window.doc.dimensions = "Window width and height packaged in an array [width,height]";
|
window.doc.dimensions = "Window width and height packaged in an array [width,height]";
|
||||||
window.doc.title = "Name in the title bar of the window.";
|
window.doc.title = "Name in the title bar of the window.";
|
||||||
window.doc.boundingbox = "Boundingbox of the window, with top and right being its height and width.";
|
window.doc.boundingbox = "Boundingbox of the window, with top and right being its height and width.";
|
||||||
window.__proto__.toJSON = function()
|
window.__proto__.toJSON = function () {
|
||||||
{
|
|
||||||
return {
|
return {
|
||||||
size: this.size,
|
size: this.size,
|
||||||
fullscreen: this.fullscreen,
|
fullscreen: this.fullscreen,
|
||||||
title: this.title
|
title: this.title,
|
||||||
};
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
global.mixin("scripts/input");
|
global.mixin("scripts/input");
|
||||||
global.mixin("scripts/std");
|
global.mixin("scripts/std");
|
||||||
|
@ -302,7 +298,7 @@ global.mixin("scripts/tween");
|
||||||
global.mixin("scripts/ai");
|
global.mixin("scripts/ai");
|
||||||
global.mixin("scripts/particle");
|
global.mixin("scripts/particle");
|
||||||
global.mixin("scripts/physics");
|
global.mixin("scripts/physics");
|
||||||
global.mixin("scripts/geometry")
|
global.mixin("scripts/geometry");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Factory for creating registries. Register one with 'X.register',
|
Factory for creating registries. Register one with 'X.register',
|
||||||
|
@ -317,44 +313,43 @@ var Register = {
|
||||||
|
|
||||||
n.register = function (fn, oname) {
|
n.register = function (fn, oname) {
|
||||||
if (!(fn instanceof Function)) return;
|
if (!(fn instanceof Function)) return;
|
||||||
|
|
||||||
var guid = prosperon.guid();
|
var guid = prosperon.guid();
|
||||||
|
|
||||||
var dofn = function(...args) {
|
var dofn = function (...args) {
|
||||||
profile.cache(name,oname);
|
profile.cache(name, oname);
|
||||||
var st = profile.now();
|
var st = profile.now();
|
||||||
fn(...args);
|
fn(...args);
|
||||||
profile.endcache();
|
profile.endcache();
|
||||||
}
|
};
|
||||||
|
|
||||||
fns.push(dofn);
|
fns.push(dofn);
|
||||||
dofn.layer = fn.layer;
|
dofn.layer = fn.layer;
|
||||||
dofn.layer ??= 0;
|
dofn.layer ??= 0;
|
||||||
|
|
||||||
fns.sort((a,b) => a.layer > b.layer);
|
fns.sort((a, b) => a.layer > b.layer);
|
||||||
|
|
||||||
return function () {
|
return function () {
|
||||||
fns.remove(dofn);
|
fns.remove(dofn);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!flush) {
|
if (!flush) {
|
||||||
prosperon[name] = function(...args) {
|
prosperon[name] = function (...args) {
|
||||||
fns.forEach(fn => fn(...args));
|
fns.forEach(fn => fn(...args));
|
||||||
}
|
};
|
||||||
}
|
} else
|
||||||
else
|
prosperon[name] = function (...args) {
|
||||||
prosperon[name] = function(...args) {
|
|
||||||
var layer = undefined;
|
var layer = undefined;
|
||||||
for (var fn of fns) {
|
for (var fn of fns) {
|
||||||
if (layer !== fn.layer) {
|
if (layer !== fn.layer) {
|
||||||
flush();
|
flush();
|
||||||
layer = fn.layer;
|
layer = fn.layer;
|
||||||
}
|
}
|
||||||
fn();
|
fn();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
prosperon[name].fns = fns;
|
prosperon[name].fns = fns;
|
||||||
n.clear = function () {
|
n.clear = function () {
|
||||||
fns = [];
|
fns = [];
|
||||||
|
@ -384,11 +379,11 @@ var Event = {
|
||||||
},
|
},
|
||||||
|
|
||||||
unobserve(name, obj) {
|
unobserve(name, obj) {
|
||||||
this.events[name] = this.events[name].filter((x) => x[0] !== obj);
|
this.events[name] = this.events[name].filter(x => x[0] !== obj);
|
||||||
},
|
},
|
||||||
|
|
||||||
rm_obj(obj) {
|
rm_obj(obj) {
|
||||||
Object.keys(this.events).forEach((name) => Event.unobserve(name, obj));
|
Object.keys(this.events).forEach(name => Event.unobserve(name, obj));
|
||||||
},
|
},
|
||||||
|
|
||||||
notify(name, ...args) {
|
notify(name, ...args) {
|
||||||
|
@ -435,5 +430,5 @@ return {
|
||||||
sim,
|
sim,
|
||||||
frame_t,
|
frame_t,
|
||||||
physlag,
|
physlag,
|
||||||
Event
|
Event,
|
||||||
}
|
};
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -3,13 +3,13 @@ var repl = {};
|
||||||
var file = "repl.jj";
|
var file = "repl.jj";
|
||||||
var last = 0;
|
var last = 0;
|
||||||
|
|
||||||
repl.hotreload = function() {
|
repl.hotreload = function () {
|
||||||
if (io.mod(file) > last) {
|
if (io.mod(file) > last) {
|
||||||
say("REPL:::");
|
say("REPL:::");
|
||||||
last = io.mod(file);
|
last = io.mod(file);
|
||||||
var script = io.slurp(file);
|
var script = io.slurp(file);
|
||||||
eval(script);
|
eval(script);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
return {repl:repl};
|
return { repl: repl };
|
||||||
|
|
101
scripts/sound.js
101
scripts/sound.js
|
@ -1,12 +1,12 @@
|
||||||
/* This file runs after the audio system is initiated */
|
/* This file runs after the audio system is initiated */
|
||||||
|
|
||||||
Object.readonly(audio, 'samplerate');
|
Object.readonly(audio, "samplerate");
|
||||||
Object.readonly(audio, 'channels');
|
Object.readonly(audio, "channels");
|
||||||
Object.readonly(audio, 'buffer_frames');
|
Object.readonly(audio, "buffer_frames");
|
||||||
|
|
||||||
var sources = [];
|
var sources = [];
|
||||||
|
|
||||||
audio.play = function(file,bus = audio.bus.master) {
|
audio.play = function (file, bus = audio.bus.master) {
|
||||||
var filename = file;
|
var filename = file;
|
||||||
file = Resources.find_sound(file);
|
file = Resources.find_sound(file);
|
||||||
if (!file) {
|
if (!file) {
|
||||||
|
@ -20,7 +20,7 @@ audio.play = function(file,bus = audio.bus.master) {
|
||||||
src.type = "source";
|
src.type = "source";
|
||||||
sources.push(src);
|
sources.push(src);
|
||||||
return src;
|
return src;
|
||||||
}
|
};
|
||||||
audio.bus = {};
|
audio.bus = {};
|
||||||
audio.bus.master = dspsound.master();
|
audio.bus.master = dspsound.master();
|
||||||
audio.dsp = {};
|
audio.dsp = {};
|
||||||
|
@ -30,47 +30,45 @@ audio.bus.master.__proto__.type = "bus";
|
||||||
audio.bus.master.name = "master";
|
audio.bus.master.name = "master";
|
||||||
|
|
||||||
var plugin_node = audio.bus.master.plugin;
|
var plugin_node = audio.bus.master.plugin;
|
||||||
audio.bus.master.__proto__.plugin = function(to)
|
audio.bus.master.__proto__.plugin = function (to) {
|
||||||
{
|
|
||||||
this.tos ??= [];
|
this.tos ??= [];
|
||||||
this.tos.push(to);
|
this.tos.push(to);
|
||||||
to.ins ??= [];
|
to.ins ??= [];
|
||||||
to.ins.push(this);
|
to.ins.push(this);
|
||||||
plugin_node.call(this, to);
|
plugin_node.call(this, to);
|
||||||
}
|
};
|
||||||
|
|
||||||
var unplug_node = audio.bus.master.unplug;
|
var unplug_node = audio.bus.master.unplug;
|
||||||
audio.bus.master.__proto__.unplug = function()
|
audio.bus.master.__proto__.unplug = function () {
|
||||||
{
|
|
||||||
if (this.tos) {
|
if (this.tos) {
|
||||||
for (var node of this.tos)
|
for (var node of this.tos) node.ins.remove(this);
|
||||||
node.ins.remove(this);
|
|
||||||
|
|
||||||
this.tos = [];
|
this.tos = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
unplug_node.call(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
audio.dsp.mix().__proto__.imgui = function()
|
unplug_node.call(this);
|
||||||
{
|
};
|
||||||
|
|
||||||
|
audio.dsp.mix().__proto__.imgui = function () {
|
||||||
imgui.pushid(this.memid());
|
imgui.pushid(this.memid());
|
||||||
this.volume = imgui.slider("Volume", this.volume);
|
this.volume = imgui.slider("Volume", this.volume);
|
||||||
this.off = imgui.checkbox("Mute", this.off);
|
this.off = imgui.checkbox("Mute", this.off);
|
||||||
imgui.popid();
|
imgui.popid();
|
||||||
}
|
};
|
||||||
|
|
||||||
audio.cry = function(file, bus = audio.bus.sfx)
|
audio.cry = function (file, bus = audio.bus.sfx) {
|
||||||
{
|
|
||||||
file = Resources.find_sound(file);
|
file = Resources.find_sound(file);
|
||||||
var player = audio.play(file, bus);
|
var player = audio.play(file, bus);
|
||||||
if (!player) return;
|
if (!player) return;
|
||||||
player.ended = function() { player.unplug(); player = undefined; }
|
player.ended = function () {
|
||||||
|
player.unplug();
|
||||||
|
player = undefined;
|
||||||
|
};
|
||||||
return player.ended;
|
return player.ended;
|
||||||
}
|
};
|
||||||
|
|
||||||
// This function is called when every audio source is finished
|
// This function is called when every audio source is finished
|
||||||
var killer = Register.appupdate.register(function() {
|
var killer = Register.appupdate.register(function () {
|
||||||
for (var src of sources) {
|
for (var src of sources) {
|
||||||
if (!src.loop && (src.frame < src.lastframe || src.frame === src.frames())) {
|
if (!src.loop && (src.frame < src.lastframe || src.frame === src.frames())) {
|
||||||
src.unplug();
|
src.unplug();
|
||||||
|
@ -83,10 +81,9 @@ var killer = Register.appupdate.register(function() {
|
||||||
var song;
|
var song;
|
||||||
|
|
||||||
// Play 'file' for new song, cross fade for seconds
|
// Play 'file' for new song, cross fade for seconds
|
||||||
audio.music = function(file, fade = 0.5) {
|
audio.music = function (file, fade = 0.5) {
|
||||||
if (!file) {
|
if (!file) {
|
||||||
if (song)
|
if (song) song.volume = 0;
|
||||||
song.volume = 0;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
file = Resources.find_sound(file);
|
file = Resources.find_sound(file);
|
||||||
|
@ -99,20 +96,20 @@ audio.music = function(file, fade = 0.5) {
|
||||||
if (!song) {
|
if (!song) {
|
||||||
song = audio.play(file, audio.bus.music);
|
song = audio.play(file, audio.bus.music);
|
||||||
song.volume = 1;
|
song.volume = 1;
|
||||||
// tween(song,'volume', 1, fade);
|
// tween(song,'volume', 1, fade);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var temp = audio.play(file, audio.bus.music);
|
var temp = audio.play(file, audio.bus.music);
|
||||||
if (!temp) return;
|
if (!temp) return;
|
||||||
|
|
||||||
temp.volume = 1;
|
temp.volume = 1;
|
||||||
var temp2 = song;
|
var temp2 = song;
|
||||||
// tween(temp, 'volume', 1, fade);
|
// tween(temp, 'volume', 1, fade);
|
||||||
// tween(temp2, 'volume', 0, fade);
|
// tween(temp2, 'volume', 0, fade);
|
||||||
song = temp;
|
song = temp;
|
||||||
song.loop = true;
|
song.loop = true;
|
||||||
}
|
};
|
||||||
|
|
||||||
audio.bus.music = audio.dsp.mix();
|
audio.bus.music = audio.dsp.mix();
|
||||||
audio.bus.music.plugin(audio.bus.master);
|
audio.bus.music.plugin(audio.bus.master);
|
||||||
|
@ -122,16 +119,16 @@ audio.bus.sfx = audio.dsp.mix();
|
||||||
audio.bus.sfx.plugin(audio.bus.master);
|
audio.bus.sfx.plugin(audio.bus.master);
|
||||||
audio.bus.sfx.name = "sfx";
|
audio.bus.sfx.name = "sfx";
|
||||||
|
|
||||||
audio.dsp.allpass = function(secs, decay) {
|
audio.dsp.allpass = function (secs, decay) {
|
||||||
var composite = {};
|
var composite = {};
|
||||||
var fwd = audio.dsp.fwd_delay(secs,-decay);
|
var fwd = audio.dsp.fwd_delay(secs, -decay);
|
||||||
var fbk = audio.dsp.delay(secs,decay);
|
var fbk = audio.dsp.delay(secs, decay);
|
||||||
composite.id = fwd.id;
|
composite.id = fwd.id;
|
||||||
composite.plugin = composite.plugin.bind(fbk);
|
composite.plugin = composite.plugin.bind(fbk);
|
||||||
composite.unplug = dsp_node.unplug.bind(fbk);
|
composite.unplug = dsp_node.unplug.bind(fbk);
|
||||||
fwd.plugin(fbk);
|
fwd.plugin(fbk);
|
||||||
return composite;
|
return composite;
|
||||||
}
|
};
|
||||||
|
|
||||||
audio.dsp.doc = {
|
audio.dsp.doc = {
|
||||||
delay: "Delays the input by secs, multiplied by decay",
|
delay: "Delays the input by secs, multiplied by decay",
|
||||||
|
@ -146,27 +143,35 @@ audio.dsp.doc = {
|
||||||
pitchshift: "Shift sound by octaves",
|
pitchshift: "Shift sound by octaves",
|
||||||
noise: "Plain randon noise",
|
noise: "Plain randon noise",
|
||||||
pink: "Pink noise",
|
pink: "Pink noise",
|
||||||
red: "Red noise"
|
red: "Red noise",
|
||||||
};
|
};
|
||||||
|
|
||||||
audio.dsp.obscure('doc');
|
audio.dsp.obscure("doc");
|
||||||
|
|
||||||
Object.mixin(audio.bus.master.__proto__, {
|
Object.mixin(audio.bus.master.__proto__, {
|
||||||
get db() { return 20*Math.log10(Math.abs(this.volume)); },
|
get db() {
|
||||||
set db(x) { x = Math.clamp(x,-100,0); this.volume = Math.pow(10, x/20); },
|
return 20 * Math.log10(Math.abs(this.volume));
|
||||||
get volume() { return this.gain; },
|
},
|
||||||
set volume(x) { this.gain = x; },
|
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()
|
audio.bus.master.__proto__.toJSON = function () {
|
||||||
{
|
|
||||||
return {
|
return {
|
||||||
volume: this.volume,
|
volume: this.volume,
|
||||||
off: this.off,
|
off: this.off,
|
||||||
pan: this.pan,
|
pan: this.pan,
|
||||||
pass: this.pass
|
pass: this.pass,
|
||||||
};
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
/*Object.mixin(audio.dsp.source().__proto__, {
|
/*Object.mixin(audio.dsp.source().__proto__, {
|
||||||
length() { return this.frames()/audio.samplerate(); },
|
length() { return this.frames()/audio.samplerate(); },
|
||||||
|
@ -175,4 +180,4 @@ audio.bus.master.__proto__.toJSON = function()
|
||||||
});
|
});
|
||||||
*/
|
*/
|
||||||
|
|
||||||
return {audio};
|
return { audio };
|
||||||
|
|
|
@ -1,117 +1,121 @@
|
||||||
var Spline = {};
|
var Spline = {};
|
||||||
Spline.sample_angle = function(type, points, angle) {
|
Spline.sample_angle = function (type, points, angle) {
|
||||||
if (type === 0) return spline.catmull(points, angle);
|
if (type === 0) return spline.catmull(points, angle);
|
||||||
else if (type === 1) return spline.bezier(points,angle);
|
else if (type === 1) return spline.bezier(points, angle);
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
};
|
||||||
|
|
||||||
Spline.bezier_loop = function(cp)
|
Spline.bezier_loop = function (cp) {
|
||||||
{
|
cp.push(Vector.reflect_point(cp.at(-2), cp.at(-1)));
|
||||||
cp.push(Vector.reflect_point(cp.at(-2),cp.at(-1)));
|
cp.push(Vector.reflect_point(cp[1], cp[0]));
|
||||||
cp.push(Vector.reflect_point(cp[1],cp[0]));
|
|
||||||
cp.push(cp[0].slice());
|
cp.push(cp[0].slice());
|
||||||
return cp;
|
return cp;
|
||||||
}
|
};
|
||||||
|
|
||||||
Spline.bezier_node_count = function(cp)
|
Spline.bezier_node_count = function (cp) {
|
||||||
{
|
|
||||||
if (cp.length === 4) return 2;
|
if (cp.length === 4) return 2;
|
||||||
return 2 + (cp.length-4)/3;
|
return 2 + (cp.length - 4) / 3;
|
||||||
}
|
};
|
||||||
|
|
||||||
Spline.is_bezier = function(t) { return t === Spline.type.bezier; }
|
Spline.is_bezier = function (t) {
|
||||||
Spline.is_catmull = function(t) { return t === Spline.type.catmull; }
|
return t === Spline.type.bezier;
|
||||||
|
};
|
||||||
|
Spline.is_catmull = function (t) {
|
||||||
|
return t === Spline.type.catmull;
|
||||||
|
};
|
||||||
|
|
||||||
Spline.bezier2catmull = function(b)
|
Spline.bezier2catmull = function (b) {
|
||||||
{
|
|
||||||
var c = [];
|
var c = [];
|
||||||
for (var i = 0; i < b.length; i += 3)
|
for (var i = 0; i < b.length; i += 3) c.push(b[i]);
|
||||||
c.push(b[i]);
|
|
||||||
return c;
|
return c;
|
||||||
}
|
};
|
||||||
|
|
||||||
Spline.catmull2bezier = function(c)
|
Spline.catmull2bezier = function (c) {
|
||||||
{
|
|
||||||
var b = [];
|
var b = [];
|
||||||
for (var i = 1; i < c.length-2; i++) {
|
for (var i = 1; i < c.length - 2; i++) {
|
||||||
b.push(c[i].slice());
|
b.push(c[i].slice());
|
||||||
b.push(c[i+1].sub(c[i-1]).scale(0.25).add(c[i]));
|
b.push(
|
||||||
b.push(c[i].sub(c[i+2]).scale(0.25).add(c[i+1]));
|
c[i + 1]
|
||||||
|
.sub(c[i - 1])
|
||||||
|
.scale(0.25)
|
||||||
|
.add(c[i]),
|
||||||
|
);
|
||||||
|
b.push(
|
||||||
|
c[i]
|
||||||
|
.sub(c[i + 2])
|
||||||
|
.scale(0.25)
|
||||||
|
.add(c[i + 1]),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
b.push(c[c.length-2]);
|
b.push(c[c.length - 2]);
|
||||||
return b;
|
return b;
|
||||||
}
|
};
|
||||||
|
|
||||||
Spline.catmull_loop = function(cp)
|
Spline.catmull_loop = function (cp) {
|
||||||
{
|
|
||||||
cp = cp.slice();
|
cp = cp.slice();
|
||||||
cp.unshift(cp.last());
|
cp.unshift(cp.last());
|
||||||
cp.push(cp[1]);
|
cp.push(cp[1]);
|
||||||
cp.push(cp[2]);
|
cp.push(cp[2]);
|
||||||
return cp;
|
return cp;
|
||||||
}
|
};
|
||||||
|
|
||||||
Spline.catmull_caps = function(cp)
|
Spline.catmull_caps = function (cp) {
|
||||||
{
|
|
||||||
if (cp.length < 2) return;
|
if (cp.length < 2) return;
|
||||||
cp = cp.slice();
|
cp = cp.slice();
|
||||||
cp.unshift(cp[0].sub(cp[1]).add(cp[0]));
|
cp.unshift(cp[0].sub(cp[1]).add(cp[0]));
|
||||||
cp.push(cp.last().sub(cp.at(-2).add(cp.last())));
|
cp.push(cp.last().sub(cp.at(-2).add(cp.last())));
|
||||||
return cp;
|
return cp;
|
||||||
}
|
};
|
||||||
|
|
||||||
Spline.catmull_caps.doc = "Given a set of control points cp, return the necessary caps added to the spline.";
|
Spline.catmull_caps.doc = "Given a set of control points cp, return the necessary caps added to the spline.";
|
||||||
|
|
||||||
Spline.catmull2bezier.doc = "Given a set of control points C for a camtull-rom type curve, return a set of cubic bezier points to give the same curve."
|
Spline.catmull2bezier.doc = "Given a set of control points C for a camtull-rom type curve, return a set of cubic bezier points to give the same curve.";
|
||||||
|
|
||||||
Spline.type = {
|
Spline.type = {
|
||||||
catmull: 0,
|
catmull: 0,
|
||||||
bezier: 1,
|
bezier: 1,
|
||||||
bspline: 2,
|
bspline: 2,
|
||||||
cubichermite: 3
|
cubichermite: 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
Spline.bezier_tan_partner = function(points, i)
|
Spline.bezier_tan_partner = function (points, i) {
|
||||||
{
|
if (i % 3 === 0) return undefined;
|
||||||
if (i%3 === 0) return undefined;
|
var partner_i = i % 3 === 2 ? i - 1 : i + 1;
|
||||||
var partner_i = (i%3) === 2 ? i-1 : i+1;
|
|
||||||
return points[i];
|
return points[i];
|
||||||
}
|
};
|
||||||
|
|
||||||
Spline.bezier_cp_mirror = function(points, i)
|
Spline.bezier_cp_mirror = function (points, i) {
|
||||||
{
|
if (i % 3 === 0) return undefined;
|
||||||
if (i%3 === 0) return undefined;
|
var partner_i = i % 3 === 2 ? i + 2 : i - 2;
|
||||||
var partner_i = (i%3) === 2 ? i+2 : i-2;
|
var node_i = i % 3 === 2 ? i + 1 : i - 1;
|
||||||
var node_i = (i%3) === 2 ? i+1 : i-1;
|
|
||||||
if (partner_i >= points.length || node_i >= points.length) return;
|
if (partner_i >= points.length || node_i >= points.length) return;
|
||||||
points[partner_i] = points[node_i].sub(points[i]).add(points[node_i]);
|
points[partner_i] = points[node_i].sub(points[i]).add(points[node_i]);
|
||||||
}
|
};
|
||||||
|
|
||||||
Spline.bezier_point_handles = function(points, i)
|
Spline.bezier_point_handles = function (points, i) {
|
||||||
{
|
if (!Spline.bezier_is_node(points, i)) return [];
|
||||||
if (!Spline.bezier_is_node(points,i)) return [];
|
var a = i - 1;
|
||||||
var a = i-1;
|
var b = i + 1;
|
||||||
var b = i+1;
|
|
||||||
var c = []
|
|
||||||
if (a > 0)
|
|
||||||
c.push(a);
|
|
||||||
|
|
||||||
if (b < points.length)
|
|
||||||
c.push(b);
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
Spline.bezier_nodes = function(points)
|
|
||||||
{
|
|
||||||
var c = [];
|
var c = [];
|
||||||
for (var i = 0; i < points.length; i+=3)
|
if (a > 0) c.push(a);
|
||||||
c.push(points[i].slice());
|
|
||||||
|
if (b < points.length) c.push(b);
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
};
|
||||||
|
|
||||||
Spline.bezier_is_node = function(points, i) { return i%3 === 0; }
|
Spline.bezier_nodes = function (points) {
|
||||||
Spline.bezier_is_handle = function(points, i) { return !Spline.bezier_is_node(points,i); }
|
var c = [];
|
||||||
|
for (var i = 0; i < points.length; i += 3) c.push(points[i].slice());
|
||||||
|
|
||||||
return {Spline};
|
return c;
|
||||||
|
};
|
||||||
|
|
||||||
|
Spline.bezier_is_node = function (points, i) {
|
||||||
|
return i % 3 === 0;
|
||||||
|
};
|
||||||
|
Spline.bezier_is_handle = function (points, i) {
|
||||||
|
return !Spline.bezier_is_node(points, i);
|
||||||
|
};
|
||||||
|
|
||||||
|
return { Spline };
|
||||||
|
|
744
scripts/std.js
744
scripts/std.js
|
@ -1,28 +1,34 @@
|
||||||
os.cwd.doc = "Get the absolute path of the current working directory.";
|
os.cwd.doc = "Get the absolute path of the current working directory.";
|
||||||
os.env.doc = "Return the value of the environment variable v.";
|
os.env.doc = "Return the value of the environment variable v.";
|
||||||
os.platform = "steam";
|
os.platform = "steam";
|
||||||
if (os.sys() === 'windows')
|
if (os.sys() === "windows") os.user = os.env("USERNAME");
|
||||||
os.user = os.env("USERNAME");
|
else os.user = os.env("USER");
|
||||||
else
|
|
||||||
os.user = os.env("USER");
|
|
||||||
|
|
||||||
var appy = {};
|
var appy = {};
|
||||||
appy.inputs = {};
|
appy.inputs = {};
|
||||||
if (os.sys() === 'macos') {
|
if (os.sys() === "macos") {
|
||||||
appy.inputs['S-q'] = os.quit;
|
appy.inputs["S-q"] = os.quit;
|
||||||
}
|
}
|
||||||
|
|
||||||
appy.inputs.f7 = function() { debug.meta = !debug.meta; }
|
appy.inputs.f7 = function () {
|
||||||
appy.inputs.f8 = function() { debug.cheat = !debug.cheat; }
|
debug.meta = !debug.meta;
|
||||||
appy.inputs.f9 = function() { debug.console = !debug.console; }
|
};
|
||||||
appy.inputs.f10 = function() { debug.show = !debug.show; }
|
appy.inputs.f8 = function () {
|
||||||
|
debug.cheat = !debug.cheat;
|
||||||
|
};
|
||||||
|
appy.inputs.f9 = function () {
|
||||||
|
debug.console = !debug.console;
|
||||||
|
};
|
||||||
|
appy.inputs.f10 = function () {
|
||||||
|
debug.show = !debug.show;
|
||||||
|
};
|
||||||
appy.inputs.f11 = window.toggle_fullscreen;
|
appy.inputs.f11 = window.toggle_fullscreen;
|
||||||
appy.inputs.f11.doc = "Toggle window fullscreen.";
|
appy.inputs.f11.doc = "Toggle window fullscreen.";
|
||||||
appy.inputs.f11.title = "Toggle Fullscreen";
|
appy.inputs.f11.title = "Toggle Fullscreen";
|
||||||
appy.inputs['M-f4'] = os.quit;
|
appy.inputs["M-f4"] = os.quit;
|
||||||
|
|
||||||
player[0].control(appy);
|
player[0].control(appy);
|
||||||
|
|
||||||
//steam.appid = 480;
|
//steam.appid = 480;
|
||||||
//steam.userid = 8437843;
|
//steam.userid = 8437843;
|
||||||
|
|
||||||
|
@ -35,30 +41,32 @@ os.home = os.env("HOME");
|
||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
var otherpath = {
|
var otherpath = {
|
||||||
windows:`C:/Users/${os.user}/Saved Games`,
|
windows: `C:/Users/${os.user}/Saved Games`,
|
||||||
macos: `${os.home}/Library/Application Support`,
|
macos: `${os.home}/Library/Application Support`,
|
||||||
linux: `${os.home}/.local/share`
|
linux: `${os.home}/.local/share`,
|
||||||
}
|
};
|
||||||
|
|
||||||
os.prefpath = function() {
|
os.prefpath = function () {
|
||||||
return otherpath[os.sys()] + "/" + (game.title ? game.title : "Untitled Prosperon Game");
|
return otherpath[os.sys()] + "/" + (game.title ? game.title : "Untitled Prosperon Game");
|
||||||
}
|
};
|
||||||
|
|
||||||
os.openurl = function(url) {
|
os.openurl = function (url) {
|
||||||
if (os.sys() === 'windows')
|
if (os.sys() === "windows") os.system(`start ${url}`);
|
||||||
os.system(`start ${url}`);
|
else os.system(`open ${url}`);
|
||||||
else
|
};
|
||||||
os.system(`open ${url}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
var projectfile = "project.prosperon";
|
var projectfile = "project.prosperon";
|
||||||
io.dumpfolder = '.prosperon';
|
io.dumpfolder = ".prosperon";
|
||||||
|
|
||||||
Resources.texture = {};
|
Resources.texture = {};
|
||||||
Resources.texture.dimensions = function(path) { texture.dimensions(path); }
|
Resources.texture.dimensions = function (path) {
|
||||||
|
texture.dimensions(path);
|
||||||
|
};
|
||||||
|
|
||||||
Resources.gif = {};
|
Resources.gif = {};
|
||||||
Resources.gif.frames = function(path) { return render.gif_frames(path); }
|
Resources.gif.frames = function (path) {
|
||||||
|
return render.gif_frames(path);
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
io path rules. Starts with, meaning:
|
io path rules. Starts with, meaning:
|
||||||
|
@ -68,30 +76,27 @@ Resources.gif.frames = function(path) { return render.gif_frames(path); }
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var tmpchm = io.chmod;
|
var tmpchm = io.chmod;
|
||||||
io.chmod = function(file,mode) {
|
io.chmod = function (file, mode) {
|
||||||
return tmpchm(file,parseInt(mode,8));
|
return tmpchm(file, parseInt(mode, 8));
|
||||||
}
|
};
|
||||||
|
|
||||||
var tmpslurp = io.slurp;
|
var tmpslurp = io.slurp;
|
||||||
io.slurp = function(path)
|
io.slurp = function (path) {
|
||||||
{
|
|
||||||
path = Resources.replpath(path);
|
path = Resources.replpath(path);
|
||||||
return tmpslurp(path);
|
return tmpslurp(path);
|
||||||
}
|
};
|
||||||
|
|
||||||
var tmpslurpb = io.slurpbytes;
|
var tmpslurpb = io.slurpbytes;
|
||||||
io.slurpbytes = function(path)
|
io.slurpbytes = function (path) {
|
||||||
{
|
|
||||||
path = Resources.replpath(path);
|
path = Resources.replpath(path);
|
||||||
return tmpslurpb(path);
|
return tmpslurpb(path);
|
||||||
}
|
};
|
||||||
|
|
||||||
io.mkpath = function(dir)
|
io.mkpath = function (dir) {
|
||||||
{
|
|
||||||
if (!dir) return;
|
if (!dir) return;
|
||||||
var mkstack = [];
|
var mkstack = [];
|
||||||
while (!io.exists(dir)) {
|
while (!io.exists(dir)) {
|
||||||
mkstack.push(dir.fromlast('/'));
|
mkstack.push(dir.fromlast("/"));
|
||||||
dir = dir.dir();
|
dir = dir.dir();
|
||||||
}
|
}
|
||||||
for (var d of mkstack) {
|
for (var d of mkstack) {
|
||||||
|
@ -99,55 +104,54 @@ io.mkpath = function(dir)
|
||||||
say(`making ${dir}`);
|
say(`making ${dir}`);
|
||||||
io.mkdir(dir);
|
io.mkdir(dir);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
var tmpslurpw = io.slurpwrite;
|
var tmpslurpw = io.slurpwrite;
|
||||||
io.slurpwrite = function(path, c)
|
io.slurpwrite = function (path, c) {
|
||||||
{
|
|
||||||
path = Resources.replpath(path);
|
path = Resources.replpath(path);
|
||||||
io.mkpath(path.dir());
|
io.mkpath(path.dir());
|
||||||
return tmpslurpw(path, c);
|
return tmpslurpw(path, c);
|
||||||
}
|
};
|
||||||
|
|
||||||
var tmpcp = io.cp;
|
var tmpcp = io.cp;
|
||||||
io.cp = function(f1,f2)
|
io.cp = function (f1, f2) {
|
||||||
{
|
|
||||||
io.mkpath(f2.dir());
|
io.mkpath(f2.dir());
|
||||||
tmpcp(f1,f2);
|
tmpcp(f1, f2);
|
||||||
}
|
};
|
||||||
|
|
||||||
var tmprm = io.rm;
|
var tmprm = io.rm;
|
||||||
io.rm = function(f)
|
io.rm = function (f) {
|
||||||
{
|
|
||||||
tmprm(Resources.replpath(f));
|
tmprm(Resources.replpath(f));
|
||||||
}
|
};
|
||||||
|
|
||||||
io.globToRegex = function(glob) {
|
io.globToRegex = function (glob) {
|
||||||
// Escape special regex characters
|
// Escape special regex characters
|
||||||
// Replace glob characters with regex equivalents
|
// Replace glob characters with regex equivalents
|
||||||
let regexStr = glob
|
let regexStr = glob
|
||||||
.replace(/[\.\\]/g, '\\$&') // Escape literal backslashes and dots
|
.replace(/[\.\\]/g, "\\$&") // Escape literal backslashes and dots
|
||||||
.replace(/([^\*])\*/g, '$1[^/]*') // * matches any number of characters except /
|
.replace(/([^\*])\*/g, "$1[^/]*") // * matches any number of characters except /
|
||||||
.replace(/\*\*/g, '.*') // ** matches any number of characters, including none
|
.replace(/\*\*/g, ".*") // ** matches any number of characters, including none
|
||||||
.replace(/\[(.*?)\]/g, '[$1]') // Character sets
|
.replace(/\[(.*?)\]/g, "[$1]") // Character sets
|
||||||
.replace(/\?/g, '.'); // ? matches any single character
|
.replace(/\?/g, "."); // ? matches any single character
|
||||||
|
|
||||||
// Ensure the regex matches the whole string
|
// Ensure the regex matches the whole string
|
||||||
regexStr = '^' + regexStr + '$';
|
regexStr = "^" + regexStr + "$";
|
||||||
|
|
||||||
// Create and return the regex object
|
// Create and return the regex object
|
||||||
return new RegExp(regexStr);
|
return new RegExp(regexStr);
|
||||||
}
|
};
|
||||||
|
|
||||||
io.mixin({
|
io.mixin({
|
||||||
extensions(ext) {
|
extensions(ext) {
|
||||||
var paths = io.ls();
|
var paths = io.ls();
|
||||||
paths = paths.filter(function(str) { return str.ext() === ext; });
|
paths = paths.filter(function (str) {
|
||||||
|
return str.ext() === ext;
|
||||||
|
});
|
||||||
return paths;
|
return paths;
|
||||||
},
|
},
|
||||||
|
|
||||||
glob(pat) {
|
glob(pat) {
|
||||||
var paths = io.ls('.');
|
var paths = io.ls(".");
|
||||||
var regex = io.globToRegex(pat);
|
var regex = io.globToRegex(pat);
|
||||||
paths = paths.filter(str => str.match(regex)).sort();
|
paths = paths.filter(str => str.match(regex)).sort();
|
||||||
return paths;
|
return paths;
|
||||||
|
@ -172,328 +176,409 @@ var Cmdline = {};
|
||||||
|
|
||||||
Cmdline.cmds = [];
|
Cmdline.cmds = [];
|
||||||
Cmdline.orders = {};
|
Cmdline.orders = {};
|
||||||
Cmdline.register_cmd = function(flag, fn, doc) {
|
Cmdline.register_cmd = function (flag, fn, doc) {
|
||||||
Cmdline.cmds.push({
|
Cmdline.cmds.push({
|
||||||
flag: flag,
|
flag: flag,
|
||||||
fn: fn,
|
fn: fn,
|
||||||
doc: doc
|
doc: doc,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Cmdline.register_order = function(order, fn, doc, usage = "") {
|
Cmdline.register_order = function (order, fn, doc, usage = "") {
|
||||||
Cmdline.orders[order] = fn;
|
Cmdline.orders[order] = fn;
|
||||||
fn.doc = doc;
|
fn.doc = doc;
|
||||||
fn.usage = `${order} ${usage}`;
|
fn.usage = `${order} ${usage}`;
|
||||||
}
|
};
|
||||||
|
|
||||||
Cmdline.register_order("edit", function() {
|
Cmdline.register_order(
|
||||||
if (!io.exists(projectfile)) {
|
"edit",
|
||||||
say("No game to edit. Try making one with 'prosperon init'.");
|
function () {
|
||||||
return;
|
if (!io.exists(projectfile)) {
|
||||||
}
|
say("No game to edit. Try making one with 'prosperon init'.");
|
||||||
|
|
||||||
window.size = [1280, 720];
|
|
||||||
window.mode = "full";
|
|
||||||
sim.pause();
|
|
||||||
|
|
||||||
game.engine_start(function() {
|
|
||||||
global.mixin("scripts/editor.js");
|
|
||||||
use("editorconfig.js");
|
|
||||||
use("config.js");
|
|
||||||
render.set_font("fonts/c64.ttf", 8);
|
|
||||||
editor.enter_editor();
|
|
||||||
});
|
|
||||||
}, "Edit the project in this folder. Give it the name of an UR to edit that specific object.", "?UR?");
|
|
||||||
|
|
||||||
Cmdline.register_order("init", function() {
|
|
||||||
if (io.exists(projectfile)) {
|
|
||||||
say("Already a game here.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
io.mkdir(io.dumpfolder);
|
|
||||||
var project = {};
|
|
||||||
project.version = prosperon.version;
|
|
||||||
project.revision = prosperon.revision;
|
|
||||||
io.slurpwrite(projectfile, json.encode(project));
|
|
||||||
}, "Turn the directory into a Prosperon game.");
|
|
||||||
|
|
||||||
Cmdline.register_order("debug", function() {
|
|
||||||
Cmdline.orders.play([]);
|
|
||||||
}, "Play the game with debugging enabled.");
|
|
||||||
|
|
||||||
Cmdline.register_order("web", function() {
|
|
||||||
Cmdline.orders.play([]);
|
|
||||||
}, "Play the game in a web browser.");
|
|
||||||
|
|
||||||
Cmdline.register_order("play", function(argv) {
|
|
||||||
if (argv[0])
|
|
||||||
io.chdir(argv[0]);
|
|
||||||
|
|
||||||
// game.loadurs();
|
|
||||||
|
|
||||||
if (!io.exists(projectfile)) {
|
|
||||||
say("No game to play. Try making one with 'prosperon init'.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var project = json.decode(io.slurp(projectfile));
|
|
||||||
game.title = project.title;
|
|
||||||
game.size = [1280,720];
|
|
||||||
window.size = game.size;
|
|
||||||
if (io.exists("config.js"))
|
|
||||||
global.mixin("config.js");
|
|
||||||
else
|
|
||||||
console.warn('No config.js file found. Starting with default parameters.');
|
|
||||||
|
|
||||||
if (project.title) window.title = project.title;
|
|
||||||
|
|
||||||
game.engine_start(function() {
|
|
||||||
render.set_font("fonts/c64.ttf", 8);
|
|
||||||
if (io.exists("game.js"))
|
|
||||||
global.app = actor.spawn("game.js");
|
|
||||||
else
|
|
||||||
global.app = actor.spawn("scripts/nogame.js");
|
|
||||||
|
|
||||||
if (project.icon) window.set_icon(game.texture(project.icon));
|
|
||||||
game.camera = world.spawn("scripts/camera2d");
|
|
||||||
});
|
|
||||||
}, "Play the game present in this folder.");
|
|
||||||
|
|
||||||
Cmdline.register_order("pack", function(str) {
|
|
||||||
var packname;
|
|
||||||
if (str.length === 0)
|
|
||||||
packname = "game.zip";
|
|
||||||
else if (str.length > 1) {
|
|
||||||
console.warn("Give me a single filename for the pack.");
|
|
||||||
return;
|
|
||||||
} else
|
|
||||||
packname = str[0];
|
|
||||||
|
|
||||||
say(`Packing into ${packname}`);
|
|
||||||
|
|
||||||
io.pack_start(packname);
|
|
||||||
var files = io.ls('.');
|
|
||||||
files = files.filter(f => !f.startsWith('.git'));
|
|
||||||
files = files.filter(f => !f.startsWith('.nova'));
|
|
||||||
files = files.filter(f => !f.includes('.DS_Store'));
|
|
||||||
files = files.filter(f => !f.startsWith('.gitignore'));
|
|
||||||
say(files);
|
|
||||||
for (var f of files)
|
|
||||||
io.pack_add(f);
|
|
||||||
io.pack_end();
|
|
||||||
}, "Pack the game into the given name.", "NAME");
|
|
||||||
|
|
||||||
Cmdline.register_order("cdb", function(argv) {
|
|
||||||
var cdb = "game.zip";
|
|
||||||
if (!io.exists(cdb)) {
|
|
||||||
say(`No 'game.zip' present.`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (argv.length === 0) {
|
|
||||||
say(`cdb name: ${cdb}`);
|
|
||||||
|
|
||||||
}
|
|
||||||
}, "CDB commands.");
|
|
||||||
|
|
||||||
Cmdline.register_order("qoa", function(argv) {
|
|
||||||
var sounds = Resources.sounds.filter(x => x !== "qoa");
|
|
||||||
for (var file of argv) {
|
|
||||||
if (!sounds.includes(file.ext())) continue;
|
|
||||||
say(`converting ${file}`);
|
|
||||||
io.save_qoa(file);
|
|
||||||
}
|
|
||||||
}, "Convert file(s) to qoa.");
|
|
||||||
|
|
||||||
Cmdline.register_order("about", function(argv) {
|
|
||||||
|
|
||||||
if (!argv[0]) {
|
|
||||||
say('About your game');
|
|
||||||
say(`Prosperon version ${prosperon.version}`);
|
|
||||||
say(`Total entities ${ur._list.length}`);
|
|
||||||
}
|
|
||||||
switch (argv[0]) {
|
|
||||||
case "entities":
|
|
||||||
for (var i of ur._list) say(i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}, "Get information about this game.");
|
|
||||||
|
|
||||||
Cmdline.register_order("ur", function(argv) {
|
|
||||||
// game.loadurs();
|
|
||||||
for (var i of ur._list.sort()) say(i);
|
|
||||||
}, "Get information about the ur types in your game.");
|
|
||||||
|
|
||||||
Cmdline.register_order("env", function(argv) {
|
|
||||||
if (argv.length > 2) return;
|
|
||||||
var gg = json.decode(io.slurp(projectfile));
|
|
||||||
if (argv.length === 0) {
|
|
||||||
say(json.encode(gg,null,1));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (argv.length === 1) {
|
|
||||||
var v = gg[argv[0]];
|
|
||||||
if (!v) {
|
|
||||||
say(`Value ${argv[0]} not found.`);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
say(`${argv[0]}:${v}`);
|
|
||||||
} else {
|
|
||||||
gg[argv[0]] = argv[1];
|
|
||||||
say(`Set ${argv[0]}:${v}`);
|
|
||||||
say(json.encode(gg,null,1));
|
|
||||||
io.slurpwrite(projectfile, json.encode(gg));
|
|
||||||
}
|
|
||||||
}, "Get or set game variables.");
|
|
||||||
|
|
||||||
Cmdline.register_order("unpack", function() {
|
window.size = [1280, 720];
|
||||||
say("Unpacking not implemented.");
|
window.mode = "full";
|
||||||
}, "Unpack this binary's contents into this folder for editing.");
|
sim.pause();
|
||||||
|
|
||||||
Cmdline.register_order("build", function() {
|
game.engine_start(function () {
|
||||||
say("Building not implemented.");
|
global.mixin("scripts/editor.js");
|
||||||
}, "Build static assets for this project.");
|
use("editorconfig.js");
|
||||||
|
use("config.js");
|
||||||
|
render.set_font("fonts/c64.ttf", 8);
|
||||||
|
editor.enter_editor();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
"Edit the project in this folder. Give it the name of an UR to edit that specific object.",
|
||||||
|
"?UR?",
|
||||||
|
);
|
||||||
|
|
||||||
Cmdline.register_order("nota", function(argv) {
|
Cmdline.register_order(
|
||||||
for (var file of argv) {
|
"init",
|
||||||
if (!io.exists(file)) {
|
function () {
|
||||||
say(`File ${file} does not exist.`);
|
if (io.exists(projectfile)) {
|
||||||
continue;
|
say("Already a game here.");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var obj = json.decode(io.slurp(file));
|
io.mkdir(io.dumpfolder);
|
||||||
var nn = nota.encode(obj);
|
var project = {};
|
||||||
io.slurpwrite(file.set_ext(".nota"), nn);
|
project.version = prosperon.version;
|
||||||
}
|
project.revision = prosperon.revision;
|
||||||
}, "Create a nota file from a json.");
|
io.slurpwrite(projectfile, json.encode(project));
|
||||||
|
},
|
||||||
|
"Turn the directory into a Prosperon game.",
|
||||||
|
);
|
||||||
|
|
||||||
Cmdline.register_order("json", function(argv) {
|
Cmdline.register_order(
|
||||||
for (var file of argv) {
|
"debug",
|
||||||
if (!io.exists(file)) {
|
function () {
|
||||||
say(`File ${file} does not exist.`);
|
Cmdline.orders.play([]);
|
||||||
continue;
|
},
|
||||||
|
"Play the game with debugging enabled.",
|
||||||
|
);
|
||||||
|
|
||||||
|
Cmdline.register_order(
|
||||||
|
"web",
|
||||||
|
function () {
|
||||||
|
Cmdline.orders.play([]);
|
||||||
|
},
|
||||||
|
"Play the game in a web browser.",
|
||||||
|
);
|
||||||
|
|
||||||
|
Cmdline.register_order(
|
||||||
|
"play",
|
||||||
|
function (argv) {
|
||||||
|
if (argv[0]) io.chdir(argv[0]);
|
||||||
|
|
||||||
|
// game.loadurs();
|
||||||
|
|
||||||
|
if (!io.exists(projectfile)) {
|
||||||
|
say("No game to play. Try making one with 'prosperon init'.");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
say(file.ext());
|
|
||||||
var obj = nota.decode(io.slurp(file));
|
|
||||||
var nn = json.encode(obj);
|
|
||||||
io.slurpwrite(file.set_ext(".json", nn));
|
|
||||||
}
|
|
||||||
}, "Create a JSON from a nota.");
|
|
||||||
|
|
||||||
Cmdline.register_order("api", function(obj) {
|
var project = json.decode(io.slurp(projectfile));
|
||||||
if (!obj[0]) {
|
game.title = project.title;
|
||||||
Cmdline.print_order("api");
|
game.size = [1280, 720];
|
||||||
return;
|
window.size = game.size;
|
||||||
}
|
if (io.exists("config.js")) global.mixin("config.js");
|
||||||
|
else console.warn("No config.js file found. Starting with default parameters.");
|
||||||
|
|
||||||
use("scripts/editor.js");
|
if (project.title) window.title = project.title;
|
||||||
var api = debug.api.print_doc(obj[0]);
|
|
||||||
if (!api)
|
|
||||||
return;
|
|
||||||
|
|
||||||
say(api);
|
game.engine_start(function () {
|
||||||
}, "Print the API for an object as markdown. Give it a file to save the output to.", "OBJECT");
|
render.set_font("fonts/c64.ttf", 8);
|
||||||
|
if (io.exists("game.js")) global.app = actor.spawn("game.js");
|
||||||
|
else global.app = actor.spawn("scripts/nogame.js");
|
||||||
|
|
||||||
Cmdline.register_order("input", function(pawn) {
|
if (project.icon) window.set_icon(game.texture(project.icon));
|
||||||
use("scripts/editor.js");
|
game.camera = world.spawn("scripts/camera2d");
|
||||||
say(`## Input for ${pawn}`);
|
});
|
||||||
eval(`say(input.print_md_kbm(${pawn}));`);
|
},
|
||||||
}, "Print input documentation for a given object as markdown. Give it a file to save the output to", "OBJECT ?FILE?");
|
"Play the game present in this folder.",
|
||||||
|
);
|
||||||
|
|
||||||
Cmdline.register_order("run", function(script) {
|
Cmdline.register_order(
|
||||||
script = script.join(" ");
|
"pack",
|
||||||
if (!script) {
|
function (str) {
|
||||||
say("Need something to run.");
|
var packname;
|
||||||
return;
|
if (str.length === 0) packname = "game.zip";
|
||||||
}
|
else if (str.length > 1) {
|
||||||
|
console.warn("Give me a single filename for the pack.");
|
||||||
say(eval(script));
|
return;
|
||||||
}, "Run a given script. SCRIPT can be the script itself, or a file containing the script", "SCRIPT");
|
} else packname = str[0];
|
||||||
|
|
||||||
|
say(`Packing into ${packname}`);
|
||||||
|
|
||||||
|
io.pack_start(packname);
|
||||||
|
var files = io.ls(".");
|
||||||
|
files = files.filter(f => !f.startsWith(".git"));
|
||||||
|
files = files.filter(f => !f.startsWith(".nova"));
|
||||||
|
files = files.filter(f => !f.includes(".DS_Store"));
|
||||||
|
files = files.filter(f => !f.startsWith(".gitignore"));
|
||||||
|
say(files);
|
||||||
|
for (var f of files) io.pack_add(f);
|
||||||
|
io.pack_end();
|
||||||
|
},
|
||||||
|
"Pack the game into the given name.",
|
||||||
|
"NAME",
|
||||||
|
);
|
||||||
|
|
||||||
|
Cmdline.register_order(
|
||||||
|
"cdb",
|
||||||
|
function (argv) {
|
||||||
|
var cdb = "game.zip";
|
||||||
|
if (!io.exists(cdb)) {
|
||||||
|
say(`No 'game.zip' present.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (argv.length === 0) {
|
||||||
|
say(`cdb name: ${cdb}`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"CDB commands.",
|
||||||
|
);
|
||||||
|
|
||||||
|
Cmdline.register_order(
|
||||||
|
"qoa",
|
||||||
|
function (argv) {
|
||||||
|
var sounds = Resources.sounds.filter(x => x !== "qoa");
|
||||||
|
for (var file of argv) {
|
||||||
|
if (!sounds.includes(file.ext())) continue;
|
||||||
|
say(`converting ${file}`);
|
||||||
|
io.save_qoa(file);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Convert file(s) to qoa.",
|
||||||
|
);
|
||||||
|
|
||||||
|
Cmdline.register_order(
|
||||||
|
"about",
|
||||||
|
function (argv) {
|
||||||
|
if (!argv[0]) {
|
||||||
|
say("About your game");
|
||||||
|
say(`Prosperon version ${prosperon.version}`);
|
||||||
|
say(`Total entities ${ur._list.length}`);
|
||||||
|
}
|
||||||
|
switch (argv[0]) {
|
||||||
|
case "entities":
|
||||||
|
for (var i of ur._list) say(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Get information about this game.",
|
||||||
|
);
|
||||||
|
|
||||||
|
Cmdline.register_order(
|
||||||
|
"ur",
|
||||||
|
function (argv) {
|
||||||
|
// game.loadurs();
|
||||||
|
for (var i of ur._list.sort()) say(i);
|
||||||
|
},
|
||||||
|
"Get information about the ur types in your game.",
|
||||||
|
);
|
||||||
|
|
||||||
|
Cmdline.register_order(
|
||||||
|
"env",
|
||||||
|
function (argv) {
|
||||||
|
if (argv.length > 2) return;
|
||||||
|
var gg = json.decode(io.slurp(projectfile));
|
||||||
|
if (argv.length === 0) {
|
||||||
|
say(json.encode(gg, null, 1));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argv.length === 1) {
|
||||||
|
var v = gg[argv[0]];
|
||||||
|
if (!v) {
|
||||||
|
say(`Value ${argv[0]} not found.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
say(`${argv[0]}:${v}`);
|
||||||
|
} else {
|
||||||
|
gg[argv[0]] = argv[1];
|
||||||
|
say(`Set ${argv[0]}:${v}`);
|
||||||
|
say(json.encode(gg, null, 1));
|
||||||
|
io.slurpwrite(projectfile, json.encode(gg));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Get or set game variables.",
|
||||||
|
);
|
||||||
|
|
||||||
|
Cmdline.register_order(
|
||||||
|
"unpack",
|
||||||
|
function () {
|
||||||
|
say("Unpacking not implemented.");
|
||||||
|
},
|
||||||
|
"Unpack this binary's contents into this folder for editing.",
|
||||||
|
);
|
||||||
|
|
||||||
|
Cmdline.register_order(
|
||||||
|
"build",
|
||||||
|
function () {
|
||||||
|
say("Building not implemented.");
|
||||||
|
},
|
||||||
|
"Build static assets for this project.",
|
||||||
|
);
|
||||||
|
|
||||||
|
Cmdline.register_order(
|
||||||
|
"nota",
|
||||||
|
function (argv) {
|
||||||
|
for (var file of argv) {
|
||||||
|
if (!io.exists(file)) {
|
||||||
|
say(`File ${file} does not exist.`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var obj = json.decode(io.slurp(file));
|
||||||
|
var nn = nota.encode(obj);
|
||||||
|
io.slurpwrite(file.set_ext(".nota"), nn);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Create a nota file from a json.",
|
||||||
|
);
|
||||||
|
|
||||||
|
Cmdline.register_order(
|
||||||
|
"json",
|
||||||
|
function (argv) {
|
||||||
|
for (var file of argv) {
|
||||||
|
if (!io.exists(file)) {
|
||||||
|
say(`File ${file} does not exist.`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
say(file.ext());
|
||||||
|
var obj = nota.decode(io.slurp(file));
|
||||||
|
var nn = json.encode(obj);
|
||||||
|
io.slurpwrite(file.set_ext(".json", nn));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Create a JSON from a nota.",
|
||||||
|
);
|
||||||
|
|
||||||
|
Cmdline.register_order(
|
||||||
|
"api",
|
||||||
|
function (obj) {
|
||||||
|
if (!obj[0]) {
|
||||||
|
Cmdline.print_order("api");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
use("scripts/editor.js");
|
||||||
|
var api = debug.api.print_doc(obj[0]);
|
||||||
|
if (!api) return;
|
||||||
|
|
||||||
|
say(api);
|
||||||
|
},
|
||||||
|
"Print the API for an object as markdown. Give it a file to save the output to.",
|
||||||
|
"OBJECT",
|
||||||
|
);
|
||||||
|
|
||||||
|
Cmdline.register_order(
|
||||||
|
"input",
|
||||||
|
function (pawn) {
|
||||||
|
use("scripts/editor.js");
|
||||||
|
say(`## Input for ${pawn}`);
|
||||||
|
eval(`say(input.print_md_kbm(${pawn}));`);
|
||||||
|
},
|
||||||
|
"Print input documentation for a given object as markdown. Give it a file to save the output to",
|
||||||
|
"OBJECT ?FILE?",
|
||||||
|
);
|
||||||
|
|
||||||
|
Cmdline.register_order(
|
||||||
|
"run",
|
||||||
|
function (script) {
|
||||||
|
script = script.join(" ");
|
||||||
|
if (!script) {
|
||||||
|
say("Need something to run.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
say(eval(script));
|
||||||
|
},
|
||||||
|
"Run a given script. SCRIPT can be the script itself, or a file containing the script",
|
||||||
|
"SCRIPT",
|
||||||
|
);
|
||||||
|
|
||||||
Cmdline.orders.script = Cmdline.orders.run;
|
Cmdline.orders.script = Cmdline.orders.run;
|
||||||
|
|
||||||
Cmdline.print_order = function(fn)
|
Cmdline.print_order = function (fn) {
|
||||||
{
|
if (typeof fn === "string") fn = Cmdline.orders[fn];
|
||||||
if (typeof fn === 'string')
|
|
||||||
fn = Cmdline.orders[fn];
|
|
||||||
|
|
||||||
if (!fn) return;
|
if (!fn) return;
|
||||||
say(`Usage: prosperon ${fn.usage}`);
|
say(`Usage: prosperon ${fn.usage}`);
|
||||||
say(fn.doc);
|
say(fn.doc);
|
||||||
}
|
};
|
||||||
|
|
||||||
Cmdline.register_order("help", function(order) {
|
Cmdline.register_order(
|
||||||
|
"help",
|
||||||
if (!Object.empty(order)) {
|
function (order) {
|
||||||
var orfn = Cmdline.orders[order];
|
if (!Object.empty(order)) {
|
||||||
|
var orfn = Cmdline.orders[order];
|
||||||
if (!orfn) {
|
|
||||||
console.warn(`No command named ${order}.`);
|
if (!orfn) {
|
||||||
|
console.warn(`No command named ${order}.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Cmdline.print_order(orfn);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Cmdline.print_order(orfn);
|
Cmdline.print_order("help");
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Cmdline.print_order("help");
|
|
||||||
|
|
||||||
for (var cmd of Object.keys(Cmdline.orders).sort())
|
for (var cmd of Object.keys(Cmdline.orders).sort()) say(cmd);
|
||||||
say(cmd);
|
|
||||||
|
|
||||||
Cmdline.orders.version();
|
Cmdline.orders.version();
|
||||||
}, "Give help with a specific command.", "TOPIC");
|
},
|
||||||
|
"Give help with a specific command.",
|
||||||
|
"TOPIC",
|
||||||
|
);
|
||||||
|
|
||||||
Cmdline.register_order("version", function() {
|
Cmdline.register_order(
|
||||||
say(`Prosperon version ${prosperon.version} [${prosperon.revision}]`);
|
"version",
|
||||||
}, "Display Prosperon info.");
|
function () {
|
||||||
|
say(`Prosperon version ${prosperon.version} [${prosperon.revision}]`);
|
||||||
|
},
|
||||||
|
"Display Prosperon info.",
|
||||||
|
);
|
||||||
|
|
||||||
function cmd_args(cmdargs)
|
function cmd_args(cmdargs) {
|
||||||
{
|
|
||||||
var play = false;
|
var play = false;
|
||||||
var cmds = cmdargs.split(/\s+/).slice(1);
|
var cmds = cmdargs.split(/\s+/).slice(1);
|
||||||
|
|
||||||
if (cmds.length === 0)
|
if (cmds.length === 0) cmds[0] = "play";
|
||||||
cmds[0] = "play";
|
|
||||||
else if (!Cmdline.orders[cmds[0]]) {
|
else if (!Cmdline.orders[cmds[0]]) {
|
||||||
console.warn(`Command ${cmds[0]} not found. Playing instead.`);
|
console.warn(`Command ${cmds[0]} not found. Playing instead.`);
|
||||||
cmds[0] = "play";
|
cmds[0] = "play";
|
||||||
}
|
}
|
||||||
|
|
||||||
Cmdline.orders[cmds[0]](cmds.slice(1));
|
Cmdline.orders[cmds[0]](cmds.slice(1));
|
||||||
if (!game.startengine)
|
if (!game.startengine) os.exit(0);
|
||||||
os.exit(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Cmdline.register_order("clean", function(argv) {
|
Cmdline.register_order(
|
||||||
say("Cleaning not implemented.");
|
"clean",
|
||||||
}, "Clean up a given object file.", "JSON ...");
|
function (argv) {
|
||||||
|
say("Cleaning not implemented.");
|
||||||
|
},
|
||||||
|
"Clean up a given object file.",
|
||||||
|
"JSON ...",
|
||||||
|
);
|
||||||
|
|
||||||
Cmdline.register_order("test", function(argv) {
|
Cmdline.register_order(
|
||||||
use("scripts/test.js");
|
"test",
|
||||||
}, "Run tests.");
|
function (argv) {
|
||||||
|
use("scripts/test.js");
|
||||||
|
},
|
||||||
|
"Run tests.",
|
||||||
|
);
|
||||||
|
|
||||||
Cmdline.register_cmd("l", function(n) {
|
Cmdline.register_cmd(
|
||||||
console.level = n;
|
"l",
|
||||||
}, "Set log level.");
|
function (n) {
|
||||||
|
console.level = n;
|
||||||
|
},
|
||||||
|
"Set log level.",
|
||||||
|
);
|
||||||
|
|
||||||
function convertYAMLtoJSON(yamlString) {
|
function convertYAMLtoJSON(yamlString) {
|
||||||
const lines = yamlString.split('\n');
|
const lines = yamlString.split("\n");
|
||||||
const jsonObj = {};
|
const jsonObj = {};
|
||||||
|
|
||||||
let currentKey = '';
|
let currentKey = "";
|
||||||
let currentValue = '';
|
let currentValue = "";
|
||||||
let currentDepth = 0;
|
let currentDepth = 0;
|
||||||
|
|
||||||
for (let i = 0; i < lines.length; i++) {
|
for (let i = 0; i < lines.length; i++) {
|
||||||
const line = lines[i].trim();
|
const line = lines[i].trim();
|
||||||
if (!line || line.startsWith('#')) {
|
if (!line || line.startsWith("#")) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const depth = (line.match(/^\s+/g) || [''])[0].length;
|
const depth = (line.match(/^\s+/g) || [""])[0].length;
|
||||||
const keyValue = line.split(':');
|
const keyValue = line.split(":");
|
||||||
const key = keyValue[0].trim();
|
const key = keyValue[0].trim();
|
||||||
const value = keyValue[1].trim();
|
const value = keyValue[1].trim();
|
||||||
|
|
||||||
|
@ -507,8 +592,8 @@ function convertYAMLtoJSON(yamlString) {
|
||||||
currentValue = value;
|
currentValue = value;
|
||||||
} else {
|
} else {
|
||||||
jsonObj[currentKey] = convertYAMLtoJSON(currentValue);
|
jsonObj[currentKey] = convertYAMLtoJSON(currentValue);
|
||||||
currentKey = '';
|
currentKey = "";
|
||||||
currentValue = '';
|
currentValue = "";
|
||||||
i--; // To reprocess the current line with updated values
|
i--; // To reprocess the current line with updated values
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -526,6 +611,5 @@ return {
|
||||||
Resources,
|
Resources,
|
||||||
Cmdline,
|
Cmdline,
|
||||||
cmd_args,
|
cmd_args,
|
||||||
convertYAMLtoJSON
|
convertYAMLtoJSON,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
var aa = [1,2,3,4,5,6,7,8,9,10];
|
var aa = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
var ta = [1,2,3,4,5,6,7,8,9,10];
|
var ta = [1,2,3,4,5,6,7,8,9,10];
|
||||||
|
|
|
@ -2,9 +2,5 @@ test.run("set transform scale", _ => {
|
||||||
var t = os.make_transform();
|
var t = os.make_transform();
|
||||||
var s1 = t.scale.slice();
|
var s1 = t.scale.slice();
|
||||||
t.scale = s1;
|
t.scale = s1;
|
||||||
return (t.scale.equal(s1));
|
return t.scale.equal(s1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,20 +7,16 @@ var pass = 0;
|
||||||
var fail = 0;
|
var fail = 0;
|
||||||
var failed = [];
|
var failed = [];
|
||||||
|
|
||||||
test.run_suite = function(file)
|
test.run_suite = function (file) {
|
||||||
{
|
|
||||||
test = [];
|
test = [];
|
||||||
pass = 0;
|
pass = 0;
|
||||||
fail = 0;
|
fail = 0;
|
||||||
failed = [];
|
failed = [];
|
||||||
|
};
|
||||||
|
|
||||||
|
test.run = function (name, fn) {
|
||||||
}
|
var func = function () {
|
||||||
|
print(`${pass + fail + 1}/${tests.length}: ${name} ... `);
|
||||||
test.run = function(name, fn)
|
|
||||||
{
|
|
||||||
var func = function() {
|
|
||||||
print(`${pass+fail+1}/${tests.length}: ${name} ... `);
|
|
||||||
var p = profile.now();
|
var p = profile.now();
|
||||||
var b = fn();
|
var b = fn();
|
||||||
p = profile.lap(p);
|
p = profile.lap(p);
|
||||||
|
@ -29,12 +25,11 @@ test.run = function(name, fn)
|
||||||
};
|
};
|
||||||
func.testname = name;
|
func.testname = name;
|
||||||
tests.push(func);
|
tests.push(func);
|
||||||
}
|
};
|
||||||
|
|
||||||
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);
|
failed.push(t.testname);
|
||||||
|
@ -42,11 +37,10 @@ for (var t of tests) {
|
||||||
print("\n");
|
print("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
say(`Passed ${pass} tests and failed ${fail} [${(pass*100/(pass+fail)).toPrecision(4)}%].`);
|
say(`Passed ${pass} tests and failed ${fail} [${((pass * 100) / (pass + fail)).toPrecision(4)}%].`);
|
||||||
say(`Failed tests are:`);
|
say(`Failed tests are:`);
|
||||||
for (var f of failed)
|
for (var f of failed) say(f);
|
||||||
say(f);
|
|
||||||
|
|
||||||
os.quit();
|
os.quit();
|
||||||
|
|
||||||
return {test};
|
return { test };
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
var texteditor = Object.copy(inputpanel, {
|
var texteditor = Object.copy(inputpanel, {
|
||||||
title: "text editor",
|
title: "text editor",
|
||||||
wh: [700,500],
|
wh: [700, 500],
|
||||||
_cursor:0, /* Text cursor: [char,line] */
|
_cursor: 0 /* Text cursor: [char,line] */,
|
||||||
get cursor() { return this._cursor; },
|
get cursor() {
|
||||||
|
return this._cursor;
|
||||||
|
},
|
||||||
set cursor(x) {
|
set cursor(x) {
|
||||||
if (x > this.value.length)
|
if (x > this.value.length) x = this.value.length;
|
||||||
x = this.value.length;
|
if (x < 0) x = 0;
|
||||||
if (x < 0)
|
|
||||||
x = 0;
|
|
||||||
|
|
||||||
this._cursor = x;
|
this._cursor = x;
|
||||||
this.line = this.get_line();
|
this.line = this.get_line();
|
||||||
},
|
},
|
||||||
|
@ -31,31 +31,27 @@ var texteditor = Object.copy(inputpanel, {
|
||||||
},
|
},
|
||||||
|
|
||||||
copy(start, end) {
|
copy(start, end) {
|
||||||
return this.value.slice(start,end);
|
return this.value.slice(start, end);
|
||||||
},
|
},
|
||||||
|
|
||||||
delete_line(p) {
|
delete_line(p) {
|
||||||
var ls = this.line_start(p);
|
var ls = this.line_start(p);
|
||||||
var le = this.line_end(p)+1;
|
var le = this.line_end(p) + 1;
|
||||||
this.cut_span(ls,le);
|
this.cut_span(ls, le);
|
||||||
this.to_line_start();
|
this.to_line_start();
|
||||||
},
|
},
|
||||||
|
|
||||||
line_blank(p) {
|
line_blank(p) {
|
||||||
var ls = this.line_start(p);
|
var ls = this.line_start(p);
|
||||||
var le = this.line_end(p);
|
var le = this.line_end(p);
|
||||||
var line = this.value.slice(ls, le);
|
var line = this.value.slice(ls, le);
|
||||||
if (line.search(/[^\s]/g) === -1)
|
if (line.search(/[^\s]/g) === -1) return true;
|
||||||
return true;
|
else return false;
|
||||||
else
|
|
||||||
return false;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
get_line() {
|
get_line() {
|
||||||
var line = 0;
|
var line = 0;
|
||||||
for (var i = 0; i < this.cursor; i++)
|
for (var i = 0; i < this.cursor; i++) if (this.value[i] === "\n") line++;
|
||||||
if (this.value[i] === "\n")
|
|
||||||
line++;
|
|
||||||
|
|
||||||
return line;
|
return line;
|
||||||
},
|
},
|
||||||
|
@ -72,14 +68,11 @@ var texteditor = Object.copy(inputpanel, {
|
||||||
src: "NEW FILE",
|
src: "NEW FILE",
|
||||||
|
|
||||||
guibody() {
|
guibody() {
|
||||||
return [
|
return [Mum.text({ str: `EDITING ${this.src}` }), Mum.text({ str: this.value, caret: this.cursor, offset: [0, -16] })];
|
||||||
Mum.text({str:`EDITING ${this.src}`}),
|
|
||||||
Mum.text({str:this.value, caret:this.cursor, offset:[0,-16]}),
|
|
||||||
];
|
|
||||||
},
|
},
|
||||||
|
|
||||||
insert_char(char) {
|
insert_char(char) {
|
||||||
this.value = this.value.slice(0,this.cursor) + char + this.value.slice(this.cursor);
|
this.value = this.value.slice(0, this.cursor) + char + this.value.slice(this.cursor);
|
||||||
this.cursor++;
|
this.cursor++;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -98,117 +91,115 @@ var texteditor = Object.copy(inputpanel, {
|
||||||
cut_span(start, end) {
|
cut_span(start, end) {
|
||||||
if (end < start) return;
|
if (end < start) return;
|
||||||
this.savestate();
|
this.savestate();
|
||||||
var ret = this.value.slice(start,end);
|
var ret = this.value.slice(start, end);
|
||||||
this.value = this.value.slice(0,start) + this.value.slice(end);
|
this.value = this.value.slice(0, start) + this.value.slice(end);
|
||||||
if (start > this.cursor)
|
if (start > this.cursor) return ret;
|
||||||
return ret;
|
|
||||||
|
|
||||||
this.cursor -= ret.length;
|
this.cursor -= ret.length;
|
||||||
return ret;
|
return ret;
|
||||||
},
|
},
|
||||||
|
|
||||||
next_word(pos) {
|
next_word(pos) {
|
||||||
var v = this.value.slice(pos+1).search(/[^\w]\w/g);
|
var v = this.value.slice(pos + 1).search(/[^\w]\w/g);
|
||||||
if (v === -1) return pos;
|
if (v === -1) return pos;
|
||||||
return pos + v + 2;
|
return pos + v + 2;
|
||||||
},
|
},
|
||||||
|
|
||||||
prev_word(pos) {
|
prev_word(pos) {
|
||||||
while (this.value.slice(pos,pos+2).search(/[^\w]\w/g) === -1 && pos > 0)
|
while (this.value.slice(pos, pos + 2).search(/[^\w]\w/g) === -1 && pos > 0) pos--;
|
||||||
pos--;
|
|
||||||
|
|
||||||
return pos+1;
|
return pos + 1;
|
||||||
},
|
},
|
||||||
|
|
||||||
end_of_word(pos) {
|
end_of_word(pos) {
|
||||||
var l = this.value.slice(pos).search(/\w[^\w]/g);
|
var l = this.value.slice(pos).search(/\w[^\w]/g);
|
||||||
return l+pos;
|
return l + pos;
|
||||||
},
|
},
|
||||||
|
|
||||||
get inset() {
|
get inset() {
|
||||||
return this.cursor - this.value.prev('\n', this.cursor) - 1;
|
return this.cursor - this.value.prev("\n", this.cursor) - 1;
|
||||||
},
|
},
|
||||||
|
|
||||||
line_start(p) {
|
line_start(p) {
|
||||||
return this.value.prev('\n', p)+1;
|
return this.value.prev("\n", p) + 1;
|
||||||
},
|
},
|
||||||
|
|
||||||
line_end(p) {
|
line_end(p) {
|
||||||
return this.value.next('\n', p);
|
return this.value.next("\n", p);
|
||||||
},
|
},
|
||||||
|
|
||||||
next_line(p) {
|
next_line(p) {
|
||||||
return this.value.next('\n',p)+1;
|
return this.value.next("\n", p) + 1;
|
||||||
},
|
},
|
||||||
|
|
||||||
prev_line(p) {
|
prev_line(p) {
|
||||||
return this.line_start(this.value.prev('\n', p));
|
return this.line_start(this.value.prev("\n", p));
|
||||||
},
|
},
|
||||||
|
|
||||||
to_line_start() {
|
to_line_start() {
|
||||||
this.cursor = this.value.prev('\n', this.cursor)+1;
|
this.cursor = this.value.prev("\n", this.cursor) + 1;
|
||||||
},
|
},
|
||||||
|
|
||||||
to_line_end() {
|
to_line_end() {
|
||||||
var p = this.value.next('\n', this.cursor);
|
var p = this.value.next("\n", this.cursor);
|
||||||
if (p === -1)
|
if (p === -1) this.to_file_end();
|
||||||
this.to_file_end();
|
else this.cursor = p;
|
||||||
else
|
|
||||||
this.cursor = p;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
line_width(pos) {
|
line_width(pos) {
|
||||||
var start = this.line_start(pos);
|
var start = this.line_start(pos);
|
||||||
var end = this.line_end(pos);
|
var end = this.line_end(pos);
|
||||||
if (end === -1)
|
if (end === -1) end = this.value.length;
|
||||||
end = this.value.length;
|
|
||||||
|
|
||||||
return end-start;
|
return end - start;
|
||||||
},
|
},
|
||||||
|
|
||||||
to_file_end() { this.cursor = this.value.length; },
|
to_file_end() {
|
||||||
|
this.cursor = this.value.length;
|
||||||
|
},
|
||||||
|
|
||||||
to_file_start() { this.cursor = 0; },
|
to_file_start() {
|
||||||
|
this.cursor = 0;
|
||||||
|
},
|
||||||
|
|
||||||
desired_inset: 0,
|
desired_inset: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
texteditor.inputs = {};
|
texteditor.inputs = {};
|
||||||
|
|
||||||
texteditor.inputs.char = function(char) {
|
(texteditor.inputs.char = function (char) {
|
||||||
this.insert_char(char);
|
this.insert_char(char);
|
||||||
this.keycb();
|
this.keycb();
|
||||||
},
|
}),
|
||||||
|
(texteditor.inputs.enter = function () {
|
||||||
|
var white = this.line_starting_whitespace(this.cursor);
|
||||||
|
this.insert_char("\n");
|
||||||
|
|
||||||
texteditor.inputs.enter = function(){
|
for (var i = 0; i < white; i++) this.insert_char(" ");
|
||||||
var white = this.line_starting_whitespace(this.cursor);
|
});
|
||||||
this.insert_char('\n');
|
|
||||||
|
|
||||||
for (var i = 0; i < white; i++)
|
|
||||||
this.insert_char(" ");
|
|
||||||
};
|
|
||||||
texteditor.inputs.enter.rep = true;
|
texteditor.inputs.enter.rep = true;
|
||||||
|
|
||||||
texteditor.inputs.backspace = function(){
|
texteditor.inputs.backspace = function () {
|
||||||
this.value = this.value.slice(0,this.cursor-1) + this.value.slice(this.cursor);
|
this.value = this.value.slice(0, this.cursor - 1) + this.value.slice(this.cursor);
|
||||||
this.cursor--;
|
this.cursor--;
|
||||||
};
|
};
|
||||||
texteditor.inputs.backspace.rep = true;
|
texteditor.inputs.backspace.rep = true;
|
||||||
|
|
||||||
|
texteditor.inputs["C-s"] = function () {
|
||||||
texteditor.inputs['C-s'] = function() {
|
if (this.srctype === "function") {
|
||||||
if (this.srctype === 'function') {
|
|
||||||
eval(`${this.src} = ${this.value}`);
|
eval(`${this.src} = ${this.value}`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
texteditor.inputs['C-s'].doc = "Save edited text.";
|
texteditor.inputs["C-s"].doc = "Save edited text.";
|
||||||
|
|
||||||
texteditor.inputs['C-u'] = function() { this.popstate(); };
|
texteditor.inputs["C-u"] = function () {
|
||||||
texteditor.inputs['C-u'].doc = "Undo.";
|
this.popstate();
|
||||||
|
};
|
||||||
|
texteditor.inputs["C-u"].doc = "Undo.";
|
||||||
|
|
||||||
texteditor.inputs['C-q'] = function() {
|
texteditor.inputs["C-q"] = function () {
|
||||||
var ws = this.prev_word(this.cursor);
|
var ws = this.prev_word(this.cursor);
|
||||||
var we = this.end_of_word(this.cursor)+1;
|
var we = this.end_of_word(this.cursor) + 1;
|
||||||
var find = this.copy(ws, we);
|
var find = this.copy(ws, we);
|
||||||
var obj = editor.edit_level.varname2obj(find);
|
var obj = editor.edit_level.varname2obj(find);
|
||||||
|
|
||||||
|
@ -217,109 +208,109 @@ texteditor.inputs['C-q'] = function() {
|
||||||
editor.selectlist.push(obj);
|
editor.selectlist.push(obj);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
texteditor.inputs['C-q'].doc = "Select object of selected word.";
|
texteditor.inputs["C-q"].doc = "Select object of selected word.";
|
||||||
|
|
||||||
texteditor.inputs['C-o'] = function() {
|
texteditor.inputs["C-o"] = function () {
|
||||||
this.insert_char('\n');
|
this.insert_char("\n");
|
||||||
this.cursor--;
|
this.cursor--;
|
||||||
};
|
};
|
||||||
texteditor.inputs['C-o'].doc = "Insert newline.";
|
texteditor.inputs["C-o"].doc = "Insert newline.";
|
||||||
texteditor.inputs['C-o'].rep = true;
|
texteditor.inputs["C-o"].rep = true;
|
||||||
|
|
||||||
texteditor.inputs['M-o'] = function() {
|
texteditor.inputs["M-o"] = function () {
|
||||||
while (this.line_blank(this.next_line(this.cursor)))
|
while (this.line_blank(this.next_line(this.cursor))) this.delete_line(this.next_line(this.cursor));
|
||||||
this.delete_line(this.next_line(this.cursor));
|
|
||||||
|
|
||||||
while (this.line_blank(this.prev_line(this.cursor)))
|
while (this.line_blank(this.prev_line(this.cursor))) this.delete_line(this.prev_line(this.cursor));
|
||||||
this.delete_line(this.prev_line(this.cursor));
|
|
||||||
};
|
};
|
||||||
texteditor.inputs['M-o'].doc = "Delete surround blank lines.";
|
texteditor.inputs["M-o"].doc = "Delete surround blank lines.";
|
||||||
|
|
||||||
texteditor.inputs['C-d'] = function () { this.value = this.value.slice(0,this.cursor) + this.value.slice(this.cursor+1); };
|
texteditor.inputs["C-d"] = function () {
|
||||||
texteditor.inputs['C-d'].doc = "Delete character.";
|
this.value = this.value.slice(0, this.cursor) + this.value.slice(this.cursor + 1);
|
||||||
|
};
|
||||||
|
texteditor.inputs["C-d"].doc = "Delete character.";
|
||||||
|
|
||||||
texteditor.inputs['M-d'] = function() { this.cut_span(this.cursor, this.end_of_word(this.cursor)+1); };
|
texteditor.inputs["M-d"] = function () {
|
||||||
texteditor.inputs['M-d'].doc = "Delete word.";
|
this.cut_span(this.cursor, this.end_of_word(this.cursor) + 1);
|
||||||
|
};
|
||||||
|
texteditor.inputs["M-d"].doc = "Delete word.";
|
||||||
|
|
||||||
texteditor.inputs['C-a'] = function() {
|
texteditor.inputs["C-a"] = function () {
|
||||||
this.to_line_start();
|
this.to_line_start();
|
||||||
this.desired_inset = this.inset;
|
this.desired_inset = this.inset;
|
||||||
};
|
};
|
||||||
texteditor.inputs['C-a'].doc = "To start of line.";
|
texteditor.inputs["C-a"].doc = "To start of line.";
|
||||||
|
|
||||||
texteditor.inputs['C-y'] = function() {
|
texteditor.inputs["C-y"] = function () {
|
||||||
if (this.killring.length === 0) return;
|
if (this.killring.length === 0) return;
|
||||||
this.insert_char(this.killring.pop());
|
this.insert_char(this.killring.pop());
|
||||||
};
|
};
|
||||||
texteditor.inputs['C-y'].doc = "Insert from killring.";
|
texteditor.inputs["C-y"].doc = "Insert from killring.";
|
||||||
|
|
||||||
texteditor.inputs['C-e'] = function() {
|
texteditor.inputs["C-e"] = function () {
|
||||||
this.to_line_end();
|
this.to_line_end();
|
||||||
this.desired_inset = this.inset;
|
this.desired_inset = this.inset;
|
||||||
};
|
};
|
||||||
texteditor.inputs['C-e'].doc = "To line end.";
|
texteditor.inputs["C-e"].doc = "To line end.";
|
||||||
|
|
||||||
texteditor.inputs['C-k'] = function() {
|
texteditor.inputs["C-k"] = function () {
|
||||||
if (this.cursor === this.value.length-1) return;
|
if (this.cursor === this.value.length - 1) return;
|
||||||
var killamt = this.value.next('\n', this.cursor) - this.cursor;
|
var killamt = this.value.next("\n", this.cursor) - this.cursor;
|
||||||
var killed = this.cut_span(this.cursor-1, this.cursor+killamt);
|
var killed = this.cut_span(this.cursor - 1, this.cursor + killamt);
|
||||||
this.killring.push(killed);
|
this.killring.push(killed);
|
||||||
};
|
};
|
||||||
texteditor.inputs['C-k'].doc = "Kill from cursor to end of line.";
|
texteditor.inputs["C-k"].doc = "Kill from cursor to end of line.";
|
||||||
|
|
||||||
texteditor.inputs['M-k'] = function() {
|
texteditor.inputs["M-k"] = function () {
|
||||||
var prevn = this.value.prev('\n', this.cursor);
|
var prevn = this.value.prev("\n", this.cursor);
|
||||||
var killamt = this.cursor - prevn;
|
var killamt = this.cursor - prevn;
|
||||||
var killed = this.cut_span(prevn+1, prevn+killamt);
|
var killed = this.cut_span(prevn + 1, prevn + killamt);
|
||||||
this.killring.push(killed);
|
this.killring.push(killed);
|
||||||
this.to_line_start();
|
this.to_line_start();
|
||||||
};
|
};
|
||||||
texteditor.inputs['M-k'].doc = "Kill entire line the cursor is on.";
|
texteditor.inputs["M-k"].doc = "Kill entire line the cursor is on.";
|
||||||
|
|
||||||
texteditor.inputs['C-b'] = function() {
|
texteditor.inputs["C-b"] = function () {
|
||||||
this.cursor--;
|
this.cursor--;
|
||||||
this.desired_inset = this.inset;
|
this.desired_inset = this.inset;
|
||||||
};
|
};
|
||||||
texteditor.inputs['C-b'].rep = true;
|
texteditor.inputs["C-b"].rep = true;
|
||||||
texteditor.inputs['M-b'] = function() {
|
texteditor.inputs["M-b"] = function () {
|
||||||
this.cursor = this.prev_word(this.cursor-2);
|
this.cursor = this.prev_word(this.cursor - 2);
|
||||||
this.desired_inset = this.inset;
|
this.desired_inset = this.inset;
|
||||||
};
|
};
|
||||||
texteditor.inputs['M-b'].rep = true;
|
texteditor.inputs["M-b"].rep = true;
|
||||||
|
|
||||||
texteditor.inputs['C-f'] = function() {
|
texteditor.inputs["C-f"] = function () {
|
||||||
this.cursor++;
|
this.cursor++;
|
||||||
this.desired_inset = this.inset;
|
this.desired_inset = this.inset;
|
||||||
};
|
};
|
||||||
texteditor.inputs['C-f'].rep = true;
|
texteditor.inputs["C-f"].rep = true;
|
||||||
texteditor.inputs['M-f'] = function() {
|
texteditor.inputs["M-f"] = function () {
|
||||||
this.cursor = this.next_word(this.cursor);
|
this.cursor = this.next_word(this.cursor);
|
||||||
this.desired_inset = this.inset;
|
this.desired_inset = this.inset;
|
||||||
};
|
};
|
||||||
texteditor.inputs['M-f'].rep = true;
|
texteditor.inputs["M-f"].rep = true;
|
||||||
|
|
||||||
texteditor.inputs['C-p'] = function() {
|
texteditor.inputs["C-p"] = function () {
|
||||||
if (this.cursor === 0) return;
|
if (this.cursor === 0) return;
|
||||||
this.desired_inset = Math.max(this.desired_inset, this.inset);
|
this.desired_inset = Math.max(this.desired_inset, this.inset);
|
||||||
this.cursor = this.prev_line(this.cursor);
|
this.cursor = this.prev_line(this.cursor);
|
||||||
var newlinew = this.line_width(this.cursor);
|
var newlinew = this.line_width(this.cursor);
|
||||||
this.cursor += Math.min(this.desired_inset, newlinew);
|
this.cursor += Math.min(this.desired_inset, newlinew);
|
||||||
};
|
};
|
||||||
texteditor.inputs['C-p'].rep = true;
|
texteditor.inputs["C-p"].rep = true;
|
||||||
|
|
||||||
texteditor.inputs['M-p'] = function() {
|
texteditor.inputs["M-p"] = function () {
|
||||||
while (this.line_blank(this.cursor))
|
while (this.line_blank(this.cursor)) this.cursor = this.prev_line(this.cursor);
|
||||||
this.cursor = this.prev_line(this.cursor);
|
|
||||||
|
|
||||||
while (!this.line_blank(this.cursor))
|
while (!this.line_blank(this.cursor)) this.cursor = this.prev_line(this.cursor);
|
||||||
this.cursor = this.prev_line(this.cursor);
|
|
||||||
};
|
};
|
||||||
texteditor.inputs['M-p'].doc = "Go up to next line with text on it.";
|
texteditor.inputs["M-p"].doc = "Go up to next line with text on it.";
|
||||||
texteditor.inputs['M-p'].rep = true;
|
texteditor.inputs["M-p"].rep = true;
|
||||||
|
|
||||||
texteditor.inputs['C-n'] = function() {
|
texteditor.inputs["C-n"] = function () {
|
||||||
if (this.cursor === this.value.length-1) return;
|
if (this.cursor === this.value.length - 1) return;
|
||||||
if (this.value.next('\n', this.cursor) === -1) {
|
if (this.value.next("\n", this.cursor) === -1) {
|
||||||
this.to_file_end();
|
this.to_file_end();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -329,20 +320,16 @@ texteditor.inputs['C-n'] = function() {
|
||||||
var newlinew = this.line_width(this.cursor);
|
var newlinew = this.line_width(this.cursor);
|
||||||
this.cursor += Math.min(this.desired_inset, newlinew);
|
this.cursor += Math.min(this.desired_inset, newlinew);
|
||||||
};
|
};
|
||||||
texteditor.inputs['C-n'].rep = true;
|
texteditor.inputs["C-n"].rep = true;
|
||||||
|
|
||||||
texteditor.inputs['M-n'] = function() {
|
texteditor.inputs["M-n"] = function () {
|
||||||
while (this.line_blank(this.cursor))
|
while (this.line_blank(this.cursor)) this.cursor = this.next_line(this.cursor);
|
||||||
this.cursor = this.next_line(this.cursor);
|
while (!this.line_blank(this.cursor)) this.cursor = this.next_line(this.cursor);
|
||||||
|
|
||||||
while (!this.line_blank(this.cursor))
|
|
||||||
this.cursor = this.next_line(this.cursor);
|
|
||||||
};
|
};
|
||||||
texteditor.inputs['M-n'].doc = "Go down to next line with text on it.";
|
texteditor.inputs["M-n"].doc = "Go down to next line with text on it.";
|
||||||
texteditor.inputs['M-n'].rep = true;
|
texteditor.inputs["M-n"].rep = true;
|
||||||
|
|
||||||
texteditor.open_fn = function(fnstr)
|
texteditor.open_fn = function (fnstr) {
|
||||||
{
|
|
||||||
var fn = eval(fnstr);
|
var fn = eval(fnstr);
|
||||||
if (!fn) {
|
if (!fn) {
|
||||||
console.warn(`${fnstr} is not a function.`);
|
console.warn(`${fnstr} is not a function.`);
|
||||||
|
@ -353,4 +340,4 @@ texteditor.open_fn = function(fnstr)
|
||||||
editor.openpanel(this);
|
editor.openpanel(this);
|
||||||
this.value = fn;
|
this.value = fn;
|
||||||
this.cursor = 0;
|
this.cursor = 0;
|
||||||
}
|
};
|
||||||
|
|
143
scripts/tween.js
143
scripts/tween.js
|
@ -1,40 +1,43 @@
|
||||||
/* Take numbers from 0 to 1 and remap them to easing functions */
|
/* Take numbers from 0 to 1 and remap them to easing functions */
|
||||||
var Ease = {
|
var Ease = {
|
||||||
linear(t) { return t; },
|
linear(t) {
|
||||||
|
return t;
|
||||||
|
},
|
||||||
|
|
||||||
in(t) { return t*t; },
|
in(t) {
|
||||||
|
return t * t;
|
||||||
|
},
|
||||||
|
|
||||||
out(t) {
|
out(t) {
|
||||||
var d = 1-t;
|
var d = 1 - t;
|
||||||
return 1 - d*d
|
return 1 - d * d;
|
||||||
},
|
},
|
||||||
|
|
||||||
inout(t) {
|
inout(t) {
|
||||||
var d = -2*t + 2;
|
var d = -2 * t + 2;
|
||||||
return t < 0.5 ? 2 * t * t : 1 - (d * d) / 2;
|
return t < 0.5 ? 2 * t * t : 1 - (d * d) / 2;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
function make_easing_fns(num) {
|
function make_easing_fns(num) {
|
||||||
var obj = {};
|
var obj = {};
|
||||||
|
|
||||||
obj.in = function(t) {
|
obj.in = function (t) {
|
||||||
return Math.pow(t,num);
|
return Math.pow(t, num);
|
||||||
};
|
};
|
||||||
|
|
||||||
obj.out = function(t) {
|
obj.out = function (t) {
|
||||||
return 1 - Math.pow(1 - t, num);
|
return 1 - Math.pow(1 - t, num);
|
||||||
};
|
};
|
||||||
|
|
||||||
var mult = Math.pow(2, num-1);
|
var mult = Math.pow(2, num - 1);
|
||||||
|
|
||||||
obj.inout = function(t) {
|
obj.inout = function (t) {
|
||||||
return t < 0.5 ? mult * Math.pow(t, num) : 1 - Math.pow(-2 * t + 2, num) / 2;
|
return t < 0.5 ? mult * Math.pow(t, num) : 1 - Math.pow(-2 * t + 2, num) / 2;
|
||||||
};
|
};
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
};
|
}
|
||||||
|
|
||||||
Ease.quad = make_easing_fns(2);
|
Ease.quad = make_easing_fns(2);
|
||||||
Ease.cubic = make_easing_fns(3);
|
Ease.cubic = make_easing_fns(3);
|
||||||
|
@ -52,7 +55,7 @@ Ease.expo = {
|
||||||
|
|
||||||
inout(t) {
|
inout(t) {
|
||||||
return t === 0 ? 0 : t === 1 ? 1 : t < 0.5 ? Math.pow(2, 20 * t - 10) / 2 : (2 - Math.pow(2, -20 * t + 10)) / 2;
|
return t === 0 ? 0 : t === 1 ? 1 : t < 0.5 ? Math.pow(2, 20 * t - 10) / 2 : (2 - Math.pow(2, -20 * t + 10)) / 2;
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
Ease.bounce = {
|
Ease.bounce = {
|
||||||
|
@ -64,52 +67,57 @@ Ease.bounce = {
|
||||||
var n1 = 7.5625;
|
var n1 = 7.5625;
|
||||||
var d1 = 2.75;
|
var d1 = 2.75;
|
||||||
|
|
||||||
if (t < 1 / d1) { return n1 * t * t; }
|
if (t < 1 / d1) {
|
||||||
else if (t < 2 / d1) { return n1 * (t -= 1.5 / d1) * t + 0.75; }
|
return n1 * t * t;
|
||||||
else if (t < 2.5 / d1) { return n1 * (t -= 2.25 / d1) * t + 0.9375; }
|
} else if (t < 2 / d1) {
|
||||||
else
|
return n1 * (t -= 1.5 / d1) * t + 0.75;
|
||||||
return n1 * (t -= 2.625 / d1) * t + 0.984375;
|
} else if (t < 2.5 / d1) {
|
||||||
|
return n1 * (t -= 2.25 / d1) * t + 0.9375;
|
||||||
|
} else return n1 * (t -= 2.625 / d1) * t + 0.984375;
|
||||||
},
|
},
|
||||||
|
|
||||||
inout(t) {
|
inout(t) {
|
||||||
return t < 0.5 ? (1 - this.out(1 - 2 * t)) / 2 : (1 + this.out(2 * t - 1)) / 2;
|
return t < 0.5 ? (1 - this.out(1 - 2 * t)) / 2 : (1 + this.out(2 * t - 1)) / 2;
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
Ease.sine = {
|
Ease.sine = {
|
||||||
in(t) { return 1 - Math.cos((t * Math.PI)/2); },
|
in(t) {
|
||||||
|
return 1 - Math.cos((t * Math.PI) / 2);
|
||||||
|
},
|
||||||
|
|
||||||
out(t) { return Math.sin((t*Math.PI)/2); },
|
out(t) {
|
||||||
|
return Math.sin((t * Math.PI) / 2);
|
||||||
|
},
|
||||||
|
|
||||||
inout(t) { return -(Math.cos(Math.PI*t) - 1) / 2; }
|
inout(t) {
|
||||||
|
return -(Math.cos(Math.PI * t) - 1) / 2;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
Ease.elastic = {
|
Ease.elastic = {
|
||||||
in(t) {
|
in(t) {
|
||||||
return t === 0 ? 0 : t === 1 ? 1 : -Math.pow(2, 10*t-10) * Math.sin((t * 10 - 10.75) * this.c4);
|
return t === 0 ? 0 : t === 1 ? 1 : -Math.pow(2, 10 * t - 10) * Math.sin((t * 10 - 10.75) * this.c4);
|
||||||
},
|
},
|
||||||
|
|
||||||
out(t) {
|
out(t) {
|
||||||
return t === 0 ? 0 : t === 1 ? 1 : Math.pow(2, -10*t) * Math.sin((t * 10 - 0.75) * this.c4) + 1;
|
return t === 0 ? 0 : t === 1 ? 1 : Math.pow(2, -10 * t) * Math.sin((t * 10 - 0.75) * this.c4) + 1;
|
||||||
},
|
},
|
||||||
|
|
||||||
inout(t) {
|
inout(t) {
|
||||||
t === 0 ? 0 : t === 1 ? 1 : t < 0.5 ?
|
t === 0 ? 0 : t === 1 ? 1 : t < 0.5 ? -(Math.pow(2, 20 * t - 10) * Math.sin((20 * t - 11.125) * this.c5)) / 2 : (Math.pow(2, -20 * t + 10) * Math.sin((20 * t - 11.125) * this.c5)) / 2 + 1;
|
||||||
-(Math.pow(2, 20 * t - 10) * Math.sin((20 * t - 11.125) * this.c5)) / 2
|
|
||||||
: (Math.pow(2, -20 * t + 10) * Math.sin((20 * t - 11.125) * this.c5)) / 2 + 1;
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
Ease.elastic.c4 = 2*Math.PI/3;
|
Ease.elastic.c4 = (2 * Math.PI) / 3;
|
||||||
Ease.elastic.c5 = 2*Math.PI / 4.5;
|
Ease.elastic.c5 = (2 * Math.PI) / 4.5;
|
||||||
|
|
||||||
var tween = function(from, to, time, fn, endfn)
|
var tween = function (from, to, time, fn, endfn) {
|
||||||
{
|
|
||||||
var start = profile.secs(profile.now());
|
var start = profile.secs(profile.now());
|
||||||
var update = function(dt) {
|
var update = function (dt) {
|
||||||
profile.frame("tween");
|
profile.frame("tween");
|
||||||
var elapsed = profile.secs(profile.now()) - start;
|
var elapsed = profile.secs(profile.now()) - start;
|
||||||
fn(from.lerp(to,elapsed/time));
|
fn(from.lerp(to, elapsed / time));
|
||||||
if (elapsed >= time) {
|
if (elapsed >= time) {
|
||||||
fn(to);
|
fn(to);
|
||||||
if (stop.then) stop.then();
|
if (stop.then) stop.then();
|
||||||
|
@ -120,7 +128,7 @@ var tween = function(from, to, time, fn, endfn)
|
||||||
};
|
};
|
||||||
var stop = Register.update.register(update);
|
var stop = Register.update.register(update);
|
||||||
return stop;
|
return stop;
|
||||||
}
|
};
|
||||||
|
|
||||||
var Tween = {
|
var Tween = {
|
||||||
default: {
|
default: {
|
||||||
|
@ -133,22 +141,19 @@ var Tween = {
|
||||||
yoyo: go up and then back down
|
yoyo: go up and then back down
|
||||||
circle: go up and back down, looped
|
circle: go up and back down, looped
|
||||||
*/
|
*/
|
||||||
time: 1, /* seconds to do */
|
time: 1 /* seconds to do */,
|
||||||
ease: Ease.linear,
|
ease: Ease.linear,
|
||||||
whole: true, /* True if time is for the entire tween, false if each stage */
|
whole: true /* True if time is for the entire tween, false if each stage */,
|
||||||
cb: function(){},
|
cb: function () {},
|
||||||
},
|
},
|
||||||
|
|
||||||
start(obj, target, tvals, options)
|
start(obj, target, tvals, options) {
|
||||||
{
|
|
||||||
var defn = Object.create(this.default);
|
var defn = Object.create(this.default);
|
||||||
Object.assign(defn, options);
|
Object.assign(defn, options);
|
||||||
|
|
||||||
if (defn.loop === 'circle')
|
if (defn.loop === "circle") tvals.push(tvals[0]);
|
||||||
tvals.push(tvals[0]);
|
else if (defn.loop === "yoyo") {
|
||||||
else if (defn.loop === 'yoyo') {
|
for (var i = tvals.length - 2; i >= 0; i--) tvals.push(tvals[i]);
|
||||||
for (var i = tvals.length-2; i >= 0; i--)
|
|
||||||
tvals.push(tvals[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
defn.accum = 0;
|
defn.accum = 0;
|
||||||
|
@ -156,22 +161,19 @@ var Tween = {
|
||||||
var slices = tvals.length - 1;
|
var slices = tvals.length - 1;
|
||||||
var slicelen = 1 / slices;
|
var slicelen = 1 / slices;
|
||||||
|
|
||||||
defn.fn = function(dt) {
|
defn.fn = function (dt) {
|
||||||
defn.accum += dt;
|
defn.accum += dt;
|
||||||
if (defn.accum >= defn.time && defn.loop === 'hold') {
|
if (defn.accum >= defn.time && defn.loop === "hold") {
|
||||||
if (typeof target === 'string')
|
if (typeof target === "string") obj[target] = tvals[tvals.length - 1];
|
||||||
obj[target] = tvals[tvals.length-1];
|
else target(tvals[tvals.length - 1]);
|
||||||
else
|
|
||||||
target(tvals[tvals.length-1]);
|
|
||||||
|
|
||||||
defn.pause();
|
defn.pause();
|
||||||
defn.cb.call(obj);
|
defn.cb.call(obj);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
defn.pct = (defn.accum % defn.time) / defn.time;
|
defn.pct = (defn.accum % defn.time) / defn.time;
|
||||||
if (defn.loop === 'none' && defn.accum >= defn.time)
|
if (defn.loop === "none" && defn.accum >= defn.time) defn.stop();
|
||||||
defn.stop();
|
|
||||||
|
|
||||||
var t = defn.whole ? defn.ease(defn.pct) : defn.pct;
|
var t = defn.whole ? defn.ease(defn.pct) : defn.pct;
|
||||||
|
|
||||||
|
@ -179,31 +181,30 @@ var Tween = {
|
||||||
var i = Math.trunc(nval);
|
var i = Math.trunc(nval);
|
||||||
nval -= i;
|
nval -= i;
|
||||||
|
|
||||||
if (!defn.whole)
|
if (!defn.whole) nval = defn.ease(nval);
|
||||||
nval = defn.ease(nval);
|
|
||||||
|
|
||||||
if (typeof target === 'string')
|
if (typeof target === "string") obj[target] = tvals[i].lerp(tvals[i + 1], nval);
|
||||||
obj[target] = tvals[i].lerp(tvals[i+1], nval);
|
else target(tvals[i].lerp(tvals[i + 1], nval));
|
||||||
else
|
|
||||||
target(tvals[i].lerp(tvals[i+1],nval));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var playing = false;
|
var playing = false;
|
||||||
|
|
||||||
defn.play = function() {
|
defn.play = function () {
|
||||||
if (playing) return;
|
if (playing) return;
|
||||||
defn._end = Register.update.register(defn.fn.bind(defn));
|
defn._end = Register.update.register(defn.fn.bind(defn));
|
||||||
playing = true;
|
playing = true;
|
||||||
};
|
};
|
||||||
defn.restart = function() {
|
defn.restart = function () {
|
||||||
defn.accum = 0;
|
defn.accum = 0;
|
||||||
if (typeof target === 'string')
|
if (typeof target === "string") obj[target] = tvals[0];
|
||||||
obj[target] = tvals[0];
|
else target(tvals[0]);
|
||||||
else
|
|
||||||
target(tvals[0]);
|
|
||||||
};
|
};
|
||||||
defn.stop = function() { if (!playing) return; defn.pause(); defn.restart(); };
|
defn.stop = function () {
|
||||||
defn.pause = function() {
|
if (!playing) return;
|
||||||
|
defn.pause();
|
||||||
|
defn.restart();
|
||||||
|
};
|
||||||
|
defn.pause = function () {
|
||||||
defn._end();
|
defn._end();
|
||||||
if (!playing) return;
|
if (!playing) return;
|
||||||
|
|
||||||
|
@ -216,4 +217,4 @@ var Tween = {
|
||||||
|
|
||||||
Tween.make = Tween.start;
|
Tween.make = Tween.start;
|
||||||
|
|
||||||
return {Tween, Ease, tween};
|
return { Tween, Ease, tween };
|
||||||
|
|
|
@ -1,63 +1,62 @@
|
||||||
var inputpanel = {
|
var inputpanel = {
|
||||||
title: "untitled",
|
title: "untitled",
|
||||||
toString() { return this.title; },
|
toString() {
|
||||||
|
return this.title;
|
||||||
|
},
|
||||||
value: "",
|
value: "",
|
||||||
on: false,
|
on: false,
|
||||||
pos:[20,window.size.y-20],
|
pos: [20, window.size.y - 20],
|
||||||
wh:[100,100],
|
wh: [100, 100],
|
||||||
anchor: [0,1],
|
anchor: [0, 1],
|
||||||
padding:[5,-15],
|
padding: [5, -15],
|
||||||
|
|
||||||
gui() {
|
gui() {
|
||||||
this.win ??= Mum.window({width:this.wh.x,height:this.wh.y, color:Color.black.alpha(0.1), anchor:this.anchor, padding:this.padding});
|
this.win ??= Mum.window({
|
||||||
|
width: this.wh.x,
|
||||||
|
height: this.wh.y,
|
||||||
|
color: Color.black.alpha(0.1),
|
||||||
|
anchor: this.anchor,
|
||||||
|
padding: this.padding,
|
||||||
|
});
|
||||||
var itms = this.guibody();
|
var itms = this.guibody();
|
||||||
if (!Array.isArray(itms)) itms = [itms];
|
if (!Array.isArray(itms)) itms = [itms];
|
||||||
if (this.title)
|
if (this.title) this.win.items = [Mum.column({ items: [Mum.text({ str: this.title }), ...itms] })];
|
||||||
this.win.items = [
|
else this.win.items = itms;
|
||||||
Mum.column({items: [Mum.text({str:this.title}), ...itms ]})
|
|
||||||
];
|
this.win.draw([100, window.size.y - 50]);
|
||||||
else
|
|
||||||
this.win.items = itms;
|
|
||||||
|
|
||||||
this.win.draw([100, window.size.y-50]);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
guibody() {
|
guibody() {
|
||||||
return [
|
return [Mum.text({ str: this.value, color: Color.green }), Mum.button({ str: "SUBMIT", action: this.submit.bind(this) })];
|
||||||
Mum.text({str:this.value, color:Color.green}),
|
|
||||||
Mum.button({str:"SUBMIT", action:this.submit.bind(this)})
|
|
||||||
];
|
|
||||||
},
|
},
|
||||||
|
|
||||||
open() {
|
open() {
|
||||||
this.on = true;
|
this.on = true;
|
||||||
this.value = "";
|
this.value = "";
|
||||||
this.start();
|
this.start();
|
||||||
this.keycb();
|
this.keycb();
|
||||||
},
|
},
|
||||||
|
|
||||||
start() {},
|
start() {},
|
||||||
|
|
||||||
close() {
|
close() {
|
||||||
player[0].uncontrol(this);
|
player[0].uncontrol(this);
|
||||||
this.on = false;
|
this.on = false;
|
||||||
if ('on_close' in this)
|
if ("on_close" in this) this.on_close();
|
||||||
this.on_close();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
action() {
|
action() {},
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
closeonsubmit: true,
|
closeonsubmit: true,
|
||||||
submit() {
|
submit() {
|
||||||
if (!this.submit_check()) return;
|
if (!this.submit_check()) return;
|
||||||
this.action();
|
this.action();
|
||||||
if (this.closeonsubmit)
|
if (this.closeonsubmit) this.close();
|
||||||
this.close();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
submit_check() { return true; },
|
submit_check() {
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
keycb() {},
|
keycb() {},
|
||||||
|
|
||||||
|
@ -67,9 +66,9 @@ var inputpanel = {
|
||||||
this.value = "";
|
this.value = "";
|
||||||
this.caret = 0;
|
this.caret = 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
input_backspace_pressrep() {
|
input_backspace_pressrep() {
|
||||||
this.value = this.value.slice(0,-1);
|
this.value = this.value.slice(0, -1);
|
||||||
this.keycb();
|
this.keycb();
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -77,49 +76,62 @@ var inputpanel = {
|
||||||
inputpanel.inputs = {};
|
inputpanel.inputs = {};
|
||||||
inputpanel.inputs.block = true;
|
inputpanel.inputs.block = true;
|
||||||
|
|
||||||
inputpanel.inputs.post = function() { this.keycb(); }
|
inputpanel.inputs.post = function () {
|
||||||
|
this.keycb();
|
||||||
|
};
|
||||||
|
|
||||||
inputpanel.inputs.char = function(c) {
|
inputpanel.inputs.char = function (c) {
|
||||||
this.value = this.value.slice(0,this.caret) + c + this.value.slice(this.caret);
|
this.value = this.value.slice(0, this.caret) + c + this.value.slice(this.caret);
|
||||||
this.caret++;
|
this.caret++;
|
||||||
}
|
};
|
||||||
inputpanel.inputs['C-d'] = function() { this.value = this.value.slice(0,this.caret) + this.value.slice(this.caret+1); };
|
inputpanel.inputs["C-d"] = function () {
|
||||||
inputpanel.inputs['C-d'].rep = true;
|
this.value = this.value.slice(0, this.caret) + this.value.slice(this.caret + 1);
|
||||||
inputpanel.inputs.tab = function() {
|
};
|
||||||
|
inputpanel.inputs["C-d"].rep = true;
|
||||||
|
inputpanel.inputs.tab = function () {
|
||||||
this.value = input.tabcomplete(this.value, this.assets);
|
this.value = input.tabcomplete(this.value, this.assets);
|
||||||
this.caret = this.value.length;
|
this.caret = this.value.length;
|
||||||
}
|
};
|
||||||
inputpanel.inputs.escape = function() { this.close(); }
|
inputpanel.inputs.escape = function () {
|
||||||
inputpanel.inputs['C-b'] = function() {
|
this.close();
|
||||||
|
};
|
||||||
|
inputpanel.inputs["C-b"] = function () {
|
||||||
if (this.caret === 0) return;
|
if (this.caret === 0) return;
|
||||||
this.caret--;
|
this.caret--;
|
||||||
};
|
};
|
||||||
inputpanel.inputs['C-b'].rep = true;
|
inputpanel.inputs["C-b"].rep = true;
|
||||||
inputpanel.inputs['C-u'] = function()
|
inputpanel.inputs["C-u"] = function () {
|
||||||
{
|
|
||||||
this.value = this.value.slice(this.caret);
|
this.value = this.value.slice(this.caret);
|
||||||
this.caret = 0;
|
this.caret = 0;
|
||||||
}
|
};
|
||||||
inputpanel.inputs['C-f'] = function() {
|
inputpanel.inputs["C-f"] = function () {
|
||||||
if (this.caret === this.value.length) return;
|
if (this.caret === this.value.length) return;
|
||||||
this.caret++;
|
this.caret++;
|
||||||
};
|
};
|
||||||
inputpanel.inputs['C-f'].rep = true;
|
inputpanel.inputs["C-f"].rep = true;
|
||||||
inputpanel.inputs['C-a'] = function() { this.caret = 0; };
|
inputpanel.inputs["C-a"] = function () {
|
||||||
inputpanel.inputs['C-e'] = function() { this.caret = this.value.length; };
|
this.caret = 0;
|
||||||
inputpanel.inputs.backspace = function() {
|
};
|
||||||
|
inputpanel.inputs["C-e"] = function () {
|
||||||
|
this.caret = this.value.length;
|
||||||
|
};
|
||||||
|
inputpanel.inputs.backspace = function () {
|
||||||
if (this.caret === 0) return;
|
if (this.caret === 0) return;
|
||||||
this.value = this.value.slice(0,this.caret-1) + this.value.slice(this.caret);
|
this.value = this.value.slice(0, this.caret - 1) + this.value.slice(this.caret);
|
||||||
this.caret--;
|
this.caret--;
|
||||||
};
|
};
|
||||||
inputpanel.inputs.backspace.rep = true;
|
inputpanel.inputs.backspace.rep = true;
|
||||||
inputpanel.inputs.enter = function() { this.submit(); }
|
inputpanel.inputs.enter = function () {
|
||||||
|
this.submit();
|
||||||
inputpanel.inputs['C-k'] = function() {
|
|
||||||
this.value = this.value.slice(0,this.caret);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inputpanel.inputs.lm = function() { gui.controls.check_submit(); }
|
inputpanel.inputs["C-k"] = function () {
|
||||||
|
this.value = this.value.slice(0, this.caret);
|
||||||
|
};
|
||||||
|
|
||||||
|
inputpanel.inputs.lm = function () {
|
||||||
|
gui.controls.check_submit();
|
||||||
|
};
|
||||||
|
|
||||||
var notifypanel = Object.copy(inputpanel, {
|
var notifypanel = Object.copy(inputpanel, {
|
||||||
title: "notification",
|
title: "notification",
|
||||||
|
@ -127,28 +139,32 @@ var notifypanel = Object.copy(inputpanel, {
|
||||||
action() {
|
action() {
|
||||||
this.close();
|
this.close();
|
||||||
},
|
},
|
||||||
|
|
||||||
guibody() {
|
guibody() {
|
||||||
return Mum.column({items: [
|
return Mum.column({
|
||||||
Mum.text({str:this.msg}),
|
items: [Mum.text({ str: this.msg }), Mum.button({ str: "OK", action: this.close.bind(this) })],
|
||||||
Mum.button({str:"OK", action:this.close.bind(this)})
|
});
|
||||||
]});
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
var gen_notify = function(val, fn) {
|
var gen_notify = function (val, fn) {
|
||||||
var panel = Object.create(notifypanel);
|
var panel = Object.create(notifypanel);
|
||||||
panel.msg = val;
|
panel.msg = val;
|
||||||
panel.yes = fn;
|
panel.yes = fn;
|
||||||
panel.inputs = {};
|
panel.inputs = {};
|
||||||
panel.inputs.y = function() { panel.yes(); panel.close(); };
|
panel.inputs.y = function () {
|
||||||
|
panel.yes();
|
||||||
|
panel.close();
|
||||||
|
};
|
||||||
panel.inputs.y.doc = "Confirm yes.";
|
panel.inputs.y.doc = "Confirm yes.";
|
||||||
panel.inputs.enter = function() { panel.close(); };
|
panel.inputs.enter = function () {
|
||||||
|
panel.close();
|
||||||
|
};
|
||||||
panel.inputs.enter.doc = "Close.";
|
panel.inputs.enter.doc = "Close.";
|
||||||
return panel;
|
return panel;
|
||||||
};
|
};
|
||||||
|
|
||||||
var listpanel = Object.copy(inputpanel, {
|
var listpanel = Object.copy(inputpanel, {
|
||||||
assets: [],
|
assets: [],
|
||||||
allassets: [],
|
allassets: [],
|
||||||
mumlist: {},
|
mumlist: {},
|
||||||
|
@ -164,28 +180,31 @@ var listpanel = Object.copy(inputpanel, {
|
||||||
this.assets = this.allassets.slice();
|
this.assets = this.allassets.slice();
|
||||||
this.caret = 0;
|
this.caret = 0;
|
||||||
this.mumlist = [];
|
this.mumlist = [];
|
||||||
this.assets.forEach(function(x) {
|
this.assets.forEach(function (x) {
|
||||||
this.mumlist[x] = Mum.text({str:x, action:this.action, color: Color.blue, hovered: {color:Color.red}, selectable:true});
|
this.mumlist[x] = Mum.text({
|
||||||
|
str: x,
|
||||||
|
action: this.action,
|
||||||
|
color: Color.blue,
|
||||||
|
hovered: { color: Color.red },
|
||||||
|
selectable: true,
|
||||||
|
});
|
||||||
}, this);
|
}, this);
|
||||||
},
|
},
|
||||||
|
|
||||||
keycb() {
|
keycb() {
|
||||||
if(this.value)
|
if (this.value) this.assets = this.allassets.filter(x => x.startsWith(this.value));
|
||||||
this.assets = this.allassets.filter(x => x.startsWith(this.value));
|
else this.assets = this.allassets.slice();
|
||||||
else
|
for (var m in this.mumlist) this.mumlist[m].hide = true;
|
||||||
this.assets = this.allassets.slice();
|
this.assets.forEach(function (x) {
|
||||||
for (var m in this.mumlist)
|
this.mumlist[x].hide = false;
|
||||||
this.mumlist[m].hide = true;
|
|
||||||
this.assets.forEach(function(x) {
|
|
||||||
this.mumlist[x].hide = false;
|
|
||||||
}, this);
|
}, this);
|
||||||
},
|
},
|
||||||
|
|
||||||
guibody() {
|
guibody() {
|
||||||
var a = [Mum.text({str:this.value,color:Color.green, caret:this.caret})];
|
var a = [Mum.text({ str: this.value, color: Color.green, caret: this.caret })];
|
||||||
var b = a.concat(Object.values(this.mumlist));
|
var b = a.concat(Object.values(this.mumlist));
|
||||||
return Mum.column({items:b, offset:[0,-10]});
|
return Mum.column({ items: b, offset: [0, -10] });
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return {inputpanel, gen_notify, notifypanel, listpanel}
|
return { inputpanel, gen_notify, notifypanel, listpanel };
|
||||||
|
|
Loading…
Reference in a new issue