diff --git a/.prosperon/imgui.ini b/.prosperon/imgui.ini new file mode 100644 index 00000000..6c933f2e --- /dev/null +++ b/.prosperon/imgui.ini @@ -0,0 +1,183 @@ +[Window][Debug##Default] +Pos=60,60 +Size=400,400 + +[Window][TEST WINDOW] +Pos=156,6 +Size=366,275 + +[Window][editor] +Pos=558,248 +Size=274,177 + +[Window][Editor] +Pos=-113,317 +Size=184,174 + +[Window][Map Editor] +Pos=96,74 +Size=312,398 + +[Window][Edit Tile] +Pos=120,99 +Size=356,275 + +[Window][Level Editor] +Pos=60,45 +Size=283,332 +Collapsed=1 + +[Window][Brush Selector] +Pos=189,35 +Size=203,474 +Collapsed=1 + +[Window][Tool Selector] +Pos=300,25 +Size=247,474 +Collapsed=1 + +[Window][FPS: 12] +Pos=60,60 +Size=32,35 + +[Window][FPS: 87] +Pos=60,60 +Size=32,35 + +[Window][FPS: 59] +Pos=60,60 +Size=32,35 + +[Window][FPS: 107] +Pos=60,60 +Size=32,35 + +[Window][FPS: 135] +Pos=60,60 +Size=32,35 + +[Window][FPS: 136] +Pos=60,60 +Size=51,48 + +[Window][FPS: 140] +Pos=60,60 +Size=51,48 + +[Window][FPS: 137] +Pos=60,60 +Size=51,48 + +[Window][FPS: 138] +Pos=60,60 +Size=51,48 + +[Window][FPS: 141] +Pos=60,60 +Size=51,48 + +[Window][FPS: 143] +Pos=60,60 +Size=51,48 + +[Window][FPS: 142] +Pos=60,60 +Size=51,48 + +[Window][FPS: 144] +Pos=60,60 +Size=32,35 + +[Window][FPS: 139] +Pos=60,60 +Size=51,48 + +[Window][FPS: 133] +Pos=60,60 +Size=32,35 + +[Window][FPS: 134] +Pos=60,60 +Size=51,48 + +[Window][FPS: 131] +Pos=60,60 +Size=51,48 + +[Window][FPS: 130] +Pos=60,60 +Size=51,48 + +[Window][FPS: 128] +Pos=60,60 +Size=51,48 + +[Window][FPS: 126] +Pos=60,60 +Size=51,48 + +[Window][FPS: 123] +Pos=60,60 +Size=32,35 + +[Window][FPS: 124] +Pos=60,60 +Size=32,35 + +[Window][FPS: 121] +Pos=60,60 +Size=32,35 + +[Window][FPS: 122] +Pos=60,60 +Size=32,35 + +[Window][FPS: 119] +Pos=60,60 +Size=51,48 + +[Window][FPS: 117] +Pos=60,60 +Size=32,35 + +[Window][FPS: 118] +Pos=60,60 +Size=32,35 + +[Window][FPS: 116] +Pos=60,60 +Size=32,35 + +[Window][FPS: 108] +Pos=60,60 +Size=32,35 + +[Window][FPS: 109] +Pos=60,60 +Size=51,48 + +[Window][FPS: 115] +Pos=60,60 +Size=51,48 + +[Window][FPS: 114] +Pos=60,60 +Size=51,48 + +[Window][FPS: 113] +Pos=60,60 +Size=51,48 + +[Window][FPS: 110] +Pos=60,60 +Size=51,48 + +[Window][FPS: 112] +Pos=60,60 +Size=51,48 + +[Window][FPS: 111] +Pos=60,60 +Size=51,48 + diff --git a/prosperon/draw2d.cm b/prosperon/draw2d.cm index 625149ae..308cd70d 100644 --- a/prosperon/draw2d.cm +++ b/prosperon/draw2d.cm @@ -137,7 +137,7 @@ draw.slice9 = function slice9(image, rect = [0,0], slice = 0, info = slice9_info }) } -draw.image = function image(image, rect, rotation, anchor, shear, info = {mode:"nearest"}, material) { +draw.image = function image(image, rect, rotation, anchor, shear, info = {mode:"nearest"}, material = {color:{r:1,g:1,b:1,a:1}}) { if (!rect) throw Error('Need rectangle to render image.') if (!image) throw Error('Need an image to render.') diff --git a/prosperon/prosperon.cm b/prosperon/prosperon.cm index 383d43fb..0d3f0ba6 100644 --- a/prosperon/prosperon.cm +++ b/prosperon/prosperon.cm @@ -212,14 +212,45 @@ function translate_draw_commands(commands) { case "draw_text": if (!cmd.text) break if (!cmd.pos) break - var rect = worldToScreenRect({x:cmd.pos.x, y:cmd.pos.y, width:8, height:8}, camera) - var pos = {x: rect.x, y: rect.y} + + // Get font from the font string (e.g., "smalle.16") + var font = graphics.get_font(cmd.font, cmd.size) + if (!font || !font.texture || !font.texture.id) break + + // Create text geometry buffer + var text_mesh = graphics.make_text_buffer( + cmd.text, + {x: cmd.pos.x, y: cmd.pos.y, width: 200, height: 50}, + cmd.size, + [cmd.material.color.r, cmd.material.color.g, cmd.material.color.b, cmd.material.color.a], + cmd.wrap || 0, + font + ) + + if (!text_mesh) break + + // Transform XY coordinates using camera matrix + var camera_params = [camera.a, camera.c, camera.e, camera.f] + var transformed_xy = geometry.transform_xy_blob(text_mesh.xy, camera_params) + + // Create transformed geometry object + var transformed_geom = { + xy: transformed_xy, + xy_stride: text_mesh.xy_stride, + uv: text_mesh.uv, + uv_stride: text_mesh.uv_stride, + color: text_mesh.color, + color_stride: text_mesh.color_stride, + indices: text_mesh.indices, + num_vertices: text_mesh.num_vertices, + num_indices: text_mesh.num_indices, + size_indices: text_mesh.size_indices, + texture_id: font.texture.id + } + renderer_commands.push({ - op: "debugText", - data: { - pos, - text: cmd.text - } + op: "geometry_raw", + data: transformed_geom }) break diff --git a/prosperon/sound.cm b/prosperon/sound.cm index 7db6bc9c..3eed622a 100644 --- a/prosperon/sound.cm +++ b/prosperon/sound.cm @@ -98,6 +98,6 @@ function pump() $_.delay(pump, 1/240) } -pump() +//pump() return audio; diff --git a/scripts/graphics.cm b/scripts/graphics.cm index accba96a..a7c0a8e4 100644 --- a/scripts/graphics.cm +++ b/scripts/graphics.cm @@ -12,6 +12,7 @@ var io = use('io') var time = use('time') var res = use('resources') var json = use('json') +var os = use('os') var GPU = Symbol() var CPU = Symbol() @@ -412,7 +413,12 @@ graphics.get_font = function get_font(path, size) { if (fontcache[fontstr]) return fontcache[fontstr] var data = io.slurpbytes(fullpath) - var font = graphics.make_font(data,size) + // Ensure size is a proper number + var numericSize = Number(size) + if (isNaN(numericSize) || numericSize <= 0) { + numericSize = 16 // default size + } + var font = graphics.make_font(data, numericSize) // Load font texture via renderer actor (async) if (renderer_actor) { diff --git a/source/font.c b/source/font.c index 0391c8c3..ea690394 100644 --- a/source/font.c +++ b/source/font.c @@ -78,7 +78,6 @@ struct sFont *MakeFont(void *ttf_buffer, size_t len, int height) { quad.h = glyph.yoff2-glyph.yoff; newfont->Characters[c].quad = quad; newfont->Characters[c].advance = glyph.xadvance; -// printf("glyph for %c is x0,y0,x1,y1: %d,%d,%d,%d\n xoff %g, yoff %g, xadvance %g, xoff2 %g, yoff2 %g\n", c, glyph.x0, glyph.y1, glyph.x1, glyph.y1, glyph.xoff, glyph.yoff, glyph.xadvance, glyph.xoff2, glyph.yoff2); } free(bitmap); @@ -109,8 +108,8 @@ void draw_char_verts(struct text_vert **buffer, struct character c, HMM_Vec2 cur // packedchar has // Adds four verts: bottom left, bottom right, top left, top right text_vert bl; - bl.pos.x = cursor.X + c.quad.x; - bl.pos.y = cursor.Y + c.quad.y; + bl.pos.x = cursor.X + c.quad.x * scale; + bl.pos.y = cursor.Y + c.quad.y * scale; bl.uv.x = c.uv.x; bl.uv.y = c.uv.y; bl.color = color; @@ -118,12 +117,12 @@ void draw_char_verts(struct text_vert **buffer, struct character c, HMM_Vec2 cur text_vert br = bl; - br.pos.x += c.quad.w; + br.pos.x += c.quad.w * scale; br.uv.x += c.uv.w; arrput(*buffer, br); text_vert ul = bl; - ul.pos.y += c.quad.h; + ul.pos.y += c.quad.h * scale; ul.uv.y += c.uv.h; arrput(*buffer, ul); @@ -238,30 +237,32 @@ struct text_vert *renderText(const char *text, HMM_Vec2 pos, font *f, float scal text_vert *buffer = NULL; HMM_Vec2 cursor = pos; - float lineHeight = f->ascent - f->descent; + float lineHeight = (f->ascent - f->descent) * scale; float lineWidth = 0; + float scaledLinegap = f->linegap * scale; for (const char *c = text; *c != 0; c++) { if (*c == '\n') { cursor.x = pos.x; - cursor.y -= lineHeight + f->linegap; + cursor.y -= lineHeight + scaledLinegap; lineWidth = 0; continue; } struct character chara = f->Characters[(unsigned char)*c]; + float scaledAdvance = chara.advance * scale; - if (wrap > 0 && lineWidth + chara.advance > wrap) { + if (wrap > 0 && lineWidth + scaledAdvance > wrap) { cursor.x = pos.x; - cursor.y -= lineHeight + f->linegap; + cursor.y -= lineHeight + scaledLinegap; lineWidth = 0; } if (!isspace(*c)) draw_char_verts(&buffer, chara, cursor, scale, color); - lineWidth += chara.advance; - cursor.x += chara.advance; + lineWidth += scaledAdvance; + cursor.x += scaledAdvance; } return buffer; diff --git a/source/jsffi.c b/source/jsffi.c index 97c70257..f121e972 100644 --- a/source/jsffi.c +++ b/source/jsffi.c @@ -296,31 +296,61 @@ JSValue quads_to_mesh(JSContext *js, text_vert *buffer) { size_t verts = arrlen(buffer); - HMM_Vec2 *pos = malloc(arrlen(buffer)*sizeof(HMM_Vec2)); - HMM_Vec2 *uv = malloc(arrlen(buffer)*sizeof(HMM_Vec2)); - HMM_Vec4 *color = malloc(arrlen(buffer)*sizeof(HMM_Vec4)); + // Allocate flat arrays for xy, uv, and color data + size_t xy_size = verts * 2 * sizeof(float); + size_t uv_size = verts * 2 * sizeof(float); + size_t color_size = verts * sizeof(SDL_FColor); + + float *xy_data = malloc(xy_size); + float *uv_data = malloc(uv_size); + SDL_FColor *color_data = malloc(color_size); - for (int i = 0; i < arrlen(buffer); i++) { - pos[i] = buffer[i].pos; - uv[i] = buffer[i].uv; - color[i] = buffer[i].color; + // Convert vertex data to flat arrays + for (int i = 0; i < verts; i++) { + xy_data[i*2] = buffer[i].pos.x; + xy_data[i*2+1] = buffer[i].pos.y; + + uv_data[i*2] = buffer[i].uv.x; + uv_data[i*2+1] = buffer[i].uv.y; + + color_data[i].r = buffer[i].color.x; + color_data[i].g = buffer[i].color.y; + color_data[i].b = buffer[i].color.z; + color_data[i].a = buffer[i].color.w; } - JSValue jspos = make_gpu_buffer(js, pos, sizeof(HMM_Vec2)*arrlen(buffer), 0, 2,0,0); - JSValue jsuv = make_gpu_buffer(js, uv, sizeof(HMM_Vec2)*arrlen(buffer), 0, 2,0,0); - JSValue jscolor = make_gpu_buffer(js, color, sizeof(HMM_Vec4)*arrlen(buffer), 0, 4,0,0); - size_t quads = verts/4; - size_t count = verts/2*3; - JSValue jsidx = make_quad_indices_buffer(js, quads); + size_t count = quads*6; + + // Create indices + uint16_t *indices = malloc(sizeof(uint16_t)*count); + for (int i = 0, v = 0; i < count; i += 6, v += 4) { + indices[i] = v; + indices[i+1] = v+2; + indices[i+2] = v+1; + indices[i+3] = v+2; + indices[i+4] = v+3; + indices[i+5] = v+1; + } JSValue ret = JS_NewObject(js); - JS_SetPropertyStr(js, ret, "pos", jspos); - JS_SetPropertyStr(js, ret, "uv", jsuv); - JS_SetPropertyStr(js, ret, "color", jscolor); - JS_SetPropertyStr(js, ret, "indices", jsidx); - JS_SetPropertyStr(js, ret, "vertices", number2js(js, verts)); - JS_SetPropertyStr(js,ret,"num_indices", number2js(js,count)); + + // Create blobs for geometry data + JS_SetPropertyStr(js, ret, "xy", js_new_blob_stoned_copy(js, xy_data, xy_size)); + JS_SetPropertyStr(js, ret, "xy_stride", JS_NewInt32(js, 2 * sizeof(float))); + JS_SetPropertyStr(js, ret, "uv", js_new_blob_stoned_copy(js, uv_data, uv_size)); + JS_SetPropertyStr(js, ret, "uv_stride", JS_NewInt32(js, 2 * sizeof(float))); + JS_SetPropertyStr(js, ret, "color", js_new_blob_stoned_copy(js, color_data, color_size)); + JS_SetPropertyStr(js, ret, "color_stride", JS_NewInt32(js, sizeof(SDL_FColor))); + JS_SetPropertyStr(js, ret, "indices", js_new_blob_stoned_copy(js, indices, sizeof(uint16_t)*count)); + JS_SetPropertyStr(js, ret, "num_vertices", JS_NewInt32(js, verts)); + JS_SetPropertyStr(js, ret, "num_indices", JS_NewInt32(js, count)); + JS_SetPropertyStr(js, ret, "size_indices", JS_NewInt32(js, 2)); // uint16_t size + + free(xy_data); + free(uv_data); + free(color_data); + free(indices); return ret; } @@ -718,7 +748,8 @@ JSC_CCALL(os_make_text_buffer, colorf c = js2color(js,argv[3]); int wrap = js2number(js,argv[4]); HMM_Vec2 startpos = {.x = rectpos.x, .y = rectpos.y }; - text_vert *buffer = renderText(s, startpos, f, size, c, wrap); + float scale = size / f->height; + text_vert *buffer = renderText(s, startpos, f, scale, c, wrap); ret = quads_to_mesh(js,buffer); JS_FreeCString(js, s); arrfree(buffer);