editor fixes
This commit is contained in:
parent
02707a9ada
commit
8ca1ab4384
|
@ -35,14 +35,14 @@ struct model *MakeModel(const char *path) {
|
||||||
|
|
||||||
if (!result == cgltf_result_success) {
|
if (!result == cgltf_result_success) {
|
||||||
YughError("Could not read file %s.", path);
|
YughError("Could not read file %s.", path);
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = cgltf_load_buffers(&options, data, path);
|
result = cgltf_load_buffers(&options, data, path);
|
||||||
|
|
||||||
if (!result == cgltf_result_success) {
|
if (!result == cgltf_result_success) {
|
||||||
YughError("Could not load buffers for file %s.", path);
|
YughError("Could not load buffers for file %s.", path);
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct model *model = malloc(sizeof(struct model));
|
struct model *model = malloc(sizeof(struct model));
|
||||||
|
|
|
@ -30,6 +30,7 @@ char consolelog[CONSOLE_BUF] = {'\0'};
|
||||||
|
|
||||||
void mYughLog(int category, int priority, int line, const char *file, const char *message, ...)
|
void mYughLog(int category, int priority, int line, const char *file, const char *message, ...)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (priority >= logLevel) {
|
if (priority >= logLevel) {
|
||||||
time_t now = time(0);
|
time_t now = time(0);
|
||||||
char *dt = ctime(&now);
|
char *dt = ctime(&now);
|
||||||
|
@ -45,6 +46,9 @@ void mYughLog(int category, int priority, int line, const char *file, const char
|
||||||
snprintf(buffer, ERROR_BUFFER, "%s:%d: %s, %s: %s\n", file, line, logstr[priority], catstr[category], msgbuffer);
|
snprintf(buffer, ERROR_BUFFER, "%s:%d: %s, %s: %s\n", file, line, logstr[priority], catstr[category], msgbuffer);
|
||||||
|
|
||||||
log_print(buffer);
|
log_print(buffer);
|
||||||
|
|
||||||
|
if (priority >= 2)
|
||||||
|
js_stacktrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -988,6 +988,10 @@ JSValue duk_register(JSContext *js, JSValueConst this, int argc, JSValueConst *a
|
||||||
case 8:
|
case 8:
|
||||||
register_gamepad(c);
|
register_gamepad(c);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 9:
|
||||||
|
stacktrace_callee = c;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return JS_NULL;
|
return JS_NULL;
|
||||||
|
@ -1455,8 +1459,8 @@ JSValue duk_make_timer(JSContext *js, JSValueConst this, int argc, JSValueConst
|
||||||
{
|
{
|
||||||
double secs = js2number(argv[1]);
|
double secs = js2number(argv[1]);
|
||||||
struct callee *c = malloc(sizeof(*c));
|
struct callee *c = malloc(sizeof(*c));
|
||||||
c->fn = argv[0];
|
c->fn = JS_DupValue(js,argv[0]);
|
||||||
c->obj = argv[2];
|
c->obj = JS_GetGlobalObject(js);
|
||||||
int id = timer_make(secs, call_callee, c, 1);
|
int id = timer_make(secs, call_callee, c, 1);
|
||||||
|
|
||||||
return JS_NewInt64(js, id);
|
return JS_NewInt64(js, id);
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "ffi.h"
|
#include "ffi.h"
|
||||||
#include "time.h"
|
#include "time.h"
|
||||||
|
#include "font.h"
|
||||||
|
|
||||||
int32_t mouseWheelX = 0;
|
int32_t mouseWheelX = 0;
|
||||||
int32_t mouseWheelY = 0;
|
int32_t mouseWheelY = 0;
|
||||||
|
@ -27,6 +28,27 @@ static int mquit = 0;
|
||||||
static struct callee pawn_callee;
|
static struct callee pawn_callee;
|
||||||
static struct callee gamepad_callee;
|
static struct callee gamepad_callee;
|
||||||
|
|
||||||
|
const char *gamepad2str(int btn)
|
||||||
|
{
|
||||||
|
switch(btn) {
|
||||||
|
case GLFW_GAMEPAD_BUTTON_CROSS: return "cross";
|
||||||
|
case GLFW_GAMEPAD_BUTTON_CIRCLE: return "circle";
|
||||||
|
case GLFW_GAMEPAD_BUTTON_SQUARE: return "square";
|
||||||
|
case GLFW_GAMEPAD_BUTTON_TRIANGLE: return "triangle";
|
||||||
|
case GLFW_GAMEPAD_BUTTON_START: return "start";
|
||||||
|
case GLFW_GAMEPAD_BUTTON_LEFT_BUMPER: return "lbump";
|
||||||
|
case GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER: return "rbump";
|
||||||
|
case GLFW_GAMEPAD_BUTTON_GUIDE: return "guide";
|
||||||
|
case GLFW_GAMEPAD_BUTTON_BACK: return "back";
|
||||||
|
case GLFW_GAMEPAD_BUTTON_DPAD_UP: return "dup";
|
||||||
|
case GLFW_GAMEPAD_BUTTON_DPAD_DOWN: return "ddown";
|
||||||
|
case GLFW_GAMEPAD_BUTTON_DPAD_LEFT: return "dleft";
|
||||||
|
case GLFW_GAMEPAD_BUTTON_DPAD_RIGHT: return "dright";
|
||||||
|
case GLFW_GAMEPAD_BUTTON_LEFT_THUMB: return "lthumb";
|
||||||
|
case GLFW_GAMEPAD_BUTTON_RIGHT_THUMB: return "rthumb";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void register_pawn(struct callee c)
|
void register_pawn(struct callee c)
|
||||||
{
|
{
|
||||||
pawn_callee = c;
|
pawn_callee = c;
|
||||||
|
@ -163,6 +185,9 @@ void joystick_cb(int jid, int event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JSValue jsgamepadstr[15];
|
||||||
|
JSValue jsaxesstr[4];
|
||||||
|
|
||||||
void input_init()
|
void input_init()
|
||||||
{
|
{
|
||||||
glfwSetCursorPosCallback(mainwin->window, cursor_pos_cb);
|
glfwSetCursorPosCallback(mainwin->window, cursor_pos_cb);
|
||||||
|
@ -175,6 +200,14 @@ void input_init()
|
||||||
glfwUpdateGamepadMappings(paddb);
|
glfwUpdateGamepadMappings(paddb);
|
||||||
free(paddb);
|
free(paddb);
|
||||||
|
|
||||||
|
for (int b = 0; b < 15; b++)
|
||||||
|
jsgamepadstr[b] = str2js(gamepad2str(b));
|
||||||
|
|
||||||
|
jsaxesstr[0] = str2js("axis_ljoy");
|
||||||
|
jsaxesstr[1] = str2js("axis_rjoy");
|
||||||
|
jsaxesstr[2] = str2js("axis_ltrigger");
|
||||||
|
jsaxesstr[3] = str2js("axis_rtrigger");
|
||||||
|
|
||||||
/* Grab all joysticks initially present */
|
/* Grab all joysticks initially present */
|
||||||
for (int i = 0; i < 16; i++)
|
for (int i = 0; i < 16; i++)
|
||||||
if (glfwJoystickPresent(i)) joystick_add(i);
|
if (glfwJoystickPresent(i)) joystick_add(i);
|
||||||
|
@ -327,26 +360,6 @@ void call_input_down(int *key) {
|
||||||
call_input_signal(keystr);
|
call_input_signal(keystr);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *gamepad2str(int btn)
|
|
||||||
{
|
|
||||||
switch(btn) {
|
|
||||||
case GLFW_GAMEPAD_BUTTON_CROSS: return "cross";
|
|
||||||
case GLFW_GAMEPAD_BUTTON_CIRCLE: return "circle";
|
|
||||||
case GLFW_GAMEPAD_BUTTON_SQUARE: return "square";
|
|
||||||
case GLFW_GAMEPAD_BUTTON_TRIANGLE: return "triangle";
|
|
||||||
case GLFW_GAMEPAD_BUTTON_START: return "start";
|
|
||||||
case GLFW_GAMEPAD_BUTTON_LEFT_BUMPER: return "lbump";
|
|
||||||
case GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER: return "rbump";
|
|
||||||
case GLFW_GAMEPAD_BUTTON_GUIDE: return "guide";
|
|
||||||
case GLFW_GAMEPAD_BUTTON_BACK: return "back";
|
|
||||||
case GLFW_GAMEPAD_BUTTON_DPAD_UP: return "dup";
|
|
||||||
case GLFW_GAMEPAD_BUTTON_DPAD_DOWN: return "ddown";
|
|
||||||
case GLFW_GAMEPAD_BUTTON_DPAD_LEFT: return "dleft";
|
|
||||||
case GLFW_GAMEPAD_BUTTON_DPAD_RIGHT: return "dright";
|
|
||||||
case GLFW_GAMEPAD_BUTTON_LEFT_THUMB: return "lthumb";
|
|
||||||
case GLFW_GAMEPAD_BUTTON_RIGHT_THUMB: return "rthumb";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *axis2str(int axis)
|
const char *axis2str(int axis)
|
||||||
{
|
{
|
||||||
|
@ -380,46 +393,50 @@ void input_poll(double wait)
|
||||||
if (!glfwGetGamepadState(joysticks[i].id, &state)) continue;
|
if (!glfwGetGamepadState(joysticks[i].id, &state)) continue;
|
||||||
|
|
||||||
JSValue argv[3];
|
JSValue argv[3];
|
||||||
argv[0] = int2js(joysticks[i].id);
|
argv[0] = num_cache[joysticks[i].id];
|
||||||
char inputstr[50];
|
char inputstr[50];
|
||||||
for (int b = 0; b < 15; b++) {
|
for (int b = 0; b < 15; b++) {
|
||||||
argv[1] = str2js(gamepad2str(b));
|
argv[1] = jsgamepadstr[b];
|
||||||
|
|
||||||
if (state.buttons[b]) {
|
if (state.buttons[b]) {
|
||||||
argv[2] = int2js(0);
|
argv[2] = num_cache[0];
|
||||||
script_callee(gamepad_callee,3,argv);
|
script_callee(gamepad_callee,3,argv);
|
||||||
|
|
||||||
if (!joysticks[i].state.buttons[b]) {
|
if (!joysticks[i].state.buttons[b]) {
|
||||||
argv[2] = int2js(1);
|
argv[2] = num_cache[1];
|
||||||
script_callee(gamepad_callee,3,argv);
|
script_callee(gamepad_callee,3,argv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!state.buttons[b] && joysticks[i].state.buttons[b]) {
|
else if (!state.buttons[b] && joysticks[i].state.buttons[b]) {
|
||||||
argv[2] = int2js(2);
|
argv[2] = num_cache[2];
|
||||||
script_callee(gamepad_callee,3,argv);
|
script_callee(gamepad_callee,3,argv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
argv[1] = str2js("axis_ljoy");
|
argv[1] = jsaxesstr[0];
|
||||||
cpVect v;
|
cpVect v;
|
||||||
v.x = state.axes[0];
|
v.x = state.axes[0];
|
||||||
v.y = -state.axes[1];
|
v.y = -state.axes[1];
|
||||||
argv[2] = vec2js(v);
|
argv[2] = vec2js(v);
|
||||||
script_callee(gamepad_callee,3,argv);
|
script_callee(gamepad_callee,3,argv);
|
||||||
|
JS_FreeValue(js, argv[2]);
|
||||||
|
|
||||||
argv[1] = str2js("axis_rjoy");
|
argv[1] = jsaxesstr[1];
|
||||||
v.x = state.axes[2];
|
v.x = state.axes[2];
|
||||||
v.y = -state.axes[3];
|
v.y = -state.axes[3];
|
||||||
argv[2] = vec2js(v);
|
argv[2] = vec2js(v);
|
||||||
script_callee(gamepad_callee,3,argv);
|
script_callee(gamepad_callee,3,argv);
|
||||||
|
JS_FreeValue(js, argv[2]);
|
||||||
|
|
||||||
argv[1] = str2js("axis_ltrigger");
|
argv[1] = jsaxesstr[2];
|
||||||
argv[2] = num2js((state.axes[4]+1)/2);
|
argv[2] = num2js((state.axes[4]+1)/2);
|
||||||
script_callee(gamepad_callee,3,argv);
|
script_callee(gamepad_callee,3,argv);
|
||||||
|
JS_FreeValue(js, argv[2]);
|
||||||
|
|
||||||
argv[1] = str2js("axis_rtrigger");
|
argv[1] = jsaxesstr[3];
|
||||||
argv[2] = num2js((state.axes[5]+1)/2);
|
argv[2] = num2js((state.axes[5]+1)/2);
|
||||||
script_callee(gamepad_callee,3,argv);
|
script_callee(gamepad_callee,3,argv);
|
||||||
|
JS_FreeValue(js, argv[2]);
|
||||||
|
|
||||||
joysticks[i].state = state;
|
joysticks[i].state = state;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,20 +30,27 @@ static int load_prefab(const char *fpath, const struct stat *sb, int typeflag) {
|
||||||
void script_startup()
|
void script_startup()
|
||||||
{
|
{
|
||||||
rt = JS_NewRuntime();
|
rt = JS_NewRuntime();
|
||||||
|
JS_SetMaxStackSize(rt,0);
|
||||||
js = JS_NewContext(rt);
|
js = JS_NewContext(rt);
|
||||||
ffi_load();
|
ffi_load();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JSValue num_cache[100] = {0};
|
||||||
|
|
||||||
void script_init() {
|
void script_init() {
|
||||||
/* Load all prefabs into memory */
|
/* Load all prefabs into memory */
|
||||||
script_dofile("scripts/engine.js");
|
script_dofile("scripts/engine.js");
|
||||||
script_dofile("config.js");
|
|
||||||
|
for (int i = 0; i < 100; i++)
|
||||||
|
num_cache[i] = int2js(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
void script_run(const char *script) {
|
void script_run(const char *script) {
|
||||||
JS_FreeValue(js, JS_Eval(js, script, strlen(script), "script", 0));
|
JS_FreeValue(js, JS_Eval(js, script, strlen(script), "script", 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct callee stacktrace_callee;
|
||||||
|
|
||||||
time_t file_mod_secs(const char *file) {
|
time_t file_mod_secs(const char *file) {
|
||||||
struct stat attr;
|
struct stat attr;
|
||||||
stat(file, &attr);
|
stat(file, &attr);
|
||||||
|
@ -52,23 +59,15 @@ time_t file_mod_secs(const char *file) {
|
||||||
|
|
||||||
void js_stacktrace()
|
void js_stacktrace()
|
||||||
{
|
{
|
||||||
YughWarn("Dumping stack ...");
|
call_callee(&stacktrace_callee);
|
||||||
JSValue error = JS_NewError(js);
|
return;
|
||||||
JSValue stack = JS_GetPropertyStr(js, error, "stack");
|
|
||||||
|
|
||||||
if (JS_IsNull(stack)) return;
|
|
||||||
|
|
||||||
const char *stackstr = JS_ToCString(js,stack);
|
|
||||||
|
|
||||||
log_print(stackstr);
|
|
||||||
|
|
||||||
JS_FreeCString(js,stackstr);
|
|
||||||
JS_FreeValue(js,stack);
|
|
||||||
JS_FreeValue(js, error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void js_dump_stack()
|
void js_dump_stack()
|
||||||
{
|
{
|
||||||
|
js_stacktrace();
|
||||||
|
return;
|
||||||
|
|
||||||
JSValue exception = JS_GetException(js);
|
JSValue exception = JS_GetException(js);
|
||||||
if (JS_IsNull(exception)) return;
|
if (JS_IsNull(exception)) return;
|
||||||
JSValue val = JS_GetPropertyStr(js, exception, "stack");
|
JSValue val = JS_GetPropertyStr(js, exception, "stack");
|
||||||
|
@ -94,7 +93,7 @@ int js_print_exception(JSValue v)
|
||||||
const char *name = JS_ToCString(js, JS_GetPropertyStr(js, exception, "name"));
|
const char *name = JS_ToCString(js, JS_GetPropertyStr(js, exception, "name"));
|
||||||
const char *msg = JS_ToCString(js, JS_GetPropertyStr(js, exception, "message"));
|
const char *msg = JS_ToCString(js, JS_GetPropertyStr(js, exception, "message"));
|
||||||
const char *stack = JS_ToCString(js, val);
|
const char *stack = JS_ToCString(js, val);
|
||||||
YughError("%s :: %s\n%s", name, msg, stack);
|
YughWarn("%s :: %s\n%s", name, msg, stack);
|
||||||
|
|
||||||
JS_FreeCString(js, name);
|
JS_FreeCString(js, name);
|
||||||
JS_FreeCString(js, msg);
|
JS_FreeCString(js, msg);
|
||||||
|
|
|
@ -12,6 +12,9 @@ struct callee {
|
||||||
JSValue obj;
|
JSValue obj;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern struct callee stacktrace_callee;
|
||||||
|
extern JSValue num_cache[100];
|
||||||
|
|
||||||
void script_startup();
|
void script_startup();
|
||||||
void script_init();
|
void script_init();
|
||||||
void script_run(const char *script);
|
void script_run(const char *script);
|
||||||
|
|
|
@ -24,7 +24,7 @@ int make_sprite(int go)
|
||||||
struct sprite sprite = {
|
struct sprite sprite = {
|
||||||
.color = {1.f, 1.f, 1.f},
|
.color = {1.f, 1.f, 1.f},
|
||||||
.size = {1.f, 1.f},
|
.size = {1.f, 1.f},
|
||||||
.tex = texture_loadfromfile("ph.png"),
|
.tex = texture_loadfromfile(NULL),
|
||||||
.go = go,
|
.go = go,
|
||||||
.next = -1,
|
.next = -1,
|
||||||
.layer = 0,
|
.layer = 0,
|
||||||
|
|
|
@ -17,9 +17,17 @@ static struct {
|
||||||
} *texhash = NULL;
|
} *texhash = NULL;
|
||||||
|
|
||||||
struct Texture *tex_default;
|
struct Texture *tex_default;
|
||||||
|
|
||||||
|
struct Texture *texture_notex()
|
||||||
|
{
|
||||||
|
return texture_pullfromfile("./icons/no_tex.png");
|
||||||
|
}
|
||||||
|
|
||||||
/* If an empty string or null is put for path, loads default texture */
|
/* If an empty string or null is put for path, loads default texture */
|
||||||
struct Texture *texture_pullfromfile(const char *path)
|
struct Texture *texture_pullfromfile(const char *path)
|
||||||
{
|
{
|
||||||
|
if (!path) return texture_notex();
|
||||||
|
|
||||||
int index = shgeti(texhash, path);
|
int index = shgeti(texhash, path);
|
||||||
if (index != -1)
|
if (index != -1)
|
||||||
return texhash[index].value;
|
return texhash[index].value;
|
||||||
|
@ -48,8 +56,7 @@ struct Texture *texture_pullfromfile(const char *path)
|
||||||
|
|
||||||
if (data == NULL) {
|
if (data == NULL) {
|
||||||
YughError("STBI failed to load file %s with message: %s\nOpening default instead.", path, stbi_failure_reason());
|
YughError("STBI failed to load file %s with message: %s\nOpening default instead.", path, stbi_failure_reason());
|
||||||
print_stacktrace();
|
return texture_notex();
|
||||||
return texture_pullfromfile("./icons/no_tex.png");
|
|
||||||
}
|
}
|
||||||
tex->data = data;
|
tex->data = data;
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ void check_timer(struct timer *t, double dt)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
t->on = 0;
|
timer_pause(t);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <execinfo.h>
|
||||||
|
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
|
|
||||||
|
@ -73,8 +74,7 @@ void print_stacktrace()
|
||||||
for (int i = 0; i < size; i++)
|
for (int i = 0; i < size; i++)
|
||||||
YughCritical(stackstr[i]);
|
YughCritical(stackstr[i]);
|
||||||
|
|
||||||
js_dump_stack();
|
js_stacktrace();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void seghandle(int sig) {
|
void seghandle(int sig) {
|
||||||
|
|
|
@ -435,6 +435,8 @@ Math.lerp = function (s, f, dt) {
|
||||||
return s + (Math.clamp(dt, 0, 1) * (f - s));
|
return s + (Math.clamp(dt, 0, 1) * (f - s));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Math.random_range = function(min,max) { return Math.random() * (max-min) + min; };
|
||||||
|
|
||||||
Math.snap = function(val, grid) {
|
Math.snap = function(val, grid) {
|
||||||
if (!grid || grid === 1) return Math.round(val);
|
if (!grid || grid === 1) return Math.round(val);
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,9 @@ var component = {
|
||||||
|
|
||||||
var sprite = clone(component, {
|
var sprite = clone(component, {
|
||||||
name: "sprite",
|
name: "sprite",
|
||||||
path: "",
|
_path: "",
|
||||||
|
get path() { return this._path; },
|
||||||
|
set path(x) { this._path = x; this.load_img(x); },
|
||||||
_pos: [0, 0],
|
_pos: [0, 0],
|
||||||
get layer() {
|
get layer() {
|
||||||
if (!this.gameobject)
|
if (!this.gameobject)
|
||||||
|
@ -101,7 +103,6 @@ var sprite = clone(component, {
|
||||||
if (!this.hasOwn('id')) return;
|
if (!this.hasOwn('id')) return;
|
||||||
cmd(60, this.id, this.layer);
|
cmd(60, this.id, this.layer);
|
||||||
cmd(37, this.id, this.pos);
|
cmd(37, this.id, this.pos);
|
||||||
cmd(12, this.id, this.path, this.rect);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
load_img(img) {
|
load_img(img) {
|
||||||
|
@ -135,11 +136,10 @@ var char2d = clone(sprite, {
|
||||||
make(go) {
|
make(go) {
|
||||||
var char = clone(this);
|
var char = clone(this);
|
||||||
char.curplaying = char.anims.array()[0];
|
char.curplaying = char.anims.array()[0];
|
||||||
Object.defineProperty(char, 'id', {value:make_sprite(go,this.path,this.pos)});
|
Object.defineProperty(char, 'id', {value:make_sprite(go,char.curplaying.path,this.pos)});
|
||||||
char.frame = 0;
|
char.frame = 0;
|
||||||
char.timer = timer.make(char.advance, 1/char.curplaying.fps, char);
|
char.timer = timer.make(char.advance.bind(char), 1/char.curplaying.fps);
|
||||||
char.timer.loop = true;
|
char.timer.loop = true;
|
||||||
char.rect = char.frame2rect(char.curplaying.frames, char.frame);
|
|
||||||
char.setsprite();
|
char.setsprite();
|
||||||
return char;
|
return char;
|
||||||
},
|
},
|
||||||
|
@ -152,7 +152,10 @@ var char2d = clone(sprite, {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.curplaying === this.anims[name]) return;
|
if (this.curplaying === this.anims[name]) {
|
||||||
|
this.timer.start();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.curplaying = this.anims[name];
|
this.curplaying = this.anims[name];
|
||||||
this.timer.time = 1/this.curplaying.fps;
|
this.timer.time = 1/this.curplaying.fps;
|
||||||
|
@ -170,6 +173,9 @@ var char2d = clone(sprite, {
|
||||||
advance() {
|
advance() {
|
||||||
this.frame = (this.frame + 1) % this.curplaying.frames;
|
this.frame = (this.frame + 1) % this.curplaying.frames;
|
||||||
this.setsprite();
|
this.setsprite();
|
||||||
|
|
||||||
|
if (this.frame === 0 && !this.curplaying.loop)
|
||||||
|
this.timer.pause();
|
||||||
},
|
},
|
||||||
|
|
||||||
devance() {
|
devance() {
|
||||||
|
@ -178,14 +184,18 @@ var char2d = clone(sprite, {
|
||||||
this.setsprite();
|
this.setsprite();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setframe(frame) {
|
||||||
|
this.frame = frame;
|
||||||
|
this.setsprite();
|
||||||
|
},
|
||||||
|
|
||||||
pause() {
|
pause() {
|
||||||
this.timer.pause();
|
this.timer.pause();
|
||||||
},
|
},
|
||||||
|
|
||||||
stop() {
|
stop() {
|
||||||
this.frame = 0;
|
this.setframe(0);
|
||||||
this.timer.stop();
|
this.timer.stop();
|
||||||
this.setsprite();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
kill() {
|
kill() {
|
||||||
|
|
|
@ -48,16 +48,6 @@ var Debug = {
|
||||||
register_debug(fn,obj);
|
register_debug(fn,obj);
|
||||||
},
|
},
|
||||||
|
|
||||||
print_callstack() {
|
|
||||||
for (var i = -3;; i--) {
|
|
||||||
var t = Duktape.act(i);
|
|
||||||
if (!t) break;
|
|
||||||
var file = t.function ? t.function.fileName : "";
|
|
||||||
var line = t.lineNumber;
|
|
||||||
Log.info(file + ":" + line);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
line(points, color, type) {
|
line(points, color, type) {
|
||||||
if (!type)
|
if (!type)
|
||||||
type = 0;
|
type = 0;
|
||||||
|
|
|
@ -82,11 +82,14 @@ function unmerge(target, source) {
|
||||||
/* Deeply merge two objects, not clobbering objects on target with objects on source */
|
/* Deeply merge two objects, not clobbering objects on target with objects on source */
|
||||||
function deep_merge(target, source)
|
function deep_merge(target, source)
|
||||||
{
|
{
|
||||||
|
Log.warn("Doing a deep merge ...");
|
||||||
for (var key in source) {
|
for (var key in source) {
|
||||||
if (typeof source[key] === 'object' && !Array.isArray(source[key]))
|
if (typeof source[key] === 'object' && !Array.isArray(source[key])) {
|
||||||
deep_merge(target[key], source[key]);
|
deep_merge(target[key], source[key]);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
target[key] = source[key];
|
target[key] = source[key];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,12 @@
|
||||||
selectable
|
selectable
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
var required_files = ["proto.json"];
|
||||||
|
|
||||||
|
required_files.forEach(x => {
|
||||||
|
if (!IO.exists(x)) slurpwrite("", x);
|
||||||
|
});
|
||||||
|
|
||||||
var editor_level = Level.create();
|
var editor_level = Level.create();
|
||||||
var editor_camera = editor_level.spawn(camera2d);
|
var editor_camera = editor_level.spawn(camera2d);
|
||||||
editor_camera.save = false;
|
editor_camera.save = false;
|
||||||
|
@ -221,7 +227,7 @@ var editor = {
|
||||||
if (this.sel_comp) return;
|
if (this.sel_comp) return;
|
||||||
|
|
||||||
if (!this.selectlist.empty) {
|
if (!this.selectlist.empty) {
|
||||||
this.selectlist.forEach(function(x) { x.draw_layer++; });
|
this.selectlist.forEach(x => x.draw_layer++);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,16 +252,21 @@ var editor = {
|
||||||
|
|
||||||
save_proto() {
|
save_proto() {
|
||||||
if (this.selectlist.length !== 1) return;
|
if (this.selectlist.length !== 1) return;
|
||||||
var protos = JSON.parse(slurp("proto.json"));
|
Log.warn(`Saving prototype ${this.selectlist[0].toString()}`);
|
||||||
|
var protos = JSON.parse(IO.slurp("proto.json"));
|
||||||
|
|
||||||
var tobj = this.selectlist[0].prop_obj();
|
var tobj = this.selectlist[0].prop_obj();
|
||||||
var pobj = this.selectlist[0].__proto__.prop_obj();
|
var pobj = this.selectlist[0].__proto__.prop_obj();
|
||||||
|
|
||||||
|
Log.warn("Going to deep merge.");
|
||||||
deep_merge(pobj, tobj);
|
deep_merge(pobj, tobj);
|
||||||
|
Log.warn("Finished deep merge.");
|
||||||
|
|
||||||
pobj.from = this.selectlist[0].__proto__.from;
|
pobj.from = this.selectlist[0].__proto__.from;
|
||||||
|
|
||||||
|
|
||||||
protos[this.selectlist[0].__proto__.name] = pobj;
|
protos[this.selectlist[0].__proto__.name] = pobj;
|
||||||
|
Log.warn(JSON.stringify(protos));
|
||||||
slurpwrite(JSON.stringify(protos, null, 2), "proto.json");
|
slurpwrite(JSON.stringify(protos, null, 2), "proto.json");
|
||||||
|
|
||||||
/* Save object changes to parent */
|
/* Save object changes to parent */
|
||||||
|
@ -265,11 +276,12 @@ var editor = {
|
||||||
unmerge(this.selectlist[0], tobj);
|
unmerge(this.selectlist[0], tobj);
|
||||||
|
|
||||||
/* Now sync all objects */
|
/* Now sync all objects */
|
||||||
Game.objects.forEach(function(x) { x.sync(); });
|
Game.objects.forEach(x => x.sync());
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
save_prototypes() {
|
save_prototypes() {
|
||||||
slurpwrite(JSON.stringify(gameobjects,null,2), "proto.json");
|
save_gameobjects_as_prototypes();
|
||||||
},
|
},
|
||||||
|
|
||||||
/* Save the selected object as a new prototype, extending the chain */
|
/* Save the selected object as a new prototype, extending the chain */
|
||||||
|
@ -278,7 +290,6 @@ var editor = {
|
||||||
Log.info("Already an object with name '" + name + "'. Choose another one.");
|
Log.info("Already an object with name '" + name + "'. Choose another one.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var newp = this.selectlist[0].__proto__.clone(name);
|
var newp = this.selectlist[0].__proto__.clone(name);
|
||||||
|
|
||||||
for (var key in newp)
|
for (var key in newp)
|
||||||
|
@ -535,7 +546,7 @@ var editor = {
|
||||||
},
|
},
|
||||||
|
|
||||||
input_delete_pressed() {
|
input_delete_pressed() {
|
||||||
this.selectlist.forEach(function(x) { x.kill(); });
|
this.selectlist.forEach(x => x.kill());
|
||||||
this.unselect();
|
this.unselect();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
var Log = {
|
var Log = {
|
||||||
set level(x) { cmd(92,x); },
|
set level(x) { cmd(92,x); },
|
||||||
get level() { return cmd(93); },
|
get level() { return cmd(93); },
|
||||||
|
@ -44,6 +46,7 @@ var Log = {
|
||||||
},
|
},
|
||||||
|
|
||||||
stack(skip = 0) {
|
stack(skip = 0) {
|
||||||
|
Log.warn("Printing stack");
|
||||||
var stack = (new Error()).stack;
|
var stack = (new Error()).stack;
|
||||||
var n = stack.next('\n',0)+1;
|
var n = stack.next('\n',0)+1;
|
||||||
for (var i = 0; i < skip; i++)
|
for (var i = 0; i < skip; i++)
|
||||||
|
@ -53,6 +56,7 @@ var Log = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
var files = {};
|
var files = {};
|
||||||
function load(file) {
|
function load(file) {
|
||||||
var modtime = cmd(0, file);
|
var modtime = cmd(0, file);
|
||||||
|
@ -162,7 +166,7 @@ var Yugine = {
|
||||||
};
|
};
|
||||||
|
|
||||||
var timer = {
|
var timer = {
|
||||||
make(fn, secs, obj, loop) {
|
make(fn, secs,obj,loop) {
|
||||||
if (secs === 0) {
|
if (secs === 0) {
|
||||||
fn.call(obj);
|
fn.call(obj);
|
||||||
return;
|
return;
|
||||||
|
@ -171,22 +175,16 @@ var timer = {
|
||||||
var t = clone(this);
|
var t = clone(this);
|
||||||
t.id = make_timer(fn, secs, obj);
|
t.id = make_timer(fn, secs, obj);
|
||||||
|
|
||||||
if (loop)
|
|
||||||
t.loop = loop;
|
|
||||||
else
|
|
||||||
t.loop = 0;
|
|
||||||
Log.info("Made timer " + t.id);
|
|
||||||
return t;
|
return t;
|
||||||
},
|
},
|
||||||
|
|
||||||
oneshot(fn, secs, obj) {
|
oneshot(fn, secs,obj) {
|
||||||
var t = clone(this);
|
var t = this.make(() => {
|
||||||
var killfn = function() {
|
fn.call();
|
||||||
fn.call(this);
|
|
||||||
t.kill();
|
t.kill();
|
||||||
};
|
},secs);
|
||||||
t.id = make_timer(killfn,secs,obj);
|
|
||||||
t.loop = 0;
|
t.loop = 0;
|
||||||
|
t.start();
|
||||||
},
|
},
|
||||||
|
|
||||||
get remain() { return cmd(32, this.id); },
|
get remain() { return cmd(32, this.id); },
|
||||||
|
@ -508,6 +506,8 @@ var Register = {
|
||||||
Player.players.forEach(x => x.uncontrol(obj));
|
Player.players.forEach(x => x.uncontrol(obj));
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Register.unregister_obj(null);
|
||||||
register(0, Register.update, Register);
|
register(0, Register.update, Register);
|
||||||
register(1, Register.physupdate, Register);
|
register(1, Register.physupdate, Register);
|
||||||
register(2, Register.gui, Register);
|
register(2, Register.gui, Register);
|
||||||
|
@ -515,6 +515,7 @@ register(3, Register.nk_gui, Register);
|
||||||
register(6, Register.debug, Register);
|
register(6, Register.debug, Register);
|
||||||
register(7, Register.kbm_input, Register);
|
register(7, Register.kbm_input, Register);
|
||||||
register(8, Register.gamepad_input, Register);
|
register(8, Register.gamepad_input, Register);
|
||||||
|
register(9, Log.stack, this);
|
||||||
|
|
||||||
Register.gamepad_playermap[0] = Player.players[0];
|
Register.gamepad_playermap[0] = Player.players[0];
|
||||||
|
|
||||||
|
@ -576,7 +577,13 @@ var Signal = {
|
||||||
|
|
||||||
var IO = {
|
var IO = {
|
||||||
exists(file) { return cmd(65, file);},
|
exists(file) { return cmd(65, file);},
|
||||||
slurp(file) { return cmd(38,file); },
|
slurp(file) {
|
||||||
|
if (!this.exists(file)) {
|
||||||
|
Log.warn(`File ${file} does not exist; can't slurp.`);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return cmd(38,file);
|
||||||
|
},
|
||||||
slurpwrite(str, file) { return cmd(39, str, file); },
|
slurpwrite(str, file) { return cmd(39, str, file); },
|
||||||
extensions(ext) { return cmd(66, "." + ext); },
|
extensions(ext) { return cmd(66, "." + ext); },
|
||||||
};
|
};
|
||||||
|
@ -1442,6 +1449,7 @@ var gameobject = {
|
||||||
},
|
},
|
||||||
|
|
||||||
kill() {
|
kill() {
|
||||||
|
Log.warn(`Killing ${this.toString()}`);
|
||||||
cmd(2, this.body);
|
cmd(2, this.body);
|
||||||
|
|
||||||
delete Game.objects[this.body];
|
delete Game.objects[this.body];
|
||||||
|
@ -1613,7 +1621,7 @@ function add_sync_prop(obj, prop, syncfn) {
|
||||||
function load_configs(file) {
|
function load_configs(file) {
|
||||||
var configs = JSON.parse(IO.slurp(file));
|
var configs = JSON.parse(IO.slurp(file));
|
||||||
for (var key in configs) {
|
for (var key in configs) {
|
||||||
Object.assign(this[key], configs[key]);
|
Object.assign(globalThis[key], configs[key]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Collision.sync();
|
Collision.sync();
|
||||||
|
@ -1653,7 +1661,7 @@ function save_game_configs() {
|
||||||
Game.objects.forEach(function(x) { x.sync(); });
|
Game.objects.forEach(function(x) { x.sync(); });
|
||||||
};
|
};
|
||||||
|
|
||||||
Collision = {
|
var Collision = {
|
||||||
types: {},
|
types: {},
|
||||||
num: 10,
|
num: 10,
|
||||||
set_collide(a, b, x) {
|
set_collide(a, b, x) {
|
||||||
|
@ -1718,3 +1726,38 @@ var camera2d = gameobject.clone("camera2d", {
|
||||||
|
|
||||||
win_make(Game.title, Game.resolution[0], Game.resolution[1]);
|
win_make(Game.title, Game.resolution[0], Game.resolution[1]);
|
||||||
win_icon("icon.png");
|
win_icon("icon.png");
|
||||||
|
|
||||||
|
/* Default objects */
|
||||||
|
gameobject.clone("polygon2d", {
|
||||||
|
polygon2d: polygon2d.clone(),
|
||||||
|
});
|
||||||
|
|
||||||
|
gameobject.clone("edge2d", {
|
||||||
|
edge2d: bucket.clone(),
|
||||||
|
});
|
||||||
|
|
||||||
|
gameobject.clone("sprite", {
|
||||||
|
sprite: sprite.clone(),
|
||||||
|
});
|
||||||
|
|
||||||
|
load("config.js");
|
||||||
|
|
||||||
|
var prototypes = JSON.parse(slurp("proto.json"));
|
||||||
|
for (var key in prototypes) {
|
||||||
|
if (key in gameobjects)
|
||||||
|
dainty_assign(gameobjects[key], prototypes[key]);
|
||||||
|
else {
|
||||||
|
/* Create this gameobject fresh */
|
||||||
|
Log.info("Making new prototype: " + key + " from " + prototypes[key].from);
|
||||||
|
var newproto = gameobjects[prototypes[key].from].clone(key);
|
||||||
|
gameobjects[key] = newproto;
|
||||||
|
|
||||||
|
for (var pkey in newproto)
|
||||||
|
if (typeof newproto[pkey] === 'object' && newproto[pkey] && 'clone' in newproto[pkey])
|
||||||
|
newproto[pkey] = newproto[pkey].clone();
|
||||||
|
|
||||||
|
dainty_assign(gameobjects[key], prototypes[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function save_gameobjects_as_prototypes() { slurpwrite(JSON.stringify(gameobjects,null,2), "proto.json"); };
|
||||||
|
|
Loading…
Reference in a new issue