editor fix

This commit is contained in:
John Alanbrook 2024-04-03 17:17:32 -05:00
parent ccdcfafdf2
commit 32268fc25d
19 changed files with 360 additions and 422 deletions

View file

@ -212,7 +212,9 @@ Components only work in the context of an entity. They have no meaning outside o
While components can be added via scripting, it is easier to add them via the editor, as we will later see. While components can be added via scripting, it is easier to add them via the editor, as we will later see.
*** Ur system *** Ur system
The ur[fn::A German prefix meaning primitive, original, or earliest.] system is a prototypical inheritence system used by the actor files. When actor files are loaded, they are stored as an ur. An *ur* represents a set of instructions to create the (text, config) needed to spawn an actor or entity. The ur[fn::A German prefix meaning primitive, original, or earliest.] system is a prototypical inheritence system used by the actor files. When actor files are loaded, they are stored as an ur. An *ur* holds a list of (text, config) required to create an entity.
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.
#+begin_scholium #+begin_scholium
Create an ur from the *hello* files above, and then spawn it. Create an ur from the *hello* files above, and then spawn it.

View file

@ -1,5 +1,5 @@
this.phys = physics.kinematic; this.phys = physics.kinematic;
this.dir_view2world = function(dir) { return dir.scale(this.realzoom()); }; this.dir_view2world = function(dir) { return dir.scale(this.zoom); };
this.view2world = function(pos) { this.view2world = function(pos) {
pos = pos.scale([window.rendersize.x/window.size.x, window.rendersize.y/window.size.y]); pos = pos.scale([window.rendersize.x/window.size.x, window.rendersize.y/window.size.y]);
pos = pos.sub(window.rendersize.scale(0.5)); pos = pos.sub(window.rendersize.scale(0.5));
@ -10,14 +10,11 @@ this.view2world = function(pos) {
this.world2view = function(pos) { this.world2view = function(pos) {
pos = pos.sub(this.pos); pos = pos.sub(this.pos);
pos = pos.scale(1.0/this.zoom); pos = pos.scale(1.0/this.zoom);
pos = pos.add(window.rendersize); pos = pos.add(window.rendersize.scale(0.5));
return pos; return pos;
}; };
this.realzoom = function() { return render.get_zoom(); };
this.screenright = function() { this.screenright = function() { return this.view2world(window.size).x; }
return this.view2world(window.size).x;
}
this.screenleft = function() { return this.pos.x - (window.rendersize.x/2); } this.screenleft = function() { return this.pos.x - (window.rendersize.x/2); }
this.zoom = 1; this.zoom = 1;

View file

@ -489,6 +489,7 @@ component.edge2d = Object.copy(collider2d, {
'points', 'points',
'hollow', 'hollow',
'hollowt', 'hollowt',
'angle',
]), ]),
dimensions:2, dimensions:2,
thickness:0, thickness:0,
@ -516,7 +517,7 @@ component.edge2d = Object.copy(collider2d, {
for (var i = spoints.length-1; i >= 0; i--) { for (var i = spoints.length-1; i >= 0; i--) {
var newpoint = spoints[i].slice(); var newpoint = spoints[i].slice();
newpoint.x = -newpoint.x; newpoint.x = -newpoint.x;
spoints.push(newpoint); spoints.push(newpoint);
} }
} }
@ -527,8 +528,8 @@ component.edge2d = Object.copy(collider2d, {
for (var i = spoints.length-1; i >= 0; i--) { for (var i = spoints.length-1; i >= 0; i--) {
var newpoint = spoints[i].slice(); var newpoint = spoints[i].slice();
newpoint.y = -newpoint.y; newpoint.y = -newpoint.y;
spoints.push(newpoint); spoints.push(newpoint);
} }
} }
@ -585,7 +586,7 @@ component.edge2d = Object.copy(collider2d, {
gizmo() { gizmo() {
if (this.type === Spline.type.catmull || this.type === -1) { if (this.type === Spline.type.catmull || this.type === -1) {
this.spoints().forEach(x => render.point(this.gameobject.this2screen(x), 3, Color.teal)); this.spoints().forEach(x => render.point(this.gameobject.this2screen(x), 3, Color.teal));
this.points.forEach((x,i) => render.coordinate(this.gameobject.this2screen(x), i)); this.points.forEach((x,i) => render.coordinate(this.gameobject.this2screen(x)));
} else { } else {
for (var i = 0; i < this.points.length; i += 3) 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]), i, Color.teal);
@ -614,23 +615,23 @@ component.edge2d = Object.copy(collider2d, {
if (p) { if (p) {
var o = { var o = {
pos: p, pos: p,
sync: me.sync.bind(me) sync: me.sync.bind(me)
}; };
if (Spline.bezier_is_handle(this.points,i)) if (Spline.bezier_is_handle(this.points,i))
o.move = function(d) { o.move = function(d) {
d = that.dir_world2this(d); d = that.dir_world2this(d);
p.x += d.x; p.x += d.x;
p.y += d.y; p.y += d.y;
Spline.bezier_cp_mirror(me.points,i); Spline.bezier_cp_mirror(me.points,i);
}; };
else else
o.move = function(d) { o.move = function(d) {
d = that.dir_world2this(d); d = that.dir_world2this(d);
p.x += d.x; p.x += d.x;
p.y += d.y; p.y += d.y;
var pp = Spline.bezier_point_handles(me.points,i); var pp = Spline.bezier_point_handles(me.points,i);
pp.forEach(ph => me.points[ph] = me.points[ph].add(d)); pp.forEach(ph => me.points[ph] = me.points[ph].add(d));
} }
return o; return o;
} }
}, },

View file

@ -22,7 +22,7 @@ debug.draw = function() {
if (this.draw_gizmos) if (this.draw_gizmos)
game.all_objects(function(x) { game.all_objects(function(x) {
if (!x.icon) return; if (!x.icon) return;
GUI.image(x.icon, game.camera.world2view(x.pos)); gui.image(x.icon, game.camera.world2view(x.pos));
}); });
if (this.draw_names) if (this.draw_names)
@ -143,12 +143,11 @@ debug.inputs.f9 = function() {
debug.inputs.f10 = function() { time.timescale = 0.1; }; debug.inputs.f10 = function() { time.timescale = 0.1; };
debug.inputs.f10.doc = "Toggle timescale to 1/10."; debug.inputs.f10.doc = "Toggle timescale to 1/10.";
debug.inputs.f10.released = function () { time.timescale = 1.0; }; debug.inputs.f10.released = function () { time.timescale = 1.0; };
debug.inputs.f12 = function() { GUI.defaults.debug = !GUI.defaults.debug; console.warn("GUI toggle debug");}; debug.inputs.f12 = function() { gui.defaults.debug = !gui.defaults.debug; console.warn("gui toggle debug");};
debug.inputs.f12.doc = "Toggle drawing GUI debugging aids."; debug.inputs.f12.doc = "Toggle drawing gui debugging aids.";
debug.inputs['M-1'] = render.normal; debug.inputs['M-1'] = render.normal;
debug.inputs['M-2'] = render.wireframe; debug.inputs['M-2'] = render.wireframe;
debug.inputs['C-M-f'] = function() {}; debug.inputs['C-M-f'] = function() {};
debug.inputs['C-M-f'].doc = "Enter camera fly mode."; debug.inputs['C-M-f'].doc = "Enter camera fly mode.";

View file

@ -36,8 +36,8 @@ function ediff(from,to)
if (Array.isArray(v)) { if (Array.isArray(v)) {
if (!Array.isArray(to[key]) || v.length !== to[key].length) { if (!Array.isArray(to[key]) || v.length !== to[key].length) {
var r = ediff(v,[]); var r = ediff(v,[]);
if (r) ret[key] = Object.values(r); if (r) ret[key] = Object.values(r);
return; return;
} }
var diff = ediff(from[key], to[key]); var diff = ediff(from[key], to[key]);
@ -47,14 +47,14 @@ function ediff(from,to)
return; return;
} }
if (typeof v === 'object') { if (typeof v === 'object' && v !== null) {
var diff = ediff(v, to[key]); var diff = ediff(v, to[key]);
if (diff && !Object.empty(diff)) if (diff && !Object.empty(diff))
ret[key] = diff; ret[key] = diff;
return; return;
} }
if (typeof v === 'number') { if (typeof v === 'number' || v === null) {
if (!isFinite(v)) v = null; // Squash infinity to null if (!isFinite(v)) v = null; // Squash infinity to null
if (v !== to[key]) if (v !== to[key])
ret[key] = v; ret[key] = v;

View file

@ -6,6 +6,8 @@
window.mode = window.modetypes.full; window.mode = window.modetypes.full;
game.loadurs(); game.loadurs();
console.info(`window size: ${window.size}, render size: ${window.rendersize}`);
player[0].control(debug); player[0].control(debug);
Register.gui.register(debug.draw, debug); Register.gui.register(debug.draw, debug);
@ -222,7 +224,7 @@ var editor = {
editor.cbs.push(Register.gui.register(editor.gui.bind(editor))); editor.cbs.push(Register.gui.register(editor.gui.bind(editor)));
editor.cbs.push(Register.draw.register(editor.draw.bind(editor))); editor.cbs.push(Register.draw.register(editor.draw.bind(editor)));
editor.cbs.push(Register.debug.register(editor.ed_debug.bind(editor))); editor.cbs.push(Register.debug.register(editor.ed_debug.bind(editor)));
editor.cbs.push(Register.update.register(GUI.controls.update, GUI.controls)); editor.cbs.push(Register.update.register(gui.controls.update, gui.controls));
this.desktop = world.spawn(); this.desktop = world.spawn();
world.rename_obj(this.desktop.toString(), "desktop"); world.rename_obj(this.desktop.toString(), "desktop");
@ -392,7 +394,6 @@ var editor = {
gui() { gui() {
/* Clean out killed objects */ /* Clean out killed objects */
this.selectlist = this.selectlist.filter(function(x) { return x.alive; });
render.text([0,0], game.camera.world2view([0,0])); render.text([0,0], game.camera.world2view([0,0]));
render.text("WORKING LAYER: " + this.working_layer, [0,520]); render.text("WORKING LAYER: " + this.working_layer, [0,520]);
@ -422,9 +423,11 @@ var editor = {
var depth = 0; var depth = 0;
var alldirty = false; var alldirty = false;
for (var lvl of lvlchain) { for (var lvl of lvlchain) {
if (!lvl._ed) continue;
if (alldirty) if (alldirty)
lvl._ed.dirty = true; lvl._ed.dirty = true;
else { else {
if (!lvl._ed) continue;
lvl.check_dirty(); lvl.check_dirty();
if (lvl._ed.dirty) alldirty = true; if (lvl._ed.dirty) alldirty = true;
} }
@ -442,7 +445,6 @@ var editor = {
depth++; depth++;
render.text("$$$$$$", [0,ypos],1,editor.color_depths[depth]); render.text("$$$$$$", [0,ypos],1,editor.color_depths[depth]);
this.selectlist.forEach(function(x) { this.selectlist.forEach(function(x) {
render.text(x.urstr(), x.screenpos().add([0, 32]), 1, Color.editor.ur); render.text(x.urstr(), x.screenpos().add([0, 32]), 1, Color.editor.ur);
render.text(x.worldpos().map(function(x) { return Math.round(x); }), x.screenpos(), 1, Color.white); render.text(x.worldpos().map(function(x) { return Math.round(x); }), x.screenpos(), 1, Color.white);
@ -452,7 +454,8 @@ var editor = {
Object.entries(thiso.objects).forEach(function(x) { Object.entries(thiso.objects).forEach(function(x) {
var p = x[1].namestr(); var p = x[1].namestr();
render.text(p, x[1].screenpos().add([0,16]),1,editor.color_depths[depth]); render.text(p, x[1].screenpos().add([0,16]),1,editor.color_depths[depth]);
render.circle(x[1].screenpos(),10,Color.blue.alpha(0.3)); render.point(x[1].screenpos(),5,Color.blue.alpha(0.3));
render.point(x[1].screenpos(), 1, Color.red);
}); });
var mg = physics.pos_query(input.mouse.worldpos(),10); var mg = physics.pos_query(input.mouse.worldpos(),10);
@ -522,9 +525,12 @@ var editor = {
lvl_history: [], lvl_history: [],
load(urstr) { load(urstr) {
var obj = editor.edit_level.spawn(urstr); var mur = ur[urstr];
if (!mur) return;
var obj = editor.edit_level.spawn(mur);
obj.set_worldpos(input.mouse.worldpos()); obj.set_worldpos(input.mouse.worldpos());
this.selectlist = [obj]; this.selectlist = [obj];
console.warn(`made something and now the selected objects is ${this.selectlist.length} long.`);
}, },
load_prev() { load_prev() {
@ -553,15 +559,15 @@ var editor = {
/* make a new type path */ /* make a new type path */
if (Object.access(ur,sub)) { if (Object.access(ur,sub)) {
console.warn(`Ur named ${sub} already exists.`); console.warn(`Ur named ${sub} already exists.`);
return; return;
} }
var file = `${sub}.json`; var file = `${sub}.json`;
io.slurpwrite(file, json.encode(obj.json_obj(),null,1)); io.slurpwrite(file, json.encode(obj.json_obj(),null,1));
ur[sub] = { ur[sub] = {
name: sub, name: sub,
data: file, data: file,
proto: json.decode(json.encode(obj)) proto: json.decode(json.encode(obj))
} }
obj.ur = sub; obj.ur = sub;
@ -583,12 +589,12 @@ var editor = {
if (obj === editor.edit_level) { if (obj === editor.edit_level) {
if (obj === editor.desktop) { if (obj === editor.desktop) {
obj.clear(); obj.clear();
var nobj = editor.edit_level.spawn(sub); var nobj = editor.edit_level.spawn(sub);
editor.selectlist = [nobj]; editor.selectlist = [nobj];
return; return;
} }
editor.edit_level = editor.edit_level.master; editor.edit_level = editor.edit_level.master;
} }
var t = obj.transform(); var t = obj.transform();
@ -664,7 +670,7 @@ editor.inputs.release_post = function() {
editor.edit_level.check_dirty(); editor.edit_level.check_dirty();
/* snap all objects to be pixel perfect */ /* snap all objects to be pixel perfect */
editor.edit_level.obj_descend(o => o.pos = o.pos.map(x => Math.round(x))); game.all_objects(o => o.pos = o.pos.map(x => Math.round(x)), editor.edit_level);
}; };
editor.inputs['C-a'] = function() { editor.inputs['C-a'] = function() {
if (!Object.empty(editor.selectlist)) { editor.unselect(); return; } if (!Object.empty(editor.selectlist)) { editor.unselect(); return; }
@ -1404,7 +1410,7 @@ var inputpanel = {
toString() { return this.title; }, toString() { return this.title; },
value: "", value: "",
on: false, on: false,
pos:[100,window.height-50], pos:[100,window.size.y-50],
wh:[350,600], wh:[350,600],
anchor: [0,1], anchor: [0,1],
padding:[5,-15], padding:[5,-15],
@ -1422,7 +1428,7 @@ var inputpanel = {
]; ];
else else
this.win.items = itms; this.win.items = itms;
this.win.draw(this.pos.slice()); this.win.draw([100, window.size.y-50]);
}, },
guibody() { guibody() {
@ -1479,10 +1485,7 @@ var inputpanel = {
inputpanel.inputs = {}; inputpanel.inputs = {};
inputpanel.inputs.post = function() inputpanel.inputs.post = function() { this.keycb(); }
{
this.keycb();
}
inputpanel.inputs.char = function(c) { inputpanel.inputs.char = function(c) {
this.value = this.value.slice(0,this.caret) + c + this.value.slice(this.caret); this.value = this.value.slice(0,this.caret) + c + this.value.slice(this.caret);
@ -1524,26 +1527,20 @@ inputpanel.inputs['C-k'] = function() {
this.value = this.value.slice(0,this.caret); this.value = this.value.slice(0,this.caret);
}; };
inputpanel.inputs.lm = function() inputpanel.inputs.lm = function() { gui.controls.check_submit(); }
{
GUI.controls.check_submit();
}
//load("scripts/textedit.js");
var replpanel = Object.copy(inputpanel, { var replpanel = Object.copy(inputpanel, {
title: "", title: "",
closeonsubmit:false, closeonsubmit:false,
wh: [700,300], wh: [700,300],
pos: [50,50], pos: [50,50],
anchor: [0,0], anchor: [0,1],
padding: [0,0], padding: [0,0],
scrolloffset: [0,0], scrolloffset: [0,0],
guibody() { guibody() {
this.win.selectable = true; this.win.selectable = true;
var log = ""; var log = console.transcript;
log = log.slice(-5000);
return [ return [
Mum.text({str:log, anchor:[0,0], offset:[0,-300].sub(this.scrolloffset), selectable: true}), Mum.text({str:log, anchor:[0,0], offset:[0,-300].sub(this.scrolloffset), selectable: true}),
Mum.text({str:this.value,color:Color.green, offset:[0,-290], caret: this.caret}) Mum.text({str:this.value,color:Color.green, offset:[0,-290], caret: this.caret})
@ -1801,8 +1798,6 @@ var objectexplorer = Object.copy(inputpanel, {
return items; return items;
}, },
}); });
var openlevelpanel = Object.copy(inputpanel, { var openlevelpanel = Object.copy(inputpanel, {
@ -2005,9 +2000,6 @@ limited_editor.inputs['C-q'] = function()
var limited_editing = {}; var limited_editing = {};
limited_editing.inputs = {}; limited_editing.inputs = {};
if (io.exists("editor.config"))
load_configs("editor.config");
/* This is the editor level & camera - NOT the currently edited level, but a level to hold editor things */ /* This is the editor level & camera - NOT the currently edited level, but a level to hold editor things */
sim.pause(); sim.pause();
window.editor = true; window.editor = true;

View file

@ -120,53 +120,53 @@ qq = 'ms';
return `${t.toPrecision(4)} ${qq}`; return `${t.toPrecision(4)} ${qq}`;
} }
Object.assign(console, { console.transcript = "";
say(msg) { console.print(msg + "\n"); }, console.say = function(msg) {
msg += "\n";
pprint(msg, lvl = 0) { console.print(msg);
if (typeof msg === 'object') console.transcript += msg;
msg = JSON.stringify(msg, null, 2); };
var file = "nofile";
var line = 0;
var caller = (new Error()).stack.split('\n')[2];
if (caller) {
var md = caller.match(/\((.*)\:/);
var m = md ? md[1] : "SCRIPT";
if (m) file = m;
md = caller.match(/\:(\d*)\)/);
m = md ? md[1] : 0;
if (m) line = m;
}
console.rec(lvl, msg, file, line);
},
spam(msg) { console.pprint (msg,0); },
debug(msg) { console.pprint(msg,1); },
info(msg) { console.pprint(msg, 2); },
warn(msg) { console.pprint(msg, 3); },
error(msg) { console.pprint(msg + "\n" + console.stackstr(2), 4);},
panic(msg) { console.pprint(msg + "\n" + console.stackstr(2), 5); },
stackstr(skip=0) {
var err = new Error();
var stack = err.stack.split('\n');
return stack.slice(skip,stack.length).join('\n');
},
stack(skip = 0) {
console.log(console.stackstr(skip+1));
},
});
console.stdout_lvl = 1;
console.log = console.say; console.log = console.say;
console.trace = console.stack;
var say = console.say; var say = console.say;
var print = console.print; var print = console.print;
console.pprint = function(msg,lvl = 0) {
if (typeof msg === 'object')
msg = JSON.stringify(msg, null, 2);
var file = "nofile";
var line = 0;
var caller = (new Error()).stack.split('\n')[2];
if (caller) {
var md = caller.match(/\((.*)\:/);
var m = md ? md[1] : "SCRIPT";
if (m) file = m;
md = caller.match(/\:(\d*)\)/);
m = md ? md[1] : 0;
if (m) line = m;
}
console.rec(lvl, msg, file, line);
};
console.spam = function(msg) { console.pprint (msg,0); };
console.debug = function(msg) { console.pprint(msg,1); };
console.info = function(msg) { console.pprint(msg, 2); };
console.warn = function(msg) { console.pprint(msg, 3); };
console.error = function(msg) { console.pprint(msg + "\n" + console.stackstr(2), 4);};
console.panic = function(msg) { console.pprint(msg + "\n" + console.stackstr(2), 5); };
console.stackstr = function(skip=0) {
var err = new Error();
var stack = err.stack.split('\n');
return stack.slice(skip,stack.length).join('\n');
};
console.stack = function(skip = 0) { console.log(console.stackstr(skip+1)); };
console.stdout_lvl = 1;
console.trace = console.stack;
console.doc = { console.doc = {
level: "Set level to output logging to console.", level: "Set level to output logging to console.",
info: "Output info level message.", info: "Output info level message.",
@ -243,15 +243,14 @@ global.mixin("scripts/debug");
var frame_t = profile.secs(profile.now()); var frame_t = profile.secs(profile.now());
var phys_step = 1/60; var phys_step = 1/60;
var sim = { var sim = {};
mode: "play", sim.mode = "play";
play() { this.mode = "play"; os.reindex_static(); }, sim.play = function() { this.mode = "play"; os.reindex_static(); };
playing() { return this.mode === 'play'; }, sim.playing = function() { return this.mode === 'play'; };
pause() { this.mode = "pause"; console.stack(); }, sim.pause = function() { this.mode = "pause"; };
paused() { return this.mode === 'pause'; }, sim.paused = function() { return this.mode === 'pause'; };
step() { this.mode = 'step'; }, sim.step = function() { this.mode = 'step'; };
stepping() { return this.mode === 'step'; } sim.stepping = function() { return this.mode === 'step'; }
}
var physlag = 0; var physlag = 0;
@ -313,7 +312,8 @@ function process()
game.timescale = 1; game.timescale = 1;
game.all_objects = function(fn) { game.all_objects = function(fn, startobj) {
startobj ??= world;
var eachobj = function(obj,fn) var eachobj = function(obj,fn)
{ {
fn(obj); fn(obj);
@ -321,7 +321,7 @@ game.all_objects = function(fn) {
eachobj(obj.objects[o],fn); eachobj(obj.objects[o],fn);
} }
eachobj(world,fn); eachobj(startobj,fn);
}; };
game.tags = {}; game.tags = {};

View file

@ -83,15 +83,10 @@ var gameobject = {
else else
this._ed.inst = false; this._ed.inst = false;
}, },
_ed: {
selectable: false,
dirty: false
},
namestr() { namestr() {
var s = this.toString(); var s = this.toString();
if (this._ed.dirty) if (this._ed?.dirty)
if (this._ed.inst) s += "#"; if (this._ed.inst) s += "#";
else s += "*"; else s += "*";
return s; return s;
@ -259,17 +254,11 @@ var gameobject = {
ent.components = {}; ent.components = {};
ent.objects = {}; ent.objects = {};
ent.timers = []; ent.timers = [];
ent.reparent(this);
ent._ed = {
selectable: true,
dirty: false,
inst: false,
urdiff: {},
};
if (typeof text === 'object') // assume it's an ur if (typeof text === 'object' && text) // assume it's an ur
{ {
config = text.data; config = text.data;
ent.ur = text.name;
text = text.text; text = text.text;
} }
@ -278,7 +267,8 @@ var gameobject = {
if (config) if (config)
Object.assign(ent, json.decode(io.slurp(config))); Object.assign(ent, json.decode(io.slurp(config)));
ent.ur = text + "+" + config; ent.ur ??= text + "+" + config;
ent.reparent(this);
for (var [prop, p] of Object.entries(ent)) { for (var [prop, p] of Object.entries(ent)) {
if (!p) continue; if (!p) continue;
@ -300,11 +290,17 @@ var gameobject = {
if (sim.playing()) if (sim.playing())
if (typeof ent.start === 'function') ent.start(); if (typeof ent.start === 'function') ent.start();
Object.hide(ent, 'ur', 'components', 'objects', '_ed', 'timers', 'master'); Object.hide(ent, 'ur', 'components', 'objects', 'timers', 'guid', 'master');
var mur = ent.get_ur(); ent._ed = {
if (mur && !mur.proto) selectable: true,
mur.proto = json.decode(json.encode(ent)); dirty: false,
inst: false,
urdiff: {},
fresh: json.decode(json.encode(ent)),
};
Object.hide(ent, '_ed');
ent.sync(); ent.sync();
@ -450,22 +446,19 @@ var gameobject = {
/* The unique components of this object. Its diff. */ /* The unique components of this object. Its diff. */
json_obj() { json_obj() {
var u = this.get_ur(); var fresh = this._ed.fresh;
if (!u) return {};
var proto = u.proto;
var thiso = json.decode(json.encode(this)); // TODO: SLOW. Used to ignore properties in toJSON of components. var thiso = json.decode(json.encode(this)); // TODO: SLOW. Used to ignore properties in toJSON of components.
var d = ediff(thiso, fresh);
var d = ediff(thiso, proto);
d ??= {}; d ??= {};
var objects = {}; var objects = {};
proto.objects ??= {}; fresh.objects ??= {};
var curobjs = {}; var curobjs = {};
for (var o in this.objects) for (var o in this.objects)
curobjs[o] = this.objects[o].instance_obj(); curobjs[o] = this.objects[o].instance_obj();
var odiff = ediff(curobjs, proto.objects); var odiff = ediff(curobjs, fresh.objects);
if (odiff) if (odiff)
d.objects = curobjs; d.objects = curobjs;
@ -484,12 +477,6 @@ var gameobject = {
return t; return t;
}, },
proto() {
var u = this.get_ur();
if (!u) return {};
return u.proto;
},
transform() { transform() {
var t = {}; var t = {};
t.pos = this.pos; t.pos = this.pos;
@ -497,7 +484,7 @@ var gameobject = {
t.angle = Math.places(this.angle, 4); t.angle = Math.places(this.angle, 4);
if (t.angle === 0) delete t.angle; if (t.angle === 0) delete t.angle;
t.scale = this.scale; t.scale = this.scale;
t.scale = t.scale.map((x, i) => x / this.proto().scale[i]); t.scale = t.scale.map((x, i) => x / this._ed.fresh.scale[i]);
t.scale = t.scale.map(x => Math.places(x, 3)); t.scale = t.scale.map(x => Math.places(x, 3));
if (t.scale.every(x => x === 1)) delete t.scale; if (t.scale.every(x => x === 1)) delete t.scale;
return t; return t;
@ -600,12 +587,6 @@ var gameobject = {
Object.assign(this[name], data); Object.assign(this[name], data);
return this[name]; return this[name];
}, },
obj_descend(fn) {
fn(this);
for (var o in this.objects)
this.objects[o].obj_descend(fn);
},
} }
function go_init() { function go_init() {

View file

@ -1,64 +1,41 @@
/* /*
GUI functions take screen space coordinates gui functions take screen space coordinates
*/ */
gui.scissor_win = function() { gui.scissor(0,0,window.width,window.height); } gui.scissor_win = function() { gui.scissor(0,0,window.width,window.height); }
var GUI = { gui.input_lmouse_pressed = function() {
newmg(img) { if (gui.selected)
var def = { gui.selected.action();
path: "", };
pos: [0,0],
size:[0,0],
frame: {
x: 0,
y: 0,
w: 1,
h: 1
},
angle: 0,
anchor: [0,0],
color: Color.white,
}
for (var i in def)
img[i] ??= def[i];
gui_newmg
},
input_lmouse_pressed() { gui.input_s_pressed = function() {
if (GUI.selected) if (gui.selected?.down) {
GUI.selected.action(); gui.selected.selected = false;
}, gui.selected = gui.selected.down;
gui.selected.selected = true;
input_s_pressed() {
if (GUI.selected?.down) {
GUI.selected.selected = false;
GUI.selected = GUI.selected.down;
GUI.selected.selected = true;
}
},
input_w_pressed() {
if (GUI.selected?.up) {
GUI.selected.selected = false;
GUI.selected = GUI.selected.up;
GUI.selected.selected = true;
}
},
input_enter_pressed() {
if (GUI.selected) {
GUI.selected.action();
}
} }
}; };
GUI.controls = {}; gui.input_w_pressed = function() {
GUI.controls.toString = function() { return "GUI controls"; }; if (gui.selected?.up) {
GUI.controls.update = function() { }; gui.selected.selected = false;
gui.selected = gui.selected.up;
gui.selected.selected = true;
}
};
GUI.controls.set_mum = function(mum) gui.input_enter_pressed = function() {
if (gui.selected) {
gui.selected.action();
}
}
gui.controls = {};
gui.controls.toString = function() { return "gui controls"; };
gui.controls.update = function() { };
gui.controls.set_mum = function(mum)
{ {
mum.selected = true; mum.selected = true;
@ -67,22 +44,22 @@ GUI.controls.set_mum = function(mum)
this.selected = mum; this.selected = mum;
} }
GUI.controls.check_bb = function(mum) gui.controls.check_bb = function(mum)
{ {
if (bbox.pointin(mum.bb, input.mouse.screenpos())) if (bbox.pointin(mum.bb, input.mouse.screenpos()))
GUI.controls.set_mum(mum); gui.controls.set_mum(mum);
} }
GUI.controls.inputs = {}; gui.controls.inputs = {};
GUI.controls.inputs.fallthru = false; gui.controls.inputs.fallthru = false;
GUI.controls.inputs.mouse = {}; gui.controls.inputs.mouse = {};
GUI.controls.inputs.mouse.move = function(pos,dpos) gui.controls.inputs.mouse.move = function(pos,dpos)
{ {
} }
GUI.controls.inputs.mouse.scroll = function(scroll) gui.controls.inputs.mouse.scroll = function(scroll)
{ {
} }
GUI.controls.check_submit = function() { gui.controls.check_submit = function() {
if (this.selected && this.selected.action) if (this.selected && this.selected.action)
this.selected.action(this.selected); this.selected.action(this.selected);
} }
@ -145,7 +122,7 @@ Mum.text = Mum.extend({
cursor ??= [0,0]; cursor ??= [0,0];
cnt ??= Mum; cnt ??= Mum;
if (this.hide) return; if (this.hide) return;
if (this.selectable) GUI.controls.check_bb(this); if (this.selectable) gui.controls.check_bb(this);
this.caret ??= -1; this.caret ??= -1;
/* if (!this.bb) /* if (!this.bb)
@ -162,7 +139,7 @@ Mum.text = Mum.extend({
var aa = [0,1].sub(params.anchor); var aa = [0,1].sub(params.anchor);
var pos = cursor.add(params.wh.scale(aa)).add(params.offset); var pos = cursor.add(params.wh.scale(aa)).add(params.offset);
gui.font_set(params.font); gui.font_set(params.font);
gui.text(params.str, pos, params.font_size, params.color, this.width, params.caret); render.text(params.str, pos, params.font_size, params.color, this.width, undefined, params.caret);
}, },
update_bb(cursor) { update_bb(cursor) {
@ -198,12 +175,12 @@ Mum.window = Mum.extend({
cursor ??= [0,0]; cursor ??= [0,0];
cnt ??= Mum; cnt ??= Mum;
var p = cursor.sub(this.wh.scale(this.anchor)).add(this.padding); var p = cursor.sub(this.wh.scale(this.anchor)).add(this.padding);
GUI.window(p,this.wh, this.color); render.window(p,this.wh, this.color);
this.bb = bbox.blwh(p, this.wh); this.bb = bbox.blwh(p, this.wh);
gui.flush(); gui.flush();
gui.scissor(p.x,p.y,this.wh.x,this.wh.y); gui.scissor(p.x,p.y,this.wh.x,this.wh.y);
this.max_width = this.width; this.max_width = this.width;
if (this.selectable) GUI.controls.check_bb(this); if (this.selectable) gui.controls.check_bb(this);
var pos = [this.bb.l, this.bb.t].add(this.padding); var pos = [this.bb.l, this.bb.t].add(this.padding);
this.items.forEach(function(item) { this.items.forEach(function(item) {
if (item.hide) return; if (item.hide) return;
@ -259,14 +236,6 @@ Mum.column = Mum.extend({
}, },
}); });
GUI.window = function(pos, wh, color)
{
var p = pos.slice();
p.x += wh.x/2;
p.y += wh.y/2;
render.box(p,wh,color);
}
Mum.debug_colors = { Mum.debug_colors = {
bounds: Color.red.slice(), bounds: Color.red.slice(),
margin: Color.blue.slice(), margin: Color.blue.slice(),
@ -275,7 +244,4 @@ Mum.debug_colors = {
Object.values(Mum.debug_colors).forEach(function(v) { v.a = 100; }); Object.values(Mum.debug_colors).forEach(function(v) { v.a = 100; });
return { return { Mum };
GUI,
Mum
};

View file

@ -1,5 +1,5 @@
input.keycodes = { input.keycodes = {
259: "back", 259: "backspace",
258: "tab", 258: "tab",
257: "enter", 257: "enter",
256: "escape", 256: "escape",
@ -111,7 +111,9 @@ prosperon.droppedfile = function(path)
var mousepos = [0,0]; var mousepos = [0,0];
prosperon.textinput = function(l){}; prosperon.textinput = function(c){
player[0].raw_input("char", "pressed", c);
};
prosperon.mousemove = function(pos, dx){ prosperon.mousemove = function(pos, dx){
mousepos = pos; mousepos = pos;
player[0].mouse_input(modstr() + "move", pos, dx); player[0].mouse_input(modstr() + "move", pos, dx);
@ -126,48 +128,46 @@ prosperon.mouseup = function(b){
player[0].raw_input(modstr() + input.mouse.button[b], "released"); player[0].raw_input(modstr() + input.mouse.button[b], "released");
}; };
input.mouse = { input.mouse = {};
screenpos() { return mousepos.slice(); }, input.mouse.screenpos = function() { return mousepos.slice(); };
worldpos() { return game.camera.view2world(mousepos); }, input.mouse.worldpos = function() { return game.camera.view2world(mousepos); };
disabled() { input.mouse_mode(1); }, input.mouse.disabled = function() { input.mouse_mode(1); };
normal() { input.mouse_mode(0); }, input.mouse.normal = function() { input.mouse_mode(0); };
input.mouse.mode = function(m) {
mode(m) { if (input.mouse.custom[m])
if (input.mouse.custom[m]) input.cursor_img(input.mouse.custom[m]);
input.cursor_img(input.mouse.custom[m]); else
else input.mouse_cursor(m);
input.mouse_cursor(m); };
},
set_custom_cursor(img, mode) { input.mouse.set_custom_cursor = function(img, mode) {
mode ??= input.mouse.cursor.default; mode ??= input.mouse.cursor.default;
if (!img) if (!img)
delete input.mouse.custom[mode]; delete input.mouse.custom[mode];
else { else {
input.cursor_img(img); input.cursor_img(img);
input.mouse.custom[mode] = img; input.mouse.custom[mode] = img;
} }
}, };
button: { /* left, right, middle mouse */ input.mouse.button = { /* left, right, middle mouse */
0: "lm", 0: "lm",
1: "rm", 1: "rm",
2: "mm" 2: "mm"
}, };
custom:[], input.mouse.custom = [];
cursor: { input.mouse.cursor = {
default: 0, default: 0,
arrow: 1, arrow: 1,
ibeam: 2, ibeam: 2,
cross: 3, cross: 3,
hand: 4, hand: 4,
ew: 5, ew: 5,
ns: 6, ns: 6,
nwse: 7, nwse: 7,
nesw: 8, nesw: 8,
resize: 9, resize: 9,
no: 10 no: 10
},
}; };
input.mouse.doc = {}; input.mouse.doc = {};

View file

@ -12,7 +12,7 @@ var HIT = {
var pq = physics.pos_query; var pq = physics.pos_query;
physics.pos_query = function(pos,give) { physics.pos_query = function(pos,give) {
give ??= 25; give ??= 25;
pq(pos,give); return pq(pos,give);
} }
physics.box_point_query = function(box,points) { physics.box_point_query = function(box,points) {

View file

@ -88,14 +88,13 @@ render.arrow = function(start, end, color, wingspan, wingangle) {
}; };
render.coordinate = function(pos, size, color) { render.coordinate = function(pos, size, color) {
color ??= Color.white; render.text(JSON.stringify(pos.map(p=>Math.round(p))), pos, size, color);
render.text(JSON.stringify(pos.map(p=>Math.round(p))), pos, size, color); render.point(pos, 2, color);
render.point(pos, 2, color);
} }
render.boundingbox = function(bb, color) { render.boundingbox = function(bb, color) {
color ??= Color.white; color ??= Color.white;
cmd_points(0, bbox.topoints(bb), color); render.poly(bbox.topoints(bb), color);
} }
render.rectangle = function(lowerleft, upperright, color) { render.rectangle = function(lowerleft, upperright, color) {
@ -110,6 +109,12 @@ render.box = function(pos, wh, color) {
render.rectangle(lower,upper,color); render.rectangle(lower,upper,color);
}; };
render.window = function(pos, wh, color) {
var p = pos.slice();
p = p.add(wh.scale(0.5));
render.box(p,wh,color);
};
render.text = function(str, pos, size, color, wrap, anchor, cursor) { render.text = function(str, pos, size, color, wrap, anchor, cursor) {
size ??= 1; size ??= 1;
color ??= Color.white; color ??= Color.white;
@ -122,7 +127,7 @@ render.text = function(str, pos, size, color, wrap, anchor, cursor) {
var w = bb.r*2; var w = bb.r*2;
var h = bb.t*2; var h = bb.t*2;
//gui.text draws with an anchor on top left corner //render.text draws with an anchor on top left corner
var p = pos.slice(); var p = pos.slice();
p.x -= w * anchor.x; p.x -= w * anchor.x;
bb.r += (w*anchor.x); bb.r += (w*anchor.x);

View file

@ -190,6 +190,8 @@ Cmdline.register_order("edit", function() {
say("No game to edit. Try making one with 'prosperon init'."); say("No game to edit. Try making one with 'prosperon init'.");
return; return;
} }
window.size = [1280, 720];
game.engine_start(function() { game.engine_start(function() {
global.mixin("scripts/editor.js"); global.mixin("scripts/editor.js");

View file

@ -48,13 +48,7 @@ cpTransform m3_to_cpt(HMM_Mat3 m)
} }
cpShape *phys2d_query_pos(cpVect pos) { cpShape *phys2d_query_pos(cpVect pos) {
cpShapeFilter filter; return cpSpacePointQueryNearest(space, pos, 0.f, allfilter, NULL);
filter.group = CP_NO_GROUP;
filter.mask = CP_ALL_CATEGORIES;
filter.categories = CP_ALL_CATEGORIES;
cpShape *find = cpSpacePointQueryNearest(space, pos, 0.f, filter, NULL);
return find;
} }

View file

@ -51,10 +51,7 @@ gameobject *pos2gameobject(HMM_Vec2 pos, float give) {
return shape2go(hit); return shape2go(hit);
for (int i = 0; i < arrlen(gameobjects); i++) { for (int i = 0; i < arrlen(gameobjects); i++) {
if (!gameobjects[i]->body) continue; float dist = HMM_DistV2(go_pos(gameobjects[i]),pos);
HMM_Vec2 gpos = go_pos(gameobjects[i]);
float dist = HMM_DistV2(gpos,pos);
if (dist <= give) return gameobjects[i]; if (dist <= give) return gameobjects[i];
} }

View file

@ -608,111 +608,6 @@ JSC_CCALL(emitter_start, start_emitter(js2emitter(this)))
JSC_CCALL(emitter_stop, stop_emitter(js2emitter(this))) JSC_CCALL(emitter_stop, stop_emitter(js2emitter(this)))
JSC_CCALL(emitter_emit, emitter_emit(js2emitter(this), js2number(argv[0]))) JSC_CCALL(emitter_emit, emitter_emit(js2emitter(this), js2number(argv[0])))
JSValue js_os_cwd(JSContext *js, JSValue this, int argc, JSValue *argv)
{
char cwd[PATH_MAX];
#ifndef __EMSCRIPTEN__
getcwd(cwd, sizeof(cwd));
#else
cwd[0] = '.';
cwd[1] = 0;
#endif
return str2js(cwd);
}
JSC_SCALL(os_env, ret = str2js(getenv(str)))
JSValue js_os_sys(JSContext *js, JSValue this, int argc, JSValue *argv)
{
#ifdef __linux__
return str2js("linux");
#elif defined(_WIN32) || defined(_WIN64)
return str2js("windows");
#elif defined(__APPLE__)
return str2js("macos");
#endif
return JS_UNDEFINED;
}
JSC_CCALL(os_quit, quit();)
JSC_CCALL(os_exit, exit(js2number(argv[0]));)
JSC_CCALL(os_reindex_static, cpSpaceReindexStatic(space));
JSC_CCALL(os_gc, script_gc());
JSC_SSCALL(os_eval, ret = script_eval(str, str2))
JSC_SCALL(os_capture, capture_screen(js2number(argv[1]), js2number(argv[2]), js2number(argv[4]), js2number(argv[5]), str))
JSC_CCALL(os_sprite,
if (js2boolean(argv[0])) return JS_GetClassProto(js,js_sprite_id);
return sprite2js(sprite_make());
)
JSC_CCALL(os_make_gameobject, return gameobject2js(MakeGameobject()))
JSC_CCALL(os_make_circle2d,
gameobject *go = js2gameobject(argv[0]);
struct phys2d_circle *circle = Make2DCircle(go);
JSValue circleval = JS_NewObject(js);
js_setprop_str(circleval, "id", ptr2js(circle));
js_setprop_str(circleval, "shape", ptr2js(&circle->shape));
return circleval;
)
JSC_CCALL(os_make_model,
gameobject *go = js2gameobject(argv[0]);
struct drawmodel *dm = make_drawmodel(go);
JSValue ret = JS_NewObject(js);
js_setprop_str(ret, "id", ptr2js(dm));
return ret;
)
JSC_CCALL(os_make_poly2d,
gameobject *go = js2gameobject(argv[0]);
struct phys2d_poly *poly = Make2DPoly(go);
phys2d_poly_setverts(poly, NULL);
JSValue polyval = JS_NewObject(js);
js_setprop_str(polyval, "id", ptr2js(poly));
js_setprop_str(polyval, "shape", ptr2js(&poly->shape));
return polyval;
)
JSC_CCALL(os_make_edge2d,
gameobject *go = js2gameobject(argv[0]);
struct phys2d_edge *edge = Make2DEdge(go);
HMM_Vec2 *points = js2cpvec2arr(argv[1]);
phys2d_edge_update_verts(edge, points);
arrfree(points);
JSValue edgeval = JS_NewObject(js);
js_setprop_str(edgeval, "id", ptr2js(edge));
js_setprop_str(edgeval, "shape", ptr2js(&edge->shape));
return edgeval;
)
JSC_SCALL(os_make_texture,
ret = texture2js(texture_from_file(str));
YughInfo("Made texture with %s", str);
JS_SetPropertyStr(js, ret, "path", JS_DupValue(js,argv[0]));
)
JSC_SCALL(os_system, system(str); )
static const JSCFunctionListEntry js_os_funcs[] = {
MIST_FUNC_DEF(os,sprite,1),
MIST_FUNC_DEF(os, cwd, 0),
MIST_FUNC_DEF(os, env, 1),
MIST_FUNC_DEF(os, sys, 0),
MIST_FUNC_DEF(os, system, 1),
MIST_FUNC_DEF(os, quit, 0),
MIST_FUNC_DEF(os, exit, 1),
MIST_FUNC_DEF(os, reindex_static, 0),
MIST_FUNC_DEF(os, gc, 0),
MIST_FUNC_DEF(os, capture, 5),
MIST_FUNC_DEF(os, eval, 2),
MIST_FUNC_DEF(os, make_gameobject, 0),
MIST_FUNC_DEF(os, make_circle2d, 1),
MIST_FUNC_DEF(os, make_poly2d, 1),
MIST_FUNC_DEF(os, make_edge2d, 1),
MIST_FUNC_DEF(os, make_model, 2),
MIST_FUNC_DEF(os, make_texture, 1),
};
JSC_CCALL(render_grid, draw_grid(js2number(argv[0]), js2number(argv[1]), js2color(argv[2]));) JSC_CCALL(render_grid, draw_grid(js2number(argv[0]), js2number(argv[1]), js2color(argv[2]));)
JSC_CCALL(render_point, draw_cppoint(js2vec2(argv[0]), js2number(argv[1]), js2color(argv[2]))) JSC_CCALL(render_point, draw_cppoint(js2vec2(argv[0]), js2number(argv[1]), js2color(argv[2])))
@ -1030,8 +925,7 @@ JSC_CCALL(physics_set_cat_mask, set_cat_mask(js2number(argv[0]), js2bitmask(argv
JSC_CCALL(physics_pos_query, JSC_CCALL(physics_pos_query,
gameobject *go = pos2gameobject(js2vec2(argv[0]), js2number(argv[1])); gameobject *go = pos2gameobject(js2vec2(argv[0]), js2number(argv[1]));
JSValue ret = go ? JS_DupValue(js,go->ref) : JS_UNDEFINED; return go ? JS_DupValue(js,go->ref) : JS_UNDEFINED;
return ret;
) )
JSC_CCALL(physics_closest_point, JSC_CCALL(physics_closest_point,
@ -1207,8 +1101,14 @@ static JSValue js_window_set_size(JSContext *js, JSValue this, JSValue v) {
return JS_UNDEFINED; return JS_UNDEFINED;
} }
static JSValue js_window_get_rendersize(JSContext *js, JSValue this) {
JSC_GETSET_APPLY(window, rendersize, vec2) window *w = js2window(this);
if (w->rendersize.x == 0 || w->rendersize.y == 0) return vec22js(w->size);
return vec22js(w->rendersize);
}
static JSValue js_window_set_rendersize(JSContext *js, JSValue this, JSValue v) {
js2window(this)->rendersize = js2vec2(v);
}
JSC_GETSET(window, mode, number) JSC_GETSET(window, mode, number)
static JSValue js_window_get_fullscreen(JSContext *js, JSValue this) { return boolean2js(js2window(this)->fullscreen); } static JSValue js_window_get_fullscreen(JSContext *js, JSValue this) { return boolean2js(js2window(this)->fullscreen); }
static JSValue js_window_set_fullscreen(JSContext *js, JSValue this, JSValue v) { window_setfullscreen(js2window(this), js2boolean(v)); } static JSValue js_window_set_fullscreen(JSContext *js, JSValue this, JSValue v) { window_setfullscreen(js2window(this), js2boolean(v)); }
@ -1235,12 +1135,13 @@ static const JSCFunctionListEntry js_window_funcs[] = {
}; };
JSValue js_gameobject_set_pos(JSContext *js, JSValue this, JSValue val) { JSValue js_gameobject_set_pos(JSContext *js, JSValue this, JSValue val) {
gameobject *go = js2gameobject(this); cpBody *b = js2gameobject(this)->body;
cpBodySetPosition(go->body, js2vec2(val).cp); cpBodySetPosition(b, js2cvec2(val));
if (go->phys == CP_BODY_TYPE_STATIC) if (cpBodyGetType(b) == CP_BODY_TYPE_STATIC)
cpSpaceReindexShapesForBody(space, go->body); cpSpaceReindexShapesForBody(space, b);
return JS_UNDEFINED;
} }
JSValue js_gameobject_get_pos(JSContext *js, JSValue this) { return vec22js((HMM_Vec2)cpBodyGetPosition(js2gameobject(this)->body)); } JSValue js_gameobject_get_pos(JSContext *js, JSValue this) { return cvec22js(cpBodyGetPosition(js2gameobject(this)->body)); }
JSValue js_gameobject_set_angle (JSContext *js, JSValue this, JSValue val) { cpBodySetAngle(js2gameobject(this)->body, HMM_TurnToRad*js2number(val)); } JSValue js_gameobject_set_angle (JSContext *js, JSValue this, JSValue val) { cpBodySetAngle(js2gameobject(this)->body, HMM_TurnToRad*js2number(val)); }
JSValue js_gameobject_get_angle (JSContext *js, JSValue this) { return number2js(HMM_RadToTurn*cpBodyGetAngle(js2gameobject(this)->body)); } JSValue js_gameobject_get_angle (JSContext *js, JSValue this) { return number2js(HMM_RadToTurn*cpBodyGetAngle(js2gameobject(this)->body)); }
JSC_GETSET_BODY(velocity, Velocity, cvec2) JSC_GETSET_BODY(velocity, Velocity, cvec2)
@ -1511,6 +1412,117 @@ static const JSCFunctionListEntry js_nota_funcs[] = {
MIST_FUNC_DEF(nota, decode, 1) MIST_FUNC_DEF(nota, decode, 1)
}; };
JSValue js_os_cwd(JSContext *js, JSValue this, int argc, JSValue *argv)
{
char cwd[PATH_MAX];
#ifndef __EMSCRIPTEN__
getcwd(cwd, sizeof(cwd));
#else
cwd[0] = '.';
cwd[1] = 0;
#endif
return str2js(cwd);
}
JSC_SCALL(os_env, ret = str2js(getenv(str)))
JSValue js_os_sys(JSContext *js, JSValue this, int argc, JSValue *argv)
{
#ifdef __linux__
return str2js("linux");
#elif defined(_WIN32) || defined(_WIN64)
return str2js("windows");
#elif defined(__APPLE__)
return str2js("macos");
#endif
return JS_UNDEFINED;
}
JSC_CCALL(os_quit, quit();)
JSC_CCALL(os_exit, exit(js2number(argv[0]));)
JSC_CCALL(os_reindex_static, cpSpaceReindexStatic(space));
JSC_CCALL(os_gc, script_gc());
JSC_SSCALL(os_eval, ret = script_eval(str, str2))
JSC_SCALL(os_capture, capture_screen(js2number(argv[1]), js2number(argv[2]), js2number(argv[4]), js2number(argv[5]), str))
JSC_CCALL(os_sprite,
if (js2boolean(argv[0])) return JS_GetClassProto(js,js_sprite_id);
return sprite2js(sprite_make());
)
JSC_CCALL(os_make_gameobject,
ret = gameobject2js(MakeGameobject());
JS_SetPropertyFunctionList(js, ret, js_gameobject_funcs, countof(js_gameobject_funcs));
return ret;
)
JSC_CCALL(os_make_circle2d,
gameobject *go = js2gameobject(argv[0]);
struct phys2d_circle *circle = Make2DCircle(go);
JSValue circleval = JS_NewObject(js);
js_setprop_str(circleval, "id", ptr2js(circle));
js_setprop_str(circleval, "shape", ptr2js(&circle->shape));
return circleval;
)
JSC_CCALL(os_make_model,
gameobject *go = js2gameobject(argv[0]);
struct drawmodel *dm = make_drawmodel(go);
JSValue ret = JS_NewObject(js);
js_setprop_str(ret, "id", ptr2js(dm));
return ret;
)
JSC_CCALL(os_make_poly2d,
gameobject *go = js2gameobject(argv[0]);
struct phys2d_poly *poly = Make2DPoly(go);
phys2d_poly_setverts(poly, NULL);
JSValue polyval = JS_NewObject(js);
js_setprop_str(polyval, "id", ptr2js(poly));
js_setprop_str(polyval, "shape", ptr2js(&poly->shape));
return polyval;
)
JSC_CCALL(os_make_edge2d,
gameobject *go = js2gameobject(argv[0]);
struct phys2d_edge *edge = Make2DEdge(go);
HMM_Vec2 *points = js2cpvec2arr(argv[1]);
phys2d_edge_update_verts(edge, points);
arrfree(points);
JSValue edgeval = JS_NewObject(js);
js_setprop_str(edgeval, "id", ptr2js(edge));
js_setprop_str(edgeval, "shape", ptr2js(&edge->shape));
return edgeval;
)
JSC_SCALL(os_make_texture,
ret = texture2js(texture_from_file(str));
YughInfo("Made texture with %s", str);
JS_SetPropertyStr(js, ret, "path", JS_DupValue(js,argv[0]));
)
JSC_SCALL(os_system, system(str); )
static const JSCFunctionListEntry js_os_funcs[] = {
MIST_FUNC_DEF(os,sprite,1),
MIST_FUNC_DEF(os, cwd, 0),
MIST_FUNC_DEF(os, env, 1),
MIST_FUNC_DEF(os, sys, 0),
MIST_FUNC_DEF(os, system, 1),
MIST_FUNC_DEF(os, quit, 0),
MIST_FUNC_DEF(os, exit, 1),
MIST_FUNC_DEF(os, reindex_static, 0),
MIST_FUNC_DEF(os, gc, 0),
MIST_FUNC_DEF(os, capture, 5),
MIST_FUNC_DEF(os, eval, 2),
MIST_FUNC_DEF(os, make_gameobject, 0),
MIST_FUNC_DEF(os, make_circle2d, 1),
MIST_FUNC_DEF(os, make_poly2d, 1),
MIST_FUNC_DEF(os, make_edge2d, 1),
MIST_FUNC_DEF(os, make_model, 2),
MIST_FUNC_DEF(os, make_texture, 1),
};
#include "steam.h" #include "steam.h"
void ffi_load() { void ffi_load() {

View file

@ -114,7 +114,6 @@ JS_SetPropertyFunctionList(js, TYPE##_proto, js_##TYPE##_funcs, countof(js_##TYP
JS_SetPropertyStr(js, TYPE##_proto, "memid", JS_NewCFunction(js, &js_##TYPE##_memid, "memid", 0)); \ JS_SetPropertyStr(js, TYPE##_proto, "memid", JS_NewCFunction(js, &js_##TYPE##_memid, "memid", 0)); \
JS_SetClassProto(js, js_##TYPE##_id, TYPE##_proto); \ JS_SetClassProto(js, js_##TYPE##_id, TYPE##_proto); \
#define countof(x) (sizeof(x)/sizeof((x)[0])) #define countof(x) (sizeof(x)/sizeof((x)[0]))
void ffi_load(); void ffi_load();

View file

@ -29,15 +29,8 @@ extern HMM_Vec3 dirl_pos;
extern HMM_Mat4 projection; extern HMM_Mat4 projection;
extern HMM_Mat4 hudproj; extern HMM_Mat4 hudproj;
extern HMM_Mat4 useproj; extern HMM_Mat4 useproj;
struct camera3d {
};
typedef struct camera3d camera3d;
struct draw_p { struct draw_p {
float x; float x;
float y; float y;
@ -61,12 +54,8 @@ void openglRender(struct window *window, gameobject *cam, float zoom);
void opengl_rendermode(enum RenderMode r); void opengl_rendermode(enum RenderMode r);
void openglInit3d(struct window *window); void openglInit3d(struct window *window);
void openglRender3d(struct window *window, camera3d *camera);
void capture_screen(int x, int y, int w, int h, const char *path); void capture_screen(int x, int y, int w, int h, const char *path);
HMM_Vec2 world2screen(HMM_Vec2 pos);
HMM_Vec2 screen2world(HMM_Vec2 pos);
void gif_rec_start(int w, int h, int cpf, int bitdepth); void gif_rec_start(int w, int h, int cpf, int bitdepth);
void gif_rec_end(const char *path); void gif_rec_end(const char *path);

View file

@ -92,6 +92,7 @@ void c_clean() {
void c_event(const sapp_event *e) void c_event(const sapp_event *e)
{ {
char lcfmt[5];
switch (e->type) { switch (e->type) {
case SAPP_EVENTTYPE_MOUSE_MOVE: case SAPP_EVENTTYPE_MOUSE_MOVE:
script_evalf("prosperon.mousemove([%g, %g], [%g, %g]);", e->mouse_x, mainwin.size.y -e->mouse_y, e->mouse_dx, -e->mouse_dy); script_evalf("prosperon.mousemove([%g, %g], [%g, %g]);", e->mouse_x, mainwin.size.y -e->mouse_y, e->mouse_dx, -e->mouse_dy);
@ -118,7 +119,8 @@ void c_event(const sapp_event *e)
break; break;
case SAPP_EVENTTYPE_CHAR: case SAPP_EVENTTYPE_CHAR:
script_evalf("prosperon.textinput(`\\%lc`);", e->char_code); snprintf(lcfmt, 5, "%lc", e->char_code);
script_evalf("prosperon.textinput(`%s`);", lcfmt);
break; break;
case SAPP_EVENTTYPE_RESIZED: case SAPP_EVENTTYPE_RESIZED: