This commit is contained in:
2023-05-02 01:58:10 +00:00
parent bea5b326cf
commit d3cb9278a9
9 changed files with 194 additions and 79 deletions

View File

@@ -41,8 +41,8 @@ void set_cat_mask(int cat, unsigned int mask)
void color2float(struct color color, float *fcolor)
{
fcolor[0] = (float)color.r/255;
fcolor[1] = (float)color.b/255;
fcolor[2] = (float)color.g/255;
fcolor[1] = (float)color.g/255;
fcolor[2] = (float)color.b/255;
}
struct color float2color(float *fcolor)

View File

@@ -65,6 +65,11 @@ double js2number(JSValue v)
return g;
}
int js2bool(JSValue v)
{
return JS_ToBool(js,v);
}
JSValue float2js(double g)
{
return JS_NewFloat64(js,g);
@@ -931,6 +936,23 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
case 93:
ret = int2js(logLevel);
break;
case 94:
str = JS_ToCString(js,argv[1]);
texture_pullfromfile(str)->opts.mips = js2bool(argv[2]);
texture_sync(str);
break;
case 95:
str = JS_ToCString(js,argv[1]);
texture_pullfromfile(str)->opts.sprite = js2bool(argv[2]);
texture_sync(str);
break;
case 96:
color2float(js2color(argv[2]), id2sprite(js2int(argv[1]))->color);
break;
}
if (str)
@@ -1237,7 +1259,6 @@ JSValue duk_make_sprite(JSContext *js, JSValueConst this, int argc, JSValueConst
JS_FreeCString(js,path);
return JS_NewInt64(js, sprite);
}
/* Make anim from texture */

View File

@@ -189,6 +189,7 @@ void joystick_cb(int jid, int event)
JSValue jsgamepadstr[15];
JSValue jsaxesstr[4];
JSValue jsaxis;
void input_init()
{
@@ -205,10 +206,11 @@ void input_init()
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");
jsaxesstr[0] = str2js("ljoy");
jsaxesstr[1] = str2js("rjoy");
jsaxesstr[2] = str2js("ltrigger");
jsaxesstr[3] = str2js("rtrigger");
jsaxis = str2js("axis");
/* Grab all joysticks initially present */
for (int i = 0; i < 16; i++)
@@ -397,7 +399,7 @@ void input_poll(double wait)
GLFWgamepadstate state;
if (!glfwGetGamepadState(joysticks[i].id, &state)) continue;
JSValue argv[3];
JSValue argv[4];
argv[0] = num_cache[joysticks[i].id];
for (int b = 0; b < 15; b++) {
argv[1] = jsgamepadstr[b];
@@ -417,30 +419,37 @@ void input_poll(double wait)
}
}
argv[2] = jsaxis;
float deadzone = 0.05;
for (int i = 0; i < 4; i++)
state.axes[i] = fabs(state.axes[i]) > deadzone ? state.axes[i] : 0;
argv[1] = jsaxesstr[0];
cpVect v;
v.x = state.axes[0];
v.y = -state.axes[1];
argv[2] = vec2js(v);
script_callee(gamepad_callee,3,argv);
JS_FreeValue(js, argv[2]);
argv[3] = vec2js(v);
script_callee(gamepad_callee,4,argv);
JS_FreeValue(js, argv[3]);
argv[1] = jsaxesstr[1];
v.x = state.axes[2];
v.y = -state.axes[3];
argv[2] = vec2js(v);
script_callee(gamepad_callee,3,argv);
JS_FreeValue(js, argv[2]);
argv[3] = vec2js(v);
script_callee(gamepad_callee,4,argv);
JS_FreeValue(js, argv[3]);
argv[1] = jsaxesstr[2];
argv[2] = num2js((state.axes[4]+1)/2);
script_callee(gamepad_callee,3,argv);
JS_FreeValue(js, argv[2]);
argv[3] = num2js((state.axes[4]+1)/2);
script_callee(gamepad_callee,4,argv);
JS_FreeValue(js, argv[3]);
argv[1] = jsaxesstr[3];
argv[2] = num2js((state.axes[5]+1)/2);
script_callee(gamepad_callee,3,argv);
JS_FreeValue(js, argv[2]);
argv[3] = num2js((state.axes[5]+1)/2);
script_callee(gamepad_callee,4,argv);
JS_FreeValue(js, argv[3]);
joysticks[i].state = state;
}

View File

