no more mum

This commit is contained in:
John Alanbrook 2024-10-15 17:15:50 -05:00
parent 91ffcf998b
commit 14deabf2dd
7 changed files with 32 additions and 375 deletions

View file

@ -105,7 +105,6 @@ prosperon.textinput = function (c) {
}; };
prosperon.mousemove = function (pos, dx) { prosperon.mousemove = function (pos, dx) {
mousepos = pos; mousepos = pos;
mousepos.y = window.size.y - mousepos.y;
player[0].mouse_input("move", pos, dx); player[0].mouse_input("move", pos, dx);
}; };
prosperon.mousescroll = function (dx) { prosperon.mousescroll = function (dx) {
@ -127,6 +126,12 @@ input.mouse.screenpos = function () {
input.mouse.worldpos = function () { input.mouse.worldpos = function () {
return prosperon.camera.screen2world(mousepos); return prosperon.camera.screen2world(mousepos);
}; };
input.mouse.viewpos = function()
{
var world = input.mouse.worldpos();
return mousepos.slice();
}
input.mouse.disabled = function () { input.mouse.disabled = function () {
input.mouse_mode(1); input.mouse_mode(1);
}; };

View file

@ -1,359 +0,0 @@
globalThis.mum = {};
var panel;
var selected = undefined;
mum.inputs = {};
mum.inputs.lm = function () {
if (!selected) return;
if (!selected.action) return;
selected.action();
};
mum.base = {
offset: [0, 0], // Move x,y to the right and down before drawing
padding: [0, 0], // Pad inwards after drawing, to prepare for the next element
font: "fonts/c64.ttf",
selectable: false,
selected: false,
font_size: 16,
scale: 1,
angle: 0,
anchor: [0, 1], // where to draw the item from, relative to the cursor. [0,1] is from the top left corner. [1,0] is from the bottom right
background_image: null,
slice: null, // pass to slice an image as a 9 slice. see render.slice9 for its format
hover: {
color: Color.red,
},
text_shadow: {
pos: [0, 0],
color: Color.white,
},
border: 0, // Draw a border around the element. For text, an outline.
overflow: "wrap", // how to deal with overflow from parent element
wrap: -1,
text_align: "left" /* left, center, right */,
shader: null, // Use this shader, instead of the engine provided one
color: Color.white,
opacity: 1,
width: 0,
height: 0,
max_width: Infinity,
max_height: Infinity,
image_repeat: false,
image_repeat_offset: [0, 0],
debug: false /* set to true to draw debug boxes */,
hide: false,
child_gap: 0,
child_layout: 'top2bottom', /* top2bottom, left2right */
tooltip: null,
children: [],
};
// data is passed into each function, and various stats are generated
// drawpos: the point to start the drawing from
// wh: an array of [width,height]
// bound: a boundingbox around the drawn UI element
// extent: a boundingbox around the total extents of the element (ie before padding)
function show_debug() {
return prosperon.debug && mum.debug;
}
var context = mum.base;
var context_stack = [];
var cursor = [0,0];
function computeContainerSize(context)
{
var sizing = context.sizing.value;
var content_dim = [0,0];
var max_child_dim = [0,0];
if (context.layout === 'left2right') {
for (var child of context.children) {
content_dim.x += child.size.x + context.child_gap;
if (child.size.y > max_child_dim.y)
max_child_dim.y = child.size.y;
}
content_dim.width -= context.child_gap; // remove extra gap after last child
content_dim.y = max_child_dim.y;
} else {
for (var child of context.children) {
content_dim.y += child.size.y + context.child_gap;
if (child.size.x > max_child_dim.x)
max_child_dim.x = child.size.x;
}
content_dim.y -= child_gap;
content_dim.x = max_child_dim.x;
}
content_dim = content_dim.add(context.padding.scale(2));
var container_size = [0,0];
if (context.sizing.x.type === 'fit')
container_size.x = content_dim.x;
else if (container.sizing.x.type === 'grow') {
}
}
mum.container = function(data, cb) {
context_stack.push(context);
data.__proto__ = mum.base;
data.children = [];
var container_context = {
pos:cursor.slice(),
size:[0,0],
children:[]
};
context = data;
cb();
computeContainerSize(context);
}
mum.debug = false;
var post = function () {};
var posts = [];
mum.style = mum.base;
var cursor = [0, 0];
var pre = function (data) {
if (data.hide) return true;
data.__proto__ = mum.style;
if (data.pos) cursor = data.pos.slice();
data.drawpos = cursor.slice().add(data.offset);
if (data.opacity && data.opacity !== 1) {
data.color = data.color.slice();
data.color[3] = data.opacity;
}
data.wh = [data.width, data.height];
};
var anchor_calc = function (data) {
var aa = [0, 1].sub(data.anchor);
data.drawpos = data.drawpos.add([data.width, data.height]).scale(aa);
};
var end = function (data) {
cursor = cursor.add(data.padding);
post(data);
};
mum.list = function (fn, data = {}) {
if (pre(data)) return;
var aa = [0, 1].sub(data.anchor);
cursor = cursor.add([data.width, data.height].scale(aa)).add(data.offset).add(data.padding);
posts.push(post);
post = mum.list.post.bind(data);
if (show_debug())
render.boundingbox({
t: cursor.y,
b: cursor.y - data.height,
l: cursor.x,
r: cursor.x + data.width,
});
//if (data.background_image) mum.image(null, Object.create(data))
if (data.background_image) {
var imgpos = data.pos.slice();
imgpos.y -= data.height / 2;
imgpos.x -= data.width / 2;
var imgscale = [data.width, data.height];
if (data.slice) render.slice9(game.texture(data.background_image), imgpos, data.slice, imgscale);
else render.image(game.texture(data.background_image), imgpos, [data.width, data.height]);
}
fn();
data.bb.l -= data.padding.x;
data.bb.r += data.padding.x;
data.bb.t += data.padding.y;
data.bb.b -= data.padding.y;
if (show_debug()) render.boundingbox(data.bb);
post = posts.pop();
end(data);
};
mum.list.post = function (e) {
cursor.y -= e.bb.t - e.bb.b;
cursor.y -= e.padding.y;
if (this.bb) this.bb = bbox.expand(this.bb, e.bb);
else this.bb = e.bb;
};
mum.label = function (str, data = {}) {
if (pre(data)) return;
render.set_font(data.font, data.font_size);
data.bb = render.text_bb(str, data.scale, -1, cursor);
data.wh = bbox.towh(data.bb);
var aa = [0, 1].sub(data.anchor);
data.drawpos.y -= data.bb.t - cursor.y;
data.drawpos = data.drawpos.add(data.wh.scale(aa)).add(data.offset);
data.bb = render.text_bb(str, data.scale, data.wrap, data.drawpos);
if (data.action && bbox.pointin(data.bb, input.mouse.screenpos())) {
if (data.hover) {
data.hover.__proto__ = data;
data = data.hover;
selected = data;
}
}
data.bb = render.text(str, data.drawpos, data.scale, data.color, data.wrap);
if (show_debug()) render.boundingbox(data.bb);
end(data);
};
mum.image = function (path, data = {}) {
if (pre(data)) return;
path ??= data.background_image;
var image = game.texture(path);
var tex = image.texture;
if (!data.height)
if (data.width) data.height = tex.height * (data.width / tex.width);
else data.height = tex.height;
if (!data.width)
if (data.height) data.width = tex.width * (data.height / tex.height);
else data.height = tex.height;
if (!data.width) data.width = tex.width;
if (!data.height) data.height = tex.height;
var aa = [0, 1].sub(data.anchor);
data.drawpos = data.drawpos.add(aa.scale([data.width, data.height]));
if (data.slice) render.slice9(tex, data.drawpos, data.slice, [data.width, data.height]);
else data.bb = render.image(image, data.drawpos, [data.width, data.height]);
end(data);
};
mum.rectangle = function (data = {}, cb) {
if (pre(data)) return;
var aa = [0, 0].sub(data.anchor);
data.drawpos = data.drawpos.add(aa.scale([data.width, data.height]));
render.rectangle(data.drawpos, data.drawpos.add([data.width, data.height]), data.color);
end(data);
};
var btnbb;
var btnpost = function () {
btnbb = data.bb;
};
mum.button = function (str, data = { padding: [4, 4], color: Color.black }) {
if (pre(data)) return;
posts.push(post);
post = btnpost;
if (typeof str === "string") render.text(str, cursor.add(data.padding), data.scale, data.color);
else str();
if (data.action && data.hover && bbox.pointin(btnbb, input.mouse.screenpos())) {
data.hover.__proto__ = data;
data = data.hover;
}
render.rectangle([btnbb.l - data.padding.x, btnbb.b - data.padding.y], [btnbb.r + data.padding.y, btnbb.t + data.padding.y], data.color);
data.bb = btnbb;
post = posts.pop();
end(data);
};
mum.window = function (pos = [0,0], size = game.size.slice(), config = {}, fn) {
if (pre(config)) return;
render.rectangle(cursor, cursor.add(data.size), data.color);
config.pos = pos;
config.pos = config.add(config.padding);
fn();
end(data);
};
mum.hstack = function(data = {}, fn)
{
}
mum.ex_hud = function () {
mum.label("TOP LEFT", { pos: [0, game.size.y], anchor: [0, 1] });
mum.label("BOTTOM LEFT", { pos: [0, 0], anchor: [0, 0] });
mum.label("TOP RIGHT", { pos: game.size, anchor: [1, 1] });
mum.label("BOTTOM RIGHT", { pos: [game.size.x, 0], anchor: [1, 0] });
};
mum.drawinput = undefined;
var ptext = "";
var panpan = {
draw() {
mum.rectangle({
pos: [0, 0],
anchor: [0, 0],
height: 20,
width: window.size.x,
padding: [10, 16],
color: Color.black,
});
mum.label("input level: ");
mum.label(ptext, { offset: [50, 0], color: Color.red });
},
inputs: {
block: true,
char(c) {
ptext += c;
},
enter() {
delete mum.drawinput;
player[0].uncontrol(panpan);
},
escape() {
delete mum.drawinput;
player[0].uncontrol(panpan);
},
backspace() {
ptext = ptext.slice(0, ptext.length - 1);
},
},
};
mum.textinput = function (fn, str = "") {
mum.drawinput = panpan.draw;
ptext = str;
player[0].control(panpan);
panpan.inputs.enter = function () {
fn(ptext);
delete mum.drawinput;
player[0].uncontrol(panpan);
};
};

View file

@ -873,11 +873,18 @@ render.rectangle = function render_rectangle(lowerleft, upperright, color, shade
check_flush(flush_poly); check_flush(flush_poly);
}; };
// brect is x,y,width,height, with x,y in the upper left corner
render.brect = function(brect, color = Color.white) render.brect = function(brect, color = Color.white)
{ {
render.rectangle([brect.x,brect.y], [brect.x+brect.width, brect.y+brect.height], color); render.rectangle([brect.x,brect.y], [brect.x+brect.width, brect.y+brect.height], color);
} }
// brect is x,y,width,height, with x,y in the upper left corner
render.urect = function(brect, color = Color.white)
{
render.rectangle([brect.x,brect.y], [brect.x+brect.width, brect.y], color);
}
render.rect = function(rect, color, shader, pipe) render.rect = function(rect, color, shader, pipe)
{ {
render.rectangle([rect.x-rect.w/2, rect.y-rect.h/2], [rect.x+rect.w/2, rect.y+rect.h/2], color, shader, pipe); render.rectangle([rect.x-rect.w/2, rect.y-rect.h/2], [rect.x+rect.w/2, rect.y+rect.h/2], color, shader, pipe);
@ -895,7 +902,7 @@ render.window = function render_window(pos, wh, color) {
render.box(pos.add(wh.scale(0.5)), wh, color); render.box(pos.add(wh.scale(0.5)), wh, color);
}; };
render.text = function (str, pos, font = cur_font, size = 1, color = Color.white, wrap = -1) { render.text = function (str, pos, font = cur_font, size = 0, color = Color.white, wrap = -1) {
if (!font) return; if (!font) return;
gui.text(str, pos, size, color, wrap, font); // this puts text into buffer gui.text(str, pos, size, color, wrap, font); // this puts text into buffer
cur_font = font; cur_font = font;
@ -1164,10 +1171,10 @@ function camscreen2world(pos) {
return view; return view;
} }
// three coordinatse
// world coordinates, the "actual" view relative to the game's universe // world coordinates, the "actual" view relative to the game's universe
// camera coordinates, normalized from 0 to 1 inside of a camera's viewport, bottom left is 0,0, top right is 1,1 // camera coordinates, normalized from 0 to 1 inside of a camera's viewport, bottom left is 0,0, top right is 1,1
// screen coordinates, pixels, 0,0 at the bottom left of the window and [w,h] at the top right of the screen // screen coordinates, pixels, 0,0 at the top left of the window and [w,h] at the top right of the screen
// hud coordinates, same as screen coordinates but the top left is 0,0
camscreen2world.doc = "Convert a view position for a camera to world."; camscreen2world.doc = "Convert a view position for a camera to world.";
@ -1327,8 +1334,9 @@ prosperon.render = function () {
profile.endreport("draws"); profile.endreport("draws");
profile.endreport("world"); profile.endreport("world");
render.fillmask(0); render.fillmask(0);
prosperon.hudcam.size = prosperon.camera.size; prosperon.hudcam.size = prosperon.camera.size.slice();
prosperon.hudcam.transform.pos = [prosperon.hudcam.size.x / 2, prosperon.hudcam.size.y / 2, -100]; prosperon.hudcam.transform.pos = [prosperon.hudcam.size.x / 2, prosperon.hudcam.size.y / 2, -100];
prosperon.hudcam.size.y *= -1;
render.set_camera(prosperon.hudcam); render.set_camera(prosperon.hudcam);
profile.report("hud"); profile.report("hud");

View file

@ -27,7 +27,7 @@ uniform mat4 vp;
void main() void main()
{ {
letter charData = ls[gl_InstanceIndex]; letter charData = ls[gl_InstanceIndex];
fuv = charData.uv + vec2(a_pos.x*charData.uv_size.x, charData.uv_size.y - a_pos.y*charData.uv_size.y); fuv = charData.uv + a_pos*charData.uv_size;
uv = a_uv; uv = a_uv;
color0 = charData.color; color0 = charData.color;
pos = charData.pos+(a_pos*charData.wh); pos = charData.pos+(a_pos*charData.wh);
@ -54,7 +54,7 @@ void main()
{ {
float lettera = texture(sampler2D(text,smp),fuv).r; float lettera = texture(sampler2D(text,smp),fuv).r;
frag(); frag();
color.a = lettera; color.a *= lettera;
} }
@end @end

View file

@ -98,6 +98,7 @@ struct sFont *MakeFont(const char *fontfile, int height) {
newfont->ascent = ascent*emscale; newfont->ascent = ascent*emscale;
newfont->descent = descent*emscale; newfont->descent = descent*emscale;
newfont->linegap = linegap*emscale; newfont->linegap = linegap*emscale;
printf("ascent %g descent %g linegap %g\n", newfont->ascent, newfont->descent, newfont->linegap); printf("ascent %g descent %g linegap %g\n", newfont->ascent, newfont->descent, newfont->linegap);
newfont->texture = malloc(sizeof(texture)); newfont->texture = malloc(sizeof(texture));
@ -131,6 +132,9 @@ struct sFont *MakeFont(const char *fontfile, int height) {
}; };
newfont->Characters[c].Advance = glyph.xadvance; /* x distance from this char to the next */ newfont->Characters[c].Advance = glyph.xadvance; /* x distance from this char to the next */
newfont->Characters[c].leftbearing = glyph.xoff;
// printf("char %c: ascent %g, yoff %g, yoff2 %g\n", c, newfont->ascent, glyph.yoff, glyph.yoff2);
newfont->Characters[c].topbearing = newfont->ascent + glyph.yoff;
newfont->Characters[c].rect = r; newfont->Characters[c].rect = r;
} }
@ -165,8 +169,8 @@ int text_flush(sg_buffer *buf) {
void sdrawCharacter(struct Character c, HMM_Vec2 cursor, float scale, struct rgba color) { void sdrawCharacter(struct Character c, HMM_Vec2 cursor, float scale, struct rgba color) {
struct text_vert vert; struct text_vert vert;
vert.pos.x = cursor.X + c.leftbearing * scale; vert.pos.x = cursor.X + c.leftbearing;
vert.pos.y = cursor.Y - c.topbearing * scale; vert.pos.y = cursor.Y + c.topbearing;
vert.wh = c.size; vert.wh = c.size;
// if (vert.pos.x > frame.l || vert.pos.y > frame.t || (vert.pos.y + vert.wh.y) < frame.b || (vert.pos.x + vert.wh.x) < frame.l) return; // if (vert.pos.x > frame.l || vert.pos.y > frame.t || (vert.pos.y + vert.wh.y) < frame.b || (vert.pos.x + vert.wh.x) < frame.l) return;

View file

@ -598,8 +598,8 @@ struct rect js2rect(JSValue v) {
struct rect rect; struct rect rect;
rect.x = js2number(js_getpropstr(v, "x")); rect.x = js2number(js_getpropstr(v, "x"));
rect.y = js2number(js_getpropstr(v, "y")); rect.y = js2number(js_getpropstr(v, "y"));
rect.w = js2number(js_getpropstr(v, "w")); rect.w = js2number(js_getpropstr(v, "width"));
rect.h = js2number(js_getpropstr(v, "h")); rect.h = js2number(js_getpropstr(v, "height"));
return rect; return rect;
} }
@ -1396,11 +1396,12 @@ JSC_CCALL(gui_scissor,
JSC_CCALL(gui_text, JSC_CCALL(gui_text,
const char *s = JS_ToCString(js, argv[0]); const char *s = JS_ToCString(js, argv[0]);
HMM_Vec2 pos = js2vec2(argv[1]); HMM_Vec2 pos = js2vec2(argv[1]);
float size = js2number(argv[2]); float size = js2number(argv[2]);
font *f = js2font(argv[5]);
if (!size) size = f->height;
struct rgba c = js2color(argv[3]); struct rgba c = js2color(argv[3]);
int wrap = js2number(argv[4]); int wrap = js2number(argv[4]);
renderText(s, pos, js2font(argv[5]), size, c, wrap); renderText(s, pos, f, size, c, wrap);
JS_FreeCString(js, s); JS_FreeCString(js, s);
return ret; return ret;
) )
@ -2890,7 +2891,7 @@ JSC_CCALL(geometry_rect_random,
JSC_CCALL(geometry_rect_point_inside, JSC_CCALL(geometry_rect_point_inside,
rect a = js2rect(argv[0]); rect a = js2rect(argv[0]);
HMM_Vec2 p = js2vec2(argv[1]); HMM_Vec2 p = js2vec2(argv[1]);
return boolean2js(p.x >= a.x-a.w/2 && p.x <= a.x+a.w/2 && p.y <= a.y+a.h/2 && p.y >= a.y-a.h/2); return boolean2js(p.x >= a.x && p.x <= a.x+a.w && p.y <= a.y+a.h && p.y >= a.y-a.h);
) )
JSC_CCALL(geometry_cwh2rect, JSC_CCALL(geometry_cwh2rect,

View file

@ -175,8 +175,6 @@ struct texture *texture_from_file(const char *path) {
struct texture *tex = calloc(1, sizeof(*tex)); struct texture *tex = calloc(1, sizeof(*tex));
stbi_set_flip_vertically_on_load(1);
int n; int n;
char *ext = strrchr(path, '.'); char *ext = strrchr(path, '.');