many fixes to editor
This commit is contained in:
parent
32268fc25d
commit
403771d7f8
|
@ -216,6 +216,15 @@ The ur[fn::A German prefix meaning primitive, original, or earliest.] system is
|
|||
|
||||
When prosperon starts, it searches for urs by name. Any file ending in ".jso" or ".json" will be interpereted as an ur, with same named jso and json being applied as (text, config) for an ur. A jso or json alone also constitute an ur.
|
||||
|
||||
An ur can also be defined by a json file. If an ur is found, it takes predecent over auto generated urs. The json of an ur looks like this:
|
||||
|
||||
| field | description |
|
||||
|----|----|
|
||||
| text | Path to a script file, or array of script files, to apply to the object |
|
||||
| data | Path to a json file, or array of json files, to apply to the object |
|
||||
|
||||
Any ur file with this sort of json creates an ur which can be created in the game. A file named "box.ur" will be ingested and be available as "ur.box". When saving differences, it creates a json file with the same name as an ur (in this case, "box.json").
|
||||
|
||||
#+begin_scholium
|
||||
Create an ur from the *hello* files above, and then spawn it.
|
||||
#+begin_src
|
||||
|
@ -225,6 +234,10 @@ Primum.spawn(ur.hello);
|
|||
When creating an actor from source files, all of its setup must take place. In this example, the setup happens during *ur.create*, and spawning is simply a matter of prototyping it.
|
||||
#+end_scholium
|
||||
|
||||
This method allows high composability of game objects.
|
||||
|
||||
If an entity is created without an ur, is ur is defined as its given text and data. It cannot be saved. It must be given a new ur name.
|
||||
|
||||
Each ur has the following fields.
|
||||
|
||||
| field | description |
|
||||
|
|
|
@ -882,6 +882,11 @@ Object.defineProperty(String.prototype, 'uc', { value: function() { return this.
|
|||
Object.defineProperty(String.prototype, 'lc', {value:function() { return this.toLowerCase(); }});
|
||||
|
||||
/* ARRAY DEFS */
|
||||
Object.defineProperty(Array.prototype, 'aspect', {
|
||||
value: function() {
|
||||
return this.x/this.y;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(Array.prototype, 'copy', {
|
||||
value: function() {
|
||||
var c = [];
|
||||
|
|
|
@ -1,20 +1,35 @@
|
|||
this.phys = physics.kinematic;
|
||||
this.dir_view2world = function(dir) { return dir.scale(this.zoom); };
|
||||
this.view2world = function(pos) {
|
||||
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.scale(this.zoom);
|
||||
pos = pos.add(this.pos);
|
||||
var useren = window.rendersize.scale(this.zoom);
|
||||
if (window.mode === window.modetypes.stretch) {
|
||||
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.scale(this.zoom);
|
||||
pos = pos.add(this.pos);
|
||||
}
|
||||
if (window.mode === window.modetypes.full) {
|
||||
pos = pos.sub(window.size.scale(0.5));
|
||||
pos = pos.scale(this.zoom);
|
||||
pos = pos.add(this.pos);
|
||||
}
|
||||
return pos;
|
||||
};
|
||||
this.world2view = function(pos) {
|
||||
pos = pos.sub(this.pos);
|
||||
pos = pos.scale(1.0/this.zoom);
|
||||
pos = pos.add(window.rendersize.scale(0.5));
|
||||
if (window.mode === window.modetypes.stretch) {
|
||||
pos = pos.sub(this.pos);
|
||||
pos = pos.scale(1.0/this.zoom);
|
||||
pos = pos.add(window.rendersize.scale(0.5));
|
||||
}
|
||||
if (window.mode === window.modetypes.full) {
|
||||
pos = pos.sub(this.pos);
|
||||
pos = pos.scale(1/this.zoom);
|
||||
pos = pos.add(window.size.scale(0.5));
|
||||
}
|
||||
return pos;
|
||||
};
|
||||
|
||||
this.screenright = function() { return this.view2world(window.size).x; }
|
||||
this.screenleft = function() { return this.pos.x - (window.rendersize.x/2); }
|
||||
this.screenleft = function() { return this.view2world([0,0]).x; }
|
||||
|
||||
this.zoom = 1;
|
||||
|
|
|
@ -425,7 +425,7 @@ component.polygon2d = Object.copy(collider2d, {
|
|||
|
||||
gizmo() {
|
||||
this.spoints().forEach(x => render.point(this.gameobject.this2screen(x), 3, Color.green));
|
||||
this.points.forEach((x,i)=>render.coordinate(this.gameobject.this2screen(x), i));
|
||||
this.points.forEach((x,i)=>render.coordinate(this.gameobject.this2screen(x)));
|
||||
},
|
||||
|
||||
pick(pos) {
|
||||
|
@ -589,11 +589,11 @@ component.edge2d = Object.copy(collider2d, {
|
|||
this.points.forEach((x,i) => render.coordinate(this.gameobject.this2screen(x)));
|
||||
} else {
|
||||
for (var i = 0; i < this.points.length; i += 3)
|
||||
render.coordinate(this.gameobject.this2screen(this.points[i]), i, Color.teal);
|
||||
render.coordinate(this.gameobject.this2screen(this.points[i]), 1, Color.teal);
|
||||
|
||||
for (var i = 1; i < this.points.length; i+=3) {
|
||||
render.coordinate(this.gameobject.this2screen(this.points[i]), i, Color.green);
|
||||
render.coordinate(this.gameobject.this2screen(this.points[i+1]), i+1, Color.green);
|
||||
render.coordinate(this.gameobject.this2screen(this.points[i]), 1, Color.green);
|
||||
render.coordinate(this.gameobject.this2screen(this.points[i+1]), 1, Color.green);
|
||||
render.line([this.gameobject.this2screen(this.points[i-1]), this.gameobject.this2screen(this.points[i])], Color.yellow);
|
||||
render.line([this.gameobject.this2screen(this.points[i+1]), this.gameobject.this2screen(this.points[i+2])], Color.yellow);
|
||||
}
|
||||
|
@ -707,7 +707,6 @@ component.edge2d.impl = Object.mix(collider2d.impl, {
|
|||
var bucket = component.edge2d;
|
||||
bucket.spoints.doc = "Returns the controls points after modifiers are applied, such as it being hollow or mirrored on its axises.";
|
||||
bucket.inputs = {};
|
||||
//bucket.inputs.post = function() { this.sync(); };
|
||||
bucket.inputs.h = function() { this.hollow = !this.hollow; };
|
||||
bucket.inputs.h.doc = "Toggle hollow.";
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ function ediff(from,to)
|
|||
|
||||
var diff = ediff(from[key], to[key]);
|
||||
if (diff && !Object.empty(diff))
|
||||
ret[key] = Object.values(ediff(v,[]));
|
||||
ret[key] = Object.values(ediff(v,[]));
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
selectable
|
||||
*/
|
||||
|
||||
window.mode = window.modetypes.full;
|
||||
game.loadurs();
|
||||
|
||||
console.info(`window size: ${window.size}, render size: ${window.rendersize}`);
|
||||
|
@ -11,6 +10,8 @@ console.info(`window size: ${window.size}, render size: ${window.rendersize}`);
|
|||
player[0].control(debug);
|
||||
Register.gui.register(debug.draw, debug);
|
||||
|
||||
var show_frame = true;
|
||||
|
||||
var editor = {
|
||||
toString() { return "editor"; },
|
||||
grid_size: 100,
|
||||
|
@ -38,8 +39,7 @@ var editor = {
|
|||
return this.do_select(go);
|
||||
},
|
||||
|
||||
/* Tries to select id */
|
||||
do_select(obj) {
|
||||
do_select(obj) { /* select an object, if it is selectable given the current editor state */
|
||||
if (!obj) return;
|
||||
if (!obj._ed.selectable) return undefined;
|
||||
|
||||
|
@ -394,13 +394,16 @@ var editor = {
|
|||
|
||||
gui() {
|
||||
/* Clean out killed objects */
|
||||
if (show_frame)
|
||||
render.line(shape.box(window.rendersize.x, window.rendersize.y).wrapped(1).map(p => game.camera.world2view(p)), Color.yellow);
|
||||
|
||||
render.text([0,0], game.camera.world2view([0,0]));
|
||||
|
||||
render.text("WORKING LAYER: " + this.working_layer, [0,520]);
|
||||
render.text("MODE: " + this.edit_mode, [0,500]);
|
||||
|
||||
if (this.comp_info && this.sel_comp)
|
||||
render.text(Input.print_pawn_kbm(this.sel_comp,false), [100,700],1);
|
||||
render.text(input.print_pawn_kbm(this.sel_comp,false), [100,700],1);
|
||||
|
||||
render.cross(editor.edit_level.screenpos(),3,Color.blue);
|
||||
|
||||
|
@ -530,7 +533,6 @@ var editor = {
|
|||
var obj = editor.edit_level.spawn(mur);
|
||||
obj.set_worldpos(input.mouse.worldpos());
|
||||
this.selectlist = [obj];
|
||||
console.warn(`made something and now the selected objects is ${this.selectlist.length} long.`);
|
||||
},
|
||||
|
||||
load_prev() {
|
||||
|
@ -567,7 +569,7 @@ var editor = {
|
|||
ur[sub] = {
|
||||
name: sub,
|
||||
data: file,
|
||||
proto: json.decode(json.encode(obj))
|
||||
fresh: json.decode(json.encode(obj))
|
||||
}
|
||||
obj.ur = sub;
|
||||
|
||||
|
@ -667,7 +669,8 @@ editor.inputs.f9 = function() { os.capture( "capture.bmp", 0, 0, 500, 500); }
|
|||
|
||||
editor.inputs.release_post = function() {
|
||||
editor.snapshot();
|
||||
editor.edit_level.check_dirty();
|
||||
|
||||
editor.selectlist?.forEach(x => x.check_dirty());
|
||||
|
||||
/* snap all objects to be pixel perfect */
|
||||
game.all_objects(o => o.pos = o.pos.map(x => Math.round(x)), editor.edit_level);
|
||||
|
@ -765,11 +768,11 @@ editor.inputs.m = function() {
|
|||
};
|
||||
editor.inputs.m.doc = "Mirror selected objects on the X axis.";
|
||||
|
||||
|
||||
editor.inputs.q = function() { editor.comp_info = !editor.comp_info; };
|
||||
editor.inputs.q.doc = "Toggle help for the selected component.";
|
||||
|
||||
editor.inputs.f = function() {
|
||||
return;
|
||||
if (editor.selectlist.length === 0) return;
|
||||
var bb = editor.selectlist[0].boundingbox();
|
||||
editor.selectlist.forEach(function(obj) { bb = bbox.expand(bb, obj.boundingbox()); });
|
||||
|
@ -787,6 +790,7 @@ editor.inputs['C-f'] = function() {
|
|||
editor.inputs['C-f'].doc = "Tunnel into the selected level object to edit it.";
|
||||
|
||||
editor.inputs['C-F'] = function() {
|
||||
console.info("PRESSED C-F");
|
||||
if (editor.edit_level.master === world) return;
|
||||
|
||||
editor.edit_level = editor.edit_level.master;
|
||||
|
@ -901,14 +905,13 @@ editor.inputs['C-s'] = function() {
|
|||
if (!tur.data) {
|
||||
io.slurpwrite(tur.text.set_ext(".json"), json.encode(savejs,null,1));
|
||||
tur.data = tur.text.set_ext(".json");
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
var oldjs = json.decode(io.slurp(tur.data));
|
||||
Object.merge(oldjs, savejs);
|
||||
io.slurpwrite(tur.data, json.encode(oldjs,null,1));
|
||||
}
|
||||
|
||||
Object.merge(tur.proto, savejs);
|
||||
Object.merge(tur.fresh, savejs);
|
||||
saveobj.check_dirty();
|
||||
|
||||
// Object.values(saveobj.objects).forEach(function(x) { x.check_dirty(); });
|
||||
|
@ -1484,6 +1487,7 @@ var inputpanel = {
|
|||
};
|
||||
|
||||
inputpanel.inputs = {};
|
||||
inputpanel.inputs.block = true;
|
||||
|
||||
inputpanel.inputs.post = function() { this.keycb(); }
|
||||
|
||||
|
|
|
@ -241,7 +241,7 @@ global.mixin("scripts/render");
|
|||
global.mixin("scripts/debug");
|
||||
|
||||
var frame_t = profile.secs(profile.now());
|
||||
var phys_step = 1/60;
|
||||
var phys_step = 1/240;
|
||||
|
||||
var sim = {};
|
||||
sim.mode = "play";
|
||||
|
@ -280,14 +280,14 @@ function process()
|
|||
prosperon.update(dt*game.timescale);
|
||||
if (sim.mode === "step")
|
||||
sim.pause();
|
||||
}
|
||||
|
||||
physlag += dt;
|
||||
|
||||
while (physlag > phys_step) {
|
||||
physlag -= phys_step;
|
||||
prosperon.phys2d_step(phys_step*game.timescale);
|
||||
prosperon.physupdate(phys_step*game.timescale);
|
||||
|
||||
physlag += dt;
|
||||
|
||||
while (physlag > phys_step) {
|
||||
physlag -= phys_step;
|
||||
prosperon.phys2d_step(phys_step*game.timescale);
|
||||
prosperon.physupdate(phys_step*game.timescale);
|
||||
}
|
||||
}
|
||||
|
||||
if (!game.camera)
|
||||
|
@ -312,15 +312,15 @@ function process()
|
|||
|
||||
game.timescale = 1;
|
||||
|
||||
var eachobj = function(obj,fn)
|
||||
{
|
||||
fn(obj);
|
||||
for (var o in obj.objects)
|
||||
eachobj(obj.objects[o],fn);
|
||||
}
|
||||
|
||||
game.all_objects = function(fn, startobj) {
|
||||
startobj ??= world;
|
||||
var eachobj = function(obj,fn)
|
||||
{
|
||||
fn(obj);
|
||||
for (var o in obj.objects)
|
||||
eachobj(obj.objects[o],fn);
|
||||
}
|
||||
|
||||
eachobj(startobj,fn);
|
||||
};
|
||||
|
||||
|
@ -529,11 +529,13 @@ var Event = {
|
|||
},
|
||||
};
|
||||
|
||||
// window.rendersize is the resolution the game renders at
|
||||
// window.size is the physical size of the window on the desktop
|
||||
window.modetypes = {
|
||||
stretch: 0, // stretch to fill window
|
||||
keep: 1, // keep exact dimensions
|
||||
width: 2, // keep width
|
||||
height: 3, // keep height
|
||||
stretch: 0, // stretch render to fill window
|
||||
keep: 1, // keep render exact dimensions, with no stretching
|
||||
width: 2, // keep render at width
|
||||
height: 3, // keep render at height
|
||||
expand: 4, // expand width or height
|
||||
full: 5 // expand out beyond window
|
||||
};
|
||||
|
@ -546,8 +548,6 @@ global.mixin("scripts/spline");
|
|||
global.mixin("scripts/components");
|
||||
|
||||
window.doc = {};
|
||||
window.doc.width = "Width of the game window.";
|
||||
window.doc.height = "Height of the game window.";
|
||||
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.boundingbox = "Boundingbox of the window, with top and right being its height and width.";
|
||||
|
@ -557,7 +557,6 @@ global.mixin("scripts/entity");
|
|||
|
||||
function world_start() {
|
||||
globalThis.world = os.make_gameobject();
|
||||
world.setref(world);
|
||||
world.objects = {};
|
||||
world.toString = function() { return "world"; };
|
||||
world.ur = "world";
|
||||
|
|
|
@ -10,8 +10,6 @@ function obj_unique_name(name, obj) {
|
|||
return n;
|
||||
}
|
||||
|
||||
var urcache = {};
|
||||
|
||||
var gameobject_impl = {
|
||||
get pos() {
|
||||
assert(this.master, `Entity ${this.toString()} has no master.`);
|
||||
|
@ -74,7 +72,7 @@ var gameobject = {
|
|||
this._ed.urdiff = this.json_obj();
|
||||
this._ed.dirty = !Object.empty(this._ed.urdiff);
|
||||
return; // TODO: IMPLEMENT
|
||||
var lur = ur[this.master.ur];
|
||||
var lur = this.master.ur;
|
||||
if (!lur) return;
|
||||
var lur = lur.objects[this.toString()];
|
||||
var d = ediff(this._ed.urdiff, lur);
|
||||
|
@ -93,8 +91,9 @@ var gameobject = {
|
|||
},
|
||||
|
||||
urstr() {
|
||||
if (this._ed.dirty) return "*" + this.ur;
|
||||
return this.ur;
|
||||
var str = this.ur.name;
|
||||
if (this._ed.dirty) str = "*" + str;
|
||||
return str;
|
||||
},
|
||||
|
||||
full_path() {
|
||||
|
@ -213,11 +212,7 @@ var gameobject = {
|
|||
},
|
||||
|
||||
cry(file) {
|
||||
this.crying = audio.play(file, audio.bus.sfx);
|
||||
var killfn = () => { this.crying = undefined;
|
||||
console.warn("killed"); }
|
||||
this.crying.hook = killfn;
|
||||
return killfn;
|
||||
return audio.cry(file);
|
||||
},
|
||||
|
||||
gscale() { return this.scale; },
|
||||
|
@ -239,7 +234,7 @@ var gameobject = {
|
|||
worldangle() { return this.angle; },
|
||||
sworldangle(x) { this.angle = x; },
|
||||
|
||||
get_ur() { return urcache[this.ur]; },
|
||||
get_ur() { return this.ur; },
|
||||
|
||||
/* spawn an entity
|
||||
text can be:
|
||||
|
@ -250,24 +245,33 @@ var gameobject = {
|
|||
spawn(text, config, callback) {
|
||||
var ent = os.make_gameobject();
|
||||
ent.guid = prosperon.guid();
|
||||
ent.setref(ent);
|
||||
ent.components = {};
|
||||
ent.objects = {};
|
||||
ent.timers = [];
|
||||
|
||||
if (typeof text === 'object' && text) // assume it's an ur
|
||||
{
|
||||
config = text.data;
|
||||
ent.ur = text.name;
|
||||
text = text.text;
|
||||
}
|
||||
|
||||
if (text)
|
||||
use(text, ent);
|
||||
if (config)
|
||||
Object.assign(ent, json.decode(io.slurp(config)));
|
||||
ent.ur = text;
|
||||
else
|
||||
ent.ur = getur(text, config);
|
||||
|
||||
text = ent.ur.text;
|
||||
config = [ent.ur.data, config];
|
||||
|
||||
if (typeof text === 'string')
|
||||
use(text, ent);
|
||||
else if (Array.isArray(text))
|
||||
text.forEach(path => use(path,ent));
|
||||
|
||||
if (typeof config === 'string')
|
||||
Object.assign(ent, json.decode(Resources.replstrs(config)));
|
||||
else if (Array.isArray(config))
|
||||
config.forEach(function(path) {
|
||||
if (typeof path === 'string')
|
||||
Object.assign(ent, json.decode(Resources.replstrs(path)));
|
||||
else if (typeof path === 'object')
|
||||
Object.assign(ent,path);
|
||||
});
|
||||
|
||||
ent.ur ??= text + "+" + config;
|
||||
ent.reparent(this);
|
||||
|
||||
for (var [prop, p] of Object.entries(ent)) {
|
||||
|
@ -296,8 +300,7 @@ var gameobject = {
|
|||
selectable: true,
|
||||
dirty: false,
|
||||
inst: false,
|
||||
urdiff: {},
|
||||
fresh: json.decode(json.encode(ent)),
|
||||
urdiff: {}
|
||||
};
|
||||
|
||||
Object.hide(ent, '_ed');
|
||||
|
@ -308,12 +311,10 @@ var gameobject = {
|
|||
var o = ent.objects;
|
||||
delete ent.objects;
|
||||
for (var i in o) {
|
||||
console.info(`MAKING ${i}`);
|
||||
var n = ent.spawn(ur[o[i].ur]);
|
||||
ent.rename_obj(n.toString(), i);
|
||||
var newur = o[i].ur;
|
||||
delete o[i].ur;
|
||||
Object.assign(n, o[i]);
|
||||
n.sync();
|
||||
var n = ent.spawn(ur[newur], o[i]);
|
||||
ent.rename_obj(n.toString(), i);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -321,6 +322,8 @@ var gameobject = {
|
|||
|
||||
if (callback) callback(ent);
|
||||
|
||||
ent.ur.fresh ??= json.decode(json.encode(ent));
|
||||
|
||||
return ent;
|
||||
},
|
||||
|
||||
|
@ -349,7 +352,7 @@ var gameobject = {
|
|||
return t;
|
||||
};
|
||||
|
||||
var name = unique_name(Object.keys(parent.objects), this.ur);
|
||||
var name = unique_name(Object.keys(parent.objects), this.ur.name);
|
||||
|
||||
parent.objects[name] = this;
|
||||
parent[name] = this;
|
||||
|
@ -446,7 +449,7 @@ var gameobject = {
|
|||
|
||||
/* The unique components of this object. Its diff. */
|
||||
json_obj() {
|
||||
var fresh = this._ed.fresh;
|
||||
var fresh = this.ur.fresh;
|
||||
var thiso = json.decode(json.encode(this)); // TODO: SLOW. Used to ignore properties in toJSON of components.
|
||||
var d = ediff(thiso, fresh);
|
||||
|
||||
|
@ -473,7 +476,7 @@ var gameobject = {
|
|||
/* The object needed to store an object as an instance of a master */
|
||||
instance_obj() {
|
||||
var t = this.transform();
|
||||
t.ur = this.ur;
|
||||
t.ur = this.ur.name;
|
||||
return t;
|
||||
},
|
||||
|
||||
|
@ -484,7 +487,7 @@ var gameobject = {
|
|||
t.angle = Math.places(this.angle, 4);
|
||||
if (t.angle === 0) delete t.angle;
|
||||
t.scale = this.scale;
|
||||
t.scale = t.scale.map((x, i) => x / this._ed.fresh.scale[i]);
|
||||
t.scale = t.scale.map((x, i) => x / this.ur.fresh.scale[i]);
|
||||
t.scale = t.scale.map(x => Math.places(x, 3));
|
||||
if (t.scale.every(x => x === 1)) delete t.scale;
|
||||
return t;
|
||||
|
@ -499,7 +502,7 @@ var gameobject = {
|
|||
},
|
||||
|
||||
dup(diff) {
|
||||
var n = this.master.spawn(this.__proto__);
|
||||
var n = this.master.spawn(this.ur);
|
||||
Object.totalmerge(n, this.instance_obj());
|
||||
return n;
|
||||
},
|
||||
|
@ -592,9 +595,8 @@ var gameobject = {
|
|||
function go_init() {
|
||||
var gop = os.make_gameobject().__proto__;
|
||||
Object.mixin(gop, gameobject);
|
||||
var gsync = gop.sync;
|
||||
gop.sync = function() {
|
||||
gsync.call(this);
|
||||
this.selfsync();
|
||||
this.components.forEach(function(x) { x.sync?.(); });
|
||||
this.objects.forEach(function(x) { x.sync?.(); });
|
||||
}
|
||||
|
@ -734,10 +736,33 @@ function file2fqn(file) {
|
|||
return ur[fqn];
|
||||
}
|
||||
|
||||
var getur = function(text, data)
|
||||
{
|
||||
var urstr = text + "+" + data;
|
||||
if (!ur[urstr]) {
|
||||
ur[urstr] = {
|
||||
name: urstr,
|
||||
text: text,
|
||||
data: data
|
||||
}
|
||||
}
|
||||
return ur[urstr];
|
||||
}
|
||||
|
||||
game.loadurs = function() {
|
||||
ur = {};
|
||||
ur._list = [];
|
||||
/* FIND ALL URS IN A PROJECT */
|
||||
for (var file of io.glob("**.ur")) {
|
||||
var urname = file.name();
|
||||
if (ur[urname]) {
|
||||
console.warn(`Tried to make another ur with the name ${urname} from ${file}, but it already exists.`);
|
||||
continue;
|
||||
}
|
||||
var urjson = json.decode(io.slurp(file));
|
||||
urjson.name = urname;
|
||||
ur[urname] = urjson;
|
||||
}
|
||||
for (var file of io.glob("**.jso")) {
|
||||
if (file[0] === '.' || file[0] === '_') continue;
|
||||
var topur = file2fqn(file);
|
||||
|
|
|
@ -309,8 +309,8 @@ var Player = {
|
|||
|
||||
switch (state) {
|
||||
case 'released':
|
||||
pawn.inputs.release_post?.call(pawn);
|
||||
break;
|
||||
pawn.inputs.release_post?.call(pawn);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!pawn.inputs.fallthru) return;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
var audio = {};
|
||||
var cries = {};
|
||||
|
||||
audio.samplerate = dspsound.samplerate();
|
||||
audio.play = function(file,bus) {
|
||||
|
@ -10,6 +11,7 @@ audio.play = function(file,bus) {
|
|||
}
|
||||
var src = audio.dsp.source(file);
|
||||
src.plugin(bus);
|
||||
src.guid = prosperon.guid();
|
||||
return src;
|
||||
}
|
||||
audio.bus = {};
|
||||
|
@ -17,15 +19,24 @@ audio.bus.master = dspsound.master();
|
|||
audio.dsp = {};
|
||||
audio.dsp = dspsound;
|
||||
|
||||
var cries = [];
|
||||
audio.cry = function(file)
|
||||
{
|
||||
var player = audio.play(file);
|
||||
cries.push(player);
|
||||
var hook = function() { console.warn("ENDED SOUND!!!!"); cries.remove(player); player = undefined; hook = undefined;}
|
||||
player.hook = hook;
|
||||
player.guid = prosperon.guid();
|
||||
cries[player.guid] = player;
|
||||
player.ended = function() { delete cries[player.guid]; player = undefined; }
|
||||
return player.ended;
|
||||
}
|
||||
|
||||
var killer = Register.appupdate.register(function() {
|
||||
for (var i in cries) {
|
||||
var cry = cries[i];
|
||||
if (!cry.ended) continue;
|
||||
if (cry.frame < cry.lastframe || cry.frame === cry.lastframe) cry.ended();
|
||||
cry.lastframe = cry.frame;
|
||||
}
|
||||
});
|
||||
|
||||
var song;
|
||||
|
||||
audio.music = function(file, fade) {
|
||||
|
|
|
@ -192,10 +192,14 @@ Cmdline.register_order("edit", function() {
|
|||
}
|
||||
|
||||
window.size = [1280, 720];
|
||||
|
||||
window.mode = window.modetypes.full;
|
||||
sim.pause();
|
||||
|
||||
game.engine_start(function() {
|
||||
global.mixin("scripts/editor.js");
|
||||
use("editorconfig.js");
|
||||
use("config.js");
|
||||
editor.enter_editor();
|
||||
});
|
||||
}, "Edit the project in this folder. Give it the name of an UR to edit that specific object.", "?UR?");
|
||||
|
|
|
@ -530,7 +530,6 @@ int shape_get_sensor(struct phys2d_shape *shape) {
|
|||
if (!shape->shape) {
|
||||
struct phys2d_edge *edge = shape->data;
|
||||
if (arrlen(edge->shapes) > 0) return cpShapeGetSensor(edge->shapes[0]);
|
||||
YughWarn("Attempted to get the sensor of an edge with no shapes. It has %d points.", arrlen(edge->points));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -50,15 +50,15 @@ void font_init() {
|
|||
.shader = fontshader,
|
||||
.layout = {
|
||||
.attrs = {
|
||||
[0].format = SG_VERTEXFORMAT_FLOAT2, /* verts */
|
||||
[0].buffer_index = 1,
|
||||
[1].format = SG_VERTEXFORMAT_FLOAT2, /* pos */
|
||||
[2].format = SG_VERTEXFORMAT_FLOAT2, /* width and height */
|
||||
[3].format = SG_VERTEXFORMAT_USHORT2N, /* uv pos */
|
||||
[4].format = SG_VERTEXFORMAT_USHORT2N, /* uv width and height */
|
||||
[5].format = SG_VERTEXFORMAT_UBYTE4N, /* color */
|
||||
[0].format = SG_VERTEXFORMAT_FLOAT2, /* verts */
|
||||
[0].buffer_index = 1,
|
||||
[1].format = SG_VERTEXFORMAT_FLOAT2, /* pos */
|
||||
[2].format = SG_VERTEXFORMAT_FLOAT2, /* width and height */
|
||||
[3].format = SG_VERTEXFORMAT_USHORT2N, /* uv pos */
|
||||
[4].format = SG_VERTEXFORMAT_USHORT2N, /* uv width and height */
|
||||
[5].format = SG_VERTEXFORMAT_UBYTE4N, /* color */
|
||||
},
|
||||
.buffers[0].step_func = SG_VERTEXSTEP_PER_INSTANCE
|
||||
.buffers[0].step_func = SG_VERTEXSTEP_PER_INSTANCE
|
||||
},
|
||||
.primitive_type = SG_PRIMITIVETYPE_TRIANGLE_STRIP,
|
||||
.colors[0].blend = blend_trans,
|
||||
|
@ -244,7 +244,7 @@ void text_flush(HMM_Mat4 *proj) {
|
|||
}
|
||||
|
||||
void sdrawCharacter(struct Character c, HMM_Vec2 cursor, float scale, struct rgba color) {
|
||||
if (curchar+1 >= max_chars)
|
||||
if (curchar-10 >= max_chars)
|
||||
return;
|
||||
|
||||
struct rgba colorbox = {0,0,0,255};
|
||||
|
@ -395,15 +395,15 @@ int renderText(const char *text, HMM_Vec2 pos, float scale, struct rgba color, f
|
|||
}
|
||||
|
||||
while (wordstart < line) {
|
||||
if (*wordstart == '\e')
|
||||
wordstart = esc_color(wordstart, &usecolor, color);
|
||||
if (*wordstart == '\e')
|
||||
wordstart = esc_color(wordstart, &usecolor, color);
|
||||
|
||||
sdrawCharacter(font->Characters[*wordstart], HMM_AddV2(cursor, HMM_MulV2F((HMM_Vec2){1,-1},scale)), scale, (rgba){0,0,0,255});
|
||||
sdrawCharacter(font->Characters[*wordstart], HMM_AddV2(cursor, HMM_MulV2F((HMM_Vec2){1,-1},scale)), scale, (rgba){0,0,0,255});
|
||||
sdrawCharacter(font->Characters[*wordstart], cursor, scale, usecolor);
|
||||
|
||||
cursor.X += font->Characters[*wordstart].Advance * tracking * scale;
|
||||
wordstart++;
|
||||
check_caret(caret, wordstart-drawstart, cursor, scale, usecolor);
|
||||
check_caret(caret, wordstart-drawstart, cursor, scale, usecolor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,10 +61,6 @@ const char *js2str(JSValue v) {
|
|||
return JS_ToCString(js, v);
|
||||
}
|
||||
|
||||
/* support functions for these macros when they involve a JSValue */
|
||||
JSValue js2JSValue(JSValue v) { return v; }
|
||||
JSValue JSValue2js(JSValue v) { return v; }
|
||||
|
||||
QJSCLASS(gameobject)
|
||||
QJSCLASS(emitter)
|
||||
QJSCLASS(dsp_node)
|
||||
|
@ -1082,14 +1078,12 @@ static const JSCFunctionListEntry js_dsp_node_funcs[] = {
|
|||
JSC_GETSET(sound, loop, boolean)
|
||||
JSC_GETSET(sound, timescale, number)
|
||||
JSC_GETSET(sound, frame, number)
|
||||
JSC_GETSET_HOOK(sound, hook)
|
||||
JSC_CCALL(sound_frames, return number2js(js2sound(this)->data->frames))
|
||||
|
||||
static const JSCFunctionListEntry js_sound_funcs[] = {
|
||||
CGETSET_ADD(sound, loop),
|
||||
CGETSET_ADD(sound, timescale),
|
||||
CGETSET_ADD(sound, frame),
|
||||
CGETSET_ADD(sound, hook),
|
||||
MIST_FUNC_DEF(sound, frames, 0),
|
||||
};
|
||||
|
||||
|
@ -1164,8 +1158,7 @@ JSC_GETSET(gameobject, maxvelocity, number)
|
|||
JSC_GETSET(gameobject, maxangularvelocity, number)
|
||||
JSC_GETSET(gameobject, warp_filter, bitmask)
|
||||
JSC_GETSET(gameobject, drawlayer, number)
|
||||
JSC_CCALL(gameobject_setref, js2gameobject(this)->ref = argv[0]);
|
||||
JSC_CCALL(gameobject_sync, gameobject_apply(js2gameobject(this)))
|
||||
JSC_CCALL(gameobject_selfsync, gameobject_apply(js2gameobject(this)))
|
||||
JSC_CCALL(gameobject_in_air, return boolean2js(phys2d_in_air(js2gameobject(this)->body)))
|
||||
JSC_CCALL(gameobject_world2this, return vec22js(world2go(js2gameobject(this), js2vec2(argv[0]))))
|
||||
JSC_CCALL(gameobject_this2world, return vec22js(go2world(js2gameobject(this), js2vec2(argv[0]))))
|
||||
|
@ -1200,8 +1193,7 @@ static const JSCFunctionListEntry js_gameobject_funcs[] = {
|
|||
MIST_FUNC_DEF(gameobject, this2world, 1),
|
||||
MIST_FUNC_DEF(gameobject, dir_world2this, 1),
|
||||
MIST_FUNC_DEF(gameobject, dir_this2world, 1),
|
||||
MIST_FUNC_DEF(gameobject,setref,1),
|
||||
MIST_FUNC_DEF(gameobject, sync, 0),
|
||||
MIST_FUNC_DEF(gameobject, selfsync, 0),
|
||||
};
|
||||
|
||||
JSC_CCALL(joint_pin, return constraint2js(constraint_make(cpPinJointNew(js2gameobject(argv[0])->body, js2gameobject(argv[1])->body, cpvzero,cpvzero))))
|
||||
|
@ -1454,6 +1446,7 @@ JSC_CCALL(os_sprite,
|
|||
JSC_CCALL(os_make_gameobject,
|
||||
ret = gameobject2js(MakeGameobject());
|
||||
JS_SetPropertyFunctionList(js, ret, js_gameobject_funcs, countof(js_gameobject_funcs));
|
||||
js2gameobject(ret)->ref = ret;
|
||||
return ret;
|
||||
)
|
||||
JSC_CCALL(os_make_circle2d,
|
||||
|
|
|
@ -278,13 +278,11 @@ void sound_fillbuf(struct sound *s, soundbyte *buf, int n) {
|
|||
if(end) {
|
||||
if (s->loop)
|
||||
s->frame = 0;
|
||||
script_call_sym(s->hook,0,NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void free_source(struct sound *s)
|
||||
{
|
||||
JS_FreeValue(js, s->hook);
|
||||
src_delete(s->src);
|
||||
free(s);
|
||||
}
|
||||
|
@ -305,7 +303,6 @@ struct dsp_node *dsp_source(const char *path)
|
|||
self->loop = false;
|
||||
self->src = src_callback_new(src_cb, SRC_SINC_MEDIUM_QUALITY, 2, NULL, self);
|
||||
self->timescale = 1;
|
||||
self->hook = JS_UNDEFINED;
|
||||
dsp_node *n = make_node(self, sound_fillbuf, free_source);
|
||||
return n;
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@ typedef struct sound {
|
|||
int loop;
|
||||
float timescale;
|
||||
SRC_STATE *src;
|
||||
JSValue hook;
|
||||
} sound;
|
||||
|
||||
/* Represents a sound file source, fulled loaded*/
|
||||
|
|
2
source/engine/thirdparty/quickjs/quickjs.c
vendored
2
source/engine/thirdparty/quickjs/quickjs.c
vendored
|
@ -112,7 +112,7 @@ void quickjs_set_dumpout(FILE *f)
|
|||
//#define DUMP_READ_OBJECT
|
||||
|
||||
#ifdef DUMP
|
||||
#define DUMP_FREE
|
||||
//#define DUMP_FREE
|
||||
#define DUMP_MEM
|
||||
#define DUMP_CLOSURE
|
||||
#define DUMP_GC
|
||||
|
|
Loading…
Reference in a new issue