bug fixes; remove texture anims
This commit is contained in:
parent
444fb98125
commit
a1aff79d5c
2
Makefile
2
Makefile
|
@ -51,7 +51,7 @@ ifdef NQOA
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(DBG),1)
|
ifeq ($(DBG),1)
|
||||||
CPPFLAGS += -g
|
CPPFLAGS += -g -fsanitize=address
|
||||||
INFO += _dbg
|
INFO += _dbg
|
||||||
else
|
else
|
||||||
CPPFLAGS += -DNDEBUG
|
CPPFLAGS += -DNDEBUG
|
||||||
|
|
|
@ -95,14 +95,14 @@
|
||||||
/* dump the occurence of the automatic GC */
|
/* dump the occurence of the automatic GC */
|
||||||
#define DUMP_GC
|
#define DUMP_GC
|
||||||
/* dump objects freed by the garbage collector */
|
/* dump objects freed by the garbage collector */
|
||||||
//#define DUMP_GC_FREE
|
#define DUMP_GC_FREE
|
||||||
/* dump objects leaking when freeing the runtime */
|
/* dump objects leaking when freeing the runtime */
|
||||||
#define DUMP_LEAKS 1
|
#define DUMP_LEAKS 1
|
||||||
/* dump memory usage before running the garbage collector */
|
/* dump memory usage before running the garbage collector */
|
||||||
//#define DUMP_MEM
|
#define DUMP_MEM
|
||||||
//#define DUMP_OBJECTS /* dump objects in JS_FreeContext */
|
#define DUMP_OBJECTS /* dump objects in JS_FreeContext */
|
||||||
//#define DUMP_ATOMS /* dump atoms in JS_FreeContext */
|
#define DUMP_ATOMS /* dump atoms in JS_FreeContext */
|
||||||
//#define DUMP_SHAPES /* dump shapes in JS_FreeContext */
|
#define DUMP_SHAPES /* dump shapes in JS_FreeContext */
|
||||||
//#define DUMP_MODULE_RESOLVE
|
//#define DUMP_MODULE_RESOLVE
|
||||||
//#define DUMP_PROMISE
|
//#define DUMP_PROMISE
|
||||||
//#define DUMP_READ_OBJECT
|
//#define DUMP_READ_OBJECT
|
||||||
|
|
|
@ -472,8 +472,8 @@ Object.hide = function(obj,...props)
|
||||||
for (var prop of props) {
|
for (var prop of props) {
|
||||||
var p = Object.getOwnPropertyDescriptor(obj,prop);
|
var p = Object.getOwnPropertyDescriptor(obj,prop);
|
||||||
if (!p) {
|
if (!p) {
|
||||||
Log.warn(`No property of name ${prop}.`);
|
Log.info(`No property of name ${prop}.`);
|
||||||
return;
|
continue;
|
||||||
}
|
}
|
||||||
p.enumerable = false;
|
p.enumerable = false;
|
||||||
Object.defineProperty(obj, prop, p);
|
Object.defineProperty(obj, prop, p);
|
||||||
|
|
|
@ -44,7 +44,7 @@ var component = {
|
||||||
|
|
||||||
make(go) {
|
make(go) {
|
||||||
var nc = Object.create(this);
|
var nc = Object.create(this);
|
||||||
nc.gameobject = go;
|
// nc.gameobject = go;
|
||||||
Object.assign(nc, this._enghook(go.body));
|
Object.assign(nc, this._enghook(go.body));
|
||||||
nc.sync();
|
nc.sync();
|
||||||
assign_impl(nc,this.impl);
|
assign_impl(nc,this.impl);
|
||||||
|
@ -571,7 +571,8 @@ component.edge2d = Object.copy(collider2d, {
|
||||||
var spoints = this.cpoints.slice();
|
var spoints = this.cpoints.slice();
|
||||||
|
|
||||||
if (this.flipx) {
|
if (this.flipx) {
|
||||||
for (var i = spoints.length-1; i >= 0; i--) {
|
var endcap = Spline.is_bezier(this.type) ? spoints.length-2 : spoints.length-1;
|
||||||
|
for (var i = endcap; 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);
|
||||||
|
@ -653,6 +654,11 @@ component.edge2d = Object.copy(collider2d, {
|
||||||
pick(pos) {
|
pick(pos) {
|
||||||
var i = Gizmos.pick_gameobject_points(pos, this.gameobject, this.cpoints);
|
var i = Gizmos.pick_gameobject_points(pos, this.gameobject, this.cpoints);
|
||||||
var p = this.cpoints[i];
|
var p = this.cpoints[i];
|
||||||
|
if (!p) return undefined;
|
||||||
|
|
||||||
|
if (Spline.is_catmull(this.type))
|
||||||
|
return make_point_obj(this,p);
|
||||||
|
|
||||||
var that = this.gameobject;
|
var that = this.gameobject;
|
||||||
var me = this;
|
var me = this;
|
||||||
if (p) {
|
if (p) {
|
||||||
|
@ -677,8 +683,6 @@ component.edge2d = Object.copy(collider2d, {
|
||||||
}
|
}
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
return undefined;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
pick_all() {
|
pick_all() {
|
||||||
|
@ -791,8 +795,6 @@ bucket.inputs['C-lm'] = function() {
|
||||||
if (this.cpoints.length >= 2)
|
if (this.cpoints.length >= 2)
|
||||||
idx = cmd(59, screen2world(Mouse.pos).sub(this.gameobject.pos), this.cpoints, 400);
|
idx = cmd(59, screen2world(Mouse.pos).sub(this.gameobject.pos), this.cpoints, 400);
|
||||||
|
|
||||||
console.say("new point");
|
|
||||||
|
|
||||||
if (idx === this.cpoints.length)
|
if (idx === this.cpoints.length)
|
||||||
this.cpoints.push(this.gameobject.world2this(screen2world(Mouse.pos)));
|
this.cpoints.push(this.gameobject.world2this(screen2world(Mouse.pos)));
|
||||||
else
|
else
|
||||||
|
|
|
@ -113,6 +113,16 @@ var Debug = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Debug.assert = function(b, str)
|
||||||
|
{
|
||||||
|
str ??= "";
|
||||||
|
|
||||||
|
if (!b) {
|
||||||
|
console.error(`Assertion failed. ${str}`);
|
||||||
|
Game.quit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Debug.Options = { };
|
Debug.Options = { };
|
||||||
Debug.Options.Color = {
|
Debug.Options.Color = {
|
||||||
set trigger(x) { cmd(17,x); },
|
set trigger(x) { cmd(17,x); },
|
||||||
|
|
|
@ -319,7 +319,7 @@ var editor = {
|
||||||
// this.backshots.push(this.edit_level.save());
|
// this.backshots.push(this.edit_level.save());
|
||||||
var dd = this.snapshots.pop();
|
var dd = this.snapshots.pop();
|
||||||
Object.dainty_assign(this.edit_level, dd);
|
Object.dainty_assign(this.edit_level, dd);
|
||||||
this.edit_level._ed.check_dirty();
|
this.edit_level.check_dirty();
|
||||||
},
|
},
|
||||||
|
|
||||||
restore_buffer() {
|
restore_buffer() {
|
||||||
|
@ -395,7 +395,7 @@ var editor = {
|
||||||
Debug.coordinate([0,0]);
|
Debug.coordinate([0,0]);
|
||||||
},
|
},
|
||||||
|
|
||||||
gui() {
|
gui() {
|
||||||
/* Clean out killed objects */
|
/* Clean out killed objects */
|
||||||
this.selectlist = this.selectlist.filter(function(x) { return x.alive; });
|
this.selectlist = this.selectlist.filter(function(x) { return x.alive; });
|
||||||
|
|
||||||
|
@ -429,14 +429,14 @@ var editor = {
|
||||||
if (alldirty)
|
if (alldirty)
|
||||||
lvl._ed.dirty = true;
|
lvl._ed.dirty = true;
|
||||||
else {
|
else {
|
||||||
lvl._ed.check_dirty();
|
lvl.check_dirty();
|
||||||
if (lvl._ed.dirty) alldirty = true;
|
if (lvl._ed.dirty) alldirty = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lvlchain.reverse();
|
lvlchain.reverse();
|
||||||
lvlchain.forEach(function(x,i) {
|
lvlchain.forEach(function(x,i) {
|
||||||
depth = i;
|
depth = i;
|
||||||
var lvlstr = x._ed.namestr();
|
var lvlstr = x.namestr();
|
||||||
if (i === lvlchain.length-1) lvlstr += "[this]";
|
if (i === lvlchain.length-1) lvlstr += "[this]";
|
||||||
GUI.text(lvlstr, [0, ypos], 1, editor.color_depths[depth]);
|
GUI.text(lvlstr, [0, ypos], 1, editor.color_depths[depth]);
|
||||||
|
|
||||||
|
@ -449,7 +449,7 @@ var editor = {
|
||||||
|
|
||||||
this.selectlist.forEach(function(x) {
|
this.selectlist.forEach(function(x) {
|
||||||
var sname = x.__proto__.toString();
|
var sname = x.__proto__.toString();
|
||||||
x._ed.check_dirty();
|
x.check_dirty();
|
||||||
if (x._ed.dirty) sname += "*";
|
if (x._ed.dirty) sname += "*";
|
||||||
|
|
||||||
GUI.text(sname, x.screenpos().add([0, 32]), 1, Color.editor.ur);
|
GUI.text(sname, x.screenpos().add([0, 32]), 1, Color.editor.ur);
|
||||||
|
@ -457,7 +457,7 @@ var editor = {
|
||||||
});
|
});
|
||||||
|
|
||||||
Object.entries(thiso.objects).forEach(function(x) {
|
Object.entries(thiso.objects).forEach(function(x) {
|
||||||
var p = x[1]._ed.namestr();
|
var p = x[1].namestr();
|
||||||
GUI.text(p, x[1].screenpos().add([0,16]),1,editor.color_depths[depth]);
|
GUI.text(p, x[1].screenpos().add([0,16]),1,editor.color_depths[depth]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -554,7 +554,6 @@ var editor = {
|
||||||
lvl_history: [],
|
lvl_history: [],
|
||||||
|
|
||||||
load(file) {
|
load(file) {
|
||||||
Log.warn("LOADING " + file);
|
|
||||||
var ur = prototypes.get_ur(file);
|
var ur = prototypes.get_ur(file);
|
||||||
if (!ur) return;
|
if (!ur) return;
|
||||||
var obj = editor.edit_level.spawn(ur);
|
var obj = editor.edit_level.spawn(ur);
|
||||||
|
@ -617,7 +616,7 @@ editor.inputs.post = function() {
|
||||||
};
|
};
|
||||||
editor.inputs.release_post = function() {
|
editor.inputs.release_post = function() {
|
||||||
editor.snapshot();
|
editor.snapshot();
|
||||||
editor.edit_level._ed.check_dirty();
|
editor.edit_level.check_dirty();
|
||||||
};
|
};
|
||||||
editor.inputs['C-a'] = function() {
|
editor.inputs['C-a'] = function() {
|
||||||
if (!editor.selectlist.empty) { editor.unselect(); return; }
|
if (!editor.selectlist.empty) { editor.unselect(); return; }
|
||||||
|
@ -833,7 +832,7 @@ editor.inputs['C-s'] = function() {
|
||||||
} else if (editor.selectlist.length === 1)
|
} else if (editor.selectlist.length === 1)
|
||||||
saveobj = editor.selectlist[0];
|
saveobj = editor.selectlist[0];
|
||||||
|
|
||||||
// saveobj._ed.check_dirty();
|
// saveobj.check_dirty();
|
||||||
// if (!saveobj._ed.dirty) return;
|
// if (!saveobj._ed.dirty) return;
|
||||||
|
|
||||||
var savejs = saveobj.json_obj();
|
var savejs = saveobj.json_obj();
|
||||||
|
@ -844,7 +843,7 @@ editor.inputs['C-s'] = function() {
|
||||||
IO.slurpwrite(JSON.stringify(saveobj.__proto__,null,1), path);
|
IO.slurpwrite(JSON.stringify(saveobj.__proto__,null,1), path);
|
||||||
Log.warn(`Wrote to file ${path}`);
|
Log.warn(`Wrote to file ${path}`);
|
||||||
|
|
||||||
Object.values(saveobj.objects).forEach(function(x) { x._ed.check_dirty(); });
|
Object.values(saveobj.objects).forEach(function(x) { x.check_dirty(); });
|
||||||
|
|
||||||
|
|
||||||
Game.all_objects(function(x) {
|
Game.all_objects(function(x) {
|
||||||
|
@ -852,7 +851,7 @@ editor.inputs['C-s'] = function() {
|
||||||
if (!('_ed' in x)) return;
|
if (!('_ed' in x)) return;
|
||||||
if (x._ed.dirty) return;
|
if (x._ed.dirty) return;
|
||||||
x.revert();
|
x.revert();
|
||||||
x._ed.check_dirty();
|
x.check_dirty();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
editor.inputs['C-s'].doc = "Save selected.";
|
editor.inputs['C-s'].doc = "Save selected.";
|
||||||
|
|
|
@ -337,6 +337,9 @@ Spline.sample_angle = function(type, points, angle) {
|
||||||
return spline_cmd(0, type, points[0].length, points, angle);
|
return spline_cmd(0, type, points[0].length, points, angle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Spline.is_bezier = function(t) { return t === Spline.type.bezier; }
|
||||||
|
Spline.is_catmull = function(t) { return t === Spline.type.catmull; }
|
||||||
|
|
||||||
Spline.bezier2catmull = function(b)
|
Spline.bezier2catmull = function(b)
|
||||||
{
|
{
|
||||||
var c = [];
|
var c = [];
|
||||||
|
@ -455,37 +458,15 @@ var Game = {
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
quit()
|
quit() { sys_cmd(0); },
|
||||||
{
|
pause() { sys_cmd(3); },
|
||||||
sys_cmd(0);
|
stop() { Game.pause(); },
|
||||||
},
|
step() { sys_cmd(4);},
|
||||||
|
|
||||||
pause()
|
|
||||||
{
|
|
||||||
sys_cmd(3);
|
|
||||||
},
|
|
||||||
|
|
||||||
stop()
|
|
||||||
{
|
|
||||||
Game.pause();
|
|
||||||
},
|
|
||||||
|
|
||||||
step()
|
|
||||||
{
|
|
||||||
sys_cmd(4);
|
|
||||||
},
|
|
||||||
|
|
||||||
editor_mode(m) { sys_cmd(10, m); },
|
editor_mode(m) { sys_cmd(10, m); },
|
||||||
|
|
||||||
playing() { return sys_cmd(5); },
|
playing() { return sys_cmd(5); },
|
||||||
paused() { return sys_cmd(6); },
|
paused() { return sys_cmd(6); },
|
||||||
stepping() {
|
stepping() { return cmd(79); },
|
||||||
return cmd(79); },
|
play() { sys_cmd(1); },
|
||||||
|
|
||||||
play()
|
|
||||||
{
|
|
||||||
sys_cmd(1);
|
|
||||||
},
|
|
||||||
|
|
||||||
wait_fns: [],
|
wait_fns: [],
|
||||||
|
|
||||||
|
@ -525,15 +506,14 @@ Register.update.register(Game.exec, Game);
|
||||||
|
|
||||||
load("scripts/entity.js");
|
load("scripts/entity.js");
|
||||||
|
|
||||||
|
|
||||||
function world_start() {
|
function world_start() {
|
||||||
globalThis.Primum = Object.create(gameobject);
|
globalThis.Primum = Object.create(gameobject);
|
||||||
Primum.objects = {};
|
Primum.objects = {};
|
||||||
|
Primum.check_dirty = function() {};
|
||||||
|
Primum.namestr = function(){};
|
||||||
Primum._ed = {
|
Primum._ed = {
|
||||||
selectable:false,
|
selectable:false,
|
||||||
check_dirty() {},
|
|
||||||
dirty:false,
|
dirty:false,
|
||||||
namestr(){},
|
|
||||||
};
|
};
|
||||||
Primum.toString = function() { return "Primum"; };
|
Primum.toString = function() { return "Primum"; };
|
||||||
Primum.ur = undefined;
|
Primum.ur = undefined;
|
||||||
|
|
|
@ -56,6 +56,25 @@ actor.remaster = function(to){
|
||||||
};
|
};
|
||||||
|
|
||||||
var gameobject = {
|
var gameobject = {
|
||||||
|
check_dirty() {
|
||||||
|
this._ed.urdiff = this.json_obj();
|
||||||
|
this._ed.dirty = !this._ed.urdiff.empty;
|
||||||
|
var lur = ur[this.level.ur];
|
||||||
|
if (!lur) return;
|
||||||
|
var lur = lur.objects[this.toString()];
|
||||||
|
var d = ediff(this._ed.urdiff,lur);
|
||||||
|
if (!d || d.empty)
|
||||||
|
this._ed.inst = true;
|
||||||
|
else
|
||||||
|
this._ed.inst = false;
|
||||||
|
},
|
||||||
|
namestr() {
|
||||||
|
var s = this.toString();
|
||||||
|
if (this._ed.dirty)
|
||||||
|
if (this._ed.inst) s += "#";
|
||||||
|
else s += "*";
|
||||||
|
return s;
|
||||||
|
},
|
||||||
full_path() {
|
full_path() {
|
||||||
return this.path_from(Primum);
|
return this.path_from(Primum);
|
||||||
},
|
},
|
||||||
|
@ -115,9 +134,10 @@ var gameobject = {
|
||||||
cmd(36,this.body,x)
|
cmd(36,this.body,x)
|
||||||
},
|
},
|
||||||
get scale() {
|
get scale() {
|
||||||
if (!this.level) return this.gscale();
|
Debug.assert(this.level, `No level set on ${this.toString()}`);
|
||||||
return this.gscale().map((x,i) => x/this.level.gscale()[i]);
|
return this.gscale().map((x,i) => x/this.level.gscale()[i]);
|
||||||
},
|
},
|
||||||
|
|
||||||
set scale(x) {
|
set scale(x) {
|
||||||
if (typeof x === 'number')
|
if (typeof x === 'number')
|
||||||
x = [x,x];
|
x = [x,x];
|
||||||
|
@ -134,21 +154,18 @@ var gameobject = {
|
||||||
},
|
},
|
||||||
|
|
||||||
set pos(x) {
|
set pos(x) {
|
||||||
if (!this.level)
|
Debug.assert(this.level, `Entity ${this.toString()} has no level.`);
|
||||||
this.set_worldpos(x);
|
this.set_worldpos(this.level.this2world(x));
|
||||||
else
|
|
||||||
this.set_worldpos(this.level.this2world(x));
|
|
||||||
},
|
},
|
||||||
|
|
||||||
get pos() {
|
get pos() {
|
||||||
if (!this.level) return this.worldpos();
|
Debug.assert(this.level, `Entity ${this.toString()} has no level.`);
|
||||||
return this.level.world2this(this.worldpos());
|
return this.level.world2this(this.worldpos());
|
||||||
},
|
},
|
||||||
|
|
||||||
get draw_layer() { return cmd(171, this.body); },
|
get draw_layer() { return cmd(171, this.body); },
|
||||||
set draw_layer(x) { cmd(172, this.body, x); },
|
set draw_layer(x) { cmd(172, this.body, x); },
|
||||||
|
|
||||||
|
|
||||||
get elasticity() { return cmd(107,this.body); },
|
get elasticity() { return cmd(107,this.body); },
|
||||||
set elasticity(x) { cmd(106,this.body,x); },
|
set elasticity(x) { cmd(106,this.body,x); },
|
||||||
|
|
||||||
|
@ -186,7 +203,8 @@ var gameobject = {
|
||||||
worldangle() { return Math.rad2deg(q_body(2,this.body))%360; },
|
worldangle() { return Math.rad2deg(q_body(2,this.body))%360; },
|
||||||
sworldangle(x) { set_body(0,this.body,Math.deg2rad(x)); },
|
sworldangle(x) { set_body(0,this.body,Math.deg2rad(x)); },
|
||||||
get angle() {
|
get angle() {
|
||||||
if (!this.level) return this.worldangle();
|
Debug.assert(this.level, `No level set on ${this.toString()}`);
|
||||||
|
|
||||||
return this.worldangle() - this.level.worldangle();
|
return this.worldangle() - this.level.worldangle();
|
||||||
},
|
},
|
||||||
set angle(x) {
|
set angle(x) {
|
||||||
|
@ -208,9 +226,7 @@ var gameobject = {
|
||||||
set_body(0,this.body,x);
|
set_body(0,this.body,x);
|
||||||
},
|
},
|
||||||
|
|
||||||
rotate(x) {
|
rotate(x) { this.sworldangle(this.worldangle()+x); },
|
||||||
this.sworldangle(this.worldangle()+x);
|
|
||||||
},
|
|
||||||
|
|
||||||
spawn_from_instance(inst) {
|
spawn_from_instance(inst) {
|
||||||
return this.spawn(inst.ur, inst);
|
return this.spawn(inst.ur, inst);
|
||||||
|
@ -231,6 +247,7 @@ var gameobject = {
|
||||||
|
|
||||||
/* Reparent 'this' to be 'parent's child */
|
/* Reparent 'this' to be 'parent's child */
|
||||||
reparent(parent) {
|
reparent(parent) {
|
||||||
|
Debug.assert(parent, `Tried to reparent ${this.toString()} to nothing.`);
|
||||||
if (this.level === parent)
|
if (this.level === parent)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -277,21 +294,21 @@ var gameobject = {
|
||||||
set_body(13, this.body, x);
|
set_body(13, this.body, x);
|
||||||
},
|
},
|
||||||
|
|
||||||
pulse(vec) { set_body(4, this.body, vec);},
|
pulse(vec) { set_body(4, this.body, vec);},
|
||||||
shove(vec) { set_body(12,this.body,vec);},
|
shove(vec) { set_body(12,this.body,vec);},
|
||||||
shove_at(vec, at) { set_body(14,this.body,vec,at); },
|
shove_at(vec, at) { set_body(14,this.body,vec,at); },
|
||||||
world2this(pos) { return cmd(70, this.body, pos); },
|
world2this(pos) { return cmd(70, this.body, pos); },
|
||||||
this2world(pos) { return cmd(71, this.body, pos); },
|
this2world(pos) { return cmd(71, this.body, pos); },
|
||||||
this2screen(pos) { return world2screen(this.this2world(pos)); },
|
this2screen(pos) { return world2screen(this.this2world(pos)); },
|
||||||
dir_world2this(dir) { return cmd(160, this.body, dir); },
|
dir_world2this(dir) { return cmd(160, this.body, dir); },
|
||||||
dir_this2world(dir) { return cmd(161, this.body, dir); },
|
dir_this2world(dir) { return cmd(161, this.body, dir); },
|
||||||
|
|
||||||
set layer(x) { cmd(75,this.body,x); },
|
set layer(x) { cmd(75,this.body,x); },
|
||||||
get layer() { cmd(77,this.body); },
|
get layer() { cmd(77,this.body); },
|
||||||
alive() { return this.body >= 0; },
|
alive() { return this.body >= 0; },
|
||||||
in_air() { return q_body(7, this.body);},
|
in_air() { return q_body(7, this.body);},
|
||||||
|
|
||||||
hide() { this.components.forEach(function(x) { x.hide(); }); this.objects.forEach(function(x) { x.hide(); }); },
|
hide() { this.components.forEach(x=>x.hide()); this.objects.forEach(x=>x.hide());},
|
||||||
show() { this.components.forEach(function(x) { x.show(); }); this.objects.forEach(function(x) { x.show(); }); },
|
show() { this.components.forEach(function(x) { x.show(); }); this.objects.forEach(function(x) { x.show(); }); },
|
||||||
|
|
||||||
get_relangle() {
|
get_relangle() {
|
||||||
|
@ -487,6 +504,7 @@ var gameobject = {
|
||||||
|
|
||||||
kill() {
|
kill() {
|
||||||
this.timers.forEach(t => t());
|
this.timers.forEach(t => t());
|
||||||
|
this.timers = undefined;
|
||||||
|
|
||||||
if (this.level) {
|
if (this.level) {
|
||||||
this.level.remove_obj(this);
|
this.level.remove_obj(this);
|
||||||
|
@ -496,19 +514,18 @@ var gameobject = {
|
||||||
Player.do_uncontrol(this);
|
Player.do_uncontrol(this);
|
||||||
Register.unregister_obj(this);
|
Register.unregister_obj(this);
|
||||||
|
|
||||||
if (this.__proto__.instances)
|
this.__proto__.instances.remove(this);
|
||||||
this.__proto__.instances.remove(this);
|
|
||||||
|
|
||||||
for (var key in this.components) {
|
for (var key in this.components) {
|
||||||
Register.unregister_obj(this.components[key]);
|
Register.unregister_obj(this.components[key]);
|
||||||
Log.info(`Destroying component ${key}`);
|
(`Destroying component ${key}`);
|
||||||
this.components[key].kill();
|
this.components[key].kill();
|
||||||
this.components.gameobject = undefined;
|
this.components.gameobject = undefined;
|
||||||
|
delete this.components[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
delete this.components;
|
|
||||||
|
|
||||||
this.clear();
|
this.clear();
|
||||||
|
this.objects = undefined;
|
||||||
|
|
||||||
if (typeof this.stop === 'function')
|
if (typeof this.stop === 'function')
|
||||||
this.stop();
|
this.stop();
|
||||||
|
@ -520,11 +537,9 @@ var gameobject = {
|
||||||
left() { return [-1,0].rotate(Math.deg2rad(this.angle));},
|
left() { return [-1,0].rotate(Math.deg2rad(this.angle));},
|
||||||
|
|
||||||
make(level, data) {
|
make(level, data) {
|
||||||
level ??= Primum;
|
|
||||||
var obj = Object.create(this);
|
var obj = Object.create(this);
|
||||||
obj.make = undefined;
|
obj.make = undefined;
|
||||||
|
|
||||||
|
|
||||||
if (this.instances)
|
if (this.instances)
|
||||||
this.instances.push(obj);
|
this.instances.push(obj);
|
||||||
|
|
||||||
|
@ -533,55 +548,32 @@ var gameobject = {
|
||||||
obj.components = {};
|
obj.components = {};
|
||||||
obj.objects = {};
|
obj.objects = {};
|
||||||
obj.timers = [];
|
obj.timers = [];
|
||||||
|
|
||||||
obj._ed = {
|
obj._ed = {
|
||||||
selectable: true,
|
selectable: true,
|
||||||
check_dirty() {
|
|
||||||
this.urdiff = obj.json_obj();
|
|
||||||
this.dirty = !this.urdiff.empty;
|
|
||||||
if (!obj.level) return;
|
|
||||||
var lur = ur[obj.level.ur];
|
|
||||||
if (!lur) return;
|
|
||||||
var lur = lur.objects[obj.toString()];
|
|
||||||
var d = ediff(this.urdiff,lur);
|
|
||||||
if (!d || d.empty)
|
|
||||||
this.inst = true;
|
|
||||||
else
|
|
||||||
this.inst = false;
|
|
||||||
},
|
|
||||||
|
|
||||||
dirty: false,
|
dirty: false,
|
||||||
inst: false,
|
inst: false,
|
||||||
urdiff: {},
|
urdiff: {},
|
||||||
namestr() {
|
|
||||||
var s = obj.toString();
|
|
||||||
if (this.dirty)
|
|
||||||
if (this.inst) s += "#";
|
|
||||||
else s += "*";
|
|
||||||
|
|
||||||
return s;
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
obj.ur = this.toString();
|
obj.ur = this.toString();
|
||||||
|
|
||||||
obj.reparent(level);
|
obj.reparent(level);
|
||||||
|
|
||||||
cmd(113, obj.body, obj); // set the internal obj reference to this obj
|
cmd(113, obj.body, obj); // set the internal obj reference to this obj
|
||||||
|
|
||||||
for (var prop in this) {
|
for (var [prop,p] of Object.entries(this)) {
|
||||||
var p = this[prop];
|
|
||||||
if (typeof p !== 'object') continue;
|
|
||||||
if (typeof p.make === 'function') {
|
if (typeof p.make === 'function') {
|
||||||
obj[prop] = p.make(obj);
|
obj[prop] = p.make(obj);
|
||||||
obj.components[prop] = obj[prop];
|
obj.components[prop] = obj[prop];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Object.hide(obj, 'ur','body', 'components', 'objects', '_ed', 'level', 'timers');
|
||||||
|
|
||||||
if (this.objects)
|
if (this.objects)
|
||||||
obj.make_objs(this.objects);
|
obj.make_objs(this.objects);
|
||||||
|
|
||||||
Object.hide(obj, 'ur','body', 'components', 'objects', '_ed', 'level', 'timers');
|
|
||||||
|
|
||||||
Object.dainty_assign(obj, this);
|
Object.dainty_assign(obj, this);
|
||||||
obj.sync();
|
obj.sync();
|
||||||
gameobject.check_registers(obj);
|
gameobject.check_registers(obj);
|
||||||
|
@ -591,7 +583,7 @@ var gameobject = {
|
||||||
|
|
||||||
if (typeof obj.warmup === 'function') obj.warmup();
|
if (typeof obj.warmup === 'function') obj.warmup();
|
||||||
if (Game.playing() && typeof obj.start === 'function') obj.start();
|
if (Game.playing() && typeof obj.start === 'function') obj.start();
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -669,6 +661,7 @@ gameobject.doc = {
|
||||||
set_worldpos: `Function to set the position of the object in world coordinates.`,
|
set_worldpos: `Function to set the position of the object in world coordinates.`,
|
||||||
worldangle: `Function to get the angle of the entity in the world.`,
|
worldangle: `Function to get the angle of the entity in the world.`,
|
||||||
rotate: `Function to rotate this object by x degrees.`,
|
rotate: `Function to rotate this object by x degrees.`,
|
||||||
|
move: 'Move an object by x,y,z. If the first parameter is an array, uses up to the first three array values.',
|
||||||
pulse: `Apply an impulse to this body in world coordinates. Impulse is a short force.`,
|
pulse: `Apply an impulse to this body in world coordinates. Impulse is a short force.`,
|
||||||
shove: `Apply a force to this body in world coordinates. Should be used over many frames.`,
|
shove: `Apply a force to this body in world coordinates. Should be used over many frames.`,
|
||||||
shove_at: 'Apply a force to this body, at a position relative to itself.',
|
shove_at: 'Apply a force to this body, at a position relative to itself.',
|
||||||
|
|
|
@ -5,20 +5,10 @@ var Input = {
|
||||||
|
|
||||||
var Mouse = {
|
var Mouse = {
|
||||||
get pos() { return cmd(45); },
|
get pos() { return cmd(45); },
|
||||||
|
|
||||||
screenpos() { return cmd(45); },
|
screenpos() { return cmd(45); },
|
||||||
|
get worldpos() { return screen2world(cmd(45)); },
|
||||||
get worldpos() {
|
disabled() { cmd(46, 1); },
|
||||||
return screen2world(cmd(45));
|
normal() { cmd(46, 0);},
|
||||||
},
|
|
||||||
|
|
||||||
disabled() {
|
|
||||||
cmd(46, 1);
|
|
||||||
},
|
|
||||||
|
|
||||||
normal() {
|
|
||||||
cmd(46, 0);
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Mouse.doc = {};
|
Mouse.doc = {};
|
||||||
|
@ -28,21 +18,10 @@ Mouse.disabled.doc = "Set the mouse to hidden. This locks it to the game and hid
|
||||||
Mouse.normal.doc = "Set the mouse to show again after hiding.";
|
Mouse.normal.doc = "Set the mouse to show again after hiding.";
|
||||||
|
|
||||||
var Keys = {
|
var Keys = {
|
||||||
shift() {
|
shift() { return cmd(50, 340); },
|
||||||
return cmd(50, 340);// || cmd(50, 344);
|
ctrl() { return cmd(50, 341); },
|
||||||
},
|
alt() { return cmd(50, 342); },
|
||||||
|
super() { return cmd(50, 343); },
|
||||||
ctrl() {
|
|
||||||
return cmd(50, 341);// || cmd(50, 344);
|
|
||||||
},
|
|
||||||
|
|
||||||
alt() {
|
|
||||||
return cmd(50, 342);// || cmd(50, 346);
|
|
||||||
},
|
|
||||||
|
|
||||||
super() {
|
|
||||||
return cmd(50, 343);// || cmd(50, 347);
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Input.state2str = function(state) {
|
Input.state2str = function(state) {
|
||||||
|
|
|
@ -11,27 +11,14 @@
|
||||||
static gameobject **gameobjects;
|
static gameobject **gameobjects;
|
||||||
|
|
||||||
gameobject *body2go(cpBody *body) { return cpBodyGetUserData(body); }
|
gameobject *body2go(cpBody *body) { return cpBodyGetUserData(body); }
|
||||||
gameobject *shape2go(cpShape *shape)
|
gameobject *shape2go(cpShape *shape) { return ((struct phys2d_shape *)cpShapeGetUserData(shape))->go; }
|
||||||
{
|
|
||||||
return ((struct phys2d_shape *)cpShapeGetUserData(shape))->go;
|
|
||||||
}
|
|
||||||
|
|
||||||
HMM_Vec2 go_pos(gameobject *go)
|
HMM_Vec2 go_pos(gameobject *go)
|
||||||
{
|
{
|
||||||
cpVect p = cpBodyGetPosition(go->body);
|
cpVect p = cpBodyGetPosition(go->body);
|
||||||
return (HMM_Vec2){p.x, p.y};
|
return (HMM_Vec2){p.x, p.y};
|
||||||
}
|
}
|
||||||
|
float go_angle(gameobject *go) { return cpBodyGetAngle(go->body); }
|
||||||
HMM_Vec2 go_worldpos(gameobject *go)
|
|
||||||
{
|
|
||||||
HMM_Vec2 ret;
|
|
||||||
ret.cp = cpBodyGetPosition(go->body);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
float go_angle(gameobject *go) { return go_worldangle(go); }
|
|
||||||
float go_worldangle(gameobject *go) { return cpBodyGetAngle(go->body); }
|
|
||||||
float go2angle(gameobject *go) { return cpBodyGetAngle(go->body); }
|
|
||||||
|
|
||||||
transform3d go2t3(gameobject *go)
|
transform3d go2t3(gameobject *go)
|
||||||
{
|
{
|
||||||
|
@ -212,8 +199,6 @@ void gameobject_clean(gameobject *go) {
|
||||||
/* Really more of a "mark for deletion" ... */
|
/* Really more of a "mark for deletion" ... */
|
||||||
void gameobject_free(gameobject *go) {
|
void gameobject_free(gameobject *go) {
|
||||||
if (!go) return;
|
if (!go) return;
|
||||||
YughWarn("FREEING A GAMEOBJECT");
|
|
||||||
JS_FreeValue(js, go->ref);
|
|
||||||
|
|
||||||
for (int i = arrlen(gameobjects)-1; i >= 0; i--)
|
for (int i = arrlen(gameobjects)-1; i >= 0; i--)
|
||||||
if (gameobjects[i] == go) {
|
if (gameobjects[i] == go) {
|
||||||
|
|
|
@ -69,11 +69,9 @@ HMM_Mat4 t3d_go2world(gameobject *go);
|
||||||
HMM_Mat4 t3d_world2go(gameobject *go);
|
HMM_Mat4 t3d_world2go(gameobject *go);
|
||||||
|
|
||||||
HMM_Vec2 go_pos(gameobject *go);
|
HMM_Vec2 go_pos(gameobject *go);
|
||||||
HMM_Vec2 go_worldpos(gameobject *go);
|
void gameobject_setpos(gameobject *go, cpVect vec);
|
||||||
//float go_angle(gameobject *go);
|
float go_angle(gameobject *go);
|
||||||
float go_worldangle(gameobject *go);
|
void gameobject_setangle(gameobject *go, float angle);
|
||||||
|
|
||||||
float go2angle(gameobject *go);
|
|
||||||
|
|
||||||
gameobject *body2go(cpBody *body);
|
gameobject *body2go(cpBody *body);
|
||||||
gameobject *shape2go(cpShape *shape);
|
gameobject *shape2go(cpShape *shape);
|
||||||
|
@ -83,10 +81,6 @@ void go_shape_apply(cpBody *body, cpShape *shape, gameobject *go);
|
||||||
/* Tries a few methods to select a gameobject; if none is selected returns -1 */
|
/* Tries a few methods to select a gameobject; if none is selected returns -1 */
|
||||||
gameobject *pos2gameobject(HMM_Vec2 pos);
|
gameobject *pos2gameobject(HMM_Vec2 pos);
|
||||||
|
|
||||||
void gameobject_move(gameobject *go, HMM_Vec2 vec);
|
|
||||||
void gameobject_rotate(gameobject *go, float as);
|
|
||||||
void gameobject_setangle(gameobject *go, float angle);
|
|
||||||
void gameobject_setpos(gameobject *go, cpVect vec);
|
|
||||||
void gameobject_draw_debug(gameobject *go);
|
void gameobject_draw_debug(gameobject *go);
|
||||||
void gameobject_draw_debugs();
|
void gameobject_draw_debugs();
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -403,8 +403,6 @@ JSValue duk_spline_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst
|
||||||
samples = bezier_cb_ma_v2(points, param);
|
samples = bezier_cb_ma_v2(points, param);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
arrfree(points);
|
arrfree(points);
|
||||||
|
|
||||||
|
@ -638,7 +636,6 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 30:
|
case 30:
|
||||||
sprite_setanim(id2sprite(js2int(argv[1])), js2ptr(argv[2]), js2int(argv[3]));
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 31:
|
case 31:
|
||||||
|
@ -784,6 +781,7 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 63:
|
case 63:
|
||||||
|
set_cam_body(NULL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 64:
|
case 64:
|
||||||
|
@ -996,7 +994,7 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 113:
|
case 113:
|
||||||
js2gameobject(argv[1])->ref = argv[2];//JS_DupValue(js,argv[2]);
|
js2gameobject(argv[1])->ref = argv[2];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 114:
|
case 114:
|
||||||
|
@ -1511,7 +1509,6 @@ JSValue duk_sys_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *ar
|
||||||
}
|
}
|
||||||
|
|
||||||
JSValue duk_make_gameobject(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) {
|
JSValue duk_make_gameobject(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) {
|
||||||
YughWarn("MAKING GAMOBJECT");
|
|
||||||
return gameobject2js(MakeGameobject());
|
return gameobject2js(MakeGameobject());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1648,19 +1645,6 @@ JSValue duk_make_sprite(JSContext *js, JSValueConst this, int argc, JSValueConst
|
||||||
return sprite;
|
return sprite;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make anim from texture */
|
|
||||||
JSValue duk_make_anim2d(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) {
|
|
||||||
const char *path = JS_ToCString(js, argv[0]);
|
|
||||||
int frames = js2int(argv[1]);
|
|
||||||
int fps = js2int(argv[2]);
|
|
||||||
|
|
||||||
struct TexAnim *anim = anim2d_from_tex(path, frames, fps);
|
|
||||||
|
|
||||||
JS_FreeCString(js, path);
|
|
||||||
|
|
||||||
return ptr2js(anim);
|
|
||||||
}
|
|
||||||
|
|
||||||
JSValue duk_make_box2d(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) {
|
JSValue duk_make_box2d(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) {
|
||||||
gameobject *go = js2gameobject(argv[0]);
|
gameobject *go = js2gameobject(argv[0]);
|
||||||
HMM_Vec2 size = js2vec2(argv[1]);
|
HMM_Vec2 size = js2vec2(argv[1]);
|
||||||
|
@ -1888,7 +1872,6 @@ void ffi_load() {
|
||||||
DUK_FUNC(sys_cmd, 1)
|
DUK_FUNC(sys_cmd, 1)
|
||||||
|
|
||||||
DUK_FUNC(make_sprite, 1)
|
DUK_FUNC(make_sprite, 1)
|
||||||
DUK_FUNC(make_anim2d, 3)
|
|
||||||
DUK_FUNC(spline_cmd, 6)
|
DUK_FUNC(spline_cmd, 6)
|
||||||
|
|
||||||
DUK_FUNC(make_box2d, 3)
|
DUK_FUNC(make_box2d, 3)
|
||||||
|
|
|
@ -466,13 +466,8 @@ void render_winsize()
|
||||||
}
|
}
|
||||||
|
|
||||||
static cpBody *camera = NULL;
|
static cpBody *camera = NULL;
|
||||||
void set_cam_body(cpBody *body) {
|
void set_cam_body(cpBody *body) { camera = body; }
|
||||||
camera = body;
|
cpVect cam_pos() { return camera ? cpBodyGetPosition(camera) : cpvzero; }
|
||||||
}
|
|
||||||
|
|
||||||
cpVect cam_pos() {
|
|
||||||
return camera ? cpBodyGetPosition(camera) : cpvzero;
|
|
||||||
}
|
|
||||||
|
|
||||||
static float zoom = 1.f;
|
static float zoom = 1.f;
|
||||||
float cam_zoom() { return zoom; }
|
float cam_zoom() { return zoom; }
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
#include "stb_ds.h"
|
#include "stb_ds.h"
|
||||||
#include "smbPitchShift.h"
|
#include "smbPitchShift.h"
|
||||||
|
|
||||||
|
#include "pthread.h"
|
||||||
|
|
||||||
#define PI 3.14159265
|
#define PI 3.14159265
|
||||||
|
|
||||||
dsp_node *masterbus = NULL;
|
dsp_node *masterbus = NULL;
|
||||||
|
@ -22,7 +24,6 @@ void iir_free(struct dsp_iir *iir)
|
||||||
free(iir);
|
free(iir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void interleave(soundbyte *a, soundbyte *b, soundbyte *stereo, int frames)
|
void interleave(soundbyte *a, soundbyte *b, soundbyte *stereo, int frames)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < frames; i++) {
|
for (int i = 0; i < frames; i++) {
|
||||||
|
@ -117,10 +118,7 @@ void scale_soundbytes(soundbyte *a, float scale, int samples)
|
||||||
for (int i = 0; i < samples; i++) a[i] *= scale;
|
for (int i = 0; i < samples; i++) a[i] *= scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
void zero_soundbytes(soundbyte *a, int samples)
|
void zero_soundbytes(soundbyte *a, int samples) { memset(a, 0, sizeof(soundbyte)*samples); }
|
||||||
{
|
|
||||||
memset(a, 0, sizeof(soundbyte)*samples);
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_soundbytes(soundbyte *a, soundbyte *b, int samples)
|
void set_soundbytes(soundbyte *a, soundbyte *b, int samples)
|
||||||
{
|
{
|
||||||
|
@ -151,13 +149,15 @@ dsp_node *make_node(void *data, void (*proc)(void *data, soundbyte *out, int sam
|
||||||
|
|
||||||
void node_free(dsp_node *node)
|
void node_free(dsp_node *node)
|
||||||
{
|
{
|
||||||
YughWarn("FREEING A NODE");
|
if (node == masterbus) return; /* Simple check to not delete the masterbus */
|
||||||
|
pthread_mutex_lock(&soundrun);
|
||||||
unplug_node(node);
|
unplug_node(node);
|
||||||
if (node->data)
|
if (node->data)
|
||||||
if (node->data_free) node->data_free(node->data);
|
if (node->data_free) node->data_free(node->data);
|
||||||
else free(node->data);
|
else free(node->data);
|
||||||
|
|
||||||
free(node);
|
free(node);
|
||||||
|
pthread_mutex_unlock(&soundrun);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dsp_node_free(dsp_node *node) { node_free(node); }
|
void dsp_node_free(dsp_node *node) { node_free(node); }
|
||||||
|
|
|
@ -8,6 +8,9 @@
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "time.h"
|
#include "time.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include "pthread.h"
|
||||||
|
|
||||||
|
pthread_mutex_t soundrun = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
#include "samplerate.h"
|
#include "samplerate.h"
|
||||||
|
|
||||||
|
@ -105,9 +108,10 @@ void change_samplerate(struct wav *w, int rate) {
|
||||||
w->samplerate = rate;
|
w->samplerate = rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
void push_sound(soundbyte *buffer, int frames, int chan)
|
void push_sound(soundbyte *buffer, int frames, int chan) {
|
||||||
{
|
pthread_mutex_lock(&soundrun);
|
||||||
set_soundbytes(buffer, dsp_node_out(masterbus), frames*chan);
|
set_soundbytes(buffer, dsp_node_out(masterbus), frames*chan);
|
||||||
|
pthread_mutex_unlock(&soundrun);
|
||||||
}
|
}
|
||||||
|
|
||||||
void filter_mod(pocketmod_context *mod, soundbyte *buffer, int frames)
|
void filter_mod(pocketmod_context *mod, soundbyte *buffer, int frames)
|
||||||
|
|
|
@ -3,8 +3,10 @@
|
||||||
|
|
||||||
#include "script.h"
|
#include "script.h"
|
||||||
#include "samplerate.h"
|
#include "samplerate.h"
|
||||||
|
#include "pthread.h"
|
||||||
|
|
||||||
typedef float soundbyte;
|
typedef float soundbyte;
|
||||||
|
extern pthread_mutex_t soundrun;
|
||||||
|
|
||||||
struct dsp_node;
|
struct dsp_node;
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ int make_sprite(gameobject *go) {
|
||||||
.t = t2d_unit,
|
.t = t2d_unit,
|
||||||
.color = color_white,
|
.color = color_white,
|
||||||
.emissive = {0,0,0,0},
|
.emissive = {0,0,0,0},
|
||||||
.tex = texture_loadfromfile(NULL),
|
.tex = texture_pullfromfile(NULL),
|
||||||
.go = go,
|
.go = go,
|
||||||
.layer = 0,
|
.layer = 0,
|
||||||
.next = -1,
|
.next = -1,
|
||||||
|
@ -83,27 +83,7 @@ struct sprite *id2sprite(int id) {
|
||||||
|
|
||||||
static int sprite_count = 0;
|
static int sprite_count = 0;
|
||||||
|
|
||||||
void sprite_flush() {
|
void sprite_flush() { sprite_count = 0; }
|
||||||
sprite_count = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sprite_io(struct sprite *sprite, FILE *f, int read) {
|
|
||||||
char path[100];
|
|
||||||
if (read) {
|
|
||||||
// fscanf(f, "%s", &path);
|
|
||||||
for (int i = 0; i < 100; i++) {
|
|
||||||
path[i] = fgetc(f);
|
|
||||||
|
|
||||||
if (path[i] == '\0') break;
|
|
||||||
}
|
|
||||||
fread(sprite, sizeof(*sprite), 1, f);
|
|
||||||
sprite_loadtex(sprite, path, ST_UNIT);
|
|
||||||
} else {
|
|
||||||
fputs(tex_get_path(sprite->tex), f);
|
|
||||||
fputc('\0', f);
|
|
||||||
fwrite(sprite, sizeof(*sprite), 1, f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int sprite_sort(int *a, int *b)
|
int sprite_sort(int *a, int *b)
|
||||||
{
|
{
|
||||||
|
@ -140,7 +120,7 @@ void sprite_loadtex(struct sprite *sprite, const char *path, struct glrect frame
|
||||||
YughWarn("NO SPRITE!");
|
YughWarn("NO SPRITE!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
sprite->tex = texture_loadfromfile(path);
|
sprite->tex = texture_pullfromfile(path);
|
||||||
sprite_setframe(sprite, &frame);
|
sprite_setframe(sprite, &frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,19 +224,12 @@ void sprite_draw(struct sprite *sprite) {
|
||||||
HMM_Mat3 sm = transform2d2mat(sprite->t);
|
HMM_Mat3 sm = transform2d2mat(sprite->t);
|
||||||
|
|
||||||
tex_draw(sprite->tex, HMM_MulM3(m, sm), sprite->frame, sprite->color, 0, (HMM_Vec2){0,0}, 0, sprite->emissive);
|
tex_draw(sprite->tex, HMM_MulM3(m, sm), sprite->frame, sprite->color, 0, (HMM_Vec2){0,0}, 0, sprite->emissive);
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void sprite_setanim(struct sprite *sprite, struct TexAnim *anim, int frame) {
|
|
||||||
if (!sprite) return;
|
|
||||||
sprite->tex = anim->tex;
|
|
||||||
sprite->frame = anim->st_frames[frame];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void gui_draw_img(const char *img, transform2d t, int wrap, HMM_Vec2 wrapoffset, float wrapscale, struct rgba color) {
|
void gui_draw_img(const char *img, transform2d t, int wrap, HMM_Vec2 wrapoffset, float wrapscale, struct rgba color) {
|
||||||
sg_apply_pipeline(pip_sprite);
|
sg_apply_pipeline(pip_sprite);
|
||||||
sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(hudproj));
|
sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(hudproj));
|
||||||
struct Texture *tex = texture_loadfromfile(img);
|
struct Texture *tex = texture_pullfromfile(img);
|
||||||
tex_draw(tex, transform2d2mat(t), tex_get_rect(tex), color, wrap, wrapoffset, wrapscale, (struct rgba){0,0,0,0});
|
tex_draw(tex, transform2d2mat(t), tex_get_rect(tex), color, wrap, wrapoffset, wrapscale, (struct rgba){0,0,0,0});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,7 +237,7 @@ void slice9_draw(const char *img, HMM_Vec2 pos, HMM_Vec2 dimensions, struct rgba
|
||||||
{
|
{
|
||||||
sg_apply_pipeline(slice9_pipe);
|
sg_apply_pipeline(slice9_pipe);
|
||||||
sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(hudproj));
|
sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(hudproj));
|
||||||
struct Texture *tex = texture_loadfromfile(img);
|
struct Texture *tex = texture_pullfromfile(img);
|
||||||
|
|
||||||
struct glrect r = tex_get_rect(tex);
|
struct glrect r = tex_get_rect(tex);
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,6 @@ void sprite_enabled(int id, int e);
|
||||||
void sprite_io(struct sprite *sprite, FILE *f, int read);
|
void sprite_io(struct sprite *sprite, FILE *f, int read);
|
||||||
void sprite_loadtex(struct sprite *sprite, const char *path, struct glrect rect);
|
void sprite_loadtex(struct sprite *sprite, const char *path, struct glrect rect);
|
||||||
void sprite_settex(struct sprite *sprite, struct Texture *tex);
|
void sprite_settex(struct sprite *sprite, struct Texture *tex);
|
||||||
void sprite_setanim(struct sprite *sprite, struct TexAnim *anim, int frame);
|
|
||||||
void sprite_setframe(struct sprite *sprite, struct glrect *frame);
|
void sprite_setframe(struct sprite *sprite, struct glrect *frame);
|
||||||
void sprite_initialize();
|
void sprite_initialize();
|
||||||
void sprite_draw(struct sprite *sprite);
|
void sprite_draw(struct sprite *sprite);
|
||||||
|
|
|
@ -29,10 +29,7 @@ static struct {
|
||||||
} *texhash = NULL;
|
} *texhash = NULL;
|
||||||
|
|
||||||
struct Texture *tex_default;
|
struct Texture *tex_default;
|
||||||
|
struct Texture *texture_notex() { return texture_pullfromfile("icons/no_tex.gif"); }
|
||||||
struct Texture *texture_notex() {
|
|
||||||
return texture_pullfromfile("icons/no_tex.gif");
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int next_pow2(unsigned int v)
|
unsigned int next_pow2(unsigned int v)
|
||||||
{
|
{
|
||||||
|
@ -201,9 +198,7 @@ struct Texture *texture_pullfromfile(const char *path) {
|
||||||
return tex;
|
return tex;
|
||||||
}
|
}
|
||||||
|
|
||||||
void texture_sync(const char *path) {
|
void texture_sync(const char *path) { YughWarn("Need to implement texture sync."); }
|
||||||
YughWarn("Need to implement texture sync.");
|
|
||||||
}
|
|
||||||
|
|
||||||
char *tex_get_path(struct Texture *tex) {
|
char *tex_get_path(struct Texture *tex) {
|
||||||
for (int i = 0; i < shlen(texhash); i++) {
|
for (int i = 0; i < shlen(texhash); i++) {
|
||||||
|
@ -289,94 +284,9 @@ struct Texture *texture_fromdata(void *raw, long size)
|
||||||
|
|
||||||
struct Texture *texture_loadfromfile(const char *path) {
|
struct Texture *texture_loadfromfile(const char *path) {
|
||||||
struct Texture *new = texture_pullfromfile(path);
|
struct Texture *new = texture_pullfromfile(path);
|
||||||
/*
|
|
||||||
if (new->id == 0) {
|
|
||||||
glGenTextures(1, &new->id);
|
|
||||||
|
|
||||||
//tex_gpu_load(new);
|
|
||||||
|
|
||||||
YughInfo("Loaded texture path %s", path);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
return new;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void tex_gpu_reload(struct Texture *tex) {
|
struct glrect tex_get_rect(struct Texture *tex) { return ST_UNIT; }
|
||||||
tex_gpu_free(tex);
|
|
||||||
|
|
||||||
// tex_gpu_load(tex);
|
|
||||||
}
|
|
||||||
|
|
||||||
void anim_calc(struct anim2d *anim) {
|
|
||||||
anim->size[0] = anim->anim->tex->width * st_s_w(anim->anim->st_frames[anim->frame]);
|
|
||||||
anim->size[1] = anim->anim->tex->height * st_s_h(anim->anim->st_frames[anim->frame]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void anim_incr(struct anim2d *anim) {
|
|
||||||
anim->frame = (anim->frame + 1) % arrlen(anim->anim->st_frames);
|
|
||||||
|
|
||||||
if (!anim->anim->loop && anim->frame == arrlen(anim->anim->st_frames))
|
|
||||||
anim_pause(anim);
|
|
||||||
|
|
||||||
anim_calc(anim);
|
|
||||||
}
|
|
||||||
|
|
||||||
void anim_decr(struct anim2d *anim) {
|
|
||||||
anim->frame = (anim->frame + arrlen(anim->anim->st_frames) - 1) % arrlen(anim->anim->st_frames);
|
|
||||||
anim_calc(anim);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct glrect anim_get_rect(struct anim2d *anim) {
|
|
||||||
return anim->anim->st_frames[anim->frame];
|
|
||||||
}
|
|
||||||
|
|
||||||
void anim_setframe(struct anim2d *anim, int frame) {
|
|
||||||
anim->frame = frame;
|
|
||||||
anim_calc(anim);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct TexAnim *anim2d_from_tex(const char *path, int frames, int fps) {
|
|
||||||
struct TexAnim *anim = malloc(sizeof(*anim));
|
|
||||||
anim->tex = texture_loadfromfile(path);
|
|
||||||
texanim_fromframes(anim, frames);
|
|
||||||
anim->ms = (float)1 / fps;
|
|
||||||
|
|
||||||
return anim;
|
|
||||||
}
|
|
||||||
|
|
||||||
void texanim_fromframes(struct TexAnim *anim, int frames) {
|
|
||||||
if (anim->st_frames) {
|
|
||||||
free(anim->st_frames);
|
|
||||||
}
|
|
||||||
|
|
||||||
arrsetlen(anim->st_frames, frames);
|
|
||||||
|
|
||||||
float width = (float)1 / frames;
|
|
||||||
|
|
||||||
for (int i = 0; i < frames; i++) {
|
|
||||||
anim->st_frames[i].s0 = width * i;
|
|
||||||
anim->st_frames[i].s1 = width * (i + 1);
|
|
||||||
anim->st_frames[i].t0 = 0.f;
|
|
||||||
anim->st_frames[i].t1 = 1.f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void tex_gpu_free(struct Texture *tex) {
|
|
||||||
/*
|
|
||||||
if (tex->id != 0) {
|
|
||||||
glDeleteTextures(1, &tex->id);
|
|
||||||
tex->id = 0;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
int anim_frames(struct TexAnim *a) {
|
|
||||||
return arrlen(a->st_frames);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct glrect tex_get_rect(struct Texture *tex) {
|
|
||||||
return ST_UNIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
HMM_Vec2 tex_get_dimensions(struct Texture *tex) {
|
HMM_Vec2 tex_get_dimensions(struct Texture *tex) {
|
||||||
if (!tex) return (HMM_Vec2){0,0};
|
if (!tex) return (HMM_Vec2){0,0};
|
||||||
|
@ -386,69 +296,6 @@ HMM_Vec2 tex_get_dimensions(struct Texture *tex) {
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tex_bind(struct Texture *tex) {
|
float st_s_w(struct glrect st) { return (st.s1 - st.s0); }
|
||||||
/* glActiveTexture(GL_TEXTURE0);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, tex->id);
|
|
||||||
glBindTexture(GL_TEXTURE_2D_ARRAY, tex->id);
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************** ANIM2D ****************/
|
float st_s_h(struct glrect st) { return (st.t1 - st.t0); }
|
||||||
|
|
||||||
void anim_load(struct anim2d *anim, const char *path) {
|
|
||||||
anim->anim = &texture_pullfromfile(path)->anim;
|
|
||||||
anim->anim->tex->opts.animation = 1;
|
|
||||||
anim_stop(anim);
|
|
||||||
anim_play(anim);
|
|
||||||
}
|
|
||||||
|
|
||||||
void anim_play(struct anim2d *anim) {
|
|
||||||
// if (anim->playing)
|
|
||||||
// return;
|
|
||||||
|
|
||||||
// if (anim->frame == anim_frames(anim->anim))
|
|
||||||
// anim->frame = 0;
|
|
||||||
|
|
||||||
// anim->playing = 1;
|
|
||||||
|
|
||||||
// if (anim->timer == NULL)
|
|
||||||
// anim->timer = id2timer(timer_make(1.f / anim->anim->ms, anim_incr, anim, 0, 0));
|
|
||||||
// else
|
|
||||||
// timerr_settime(anim->timer, 1.f / anim->anim->ms);
|
|
||||||
|
|
||||||
// timer_start(anim->timer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void anim_stop(struct anim2d *anim) {
|
|
||||||
if (!anim->playing)
|
|
||||||
return;
|
|
||||||
|
|
||||||
anim->playing = 0;
|
|
||||||
anim->frame = 0;
|
|
||||||
anim->pausetime = 0;
|
|
||||||
timer_stop(anim->timer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void anim_pause(struct anim2d *anim) {
|
|
||||||
if (!anim->playing)
|
|
||||||
return;
|
|
||||||
|
|
||||||
anim->playing = 0;
|
|
||||||
timer_pause(anim->timer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void anim_fwd(struct anim2d *anim) {
|
|
||||||
anim_incr(anim);
|
|
||||||
}
|
|
||||||
|
|
||||||
void anim_bkwd(struct anim2d *anim) {
|
|
||||||
anim_decr(anim);
|
|
||||||
}
|
|
||||||
|
|
||||||
float st_s_w(struct glrect st) {
|
|
||||||
return (st.s1 - st.s0);
|
|
||||||
}
|
|
||||||
|
|
||||||
float st_s_h(struct glrect st) {
|
|
||||||
return (st.t1 - st.t0);
|
|
||||||
}
|
|
||||||
|
|
|
@ -33,25 +33,6 @@ struct uvrect {
|
||||||
int v1;
|
int v1;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Tracks a playing animation */
|
|
||||||
/* Objects should keep this, and just change what TexAnim they are pointing to */
|
|
||||||
struct anim2d {
|
|
||||||
int frame;
|
|
||||||
int playing;
|
|
||||||
int pausetime;
|
|
||||||
struct timer *timer;
|
|
||||||
struct TexAnim *anim;
|
|
||||||
float size[2]; /* Current size of animation in pixels*/
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Describes an animation on a particular texture */
|
|
||||||
struct TexAnim {
|
|
||||||
struct Texture *tex;
|
|
||||||
struct glrect *st_frames; /* Dynamic array of frames of animation */
|
|
||||||
int ms;
|
|
||||||
int loop;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TextureOptions {
|
struct TextureOptions {
|
||||||
int sprite;
|
int sprite;
|
||||||
int mips;
|
int mips;
|
||||||
|
@ -59,7 +40,6 @@ struct TextureOptions {
|
||||||
int animation;
|
int animation;
|
||||||
int wrapx;
|
int wrapx;
|
||||||
int wrapy;
|
int wrapy;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Represents an actual texture on the GPU */
|
/* Represents an actual texture on the GPU */
|
||||||
|
@ -69,7 +49,6 @@ struct Texture {
|
||||||
uint16_t height;
|
uint16_t height;
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
struct TextureOptions opts;
|
struct TextureOptions opts;
|
||||||
struct TexAnim anim;
|
|
||||||
int frames;
|
int frames;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -79,30 +58,15 @@ struct Image {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Texture *texture_pullfromfile(const char *path); // Create texture from image
|
struct Texture *texture_pullfromfile(const char *path); // Create texture from image
|
||||||
struct Texture *texture_loadfromfile(const char *path); // Create texture & load to gpu
|
|
||||||
struct Texture *texture_fromdata(void *raw, long size);
|
struct Texture *texture_fromdata(void *raw, long size);
|
||||||
|
|
||||||
|
/* Hot reloads a texture, if needed */
|
||||||
void texture_sync(const char *path);
|
void texture_sync(const char *path);
|
||||||
struct Texture *str2tex(const char *path);
|
|
||||||
void tex_gpu_reload(struct Texture *tex); // gpu_free then gpu_load
|
|
||||||
void tex_gpu_free(struct Texture *tex); // Remove texture data from gpu
|
|
||||||
void tex_bind(struct Texture *tex); // Bind to gl context
|
|
||||||
|
|
||||||
char * tex_get_path(struct Texture *tex); // Get image path for texture
|
char * tex_get_path(struct Texture *tex); // Get image path for texture
|
||||||
|
|
||||||
struct TexAnim *anim2d_from_tex(const char *path, int frames, int fps);
|
|
||||||
void texanim_fromframes(struct TexAnim *anim, int frames);
|
void texanim_fromframes(struct TexAnim *anim, int frames);
|
||||||
|
|
||||||
void anim_load(struct anim2d *anim, const char *path); /* Load and start new animation */
|
|
||||||
void anim_calc(struct anim2d *anim);
|
|
||||||
void anim_play(struct anim2d *anim);
|
|
||||||
void anim_setframe(struct anim2d *anim, int frame);
|
|
||||||
void anim_stop(struct anim2d *anim);
|
|
||||||
void anim_pause(struct anim2d *anim);
|
|
||||||
void anim_fwd(struct anim2d *anim);
|
|
||||||
void anim_bkwd(struct anim2d *anim);
|
|
||||||
void anim_incr(struct anim2d *anim);
|
|
||||||
void anim_decr(struct anim2d *anim);
|
|
||||||
|
|
||||||
int gif_nframes(const char *path);
|
int gif_nframes(const char *path);
|
||||||
|
|
||||||
struct glrect tex_get_rect(struct Texture *tex);
|
struct glrect tex_get_rect(struct Texture *tex);
|
||||||
|
|
|
@ -304,7 +304,7 @@ dam->update_activity(dam, &da, NULL, NULL);
|
||||||
if (argc > i+1) argsize++;
|
if (argc > i+1) argsize++;
|
||||||
}
|
}
|
||||||
|
|
||||||
char cmdstr[argsize];
|
char cmdstr[argsize+1];
|
||||||
cmdstr[0] = '\0';
|
cmdstr[0] = '\0';
|
||||||
|
|
||||||
for (int i = 0; i < argc; i++) {
|
for (int i = 0; i < argc; i++) {
|
||||||
|
|
Loading…
Reference in a new issue