@@ -122,7 +122,7 @@ void sprite_initialize()
glEnableVertexAttribArray(0);
}
void tex_draw(struct Texture *tex, float pos[2], float angle, float size[2], float offset[2], struct glrect r) {
void tex_draw(struct Texture *tex, float pos[2], float angle, float size[2], float offset[2], struct glrect r, mfloat_t color[3]) {
mfloat_t model[16] = { 0.f };
mfloat_t r_model[16] = { 0.f };
mfloat_t s_model[16] = { 0.f };
@@ -142,9 +142,8 @@ void tex_draw(struct Texture *tex, float pos[2], float angle, float size[2], flo
mat4_translate_vec2(model, pos);
float white[3] = { 1.f, 1.f, 1.f };
shader_setmat4(spriteShader, "model", model);
shader_setvec3(spriteShader, "spriteColor", white);
shader_setvec3(spriteShader, "spriteColor", color);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, tex->id);
@@ -173,7 +172,7 @@ void sprite_draw(struct sprite *sprite)
cpVect cpos = cpBodyGetPosition(go->body);
float pos[2] = {cpos.x, cpos.y};
float size[2] = { sprite->size[0] * go->scale * go->flipx, sprite->size[1] * go->scale * go->flipy };
tex_draw(sprite->tex, pos, cpBodyGetAngle(go->body), size, sprite->pos, sprite->frame);
tex_draw(sprite->tex, pos, cpBodyGetAngle(go->body), size, sprite->pos, sprite->frame, sprite->color);
}
}
@@ -190,7 +189,8 @@ void gui_draw_img(const char *img, float x, float y) {
float pos[2] = {x, y};
float size[2] = {1.f, 1.f};
float offset[2] = { 0.f, 0.f };
tex_draw(tex, pos, 0.f, size, offset, tex_get_rect(tex));
float white[3] = {1.f,1.f,1.f};
tex_draw(tex, pos, 0.f, size, offset, tex_get_rect(tex), white);
}
void sprite_setframe(struct sprite *sprite, struct glrect *frame)

View File

