nodes,gameobjects cleanup
This commit is contained in:
parent
7e7514f5d7
commit
b9db31c84e
|
@ -1,5 +1,9 @@
|
|||
# Yugine Scripting Guide
|
||||
|
||||
Primum programs are organized into two different types of source files: scripts and entities. Scripts end with .js, entities end with .jso.
|
||||
|
||||
## Scripts
|
||||
|
||||
Script hooks exist to allow to modification of the game.
|
||||
|
||||
|config.js|called before any game play, including play from editor|
|
||||
|
@ -9,7 +13,13 @@ Script hooks exist to allow to modification of the game.
|
|||
|debug.js|called when play in editor is selected, after level load|
|
||||
|dbgret.js|called when play in editor returns to editor|
|
||||
|
||||
All objects in the Yugine can have an associated script. This script can perform setup, teardown, and handles responses for the object.
|
||||
In addition, any script can be run by running "load".
|
||||
|
||||
## Entities
|
||||
|
||||
Entities are defined in a jso file. The "this" parameter in the jso file is a reference to the actor, allowing you to define properties on it.
|
||||
|
||||
Computation takes place in turns. Each entity has functions called, if they exist. If a machine has multiple threads, multiple entities may be taking turns at a time.
|
||||
|
||||
|function|description|
|
||||
|---|---|
|
||||
|
|
|
@ -23,6 +23,17 @@ Promise = undefined;
|
|||
Set = undefined;
|
||||
WeakSet = undefined;
|
||||
|
||||
var json = {};
|
||||
json.encode = function(value, space, replacer, whitelist)
|
||||
{
|
||||
return JSON.stringify(value, space, replacer);
|
||||
}
|
||||
|
||||
json.decode = function(text, reviver)
|
||||
{
|
||||
return JSON.parse(text,reviver);
|
||||
}
|
||||
|
||||
Object.methods = function(o)
|
||||
{
|
||||
var m = [];
|
||||
|
@ -31,6 +42,7 @@ Object.methods = function(o)
|
|||
});
|
||||
return m;
|
||||
}
|
||||
Object.methods.doc = "Retun an array of all functions an object has access to.";
|
||||
|
||||
Object.dig = function(obj, path, def)
|
||||
{
|
||||
|
@ -43,6 +55,17 @@ Object.dig = function(obj, path, def)
|
|||
return def;
|
||||
}
|
||||
|
||||
Object.samenewkeys = function(a,b)
|
||||
{
|
||||
b ??= a.__proto__;
|
||||
var ret = {};
|
||||
ret.same = [];
|
||||
ret.unique = [];
|
||||
Object.keys(a).forEach(key => (key in b) ? ret.same.push(key) : ret.unique.push(key));
|
||||
return ret;
|
||||
}
|
||||
Object.samenewkeys.doc = "Return an object listing which keys are the same and unique on a compared to b.";
|
||||
|
||||
Object.rkeys = function(o)
|
||||
{
|
||||
var keys = [];
|
||||
|
|
202
scripts/color.js
Normal file
202
scripts/color.js
Normal file
|
@ -0,0 +1,202 @@
|
|||
var Color = {
|
||||
white: [255,255,255],
|
||||
black: [0,0,0],
|
||||
blue: [84,110,255],
|
||||
green: [120,255,10],
|
||||
yellow: [251,255,43],
|
||||
red: [255,36,20],
|
||||
teal: [96, 252, 237],
|
||||
gray: [181,181,181],
|
||||
cyan: [0,255,255],
|
||||
purple: [162,93,227],
|
||||
};
|
||||
|
||||
Color.editor = {};
|
||||
Color.editor.ur = Color.green;
|
||||
|
||||
Color.tohtml = function(v)
|
||||
{
|
||||
var html = v.map(function(n) { return Number.hex(n*255); });
|
||||
return "#" + html.join('');
|
||||
}
|
||||
|
||||
Color.toesc = function(v)
|
||||
{
|
||||
return Esc.color(v);
|
||||
}
|
||||
|
||||
var Esc = {};
|
||||
Esc.reset = "\x1b[0";
|
||||
Esc.color = function(v) {
|
||||
var c = v.map(function(n) { return Math.floor(n*255); });
|
||||
var truecolor = "\x1b[38;2;" + c.join(';') + ';';
|
||||
return truecolor;
|
||||
}
|
||||
|
||||
Color.Arkanoid = {
|
||||
orange: [255,143,0],
|
||||
teal: [0,255,255],
|
||||
green: [0,255,0],
|
||||
red: [255,0,0],
|
||||
blue: [0,112,255],
|
||||
purple: [255,0,255],
|
||||
yellow: [255,255,0],
|
||||
silver: [157,157,157],
|
||||
gold: [188,174,0],
|
||||
};
|
||||
|
||||
Color.Arkanoid.Powerups = {
|
||||
red: [174,0,0], /* laser */
|
||||
blue: [0,0,174], /* enlarge */
|
||||
green: [0,174,0], /* catch */
|
||||
orange: [224,143,0], /* slow */
|
||||
purple: [210,0,210], /* break */
|
||||
cyan: [0,174,255], /* disruption */
|
||||
gray: [143,143,143] /* 1up */
|
||||
};
|
||||
|
||||
Color.Gameboy = {
|
||||
darkest: [229,107,26],
|
||||
dark: [229,189,26],
|
||||
light: [189,229,26],
|
||||
lightest: [107,229,26],
|
||||
};
|
||||
|
||||
Color.Apple = {
|
||||
green: [94,189,62],
|
||||
yellow: [255,185,0],
|
||||
orange: [247,130,0],
|
||||
red: [226,56,56],
|
||||
purple: [151,57,153],
|
||||
blue: [0,156,223]
|
||||
};
|
||||
|
||||
Color.Debug = {
|
||||
boundingbox: Color.white,
|
||||
names: [84,110,255],
|
||||
};
|
||||
|
||||
Color.Editor = {
|
||||
grid: [99,255,128],
|
||||
select: [255,255,55],
|
||||
newgroup: [120,255,10],
|
||||
};
|
||||
|
||||
/* Detects the format of all colors and munges them into a floating point format */
|
||||
Color.normalize = function(c) {
|
||||
var add_a = function(a) {
|
||||
var n = this.slice();
|
||||
n.a = a;
|
||||
return n;
|
||||
};
|
||||
|
||||
for (var p of Object.keys(c)) {
|
||||
var fmt = "nrm";
|
||||
if (typeof c[p] !== 'object') continue;
|
||||
if (!Array.isArray(c[p])) {
|
||||
Color.normalize(c[p]);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (var color of c[p]) {
|
||||
if (color > 1) {
|
||||
fmt = "8b";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch(fmt) {
|
||||
case "8b":
|
||||
c[p] = c[p].map(function(x) { return x/255; });
|
||||
}
|
||||
c[p].alpha = add_a;
|
||||
}
|
||||
};
|
||||
|
||||
Color.normalize(Color);
|
||||
|
||||
Object.deepfreeze(Color);
|
||||
|
||||
var ColorMap = {};
|
||||
ColorMap.makemap = function(map)
|
||||
{
|
||||
var newmap = Object.create(ColorMap);
|
||||
Object.assign(newmap, map);
|
||||
return newmap;
|
||||
}
|
||||
ColorMap.Jet = ColorMap.makemap({
|
||||
0: [0,0,131],
|
||||
0.125: [0,60,170],
|
||||
0.375: [5,255,255],
|
||||
0.625: [255,255,0],
|
||||
0.875: [250,0,0],
|
||||
1: [128,0,0]
|
||||
});
|
||||
|
||||
ColorMap.BlueRed = ColorMap.makemap({
|
||||
0: [0,0,255],
|
||||
1: [255,0,0]
|
||||
});
|
||||
|
||||
ColorMap.Inferno = ColorMap.makemap({
|
||||
0:[0,0,4],
|
||||
0.13: [31,12,72],
|
||||
0.25: [85,15,109],
|
||||
0.38: [136,34,106],
|
||||
0.5: [186,54,85],
|
||||
0.63: [227,89,51],
|
||||
0.75: [249,140,10],
|
||||
0.88: [249,201,50],
|
||||
1: [252,255,164]
|
||||
});
|
||||
|
||||
ColorMap.Bathymetry = ColorMap.makemap({
|
||||
0: [40,26,44],
|
||||
0.13: [59.49,90],
|
||||
0.25: [64,76,139],
|
||||
0.38: [63,110,151],
|
||||
0.5: [72,142,158],
|
||||
0.63: [85,174,163],
|
||||
0.75: [120,206,163],
|
||||
0.88: [187,230,172],
|
||||
1: [253,254,204]
|
||||
});
|
||||
|
||||
ColorMap.Viridis = ColorMap.makemap({
|
||||
0: [68,1,84],
|
||||
0.13: [71,44,122],
|
||||
0.25: [59,81,139],
|
||||
0.38: [44,113,142],
|
||||
0.5: [33,144,141],
|
||||
0.63: [39,173,129],
|
||||
0.75: [92,200,99],
|
||||
0.88: [170,220,50],
|
||||
1: [253,231,37]
|
||||
});
|
||||
|
||||
Color.normalize(ColorMap);
|
||||
|
||||
ColorMap.sample = function(t, map)
|
||||
{
|
||||
map ??= this;
|
||||
if (t < 0) return map[0];
|
||||
if (t > 1) return map[1];
|
||||
|
||||
var lastkey = 0;
|
||||
for (var key of Object.keys(map).sort()) {
|
||||
if (t < key) {
|
||||
var b = map[key];
|
||||
var a = map[lastkey];
|
||||
var tt = (key - lastkey) * t;
|
||||
return a.lerp(b, tt);
|
||||
}
|
||||
lastkey = key;
|
||||
}
|
||||
return map[1];
|
||||
}
|
||||
|
||||
ColorMap.doc = {
|
||||
sample: "Sample a given colormap at the given percentage (0 to 1).",
|
||||
};
|
||||
|
||||
Object.freeze(ColorMap);
|
|
@ -85,18 +85,18 @@ var Debug = {
|
|||
|
||||
draw() {
|
||||
if (this.draw_bb)
|
||||
Game.objects.forEach(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 (Game.paused()) GUI.text("PAUSED", [0,0],1);
|
||||
|
||||
if (this.draw_gizmos)
|
||||
Game.objects.forEach(function(x) {
|
||||
Game.all_objects(function(x) {
|
||||
if (!x.icon) return;
|
||||
GUI.image(x.icon, world2screen(x.pos));
|
||||
});
|
||||
|
||||
if (this.draw_names)
|
||||
Game.objects.forEach(function(x) {
|
||||
Game.all_objects(function(x) {
|
||||
GUI.text(x, world2screen(x.pos).add([0,32]), 1, Color.Debug.names);
|
||||
});
|
||||
|
||||
|
|
|
@ -4,23 +4,12 @@
|
|||
*/
|
||||
prototypes.generate_ur('.');
|
||||
|
||||
var editor_config = {
|
||||
var editor = {
|
||||
toString() { return "editor"; },
|
||||
grid_size: 100,
|
||||
ruler_mark_px: 100,
|
||||
grid_color: Color.green.alpha(0.3),
|
||||
|
||||
};
|
||||
|
||||
var configs = {
|
||||
toString() { return "configs"; },
|
||||
editor: editor_config,
|
||||
physics: physics,
|
||||
local: local_conf,
|
||||
collision: Collision,
|
||||
};
|
||||
|
||||
var editor = {
|
||||
toString() { return "editor"; },
|
||||
dbg_ur: "arena.level1",
|
||||
machine: undefined,
|
||||
device_test: undefined,
|
||||
|
@ -34,7 +23,7 @@ var editor = {
|
|||
working_layer: 0,
|
||||
get cursor() {
|
||||
if (this.selectlist.length === 0 ) return Mouse.worldpos;
|
||||
return find_com(this.selectlist);
|
||||
return physics.com(this.selectlist.map(x => x.pos));
|
||||
},
|
||||
edit_mode: "basic",
|
||||
|
||||
|
@ -52,9 +41,9 @@ var editor = {
|
|||
},
|
||||
|
||||
/* Tries to select id */
|
||||
do_select(go) {
|
||||
var obj = (go >= 0 ? Game.object(go) : undefined);
|
||||
if (!obj || !obj._ed.selectable) return undefined;
|
||||
do_select(obj) {
|
||||
if (!obj) return;
|
||||
// if (!obj || !obj._ed.selectable) return undefined;
|
||||
|
||||
if (obj.level !== this.edit_level) {
|
||||
var testlevel = obj.level;
|
||||
|
@ -102,7 +91,7 @@ var editor = {
|
|||
step_amt() { return Keys.shift() ? 10 : 1; },
|
||||
|
||||
on_grid(pos) {
|
||||
return pos.every(function(x) { return x % editor_config.grid_size === 0; });
|
||||
return pos.every(function(x) { return x % editor.grid_size === 0; });
|
||||
},
|
||||
|
||||
snapper(dir, grid) {
|
||||
|
@ -115,7 +104,7 @@ var editor = {
|
|||
key_move(dir) {
|
||||
if (!editor.grabselect) return;
|
||||
if (Keys.ctrl())
|
||||
this.selectlist.forEach(this.snapper(dir.scale(1.01), editor_config.grid_size));
|
||||
this.selectlist.forEach(this.snapper(dir.scale(1.01), editor.grid_size));
|
||||
else
|
||||
this.selectlist.forEach(this.mover(dir.scale(this.step_amt())));
|
||||
},
|
||||
|
@ -234,8 +223,6 @@ var editor = {
|
|||
Register.draw.register(editor.draw, editor);
|
||||
Debug.register_call(editor.ed_debug, editor);
|
||||
Register.update.register(gui_controls.update, gui_controls);
|
||||
// Player.players[0].control(gui_controls);
|
||||
|
||||
this.desktop = Primum.spawn(ur.arena);
|
||||
Primum.rename_obj(this.desktop.toString(), "desktop");
|
||||
this.edit_level = this.desktop;
|
||||
|
@ -313,17 +300,6 @@ var editor = {
|
|||
this.edit_level.check_dirty();
|
||||
},
|
||||
|
||||
diff_lvl(d) {
|
||||
this.unselect();
|
||||
for (var key in d) {
|
||||
if (d[key] === "DELETE")
|
||||
Game.objects[key].kill();
|
||||
}
|
||||
diffassign(Game.objects, d);
|
||||
Game.objects.forEach(function(x) { x.sync(); });
|
||||
this.curlvl = this.edit_level.save();
|
||||
},
|
||||
|
||||
redo() {
|
||||
if (this.backshots.empty) {
|
||||
Log.info("Nothing to redo.");
|
||||
|
@ -336,17 +312,6 @@ var editor = {
|
|||
this.edit_level.load(dd);
|
||||
this.edit_level.check_dirty();
|
||||
this.curlvl = dd;
|
||||
return;
|
||||
|
||||
var dd = this.backshots.pop();
|
||||
this.snapshots.push(dd);
|
||||
if (this.was_undoing) {
|
||||
dd = this.backshots.pop();
|
||||
this.snapshots.push(dd);
|
||||
this.was_undoing = false;
|
||||
}
|
||||
|
||||
this.diff_lvl(dd);
|
||||
},
|
||||
|
||||
undo() {
|
||||
|
@ -359,17 +324,6 @@ var editor = {
|
|||
var dd = this.snapshots.pop();
|
||||
Object.dainty_assign(this.edit_level, dd);
|
||||
this.edit_level._ed.check_dirty();
|
||||
return;
|
||||
|
||||
this.backshots.push(dd);
|
||||
|
||||
if (!this.was_undoing) {
|
||||
dd = this.snapshots.pop();
|
||||
this.backshots.push(dd);
|
||||
this.was_undoing = true;
|
||||
}
|
||||
|
||||
this.diff_lvl(dd);
|
||||
},
|
||||
|
||||
restore_buffer() {
|
||||
|
@ -511,7 +465,7 @@ var editor = {
|
|||
GUI.text(p, world2screen(x[1].worldpos().add([0,16])),1,editor.color_depths[depth]);
|
||||
});
|
||||
|
||||
var mg = Game.obj_at(Mouse.worldpos);
|
||||
var mg = physics.pos_query(Mouse.worldpos);
|
||||
|
||||
if (mg) {
|
||||
var p = mg.path_from(thiso);
|
||||
|
@ -536,15 +490,15 @@ var editor = {
|
|||
GUI.image("icons/icons8-lock-16.png", world2screen(obj.worldpos()));
|
||||
});
|
||||
|
||||
Debug.draw_grid(1, editor_config.grid_size, Color.Editor.grid.alpha(0.3));
|
||||
var startgrid = screen2world([-20,0]).map(function(x) { return Math.snap(x, editor_config.grid_size); });
|
||||
Debug.draw_grid(1, editor.grid_size, Color.Editor.grid.alpha(0.3));
|
||||
var startgrid = screen2world([-20,0]).map(function(x) { return Math.snap(x, editor.grid_size); });
|
||||
var endgrid = screen2world([Window.width, Window.height]);
|
||||
|
||||
var w_step = Math.round(editor_config.ruler_mark_px/Window.width * (endgrid.x-startgrid.x)/editor_config.grid_size)*editor_config.grid_size;
|
||||
if (w_step === 0) w_step = editor_config.grid_size;
|
||||
var w_step = Math.round(editor.ruler_mark_px/Window.width * (endgrid.x-startgrid.x)/editor.grid_size)*editor.grid_size;
|
||||
if (w_step === 0) w_step = editor.grid_size;
|
||||
|
||||
var h_step = Math.round(editor_config.ruler_mark_px/Window.height * (endgrid.y-startgrid.y)/editor_config.grid_size)*editor_config.grid_size;
|
||||
if (h_step === 0) h_step = editor_config.grid_size;
|
||||
var h_step = Math.round(editor.ruler_mark_px/Window.height * (endgrid.y-startgrid.y)/editor.grid_size)*editor.grid_size;
|
||||
if (h_step === 0) h_step = editor.grid_size;
|
||||
|
||||
while(startgrid[0] <= endgrid[0]) {
|
||||
GUI.text(startgrid[0], [world2screen([startgrid[0], 0])[0],0]);
|
||||
|
@ -620,25 +574,6 @@ var editor = {
|
|||
this.unselect();
|
||||
},
|
||||
|
||||
groupsaveas(group, file) {
|
||||
if (!file) return;
|
||||
|
||||
file = file+".lvl";
|
||||
if (IO.exists(file)) {
|
||||
this.openpanel(gen_notify("Level already exists with that name. Overwrite?", dosave.bind(this,file)));
|
||||
return;
|
||||
} else
|
||||
dosave(file);
|
||||
|
||||
function dosave(file) {
|
||||
var com = find_com(group);
|
||||
Level.saveas(group, file);
|
||||
editor.addlevel(file, com);
|
||||
|
||||
group.forEach(function(x) { x.kill(); });
|
||||
}
|
||||
},
|
||||
|
||||
/* Checking to save an entity as a subtype. */
|
||||
/* sub is the name of the (sub)type; obj is the object to save it as */
|
||||
saveas_check(sub, obj) {
|
||||
|
@ -924,7 +859,8 @@ editor.inputs['C-s'] = function() {
|
|||
|
||||
Object.values(saveobj.objects).forEach(function(x) { x._ed.check_dirty(); });
|
||||
|
||||
Game.objects.forEach(function(x) {
|
||||
|
||||
Game.all_objects(function(x) {
|
||||
if (typeof x !== 'object') return;
|
||||
if (!('_ed' in x)) return;
|
||||
if (x._ed.dirty) return;
|
||||
|
@ -1141,7 +1077,7 @@ editor.inputs['C-mm'] = editor.inputs.mm;
|
|||
|
||||
editor.inputs['C-M-lm'] = function()
|
||||
{
|
||||
var go = Game.obj_at(Mouse.worldpos);
|
||||
var go = physics.pos_query(Mouse.worldpos);
|
||||
if (!go) return;
|
||||
editor.edit_level = go.level;
|
||||
}
|
||||
|
@ -1312,20 +1248,20 @@ editor.inputs['M-g'] = function()
|
|||
editor.inputs['M-g'].doc = "Move all.";
|
||||
|
||||
editor.inputs['C-lb'] = function() {
|
||||
editor_config.grid_size -= Keys.shift() ? 10 : 1;
|
||||
if (editor_config.grid_size <= 0) editor_config.grid_size = 1;
|
||||
editor.grid_size -= Keys.shift() ? 10 : 1;
|
||||
if (editor.grid_size <= 0) editor.grid_size = 1;
|
||||
};
|
||||
editor.inputs['C-lb'].doc = "Decrease grid size. Hold shift to decrease it more.";
|
||||
editor.inputs['C-lb'].rep = true;
|
||||
|
||||
editor.inputs['C-rb'] = function() { editor_config.grid_size += Keys.shift() ? 10 : 1; };
|
||||
editor.inputs['C-rb'] = function() { editor.grid_size += Keys.shift() ? 10 : 1; };
|
||||
editor.inputs['C-rb'].doc = "Increase grid size. Hold shift to increase it more.";
|
||||
editor.inputs['C-rb'].rep = true;
|
||||
|
||||
editor.inputs['C-c'] = function() {
|
||||
this.killring = [];
|
||||
this.killcom = [];
|
||||
this.killcom = find_com(this.selectlist);
|
||||
this.killcom = physics.com(this.selectlist.map(x=>x.pos));
|
||||
|
||||
this.selectlist.forEach(function(x) {
|
||||
this.killring.push(x.make_ur());
|
||||
|
@ -1590,7 +1526,7 @@ replpanel.inputs = Object.create(inputpanel.inputs);
|
|||
replpanel.inputs.block = true;
|
||||
replpanel.inputs.lm = function()
|
||||
{
|
||||
var mg = Game.obj_at(Mouse.worldpos);
|
||||
var mg = physics.pos_query(Mouse.worldpos);
|
||||
if (!mg) return;
|
||||
var p = mg.path_from(editor.get_this());
|
||||
this.value = p;
|
||||
|
@ -1833,7 +1769,7 @@ var objectexplorer = Object.copy(inputpanel, {
|
|||
// this.obj[key] = this.obj[key];
|
||||
});
|
||||
|
||||
// Game.objects.forEach(function(x) { x.sync(); });
|
||||
// Game.all_objects(function(x) { x.sync(); });
|
||||
return items;
|
||||
},
|
||||
|
||||
|
|
|
@ -28,208 +28,7 @@ function run_env(file, env)
|
|||
load("scripts/diff.js");
|
||||
Log.level = 1;
|
||||
|
||||
var Color = {
|
||||
white: [255,255,255],
|
||||
black: [0,0,0],
|
||||
blue: [84,110,255],
|
||||
green: [120,255,10],
|
||||
yellow: [251,255,43],
|
||||
red: [255,36,20],
|
||||
teal: [96, 252, 237],
|
||||
gray: [181,181,181],
|
||||
cyan: [0,255,255],
|
||||
purple: [162,93,227],
|
||||
};
|
||||
|
||||
Color.editor = {};
|
||||
Color.editor.ur = Color.green;
|
||||
|
||||
Color.tohtml = function(v)
|
||||
{
|
||||
var html = v.map(function(n) { return Number.hex(n*255); });
|
||||
return "#" + html.join('');
|
||||
}
|
||||
|
||||
Color.toesc = function(v)
|
||||
{
|
||||
return Esc.color(v);
|
||||
}
|
||||
|
||||
var Esc = {};
|
||||
Esc.reset = "\x1b[0";
|
||||
Esc.color = function(v) {
|
||||
var c = v.map(function(n) { return Math.floor(n*255); });
|
||||
var truecolor = "\x1b[38;2;" + c.join(';') + ';';
|
||||
return truecolor;
|
||||
}
|
||||
|
||||
Color.Arkanoid = {
|
||||
orange: [255,143,0],
|
||||
teal: [0,255,255],
|
||||
green: [0,255,0],
|
||||
red: [255,0,0],
|
||||
blue: [0,112,255],
|
||||
purple: [255,0,255],
|
||||
yellow: [255,255,0],
|
||||
silver: [157,157,157],
|
||||
gold: [188,174,0],
|
||||
};
|
||||
|
||||
Color.Arkanoid.Powerups = {
|
||||
red: [174,0,0], /* laser */
|
||||
blue: [0,0,174], /* enlarge */
|
||||
green: [0,174,0], /* catch */
|
||||
orange: [224,143,0], /* slow */
|
||||
purple: [210,0,210], /* break */
|
||||
cyan: [0,174,255], /* disruption */
|
||||
gray: [143,143,143] /* 1up */
|
||||
};
|
||||
|
||||
Color.Gameboy = {
|
||||
darkest: [229,107,26],
|
||||
dark: [229,189,26],
|
||||
light: [189,229,26],
|
||||
lightest: [107,229,26],
|
||||
};
|
||||
|
||||
Color.Apple = {
|
||||
green: [94,189,62],
|
||||
yellow: [255,185,0],
|
||||
orange: [247,130,0],
|
||||
red: [226,56,56],
|
||||
purple: [151,57,153],
|
||||
blue: [0,156,223]
|
||||
};
|
||||
|
||||
Color.Debug = {
|
||||
boundingbox: Color.white,
|
||||
names: [84,110,255],
|
||||
};
|
||||
|
||||
Color.Editor = {
|
||||
grid: [99,255,128],
|
||||
select: [255,255,55],
|
||||
newgroup: [120,255,10],
|
||||
};
|
||||
|
||||
/* Detects the format of all colors and munges them into a floating point format */
|
||||
Color.normalize = function(c) {
|
||||
var add_a = function(a) {
|
||||
var n = this.slice();
|
||||
n.a = a;
|
||||
return n;
|
||||
};
|
||||
|
||||
for (var p of Object.keys(c)) {
|
||||
var fmt = "nrm";
|
||||
if (typeof c[p] !== 'object') continue;
|
||||
if (!Array.isArray(c[p])) {
|
||||
Color.normalize(c[p]);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (var color of c[p]) {
|
||||
if (color > 1) {
|
||||
fmt = "8b";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch(fmt) {
|
||||
case "8b":
|
||||
c[p] = c[p].map(function(x) { return x/255; });
|
||||
}
|
||||
c[p].alpha = add_a;
|
||||
}
|
||||
};
|
||||
|
||||
Color.normalize(Color);
|
||||
|
||||
Object.deepfreeze(Color);
|
||||
|
||||
var ColorMap = {};
|
||||
ColorMap.makemap = function(map)
|
||||
{
|
||||
var newmap = Object.create(ColorMap);
|
||||
Object.assign(newmap, map);
|
||||
return newmap;
|
||||
}
|
||||
ColorMap.Jet = ColorMap.makemap({
|
||||
0: [0,0,131],
|
||||
0.125: [0,60,170],
|
||||
0.375: [5,255,255],
|
||||
0.625: [255,255,0],
|
||||
0.875: [250,0,0],
|
||||
1: [128,0,0]
|
||||
});
|
||||
|
||||
ColorMap.BlueRed = ColorMap.makemap({
|
||||
0: [0,0,255],
|
||||
1: [255,0,0]
|
||||
});
|
||||
|
||||
ColorMap.Inferno = ColorMap.makemap({
|
||||
0:[0,0,4],
|
||||
0.13: [31,12,72],
|
||||
0.25: [85,15,109],
|
||||
0.38: [136,34,106],
|
||||
0.5: [186,54,85],
|
||||
0.63: [227,89,51],
|
||||
0.75: [249,140,10],
|
||||
0.88: [249,201,50],
|
||||
1: [252,255,164]
|
||||
});
|
||||
|
||||
ColorMap.Bathymetry = ColorMap.makemap({
|
||||
0: [40,26,44],
|
||||
0.13: [59.49,90],
|
||||
0.25: [64,76,139],
|
||||
0.38: [63,110,151],
|
||||
0.5: [72,142,158],
|
||||
0.63: [85,174,163],
|
||||
0.75: [120,206,163],
|
||||
0.88: [187,230,172],
|
||||
1: [253,254,204]
|
||||
});
|
||||
|
||||
ColorMap.Viridis = ColorMap.makemap({
|
||||
0: [68,1,84],
|
||||
0.13: [71,44,122],
|
||||
0.25: [59,81,139],
|
||||
0.38: [44,113,142],
|
||||
0.5: [33,144,141],
|
||||
0.63: [39,173,129],
|
||||
0.75: [92,200,99],
|
||||
0.88: [170,220,50],
|
||||
1: [253,231,37]
|
||||
});
|
||||
|
||||
Color.normalize(ColorMap);
|
||||
|
||||
ColorMap.sample = function(t, map)
|
||||
{
|
||||
map ??= this;
|
||||
if (t < 0) return map[0];
|
||||
if (t > 1) return map[1];
|
||||
|
||||
var lastkey = 0;
|
||||
for (var key of Object.keys(map).sort()) {
|
||||
if (t < key) {
|
||||
var b = map[key];
|
||||
var a = map[lastkey];
|
||||
var tt = (key - lastkey) * t;
|
||||
return a.lerp(b, tt);
|
||||
}
|
||||
lastkey = key;
|
||||
}
|
||||
return map[1];
|
||||
}
|
||||
|
||||
ColorMap.doc = {
|
||||
sample: "Sample a given colormap at the given percentage (0 to 1).",
|
||||
};
|
||||
|
||||
Object.freeze(ColorMap);
|
||||
load("scripts/color.js");
|
||||
|
||||
function bb2wh(bb) {
|
||||
return [bb.r-bb.l, bb.t-bb.b];
|
||||
|
@ -269,7 +68,6 @@ var Device = {
|
|||
gamegear: [160,144,3.2],
|
||||
};
|
||||
|
||||
|
||||
load("scripts/gui.js");
|
||||
|
||||
var ctimer = {
|
||||
|
@ -348,6 +146,7 @@ var timer = {
|
|||
var t = timer.make(fn,secs,desc);
|
||||
t.loop = false;
|
||||
t.restart();
|
||||
return t;
|
||||
t.fn = function() { fn(); t.kill(); };
|
||||
return function() { t.kill(); };
|
||||
},
|
||||
|
@ -378,78 +177,7 @@ timer.doc = {
|
|||
remain: "The time remianing before the function is executed.",
|
||||
};
|
||||
|
||||
var animation = {
|
||||
time: 0,
|
||||
loop: false,
|
||||
playtime: 0,
|
||||
playing: false,
|
||||
keyframes: [],
|
||||
|
||||
create() {
|
||||
var anim = Object.create(animation);
|
||||
Register.update.register(anim.update, anim);
|
||||
return anim;
|
||||
},
|
||||
|
||||
start() {
|
||||
this.playing = true;
|
||||
this.time = this.keyframes.last[1];
|
||||
this.playtime = 0;
|
||||
},
|
||||
|
||||
interval(a, b, t) {
|
||||
return (t - a) / (b - a);
|
||||
},
|
||||
|
||||
near_val(t) {
|
||||
for (var i = 0; i < this.keyframes.length-1; i++) {
|
||||
if (t > this.keyframes[i+1][1]) continue;
|
||||
|
||||
return this.interval(this.keyframes[i][1], this.keyframes[i+1][1], t) >= 0.5 ? this.keyframes[i+1][0] : this.keyframes[i][0];
|
||||
}
|
||||
|
||||
return this.keyframes.last[0];
|
||||
},
|
||||
|
||||
lerp_val(t) {
|
||||
for (var i = 0; i < this.keyframes.length-1; i++) {
|
||||
if (t > this.keyframes[i+1][1]) continue;
|
||||
|
||||
var intv = this.interval(this.keyframes[i][1], this.keyframes[i+1][1], t);
|
||||
return ((1 - intv) * this.keyframes[i][0]) + (intv * this.keyframes[i+1][0]);
|
||||
}
|
||||
|
||||
return this.keyframes.last[0];
|
||||
},
|
||||
|
||||
cubic_val(t) {
|
||||
|
||||
},
|
||||
|
||||
mirror() {
|
||||
if (this.keyframes.length <= 1) return;
|
||||
for (var i = this.keyframes.length-1; i >= 1; i--) {
|
||||
this.keyframes.push(this.keyframes[i-1]);
|
||||
this.keyframes.last[1] = this.keyframes[i][1] + (this.keyframes[i][1] - this.keyframes[i-1][1]);
|
||||
}
|
||||
},
|
||||
|
||||
update(dt) {
|
||||
if (!this.playing) return;
|
||||
|
||||
this.playtime += dt;
|
||||
if (this.playtime >= this.time) {
|
||||
if (this.loop)
|
||||
this.playtime = 0;
|
||||
else {
|
||||
this.playing = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.fn(this.lerp_val(this.playtime));
|
||||
},
|
||||
};
|
||||
load("scripts/animation.js");
|
||||
|
||||
var Render = {
|
||||
normal() {
|
||||
|
@ -717,24 +445,6 @@ Spline.type = {
|
|||
|
||||
load("scripts/components.js");
|
||||
|
||||
function find_com(objects)
|
||||
{
|
||||
if (!objects || objects.length === 0)
|
||||
return [0,0];
|
||||
var com = [0,0];
|
||||
com[0] = objects.reduce(function(acc, val) {
|
||||
return acc + val.pos[0];
|
||||
}, 0);
|
||||
com[0] /= objects.length;
|
||||
|
||||
com[1] = objects.reduce(function(acc, val) {
|
||||
return acc + val.pos[1];
|
||||
}, 0);
|
||||
com[1] /= objects.length;
|
||||
|
||||
return com;
|
||||
};
|
||||
|
||||
var Game = {
|
||||
init() {
|
||||
if (!Game.edit) {
|
||||
|
@ -747,29 +457,13 @@ var Game = {
|
|||
editor.enter_editor();
|
||||
}
|
||||
},
|
||||
objects: [],
|
||||
|
||||
native: Device.pc,
|
||||
|
||||
edit: true,
|
||||
register_obj(obj) {
|
||||
this.objects[obj.body] = obj;
|
||||
},
|
||||
|
||||
unregister_obj(obj) {
|
||||
if (this.objects[obj.body] === obj)
|
||||
this.objects[obj.body] = undefined;
|
||||
},
|
||||
|
||||
obj_at(worldpos) {
|
||||
var idx = physics.pos_query(worldpos);
|
||||
if (idx === -1) return undefined;
|
||||
return Game.objects[idx];
|
||||
},
|
||||
|
||||
/* Returns an object given an id */
|
||||
object(id) {
|
||||
return this.objects[id];
|
||||
all_objects(fn) {
|
||||
/* Wind down from Primum */
|
||||
},
|
||||
|
||||
/* Returns a list of objects by name */
|
||||
|
@ -787,35 +481,6 @@ var Game = {
|
|||
|
||||
},
|
||||
|
||||
groupify(objects, spec) {
|
||||
var newgroup = {
|
||||
locked: true,
|
||||
breakable: true,
|
||||
objs: objects,
|
||||
// get pos() { return find_com(objects); },
|
||||
// set pos(x) { this.objs.forEach(function(obj) { obj.pos = x; }) },
|
||||
};
|
||||
|
||||
Object.assign(newgroup, spec);
|
||||
objects.forEach(function(x) {
|
||||
x.defn('group', newgroup);
|
||||
});
|
||||
|
||||
var bb = bb_from_objects(newgroup.objs);
|
||||
newgroup.startbb = bb2cwh(bb);
|
||||
newgroup.bboffset = newgroup.startbb.c.sub(newgroup.objs[0].pos);
|
||||
|
||||
newgroup.boundingbox = function() {
|
||||
newgroup.startbb.c = newgroup.objs[0].pos.add(newgroup.bboffset);
|
||||
return cwh2bb(newgroup.startbb.c, newgroup.startbb.wh);
|
||||
};
|
||||
|
||||
if (newgroup.file)
|
||||
newgroup.color = Color.Editor.newgroup;
|
||||
|
||||
return newgroup;
|
||||
},
|
||||
|
||||
quit()
|
||||
{
|
||||
sys_cmd(0);
|
||||
|
@ -890,81 +555,21 @@ Register.update.register(Game.exec, Game);
|
|||
|
||||
load("scripts/entity.js");
|
||||
|
||||
|
||||
function world_start() {
|
||||
globalThis.preprimum = Object.create(gameobject);
|
||||
var preprimum = globalThis.preprimum;
|
||||
preprimum.objects = {};
|
||||
preprimum.worldpos = function() { return [0,0]; };
|
||||
preprimum.worldangle = function() { return 0; };
|
||||
preprimum.scale = [1,1,1];
|
||||
preprimum.gscale = function() { return [1,1,1]; };
|
||||
preprimum.pos = [0,0];
|
||||
preprimum.angle = 0;
|
||||
preprimum.remove_obj = function() {};
|
||||
preprimum.toString = function() { return "preprimum"; };
|
||||
globalThis.World = preprimum.make(preprimum);
|
||||
globalThis.Primum = World;
|
||||
var Primum = globalThis.Primum;
|
||||
Primum.level = undefined;
|
||||
globalThis.Primum = Object.create(gameobject);
|
||||
Primum.objects = {};
|
||||
Primum._ed = {
|
||||
selectable:false,
|
||||
check_dirty() {},
|
||||
dirty:false,
|
||||
namestr(){},
|
||||
};
|
||||
Primum.toString = function() { return "Primum"; };
|
||||
Primum._ed.selectable = false;
|
||||
Primum._ed.check_dirty = function() { };
|
||||
Primum._ed.dirty = false;
|
||||
Primum.revert = function(){};
|
||||
Primum.ur = undefined;
|
||||
globalThis.World.reparent = function(parent) { Log.warn("Cannot reparent the Primum."); }
|
||||
Game.view_camera(Primum.spawn(ur.camera2d));
|
||||
}
|
||||
|
||||
/* Load configs */
|
||||
function load_configs(file) {
|
||||
Log.info(`Loading config file ${file}.`);
|
||||
var configs = JSON.parse(IO.slurp(file));
|
||||
for (var key in configs) {
|
||||
if (typeof globalThis[key] !== "object") continue;
|
||||
Object.assign(globalThis[key], configs[key]);
|
||||
}
|
||||
|
||||
Collision.sync();
|
||||
Game.objects.forEach(function(x) { x.sync(); });
|
||||
|
||||
if (!local_conf.mouse) {
|
||||
Log.info("disabling mouse features");
|
||||
Mouse.disabled = function() {};
|
||||
Mouse.hidden = function() {};
|
||||
};
|
||||
};
|
||||
|
||||
var local_conf = {
|
||||
mouse: true,
|
||||
};
|
||||
|
||||
if (IO.exists("game.config"))
|
||||
load_configs("game.config");
|
||||
|
||||
/* Save configs */
|
||||
function save_configs() {
|
||||
Log.info("saving configs");
|
||||
var configs = {};
|
||||
configs.editor_config = editor_config;
|
||||
configs.Nuke = Nuke;
|
||||
configs.local_conf = local_conf;
|
||||
IO.slurpwrite(JSON.stringify(configs, null, 1), "editor.config");
|
||||
|
||||
save_game_configs();
|
||||
};
|
||||
|
||||
function save_game_configs() {
|
||||
var configs = {};
|
||||
configs.physics = physics;
|
||||
configs.Collision = Collision;
|
||||
Log.info(configs);
|
||||
IO.slurpwrite(JSON.stringify(configs,null,1), "game.config");
|
||||
|
||||
Collision.sync();
|
||||
Game.objects.forEach(function(x) { x.sync(); });
|
||||
};
|
||||
|
||||
load("scripts/physics.js");
|
||||
|
||||
Game.view_camera = function(cam)
|
||||
|
|
|
@ -11,19 +11,34 @@ function grab_from_points(pos, points, slop) {
|
|||
};
|
||||
|
||||
var actor = {};
|
||||
actor.spawn = function(ur, config){};
|
||||
actor.die = function(actor){};
|
||||
actor.kill = function(actor){};
|
||||
actor.delay = function(fn, seconds) {};
|
||||
actor.spawn = function(script, config){
|
||||
if (typeof script !== 'string') return;
|
||||
var padawan = Object.create(actor);
|
||||
compile_env(script, padawan, "script");
|
||||
|
||||
if (typeof config === 'object')
|
||||
Object.merge(padawan, config);
|
||||
|
||||
return padawan;
|
||||
};
|
||||
actor.die = function(actor){
|
||||
|
||||
};
|
||||
actor.kill = function(actor){
|
||||
this.timers.forEach(t => t());
|
||||
this.timers = undefined;
|
||||
};
|
||||
actor.delay = function(fn, seconds) {
|
||||
var t = timer.delay(fn.bind(this), seconds, true);
|
||||
this.timers.push(t);
|
||||
return function() { t.kill(); };
|
||||
};
|
||||
actor.clock = function(fn){};
|
||||
|
||||
var Empyrean = Object.create(actor);
|
||||
|
||||
var gameobject = {
|
||||
impl: {
|
||||
full_path() {
|
||||
return this.path_from(Primum);
|
||||
},
|
||||
full_path() {
|
||||
return this.path_from(Primum);
|
||||
},
|
||||
|
||||
path_from(o) {
|
||||
var p = this.toString();
|
||||
|
@ -46,8 +61,9 @@ var gameobject = {
|
|||
|
||||
delay(fn, seconds) {
|
||||
var t = timer.delay(fn.bind(this), seconds, false);
|
||||
this.timers.push(t);
|
||||
return t;
|
||||
var killfn = function() { t.kill(); };
|
||||
this.timers.push(killfn);
|
||||
return killfn;
|
||||
},
|
||||
|
||||
tween(prop, values, def){
|
||||
|
@ -98,7 +114,10 @@ var gameobject = {
|
|||
},
|
||||
|
||||
set pos(x) {
|
||||
this.set_worldpos(this.level.this2world(x));
|
||||
if (!this.level)
|
||||
this.set_worldpos(x);
|
||||
else
|
||||
this.set_worldpos(this.level.this2world(x));
|
||||
},
|
||||
|
||||
get pos() {
|
||||
|
@ -133,7 +152,7 @@ var gameobject = {
|
|||
get phys() { return q_body(0,this.body); },
|
||||
get velocity() { return q_body(3, this.body); },
|
||||
set velocity(x) { set_body(9, this.body, x); },
|
||||
// get damping() { return cmd(157,this.body); },
|
||||
get damping() { return cmd(157,this.body); },
|
||||
set_damping(x) { cmd(156, this.body, x); },
|
||||
get angularvelocity() { return Math.rad2deg(q_body(4, this.body)); },
|
||||
set angularvelocity(x) { set_body(8, this.body, Math.deg2rad(x)); },
|
||||
|
@ -155,7 +174,6 @@ var gameobject = {
|
|||
var thatpos = this.pos;
|
||||
this.objects.forEach(function(x) {
|
||||
x.rotate(diff);
|
||||
// x.angle = x.angle + diff;
|
||||
var opos = x.pos;
|
||||
var r = Vector.length(opos);
|
||||
var p = Math.rad2deg(Math.atan2(opos.y, opos.x));
|
||||
|
@ -164,7 +182,10 @@ var gameobject = {
|
|||
x.pos = [r*Math.cos(p), r*Math.sin(p)];
|
||||
});
|
||||
|
||||
set_body(0,this.body, Math.deg2rad(x - this.level.worldangle()));
|
||||
if (this.level)
|
||||
set_body(0,this.body, Math.deg2rad(x - this.level.worldangle()));
|
||||
else
|
||||
set_body(0,this.body,x);
|
||||
},
|
||||
|
||||
rotate(x) {
|
||||
|
@ -223,9 +244,6 @@ var gameobject = {
|
|||
delete this[obj.toString()];
|
||||
},
|
||||
|
||||
|
||||
},
|
||||
|
||||
components: {},
|
||||
objects: {},
|
||||
level: undefined,
|
||||
|
@ -242,7 +260,6 @@ var gameobject = {
|
|||
pulse(vec) { set_body(4, this.body, vec);},
|
||||
shove(vec) { set_body(12,this.body,vec);},
|
||||
shove_at(vec, at) { set_body(14,this.body,vec,at); },
|
||||
// torque(val) { cmd(153, this.body, val); },
|
||||
world2this(pos) { return cmd(70, this.body, pos); },
|
||||
this2world(pos) { return cmd(71, this.body,pos); },
|
||||
dir_world2this(dir) { return cmd(160, this.body, dir); },
|
||||
|
@ -281,6 +298,10 @@ var gameobject = {
|
|||
|
||||
/* Make a unique object the same as its prototype */
|
||||
revert() {
|
||||
// var keys = Object.samenewkeys(this, this.__proto__);
|
||||
// keys.unique.forEach(x => delete this[x]);
|
||||
// keys.same.forEach(x => this[x] = this.__proto__[x]);
|
||||
|
||||
var jobj = this.json_obj();
|
||||
var lobj = this.level.__proto__.objects[this.toString()];
|
||||
delete jobj.objects;
|
||||
|
@ -328,39 +349,22 @@ var gameobject = {
|
|||
register_collide(1, x.collide, x, obj.body, x.shape);
|
||||
});
|
||||
},
|
||||
pos: [0,0],
|
||||
angle:0,
|
||||
velocity:[0,0],
|
||||
angularvelocity:0,
|
||||
phys:Physics.static,
|
||||
|
||||
flipx() { return this.scale.x < 0; },
|
||||
flipy() { return this.scale.y < 0; },
|
||||
timescale: 1,
|
||||
scale:[1,1],
|
||||
mirror(plane) {
|
||||
this.scale = Vector.reflect(this.scale, plane);
|
||||
},
|
||||
elasticity:0.5,
|
||||
friction:1,
|
||||
gravity: true,
|
||||
max_velocity: Infinity,
|
||||
max_angularvelocity: Infinity,
|
||||
mass:1,
|
||||
layer:0,
|
||||
draw_layer:0,
|
||||
worldpos() { return [0,0]; },
|
||||
|
||||
save:true,
|
||||
selectable:true,
|
||||
ed_locked:false,
|
||||
|
||||
|
||||
disable() { this.components.forEach(function(x) { x.disable(); });},
|
||||
enable() { this.components.forEach(function(x) { x.enable(); });},
|
||||
sync() {
|
||||
this.components.forEach(function(x) { x.sync(); });
|
||||
this.objects.forEach(function(x) { x.sync(); });
|
||||
},
|
||||
disable() { this.components.forEach(function(x) { x.disable(); });},
|
||||
enable() { this.components.forEach(function(x) { x.enable(); });},
|
||||
sync() {
|
||||
this.components.forEach(function(x) { x.sync(); });
|
||||
this.objects.forEach(function(x) { x.sync(); });
|
||||
},
|
||||
|
||||
/* Bounding box of the object in world dimensions */
|
||||
boundingbox() {
|
||||
|
@ -416,10 +420,6 @@ var gameobject = {
|
|||
return d;
|
||||
},
|
||||
|
||||
full_obj() {
|
||||
|
||||
},
|
||||
|
||||
transform_obj() {
|
||||
var t = this.json_obj();
|
||||
Object.assign(t, this.transform());
|
||||
|
@ -468,56 +468,42 @@ var gameobject = {
|
|||
return n;
|
||||
},
|
||||
|
||||
kill() {
|
||||
if (this.body === -1) {
|
||||
// Log.warn(`Object is already dead!`);
|
||||
return;
|
||||
}
|
||||
kill() {
|
||||
this.timers.forEach(t => t());
|
||||
|
||||
if (this.level) {
|
||||
this.level.remove_obj(this);
|
||||
this.level = undefined;
|
||||
}
|
||||
|
||||
// Register.endofloop(() => {
|
||||
// cmd(2, this.body);
|
||||
q_body(8,this.body);
|
||||
Game.unregister_obj(this);
|
||||
Player.do_uncontrol(this);
|
||||
Register.unregister_obj(this);
|
||||
|
||||
this.timers.forEach(t => t());
|
||||
if (this.__proto__.instances)
|
||||
this.__proto__.instances.remove(this);
|
||||
|
||||
if (this.level) {
|
||||
this.level.remove_obj(this);
|
||||
this.level = undefined;
|
||||
}
|
||||
for (var key in this.components) {
|
||||
Register.unregister_obj(this.components[key]);
|
||||
Log.info(`Destroying component ${key}`);
|
||||
this.components[key].kill();
|
||||
this.components.gameobject = undefined;
|
||||
}
|
||||
|
||||
Player.do_uncontrol(this);
|
||||
Register.unregister_obj(this);
|
||||
delete this.components;
|
||||
|
||||
if (this.__proto__.instances)
|
||||
this.__proto__.instances.remove(this);
|
||||
this.clear();
|
||||
|
||||
this.body = -1;
|
||||
if (typeof this.stop === 'function')
|
||||
this.stop();
|
||||
},
|
||||
|
||||
for (var key in this.components) {
|
||||
Register.unregister_obj(this.components[key]);
|
||||
Log.info(`Destroying component ${key}`);
|
||||
this.components[key].kill();
|
||||
this.components.gameobject = undefined;
|
||||
}
|
||||
delete this.components;
|
||||
|
||||
this.clear();
|
||||
|
||||
if (typeof this.stop === 'function')
|
||||
this.stop();
|
||||
// });
|
||||
|
||||
},
|
||||
|
||||
up() { return [0,1].rotate(Math.deg2rad(this.angle));},
|
||||
down() { return [0,-1].rotate(Math.deg2rad(this.angle));},
|
||||
right() { return [1,0].rotate(Math.deg2rad(this.angle));},
|
||||
left() { return [-1,0].rotate(Math.deg2rad(this.angle));},
|
||||
up() { return [0,1].rotate(Math.deg2rad(this.angle));},
|
||||
down() { return [0,-1].rotate(Math.deg2rad(this.angle));},
|
||||
right() { return [1,0].rotate(Math.deg2rad(this.angle));},
|
||||
left() { return [-1,0].rotate(Math.deg2rad(this.angle));},
|
||||
|
||||
make(level, data) {
|
||||
level ??= Primum;
|
||||
// level ??= Primum;
|
||||
var obj = Object.create(this);
|
||||
obj.make = undefined;
|
||||
obj.level = level;
|
||||
|
@ -525,10 +511,10 @@ var gameobject = {
|
|||
this.instances.push(obj);
|
||||
|
||||
obj.body = make_gameobject();
|
||||
|
||||
obj.components = {};
|
||||
obj.objects = {};
|
||||
obj.timers = [];
|
||||
assign_impl(obj, gameobject.impl);
|
||||
obj._ed = {
|
||||
selectable: true,
|
||||
check_dirty() {
|
||||
|
@ -547,7 +533,6 @@ var gameobject = {
|
|||
|
||||
dirty: false,
|
||||
inst: false,
|
||||
model: Object.create(this),
|
||||
urdiff: {},
|
||||
namestr() {
|
||||
var s = obj.toString();
|
||||
|
@ -558,9 +543,8 @@ var gameobject = {
|
|||
return s;
|
||||
},
|
||||
};
|
||||
obj.ur = this.toString();
|
||||
|
||||
Game.register_obj(obj);
|
||||
obj.ur = this.toString();
|
||||
|
||||
cmd(113, obj.body, obj); // set the internal obj reference to this obj
|
||||
|
||||
|
@ -579,7 +563,7 @@ var gameobject = {
|
|||
obj.level = undefined;
|
||||
obj.reparent(level);
|
||||
|
||||
Object.hide(obj, 'ur','body', 'components', 'objects', '_ed', 'level', 'timers', 'timescale');
|
||||
Object.hide(obj, 'ur','body', 'components', 'objects', '_ed', 'level', 'timers');
|
||||
|
||||
Object.dainty_assign(obj, this);
|
||||
obj.sync();
|
||||
|
@ -596,6 +580,7 @@ var gameobject = {
|
|||
|
||||
make_objs(objs) {
|
||||
for (var prop in objs) {
|
||||
Log.warn(prop);
|
||||
var newobj = this.spawn_from_instance(objs[prop]);
|
||||
if (!newobj) continue;
|
||||
this.rename_obj(newobj.toString(), prop);
|
||||
|
@ -624,7 +609,8 @@ var gameobject = {
|
|||
},
|
||||
|
||||
add_component(comp) {
|
||||
if (typeof comp['comp'] !== 'string') return;
|
||||
if (typeof comp.make !== 'function') return;
|
||||
return {comp:comp.toString()};
|
||||
},
|
||||
|
||||
register_hit(fn, obj) {
|
||||
|
@ -642,7 +628,11 @@ var gameobject = {
|
|||
},
|
||||
}
|
||||
|
||||
gameobject.impl.spawn.doc = `Spawn an entity of type 'ur' on this entity. Returns the spawned entity.`;
|
||||
gameobject.body = make_gameobject();
|
||||
cmd(113,gameobject.body, gameobject);
|
||||
Object.hide(gameobject, 'timescale');
|
||||
|
||||
gameobject.spawn.doc = `Spawn an entity of type 'ur' on this entity. Returns the spawned entity.`;
|
||||
|
||||
gameobject.doc = {
|
||||
doc: "All objects in the game created through spawning have these attributes.",
|
||||
|
|
189
scripts/gui.js
189
scripts/gui.js
|
@ -283,192 +283,3 @@ Mum.debug_colors = {
|
|||
};
|
||||
|
||||
Object.values(Mum.debug_colors).forEach(function(v) { v.a = 100; });
|
||||
|
||||
/* Take numbers from 0 to 1 and remap them to easing functions */
|
||||
var Ease = {
|
||||
linear(t) { return t; },
|
||||
|
||||
in(t) { return t*t; },
|
||||
|
||||
out(t) {
|
||||
var d = 1-t;
|
||||
return 1 - d*d
|
||||
},
|
||||
|
||||
inout(t) {
|
||||
var d = -2*t + 2;
|
||||
return t < 0.5 ? 2 * t * t : 1 - (d * d) / 2;
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
function make_easing_fns(num) {
|
||||
var obj = {};
|
||||
|
||||
obj.in = function(t) {
|
||||
return Math.pow(t,num);
|
||||
};
|
||||
|
||||
obj.out = function(t) {
|
||||
return 1 - Math.pow(1 - t, num);
|
||||
};
|
||||
|
||||
var mult = Math.pow(2, num-1);
|
||||
|
||||
obj.inout = function(t) {
|
||||
return t < 0.5 ? mult * Math.pow(t, num) : 1 - Math.pow(-2 * t + 2, num) / 2;
|
||||
};
|
||||
|
||||
return obj;
|
||||
};
|
||||
|
||||
Ease.quad = make_easing_fns(2);
|
||||
Ease.cubic = make_easing_fns(3);
|
||||
Ease.quart = make_easing_fns(4);
|
||||
Ease.quint = make_easing_fns(5);
|
||||
|
||||
Ease.expo = {
|
||||
in(t) {
|
||||
return t === 0 ? 0 : Math.pow(2, 10 * t - 10);
|
||||
},
|
||||
|
||||
out(t) {
|
||||
return t === 1 ? 1 : 1 - Math.pow(2, -10 * 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;
|
||||
}
|
||||
};
|
||||
|
||||
Ease.bounce = {
|
||||
in(t) {
|
||||
return 1 - this.out(t - 1);
|
||||
},
|
||||
|
||||
out(t) {
|
||||
var n1 = 7.5625;
|
||||
var d1 = 2.75;
|
||||
|
||||
if (t < 1 / d1) { return n1 * t * t; }
|
||||
else if (t < 2 / d1) { return n1 * (t -= 1.5 / d1) * t + 0.75; }
|
||||
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) {
|
||||
return t < 0.5 ? (1 - this.out(1 - 2 * t)) / 2 : (1 + this.out(2 * t - 1)) / 2;
|
||||
}
|
||||
};
|
||||
|
||||
Ease.sine = {
|
||||
in(t) { return 1 - Math.cos((t * Math.PI)/2); },
|
||||
|
||||
out(t) { return Math.sin((t*Math.PI)/2); },
|
||||
|
||||
inout(t) { return -(Math.cos(Math.PI*t) - 1) / 2; }
|
||||
};
|
||||
|
||||
Ease.elastic = {
|
||||
in(t) {
|
||||
return t === 0 ? 0 : t === 1 ? 1 : -Math.pow(2, 10*t-10) * Math.sin((t * 10 - 10.75) * this.c4);
|
||||
},
|
||||
|
||||
out(t) {
|
||||
return t === 0 ? 0 : t === 1 ? 1 : Math.pow(2, -10*t) * Math.sin((t * 10 - 0.75) * this.c4) + 1;
|
||||
},
|
||||
|
||||
inout(t) {
|
||||
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;
|
||||
},
|
||||
};
|
||||
|
||||
Ease.elastic.c4 = 2*Math.PI/3;
|
||||
Ease.elastic.c5 = 2*Math.PI / 4.5;
|
||||
|
||||
var Tween = {
|
||||
default: {
|
||||
loop: "restart",
|
||||
/*
|
||||
loop types
|
||||
none: when done, return to first value
|
||||
hold: hold last value of tween
|
||||
restart: restart at beginning, looping
|
||||
yoyo: go up and then back down
|
||||
circle: go up and back down, looped
|
||||
*/
|
||||
time: 1, /* seconds to do */
|
||||
ease: Ease.linear,
|
||||
whole: true, /* True if time is for the entire tween, false if each stage */
|
||||
cb: function(){},
|
||||
},
|
||||
|
||||
start(obj, target, tvals, options)
|
||||
{
|
||||
var defn = Object.create(this.default);
|
||||
Object.assign(defn, options);
|
||||
|
||||
if (defn.loop === 'circle')
|
||||
tvals.push(tvals[0]);
|
||||
else if (defn.loop === 'yoyo') {
|
||||
for (var i = tvals.length-2; i >= 0; i--)
|
||||
tvals.push(tvals[i]);
|
||||
}
|
||||
|
||||
defn.accum = 0;
|
||||
|
||||
var slices = tvals.length - 1;
|
||||
var slicelen = 1 / slices;
|
||||
|
||||
defn.fn = function(dt) {
|
||||
defn.accum += dt;
|
||||
if (defn.accum >= defn.time && defn.loop === 'hold') {
|
||||
obj[target] = tvals[tvals.length-1];
|
||||
defn.pause();
|
||||
defn.cb.call(obj);
|
||||
return;
|
||||
}
|
||||
|
||||
defn.pct = (defn.accum % defn.time) / defn.time;
|
||||
if (defn.loop === 'none' && defn.accum >= defn.time)
|
||||
defn.stop();
|
||||
|
||||
var t = defn.whole ? defn.ease(defn.pct) : defn.pct;
|
||||
|
||||
var nval = t / slicelen;
|
||||
var i = Math.trunc(nval);
|
||||
nval -= i;
|
||||
|
||||
if (!defn.whole)
|
||||
nval = defn.ease(nval);
|
||||
|
||||
obj[target] = tvals[i].lerp(tvals[i+1], nval);
|
||||
};
|
||||
|
||||
var playing = false;
|
||||
|
||||
defn.play = function() {
|
||||
if (playing) return;
|
||||
Register.update.register(defn.fn, defn);
|
||||
playing = true;
|
||||
};
|
||||
defn.restart = function() {
|
||||
defn.accum = 0;
|
||||
obj[target] = tvals[0];
|
||||
};
|
||||
defn.stop = function() { if (!playing) return; defn.pause(); defn.restart(); };
|
||||
defn.pause = function() {
|
||||
Register.update.unregister(defn.fn);
|
||||
if (!playing) return;
|
||||
|
||||
playing = false;
|
||||
};
|
||||
|
||||
return defn;
|
||||
},
|
||||
};
|
||||
|
||||
Tween.make = Tween.start;
|
||||
|
|
|
@ -27,7 +27,6 @@ var physics = {
|
|||
|
||||
/* Returns a list of body ids that a box collides with */
|
||||
box_query(box) {
|
||||
var pts = cmd(52,box.pos,box.wh);
|
||||
return cmd(52, box.pos, box.wh);
|
||||
},
|
||||
|
||||
|
@ -41,6 +40,18 @@ var physics = {
|
|||
shape_query(shape) {
|
||||
return cmd(80,shape);
|
||||
},
|
||||
|
||||
com(pos) {
|
||||
if (!Array.isArray(pos)) return;
|
||||
var com = [];
|
||||
for (var i = 0; i < pos[0].length; i++) {
|
||||
com[i] = pos.reduce(function(acc,val) {
|
||||
return acc + val[i];
|
||||
});
|
||||
com[i] /= pos.length;
|
||||
}
|
||||
return com;
|
||||
},
|
||||
};
|
||||
|
||||
physics.doc = {};
|
||||
|
|
|
@ -233,6 +233,7 @@ int pos2gameobject(HMM_Vec2 pos) {
|
|||
|
||||
if (dist <= 25) return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -373,11 +374,11 @@ int MakeGameobject() {
|
|||
.cgravity = (HMM_Vec2){0,0},
|
||||
.damping = NAN,
|
||||
.timescale = 1.0,
|
||||
.ref = JS_NULL,
|
||||
.ref = JS_UNDEFINED,
|
||||
};
|
||||
|
||||
go.cbs.begin.obj = JS_NULL;
|
||||
go.cbs.separate.obj = JS_NULL;
|
||||
go.cbs.begin.obj = JS_UNDEFINED;
|
||||
go.cbs.separate.obj = JS_UNDEFINED;
|
||||
|
||||
go.body = cpSpaceAddBody(space, cpBodyNew(go.mass, 1.f));
|
||||
cpBodySetVelocityUpdateFunc(go.body, velocityFn);
|
||||
|
@ -432,6 +433,13 @@ void gameobject_delete(int id) {
|
|||
gameobject_clean(id);
|
||||
}
|
||||
|
||||
void gameobject_free(int id)
|
||||
{
|
||||
YughWarn("FREED A GAMEOBJECT!!!");
|
||||
if (id >= 0)
|
||||
gameobject_delete(id);
|
||||
}
|
||||
|
||||
void gameobjects_cleanup() {
|
||||
for (int i = 0; i < arrlen(go_toclean); i++)
|
||||
gameobject_clean(go_toclean[i]);
|
||||
|
|
|
@ -69,6 +69,7 @@ extern struct gameobject *gameobjects;
|
|||
int MakeGameobject();
|
||||
void gameobject_apply(struct gameobject *go);
|
||||
void gameobject_delete(int id);
|
||||
void gameobject_free(int id);
|
||||
void gameobjects_cleanup();
|
||||
|
||||
void gameobject_set_sensor(int id, int sensor);
|
||||
|
|
|
@ -73,7 +73,7 @@ JSValue input2js(int state)
|
|||
case 3: return jstr("pressrep");
|
||||
case 4: return jstr("down");
|
||||
}
|
||||
return JS_NULL;
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
void input_mouse(int btn, int state, uint32_t mod)
|
||||
|
|
|
@ -36,7 +36,6 @@ static JSValue globalThis;
|
|||
static JSClassID js_ptr_id;
|
||||
static JSClassDef js_ptr_class = { "POINTER" };
|
||||
|
||||
|
||||
#define QJSCLASS(TYPE)\
|
||||
static JSClassID js_ ## TYPE ## _id;\
|
||||
static void js_##TYPE##_finalizer(JSRuntime *rt, JSValue val){\
|
||||
|
@ -44,22 +43,25 @@ TYPE *n = JS_GetOpaque(val, js_##TYPE##_id);\
|
|||
TYPE##_free(n);}\
|
||||
static JSClassDef js_##TYPE##_class = {\
|
||||
#TYPE,\
|
||||
.finalizer = js_##TYPE##_finalizer\
|
||||
.finalizer = js_##TYPE##_finalizer,\
|
||||
};\
|
||||
static TYPE *js2##TYPE (JSValue val) { return JS_GetOpaque(val,js_##TYPE##_id); }\
|
||||
static JSValue js_##TYPE##2js(TYPE *n) { \
|
||||
static JSValue TYPE##2js(TYPE *n) { \
|
||||
JSValue j = JS_NewObjectClass(js,js_##TYPE##_id);\
|
||||
JS_SetOpaque(j,n);\
|
||||
return j; }\
|
||||
|
||||
QJSCLASS(dsp_node)
|
||||
|
||||
// gamobject2js, js2gameobject deals with gameobject*
|
||||
// go2js,js2go deals with gameobject ids
|
||||
|
||||
QJSCLASS(gameobject)
|
||||
|
||||
#define QJSCLASSPREP(TYPE) \
|
||||
JS_NewClassID(&js_##TYPE##_id);\
|
||||
JS_NewClass(JS_GetRuntime(js), js_##TYPE##_id, &js_##TYPE##_class);\
|
||||
|
||||
//QJSCLASS(sprite)
|
||||
|
||||
#define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c"
|
||||
#define BYTE_TO_BINARY(byte) \
|
||||
(byte & 0x80 ? '1' : '0'), \
|
||||
|
@ -81,6 +83,21 @@ void js_setprop_num(JSValue obj, uint32_t i, JSValue v)
|
|||
JS_SetPropertyUint32(js, obj, i, v);
|
||||
}
|
||||
|
||||
JSValue go2ref(int id)
|
||||
{
|
||||
if (id == -1) return JS_UNDEFINED;
|
||||
return JS_DupValue(js,id2go(id)->ref);
|
||||
}
|
||||
|
||||
JSValue gos2ref(int *go)
|
||||
{
|
||||
JSValue array = JS_NewArray(js);
|
||||
for (int i = 0; i < arrlen(go); i++)
|
||||
js_setprop_num(array,i,go2ref(go[i]));
|
||||
return array;
|
||||
}
|
||||
|
||||
|
||||
JSValue js_getpropstr(JSValue v, const char *str)
|
||||
{
|
||||
JSValue p = JS_GetPropertyStr(js,v,str);
|
||||
|
@ -155,9 +172,11 @@ JSValue num2js(double g) {
|
|||
}
|
||||
|
||||
struct gameobject *js2go(JSValue v) {
|
||||
return id2go(js2int(v));
|
||||
return id2go(js2gameobject(v));
|
||||
}
|
||||
|
||||
static int jsgo2id(JSValue v) { return go2id(js2go(v)); }
|
||||
|
||||
struct sprite *js2sprite(JSValue v) { return id2sprite(js2int(v)); }
|
||||
|
||||
void *js2ptr(JSValue v) {
|
||||
|
@ -343,7 +362,7 @@ JSValue duk_gui_img(JSContext *js, JSValueConst this, int argc, JSValueConst *ar
|
|||
const char *img = JS_ToCString(js, argv[0]);
|
||||
gui_draw_img(img, js2vec2(argv[1]), js2vec2(argv[2]), js2number(argv[3]), js2bool(argv[4]), js2vec2(argv[5]), 1.0, js2color(argv[6]));
|
||||
JS_FreeCString(js, img);
|
||||
return JS_NULL;
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
struct rect js2rect(JSValue v) {
|
||||
|
@ -375,7 +394,6 @@ JSValue bb2js(struct boundingbox bb)
|
|||
return obj;
|
||||
}
|
||||
|
||||
|
||||
JSValue duk_spline_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) {
|
||||
// static_assert(sizeof(tsReal) * 2 == sizeof(HMM_Vec2));
|
||||
|
||||
|
@ -501,7 +519,7 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
|
|||
const char *str2 = NULL;
|
||||
const void *d1 = NULL;
|
||||
const void *d2 = NULL;
|
||||
JSValue ret = JS_NULL;
|
||||
JSValue ret = JS_UNDEFINED;
|
||||
|
||||
switch (cmd) {
|
||||
case 0:
|
||||
|
@ -700,7 +718,7 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
|
|||
break;
|
||||
|
||||
case 44:
|
||||
ret = JS_NewInt64(js, pos2gameobject(js2vec2(argv[1])));
|
||||
ret = go2ref(pos2gameobject(js2vec2(argv[1])));
|
||||
break;
|
||||
|
||||
case 45:
|
||||
|
@ -732,7 +750,7 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
|
|||
break;
|
||||
|
||||
case 52:
|
||||
ret = ints2js(phys2d_query_box(js2vec2(argv[1]), js2vec2(argv[2])));
|
||||
ret = gos2ref(phys2d_query_box(js2vec2(argv[1]), js2vec2(argv[2])));
|
||||
break;
|
||||
|
||||
case 53:
|
||||
|
@ -803,7 +821,7 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
|
|||
break;
|
||||
|
||||
case 69:
|
||||
gameobject_set_sensor(js2int(argv[1]), JS_ToBool(js, argv[2]));
|
||||
gameobject_set_sensor(js2go(argv[1]), JS_ToBool(js, argv[2]));
|
||||
break;
|
||||
|
||||
case 70:
|
||||
|
@ -846,7 +864,7 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
|
|||
break;
|
||||
|
||||
case 80:
|
||||
ret = ints2js(phys2d_query_shape(js2ptr(argv[1])));
|
||||
ret = gos2ref(phys2d_query_shape(js2ptr(argv[1])));
|
||||
break;
|
||||
|
||||
case 81:
|
||||
|
@ -854,7 +872,7 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
|
|||
break;
|
||||
|
||||
case 82:
|
||||
gameobject_draw_debug(js2int(argv[1]));
|
||||
gameobject_draw_debug(js2go(argv[1]));
|
||||
break;
|
||||
|
||||
case 83:
|
||||
|
@ -870,7 +888,7 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
|
|||
break;
|
||||
|
||||
case 86:
|
||||
ret = ints2js(phys2d_query_box_points(js2vec2(argv[1]), js2vec2(argv[2]), js2cpvec2arr(argv[3]), js2int(argv[4])));
|
||||
ret = gos2ref(phys2d_query_box_points(js2vec2(argv[1]), js2vec2(argv[2]), js2cpvec2arr(argv[3]), js2int(argv[4])));
|
||||
break;
|
||||
|
||||
case 87:
|
||||
|
@ -985,7 +1003,7 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
|
|||
break;
|
||||
|
||||
case 113:
|
||||
js2go(argv[1])->ref = JS_DupValue(js,argv[2]);
|
||||
js2go(argv[1])->ref = argv[2];//JS_DupValue(js,argv[2]);
|
||||
break;
|
||||
|
||||
case 114:
|
||||
|
@ -1222,115 +1240,110 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
|
|||
str = js2str(argv[1]);
|
||||
ds_openvideo(str);
|
||||
break;
|
||||
|
||||
case 175:
|
||||
ret = num2js(((dsp_node*)js2ptr(argv[1]))->gain);
|
||||
ret = num2js((js2dsp_node(argv[1]))->gain);
|
||||
break;
|
||||
case 176:
|
||||
((dsp_node*)js2ptr(argv[1]))->gain = js2number(argv[2]);
|
||||
js2dsp_node(argv[1])->gain = js2number(argv[2]);
|
||||
break;
|
||||
case 177:
|
||||
plugin_node(js2ptr(argv[1]), js2ptr(argv[2]));
|
||||
break;
|
||||
case 178:
|
||||
ret = num2js(((dsp_node*)js2ptr(argv[1]))->pan);
|
||||
ret = num2js(js2dsp_node(argv[1])->pan);
|
||||
break;
|
||||
case 179:
|
||||
((dsp_node*)js2ptr(argv[1]))->pan=js2number(argv[2]);
|
||||
js2dsp_node(argv[1])->pan=js2number(argv[2]);
|
||||
break;
|
||||
case 180:
|
||||
ret = ptr2js(masterbus);
|
||||
ret = dsp_node2js(masterbus);
|
||||
break;
|
||||
case 181:
|
||||
ret = ptr2js(make_node(NULL,NULL,NULL));
|
||||
ret = dsp_node2js(make_node(NULL,NULL,NULL));
|
||||
break;
|
||||
case 182:
|
||||
str = js2str(argv[1]);
|
||||
ret = ptr2js(dsp_source(str));
|
||||
((sound*)((dsp_node*)js2ptr(ret))->data)->hook = JS_DupValue(js,argv[2]);
|
||||
((sound*)js2dsp_node(ret)->data)->hook = JS_DupValue(js,argv[2]);
|
||||
break;
|
||||
case 183:
|
||||
((dsp_node*)js2ptr(argv[1]))->off = js2bool(argv[2]);
|
||||
js2dsp_node(argv[1])->off = js2bool(argv[2]);
|
||||
break;
|
||||
case 184:
|
||||
((dsp_node*)js2ptr(argv[1]))->pass = js2bool(argv[2]);
|
||||
js2dsp_node(argv[1])->pass = js2bool(argv[2]);
|
||||
break;
|
||||
case 185:
|
||||
ret = ptr2js(dsp_delay(js2number(argv[1]), js2number(argv[2])));
|
||||
ret = dsp_node2js(dsp_delay(js2number(argv[1]), js2number(argv[2])));
|
||||
break;
|
||||
case 186:
|
||||
ret = ptr2js(dsp_lpf(js2number(argv[1])));
|
||||
ret = dsp_node2js(dsp_lpf(js2number(argv[1])));
|
||||
break;
|
||||
case 187:
|
||||
ret = ptr2js(dsp_hpf(js2number(argv[1])));
|
||||
ret = dsp_node2js(dsp_hpf(js2number(argv[1])));
|
||||
break;
|
||||
case 188:
|
||||
str = js2str(argv[1]);
|
||||
ret = ptr2js(dsp_mod(str));
|
||||
ret = dsp_node2js(dsp_mod(str));
|
||||
break;
|
||||
case 189:
|
||||
ret = ptr2js(dsp_bitcrush(js2number(argv[1]), js2number(argv[2])));
|
||||
ret = dsp_node2js(dsp_bitcrush(js2number(argv[1]), js2number(argv[2])));
|
||||
break;
|
||||
case 190:
|
||||
ret = ptr2js(dsp_compressor());
|
||||
ret = dsp_node2js(dsp_compressor());
|
||||
break;
|
||||
case 191:
|
||||
ret = ptr2js(dsp_limiter(js2number(argv[1])));
|
||||
ret = dsp_node2js(dsp_limiter(js2number(argv[1])));
|
||||
break;
|
||||
case 192:
|
||||
ret = ptr2js(dsp_noise_gate(js2number(argv[1])));
|
||||
ret = dsp_node2js(dsp_noise_gate(js2number(argv[1])));
|
||||
break;
|
||||
case 193:
|
||||
node_free(js2ptr(argv[1]));
|
||||
// node_free(js2ptr(argv[1]));
|
||||
break;
|
||||
case 194:
|
||||
ret = bool2js(((sound*)((dsp_node*)js2ptr(argv[1]))->data)->loop);
|
||||
ret = bool2js(((sound*)js2dsp_node(argv[1])->data)->loop);
|
||||
break;
|
||||
case 195:
|
||||
((sound*)((dsp_node*)js2ptr(argv[1]))->data)->loop = js2bool(argv[2]);
|
||||
((sound*)js2dsp_node(argv[1])->data)->loop = js2bool(argv[2]);
|
||||
break;
|
||||
case 196:
|
||||
ret = num2js(((sound*)((dsp_node*)js2ptr(argv[1]))->data)->frame);
|
||||
ret = num2js(((sound*)js2dsp_node(argv[1])->data)->frame);
|
||||
break;
|
||||
case 197:
|
||||
ret = num2js(((sound*)((dsp_node*)js2ptr(argv[1]))->data)->data->frames);
|
||||
ret = num2js(((sound*)js2dsp_node(argv[1])->data)->data->frames);
|
||||
break;
|
||||
case 198:
|
||||
ret = num2js(SAMPLERATE);
|
||||
break;
|
||||
case 199:
|
||||
((sound*)((dsp_node*)js2ptr(argv[1]))->data)->frame = js2number(argv[2]);
|
||||
((sound*)js2dsp_node(argv[1])->data)->frame = js2number(argv[2]);
|
||||
break;
|
||||
case 200:
|
||||
ret = ptr2js(dsp_pitchshift(js2number(argv[1])));
|
||||
ret = dsp_node2js(dsp_pitchshift(js2number(argv[1])));
|
||||
break;
|
||||
case 201:
|
||||
ret = num2js(((sound*)((dsp_node*)js2ptr(argv[1]))->data)->timescale);
|
||||
ret = num2js(((sound*)js2dsp_node(argv[1])->data)->timescale);
|
||||
break;
|
||||
case 202:
|
||||
YughWarn("%g", js2number(argv[2]));
|
||||
((sound*)((dsp_node*)js2ptr(argv[1]))->data)->timescale = js2number(argv[2]);
|
||||
((sound*)js2dsp_node(argv[1])->data)->timescale = js2number(argv[2]);
|
||||
break;
|
||||
case 203:
|
||||
ret = ptr2js(dsp_whitenoise());
|
||||
ret = dsp_node2js(dsp_whitenoise());
|
||||
break;
|
||||
case 204:
|
||||
ret = ptr2js(dsp_pinknoise());
|
||||
ret = dsp_node2js(dsp_pinknoise());
|
||||
break;
|
||||
case 205:
|
||||
ret = ptr2js(dsp_rednoise());
|
||||
ret = dsp_node2js(dsp_rednoise());
|
||||
break;
|
||||
case 206:
|
||||
str = js2str(argv[1]);
|
||||
str2 = js2str(argv[2]);
|
||||
ret = ptr2js(dsp_midi(str, make_soundfont(str2)));
|
||||
ret = dsp_node2js(dsp_midi(str, make_soundfont(str2)));
|
||||
break;
|
||||
case 207:
|
||||
ret = ptr2js(dsp_fwd_delay(js2number(argv[1]), js2number(argv[2])));
|
||||
break;
|
||||
case 208:
|
||||
ret = JS_NewObjectClass(js, js_dsp_node_id);
|
||||
JS_SetOpaque(ret, dsp_mixer_node());
|
||||
ret = dsp_node2js(dsp_fwd_delay(js2number(argv[1]), js2number(argv[2])));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1347,7 +1360,7 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
|
|||
return ret;
|
||||
}
|
||||
|
||||
return JS_NULL;
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
JSValue duk_register(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) {
|
||||
|
@ -1402,7 +1415,7 @@ JSValue duk_register(JSContext *js, JSValueConst this, int argc, JSValueConst *a
|
|||
break;
|
||||
}
|
||||
|
||||
return JS_NULL;
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
void gameobject_add_shape_collider(int go, struct callee c, struct phys2d_shape *shape) {
|
||||
|
@ -1414,7 +1427,7 @@ void gameobject_add_shape_collider(int go, struct callee c, struct phys2d_shape
|
|||
|
||||
JSValue duk_register_collide(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) {
|
||||
int cmd = js2int(argv[0]);
|
||||
int go = js2int(argv[3]);
|
||||
int go = jsgo2id(argv[3]);
|
||||
struct callee c;
|
||||
c.fn = argv[1];
|
||||
c.obj = argv[2];
|
||||
|
@ -1437,7 +1450,7 @@ JSValue duk_register_collide(JSContext *js, JSValueConst this, int argc, JSValue
|
|||
break;
|
||||
}
|
||||
|
||||
return JS_NULL;
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
JSValue duk_sys_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) {
|
||||
|
@ -1486,11 +1499,11 @@ JSValue duk_sys_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *ar
|
|||
break;
|
||||
}
|
||||
|
||||
return JS_NULL;
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
JSValue duk_make_gameobject(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) {
|
||||
return JS_NewInt64(js, MakeGameobject());
|
||||
return gameobject2js(MakeGameobject());
|
||||
}
|
||||
|
||||
JSValue duk_yughlog(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) {
|
||||
|
@ -1504,15 +1517,14 @@ JSValue duk_yughlog(JSContext *js, JSValueConst this, int argc, JSValueConst *ar
|
|||
JS_FreeCString(js, s);
|
||||
JS_FreeCString(js, f);
|
||||
|
||||
return JS_NULL;
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
JSValue duk_set_body(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) {
|
||||
int cmd = js2int(argv[0]);
|
||||
int id = js2int(argv[1]);
|
||||
struct gameobject *go = get_gameobject_from_id(id);
|
||||
struct gameobject *go = js2go(argv[1]);
|
||||
|
||||
if (!go) return JS_NULL;
|
||||
if (!go) return JS_UNDEFINED;
|
||||
|
||||
/* TODO: Possible that reindexing shapes only needs done for static shapes? */
|
||||
switch (cmd) {
|
||||
|
@ -1536,7 +1548,7 @@ JSValue duk_set_body(JSContext *js, JSValueConst this, int argc, JSValueConst *a
|
|||
|
||||
case 4:
|
||||
cpBodyApplyImpulseAtWorldPoint(go->body, js2vec2(argv[2]).cp, cpBodyGetPosition(go->body));
|
||||
return JS_NULL;
|
||||
return JS_UNDEFINED;
|
||||
|
||||
case 5:
|
||||
// go->flipx = JS_ToBool(js, argv[2]);
|
||||
|
@ -1554,11 +1566,11 @@ JSValue duk_set_body(JSContext *js, JSValueConst this, int argc, JSValueConst *a
|
|||
|
||||
case 8:
|
||||
cpBodySetAngularVelocity(go->body, js2number(argv[2]));
|
||||
return JS_NULL;
|
||||
return JS_UNDEFINED;
|
||||
|
||||
case 9:
|
||||
cpBodySetVelocity(go->body, js2vec2(argv[2]).cp);
|
||||
return JS_NULL;
|
||||
return JS_UNDEFINED;
|
||||
|
||||
case 10:
|
||||
go->e = fmax(js2number(argv[2]), 0);
|
||||
|
@ -1570,27 +1582,26 @@ JSValue duk_set_body(JSContext *js, JSValueConst this, int argc, JSValueConst *a
|
|||
|
||||
case 12:
|
||||
cpBodyApplyForceAtWorldPoint(go->body, js2vec2(argv[2]).cp, cpBodyGetPosition(go->body));
|
||||
return JS_NULL;
|
||||
return JS_UNDEFINED;
|
||||
|
||||
case 13:
|
||||
cpBodySetMoment(go->body, js2number(argv[2]));
|
||||
return JS_NULL;
|
||||
return JS_UNDEFINED;
|
||||
case 14:
|
||||
cpBodyApplyForceAtLocalPoint(go->body, js2vec2(argv[2]).cp, js2vec2(argv[3]).cp);
|
||||
return JS_NULL;
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
cpSpaceReindexShapesForBody(space, go->body);
|
||||
|
||||
return JS_NULL;
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
JSValue duk_q_body(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) {
|
||||
int q = js2int(argv[0]);
|
||||
int goid = js2int(argv[1]);
|
||||
struct gameobject *go = get_gameobject_from_id(goid);
|
||||
struct gameobject *go = js2go(argv[1]);
|
||||
|
||||
if (!go) return JS_NULL;
|
||||
if (!go) return JS_UNDEFINED;
|
||||
|
||||
switch (q) {
|
||||
case 0:
|
||||
|
@ -1618,16 +1629,16 @@ JSValue duk_q_body(JSContext *js, JSValueConst this, int argc, JSValueConst *arg
|
|||
return JS_NewBool(js, phys2d_in_air(go->body));
|
||||
|
||||
case 8:
|
||||
gameobject_delete(goid);
|
||||
// gameobject_delete(goid);
|
||||
break;
|
||||
}
|
||||
|
||||
return JS_NULL;
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
JSValue duk_make_sprite(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) {
|
||||
JSValue sprite = JS_NewObject(js);
|
||||
js_setprop_str(sprite,"id",JS_NewInt64(js, make_sprite(js2int(argv[0]))));
|
||||
js_setprop_str(sprite,"id",JS_NewInt64(js, make_sprite(jsgo2id(argv[0]))));
|
||||
return sprite;
|
||||
}
|
||||
|
||||
|
@ -1645,7 +1656,7 @@ JSValue duk_make_anim2d(JSContext *js, JSValueConst this, int argc, JSValueConst
|
|||
}
|
||||
|
||||
JSValue duk_make_box2d(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) {
|
||||
int go = js2int(argv[0]);
|
||||
int go = jsgo2id(argv[0]);
|
||||
HMM_Vec2 size = js2vec2(argv[1]);
|
||||
|
||||
struct phys2d_box *box = Make2DBox(go);
|
||||
|
@ -1666,7 +1677,7 @@ JSValue duk_cmd_box2d(JSContext *js, JSValueConst this, int argc, JSValueConst *
|
|||
struct phys2d_box *box = js2ptr(argv[1]);
|
||||
HMM_Vec2 arg;
|
||||
|
||||
if (!box) return JS_NULL;
|
||||
if (!box) return JS_UNDEFINED;
|
||||
|
||||
switch (cmd) {
|
||||
case 0:
|
||||
|
@ -1685,11 +1696,11 @@ JSValue duk_cmd_box2d(JSContext *js, JSValueConst this, int argc, JSValueConst *
|
|||
}
|
||||
|
||||
phys2d_applybox(box);
|
||||
return JS_NULL;
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
JSValue duk_make_circle2d(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) {
|
||||
int go = js2int(argv[0]);
|
||||
int go = jsgo2id(argv[0]);
|
||||
|
||||
struct phys2d_circle *circle = Make2DCircle(go);
|
||||
|
||||
|
@ -1701,7 +1712,7 @@ JSValue duk_make_circle2d(JSContext *js, JSValueConst this, int argc, JSValueCon
|
|||
|
||||
JSValue duk_make_model(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
|
||||
{
|
||||
int go = js2int(argv[0]);
|
||||
int go = jsgo2id(argv[0]);
|
||||
struct drawmodel *dm = make_drawmodel(go);
|
||||
JSValue ret = JS_NewObject(js);
|
||||
js_setprop_str(ret, "id", ptr2js(dm));
|
||||
|
@ -1712,7 +1723,7 @@ JSValue duk_cmd_circle2d(JSContext *js, JSValueConst this, int argc, JSValueCons
|
|||
int cmd = js2int(argv[0]);
|
||||
struct phys2d_circle *circle = js2ptr(argv[1]);
|
||||
|
||||
if (!circle) return JS_NULL;
|
||||
if (!circle) return JS_UNDEFINED;
|
||||
|
||||
switch (cmd) {
|
||||
case 0:
|
||||
|
@ -1731,11 +1742,11 @@ JSValue duk_cmd_circle2d(JSContext *js, JSValueConst this, int argc, JSValueCons
|
|||
}
|
||||
|
||||
phys2d_applycircle(circle);
|
||||
return JS_NULL;
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
JSValue duk_make_poly2d(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) {
|
||||
int go = js2int(argv[0]);
|
||||
int go = jsgo2id(argv[0]);
|
||||
struct phys2d_poly *poly = Make2DPoly(go);
|
||||
phys2d_poly_setverts(poly, NULL);
|
||||
JSValue polyval = JS_NewObject(js);
|
||||
|
@ -1748,7 +1759,7 @@ JSValue duk_cmd_poly2d(JSContext *js, JSValueConst this, int argc, JSValueConst
|
|||
int cmd = js2int(argv[0]);
|
||||
struct phys2d_poly *poly = js2ptr(argv[1]);
|
||||
|
||||
if (!poly) return JS_NULL;
|
||||
if (!poly) return JS_UNDEFINED;
|
||||
|
||||
switch (cmd) {
|
||||
case 0:
|
||||
|
@ -1756,11 +1767,11 @@ JSValue duk_cmd_poly2d(JSContext *js, JSValueConst this, int argc, JSValueConst
|
|||
break;
|
||||
}
|
||||
|
||||
return JS_NULL;
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
JSValue duk_make_edge2d(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) {
|
||||
int go = js2int(argv[0]);
|
||||
int go = jsgo2id(argv[0]);
|
||||
struct phys2d_edge *edge = Make2DEdge(go);
|
||||
|
||||
int n = js_arrlen(argv[1]);
|
||||
|
@ -1784,7 +1795,7 @@ JSValue duk_cmd_edge2d(JSContext *js, JSValueConst this, int argc, JSValueConst
|
|||
|
||||
if (!edge) {
|
||||
YughError("Attempted to do a cmd on edge %p. Not found.", edge);
|
||||
return JS_NULL;
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
|
@ -1798,7 +1809,7 @@ JSValue duk_cmd_edge2d(JSContext *js, JSValueConst this, int argc, JSValueConst
|
|||
break;
|
||||
}
|
||||
|
||||
return JS_NULL;
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
JSValue duk_inflate_cpv(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) {
|
||||
|
@ -1835,7 +1846,7 @@ JSValue duk_anim(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
|
|||
JS_FreeValue(js,vv);
|
||||
}
|
||||
|
||||
return JS_NULL;
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
JSValue duk_make_timer(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) {
|
||||
|
@ -1843,7 +1854,7 @@ JSValue duk_make_timer(JSContext *js, JSValueConst this, int argc, JSValueConst
|
|||
// struct callee *c = make_callee(argv[0], argv[3]);
|
||||
// int id = timer_make(secs, call_callee, c, 1, js2bool(argv[2]));
|
||||
// return JS_NewInt64(js, id);
|
||||
return JS_NULL;
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
JSValue duk_cmd_points(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
|
||||
|
@ -1862,7 +1873,7 @@ JSValue duk_cmd_points(JSContext *js, JSValueConst this, int argc, JSValueConst
|
|||
break;
|
||||
}
|
||||
|
||||
return JS_NULL;
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
//#include "dlfcn.h"
|
||||
|
@ -1885,7 +1896,7 @@ JSValue duk_cmd_points(JSContext *js, JSValueConst this, int argc, JSValueConst
|
|||
ffi_call(&cif, fn, &rc, values);
|
||||
}
|
||||
|
||||
return JS_NULL;
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
*/
|
||||
#define DUK_FUNC(NAME, ARGS) JS_SetPropertyStr(js, globalThis, #NAME, JS_NewCFunction(js, duk_##NAME, #NAME, ARGS));
|
||||
|
@ -1936,4 +1947,6 @@ void ffi_load() {
|
|||
JS_NewClass(JS_GetRuntime(js), js_ptr_id, &js_ptr_class);
|
||||
|
||||
QJSCLASSPREP(dsp_node);
|
||||
QJSCLASSPREP(gameobject);
|
||||
}
|
||||
|
||||
|
|
|
@ -193,7 +193,7 @@ JSValue script_runfile(const char *file)
|
|||
{
|
||||
size_t len;
|
||||
const char *script = slurp_text(file, &len);
|
||||
if (!script) return JS_NULL;
|
||||
if (!script) return JS_UNDEFINED;
|
||||
|
||||
JSValue obj = JS_Eval(js, script, len, file, JS_EVAL_FLAGS);
|
||||
js_print_exception(obj);
|
||||
|
@ -266,13 +266,13 @@ void out_memusage(const char *file)
|
|||
|
||||
JSValue js_callee_exec(struct callee *c, int argc, JSValue *argv)
|
||||
{
|
||||
if (JS_IsUndefined(c->fn)) return JS_NULL;
|
||||
if (JS_IsUndefined(c->obj)) return JS_NULL;
|
||||
if (JS_IsUndefined(c->fn)) return JS_UNDEFINED;
|
||||
if (JS_IsUndefined(c->obj)) return JS_UNDEFINED;
|
||||
|
||||
JSValue ret = JS_Call(js, c->fn, c->obj, argc, argv);
|
||||
js_print_exception(ret);
|
||||
JS_FreeValue(js, ret);
|
||||
return JS_NULL;
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
void call_callee(struct callee *c) {
|
||||
|
|
|
@ -151,6 +151,7 @@ dsp_node *make_node(void *data, void (*proc)(void *data, soundbyte *out, int sam
|
|||
|
||||
void node_free(dsp_node *node)
|
||||
{
|
||||
YughWarn("FREEING A NODE");
|
||||
unplug_node(node);
|
||||
if (node->data)
|
||||
if (node->data_free) node->data_free(node->data);
|
||||
|
|
|
@ -53,6 +53,7 @@ struct slice9_vert {
|
|||
};
|
||||
|
||||
int make_sprite(int go) {
|
||||
YughWarn("Attaching sprite to gameobject %d", go);
|
||||
struct sprite sprite = {
|
||||
.color = color_white,
|
||||
.emissive = {0,0,0,0},
|
||||
|
|
Loading…
Reference in a new issue