@@ -34,24 +34,11 @@ struct Texture *texture_pullfromfile(const char *path)
YughInfo("Loading texture %s.", path);
struct Texture *tex = calloc(1, sizeof(*tex));
/* Find texture's asset; otherwise load default asset */
JSON_Value *rv = json_parse_file("texture.asset");
JSON_Object *ro = json_value_get_object(rv);
tex->opts.sprite = json_object_get_boolean(ro, "sprite");
tex->opts.mips = json_object_get_boolean(ro, "mips");
json_value_free(rv);
tex->opts.sprite = 1;
tex->opts.mips = 0;
tex->opts.gamma = 0;
tex->anim.ms = 2;
tex->anim.tex = tex;
texanim_fromframes(&tex->anim, 2);
tex->anim.loop = 1;
int n;
unsigned char *data = stbi_load(path, &tex->width, &tex->height, &n, 4);
if (data == NULL) {
@@ -89,11 +76,21 @@ struct Texture *texture_pullfromfile(const char *path)
glGenerateMipmap(GL_TEXTURE_2D);
if (tex->opts.sprite) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
if (tex->opts.mips) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_NEAREST);
} else {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}
} else {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
if (tex->opts.mips) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
} else {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
@@ -107,6 +104,36 @@ struct Texture *texture_pullfromfile(const char *path)
return tex;
}
void texture_sync(const char *path)
{
struct Texture *tex = texture_pullfromfile(path);
glBindTexture(GL_TEXTURE_2D, tex->id);
if (tex->opts.mips)
glGenerateMipmap(GL_TEXTURE_2D);
if (tex->opts.sprite) {
if (tex->opts.mips) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_NEAREST);
} else {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}
} else {
if (tex->opts.mips) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
} else {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
}
char *tex_get_path(struct Texture *tex) {
for (int i = 0; i < shlen(texhash); i++) {
if (tex == texhash[i].value) {

View File

@@ -68,6 +68,7 @@ struct Texture {
struct Texture *texture_pullfromfile(const char *path); // Create texture from image
struct Texture *texture_loadfromfile(const char *path); // Create texture & load to gpu
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

View File

@@ -105,6 +105,10 @@ var sprite = clone(component, {
cmd(37, this.id, this.pos);
},
set color(x) {
cmd(96, this.id, x);
},
load_img(img) {
cmd(12, this.id, img, this.rect);
},
@@ -679,3 +683,35 @@ var circle2d = clone(collider2d, {
this.coll_sync();
},
});
/* ASSETS */
var Texture = {
mipmaps(path, x) {
cmd(94, path, x);
},
sprite(path, x) {
cmd(95, path, x);
},
};
var Resources = {
load(path) {
if (path in this)
return this[path];
var src = {};
this[path] = src;
src.path = path;
if (!IO.exists(`${path}.asset`))
return this[path];
var data = JSON.parse(IO.slurp(`${path}.asset`));
Object.assign(src,data);
return this[path];
},
};

View File

@@ -420,7 +420,7 @@ var Action = {
var Player = {
players: [],
input(fn, ...args) {
this.pawns.forEach(x => { if (fn in x) x[fn](...args); });
this.pawns.forEach(x => x[fn]?.(...args));
},
control(pawn) {
@@ -440,6 +440,7 @@ for (var i = 0; i < 4; i++) {
}
function state2str(state) {
if (typeof state === 'string') return state;
switch (state) {
case 0:
return "down";
@@ -723,6 +724,7 @@ var Game = {
},
};
var Level = {
levels: [],
objects: [],
@@ -922,6 +924,8 @@ var Level = {
newobj.defn('level', this);
this.objects.push(newobj);
Game.register_obj(newobj);
newobj.setup?.();
newobj.start?.();
return newobj;
},
@@ -1185,9 +1189,11 @@ var Level = {
get left() {
return [-1,0].rotate(Math.deg2rad(this.angle));
},
};
var World = Level.create();
World.name = "World";
var gameobjects = {};
/* Returns the index of the smallest element in array, defined by a function that returns a number */
@@ -1211,7 +1217,13 @@ function grab_from_points(pos, points, slop) {
var gameobject = {
get scale() { return this._scale; },
set scale(x) { this._scale = Math.max(0,x); if (this.body > -1) cmd(36, this.body, this._scale); this.sync(); },
set scale(x) {
this._scale = Math.max(0,x);
if (this.body > -1)
cmd(36, this.body, this._scale);
this.sync();
},
_scale: 1.0,
save: true,
@@ -1309,6 +1321,26 @@ var gameobject = {
body: -1,
controlled: false,
get properties() {
var keys = [];
for (var key of Object.keys(this)) {
if (key.startsWith("_"))
keys.push(key.substring(1));
else
keys.push(key);
}
return keys;
},
toJSON() {
var obj = {};
for (var key of this.properties)
obj[key] = this[key];
return obj;
},
set_center(pos) {
var change = pos.sub(this.pos);
@@ -1515,6 +1547,7 @@ var gameobject = {
this2world(pos) { return cmd(71, this.body,pos); },
make(props, level) {
level ??= World;
var obj = Object.create(this);
this.instances.push(obj);
obj.toString = function() {
@@ -1584,39 +1617,11 @@ var gameobject = {
}
var locks = ['draw_layer', 'friction','elasticity', 'visible', 'body', 'flipx', 'flipy', 'scale', 'controlled', 'selectable', 'save', 'velocity', 'angularvelocity', 'alive', 'boundingbox', 'name'];
var locks = ['draw_layer', 'friction','elasticity', 'visible', 'body', 'flipx', 'flipy', 'controlled', 'selectable', 'save', 'velocity', 'angularvelocity', 'alive', 'boundingbox', 'name', 'scale', 'angle', 'properties', 'moi', 'relpos', 'relangle', 'up', 'down', 'right', 'left', 'bodytype', 'gizmo', 'pos'];
locks.forEach(function(x) {
Object.defineProperty(gameobject, x, {enumerable:false});
});
function private_non_enumerable(obj) {
for (var key in obj) {
if (key.startsWith('_'))
Object.defineProperty(obj, key, {enumerable:false});
}
}
function add_sync_prop(obj, prop, syncfn) {
var hidden = "_"+prop;
Log.info(hidden);
Object.defineProperty(obj, hidden, {
value: null,
writable: true,
});
Object.defineProperty(obj, prop, {
get: function() { return obj[hidden]; },
set: function(x) {
obj[hidden] = x;
syncfn(obj[hidden]);
},
enumerable: true,
});
return obj;
};
/* Load configs */
function load_configs(file) {
var configs = JSON.parse(IO.slurp(file));
@@ -1761,5 +1766,3 @@ for (var key in prototypes) {
}
function save_gameobjects_as_prototypes() { slurpwrite(JSON.stringify(gameobjects,null,2), "proto.json"); };
Resources = {};