2023.11 release!
parent
ed13bab0b9
commit
2562509584
30
bind/v4k.lua
30
bind/v4k.lua
|
@ -1515,11 +1515,16 @@ ffi.cdef([[
|
|||
//lcpp INF [0000] vec2: macro name but used as C declaration in:vec2* uvs;
|
||||
//lcpp INF [0000] vec4: macro name but used as C declaration in:vec4 bounds;
|
||||
//lcpp INF [0000] vec4: macro name but used as C declaration in:vec4 core;
|
||||
//lcpp INF [0000] vec2: macro name but used as C declaration in:vec2 pivot;
|
||||
//lcpp INF [0000] vec4: macro name but used as C declaration in:vec4 gamepad;
|
||||
//lcpp INF [0000] vec2: macro name but used as C declaration in:vec2 fire;
|
||||
//lcpp INF [0000] vec4: macro name but used as C declaration in:vec4 pos;
|
||||
//lcpp INF [0000] vec2: macro name but used as C declaration in:vec2 sca;
|
||||
//lcpp INF [0000] vec4: macro name but used as C declaration in:void (*draw_rect_func)(void* userdata, const char *skin, vec4 rect);
|
||||
//lcpp INF [0000] vec4: macro name but used as C declaration in:void (*drawrect)(void* userdata, const char *skin, vec4 rect);
|
||||
//lcpp INF [0000] vec2: macro name but used as C declaration in:void (*getskinsize)(void* userdata, const char *skin, vec2 *size);
|
||||
//lcpp INF [0000] vec2: macro name but used as C declaration in:API vec2 gui_getskinsize(const char *skin);
|
||||
//lcpp INF [0000] vec2: macro name but used as C declaration in:STATIC vec2 gui_getskinsize(const char *skin);
|
||||
//lcpp INF [0000] vec2: macro name but used as C declaration in: vec2 gui_getskinsize(const char *skin);
|
||||
//lcpp INF [0000] vec4: macro name but used as C declaration in:API void gui_panel(int id, vec4 rect, const char *skin);
|
||||
//lcpp INF [0000] vec4: macro name but used as C declaration in:STATIC void gui_panel(int id, vec4 rect, const char *skin);
|
||||
//lcpp INF [0000] vec4: macro name but used as C declaration in: void gui_panel(int id, vec4 rect, const char *skin);
|
||||
|
@ -1621,12 +1626,12 @@ ffi.cdef([[
|
|||
//lcpp INF [0000] vec3: macro name but used as C declaration in:API vec3 editor_pick(float mouse_x, float mouse_y);
|
||||
//lcpp INF [0000] vec3: macro name but used as C declaration in:STATIC vec3 editor_pick(float mouse_x, float mouse_y);
|
||||
//lcpp INF [0000] vec3: macro name but used as C declaration in: vec3 editor_pick(float mouse_x, float mouse_y);
|
||||
//lcpp INF [0000] vec2: macro name but used as C declaration in:API vec2 editor_glyph(int x, int y, unsigned cp);
|
||||
//lcpp INF [0000] vec2: macro name but used as C declaration in:STATIC vec2 editor_glyph(int x, int y, unsigned cp);
|
||||
//lcpp INF [0000] vec2: macro name but used as C declaration in: vec2 editor_glyph(int x, int y, unsigned cp);
|
||||
//lcpp INF [0000] vec2: macro name but used as C declaration in:API vec2 editor_glyphstr(int x, int y, const char *utf8);
|
||||
//lcpp INF [0000] vec2: macro name but used as C declaration in:STATIC vec2 editor_glyphstr(int x, int y, const char *utf8);
|
||||
//lcpp INF [0000] vec2: macro name but used as C declaration in: vec2 editor_glyphstr(int x, int y, const char *utf8);
|
||||
//lcpp INF [0000] vec2: macro name but used as C declaration in:API vec2 editor_glyph(int x, int y, const char *style, unsigned codepoint);
|
||||
//lcpp INF [0000] vec2: macro name but used as C declaration in:STATIC vec2 editor_glyph(int x, int y, const char *style, unsigned codepoint);
|
||||
//lcpp INF [0000] vec2: macro name but used as C declaration in: vec2 editor_glyph(int x, int y, const char *style, unsigned codepoint);
|
||||
//lcpp INF [0000] vec2: macro name but used as C declaration in:API vec2 editor_glyphs(int x, int y, const char *style, const char *utf8);
|
||||
//lcpp INF [0000] vec2: macro name but used as C declaration in:STATIC vec2 editor_glyphs(int x, int y, const char *style, const char *utf8);
|
||||
//lcpp INF [0000] vec2: macro name but used as C declaration in: vec2 editor_glyphs(int x, int y, const char *style, const char *utf8);
|
||||
typedef struct FILE FILE;
|
||||
typedef long int ptrdiff_t;
|
||||
typedef long unsigned int size_t;
|
||||
|
@ -3257,6 +3262,7 @@ typedef struct atlas_slice_frame_t {
|
|||
vec4 bounds;
|
||||
bool has_9slice;
|
||||
vec4 core;
|
||||
vec2 pivot;
|
||||
} atlas_slice_frame_t;
|
||||
typedef struct atlas_slice_t {
|
||||
unsigned name;
|
||||
|
@ -3288,7 +3294,7 @@ unsigned play;
|
|||
bool paused;
|
||||
struct atlas_t *a;
|
||||
} sprite_t;
|
||||
enum { OBJTYPE_sprite_t = 10 }; typedef struct { unsigned static_assert_on_L__LINE__ : !!(10 <= 255); } static_assert_on_Lconcat(_L,3937)___COUNTER__; typedef struct { unsigned static_assert_on_L__LINE__ : !!(sizeof(sprite_t)); } static_assert_on_Lconcat(_L,3937)___COUNTER__;;
|
||||
enum { OBJTYPE_sprite_t = 10 }; typedef struct { unsigned static_assert_on_L__LINE__ : !!(10 <= 255); } static_assert_on_Lconcat(_L,3938)___COUNTER__; typedef struct { unsigned static_assert_on_L__LINE__ : !!(sizeof(sprite_t)); } static_assert_on_Lconcat(_L,3938)___COUNTER__;;
|
||||
void sprite_ctor(sprite_t *s);
|
||||
void sprite_dtor(sprite_t *s);
|
||||
void sprite_tick(sprite_t *s);
|
||||
|
@ -3298,12 +3304,14 @@ enum { OBJTYPE_sprite_t = 10 }; typedef struct { unsigned static_assert_on
|
|||
void sprite_del(sprite_t *s);
|
||||
void sprite_setanim(sprite_t *s, unsigned name);
|
||||
typedef struct guiskin_t {
|
||||
void (*draw_rect_func)(void* userdata, const char *skin, vec4 rect);
|
||||
void (*drawrect)(void* userdata, const char *skin, vec4 rect);
|
||||
void (*getskinsize)(void* userdata, const char *skin, vec2 *size);
|
||||
void (*free)(void* userdata);
|
||||
void *userdata;
|
||||
} guiskin_t;
|
||||
void gui_pushskin(guiskin_t skin);
|
||||
void* gui_userdata();
|
||||
vec2 gui_getskinsize(const char *skin);
|
||||
void gui_panel(int id, vec4 rect, const char *skin);
|
||||
bool gui_button(int id, vec4 rect, const char *skin);
|
||||
void gui_popskin();
|
||||
|
@ -3679,8 +3687,8 @@ EDITOR_WINDOW_NK_SMALL,
|
|||
vec3 editor_pick(float mouse_x, float mouse_y);
|
||||
char* editor_path(const char *path);
|
||||
void editor_setmouse(int x, int y);
|
||||
vec2 editor_glyph(int x, int y, unsigned cp);
|
||||
vec2 editor_glyphstr(int x, int y, const char *utf8);
|
||||
vec2 editor_glyph(int x, int y, const char *style, unsigned codepoint);
|
||||
vec2 editor_glyphs(int x, int y, const char *style, const char *utf8);
|
||||
void editor_gizmos(int dim);
|
||||
int editor_send(const char *cmd);
|
||||
const char* editor_recv(int jobid, double timeout_ss);
|
||||
|
|
|
@ -37,11 +37,16 @@ int main() {
|
|||
printf("%s\n", "Button pressed!");
|
||||
}
|
||||
|
||||
gui_panel(vec4(40,140, 320, 40), "vial");
|
||||
gui_panel(vec4(40+9*skinned->scale,140+2*skinned->scale, 200, 64), "hp");
|
||||
gui_panel(vec4(40,140, 320, 20*skinned->scale), "vial");
|
||||
gui_panel(vec4(40,140, 200, 14*skinned->scale), "hp");
|
||||
gui_panel(vec4(40,240, 240, 20*skinned->scale), "vial");
|
||||
gui_panel(vec4(40,240, 160, 14*skinned->scale), "mp");
|
||||
|
||||
gui_panel(vec4(40,230, 280, 40), "vial");
|
||||
gui_panel(vec4(40+9*skinned->scale,230+2*skinned->scale, 280-18*skinned->scale, 64), "mp");
|
||||
vec2 badge_size = gui_getskinsize("badge");
|
||||
badge_size.x += 2; // padding
|
||||
gui_panel(vec4(60+badge_size.x*0,320, 1, 1), "badge");
|
||||
gui_panel(vec4(60+badge_size.x*1,320, 1, 1), "badge");
|
||||
gui_panel(vec4(60+badge_size.x*2,320, 1, 1), "badge_empty");
|
||||
}
|
||||
|
||||
gui_popskin();
|
||||
|
|
Binary file not shown.
|
@ -162,8 +162,8 @@ int editor_toolbar(int x, int y, int incw, int inch, const char *sym) {
|
|||
for each_array(codepoints, uint32_t, g) {
|
||||
int selected = oo ? is_hovering(vec4(ix,iy,ix+inc,iy+inc),vec2(ox,oy)) : 0;
|
||||
int hovering = dragging ? 0 : is_hovering(vec4(ix,iy,ix+inc,iy+inc), vec2(mx,my));
|
||||
const char *str8 = va("%s%s", selected || hovering ? FONT_COLOR1 : FONT_COLOR2, codepoint_to_utf8(g));
|
||||
editor_glyphstr(ix + inc/8, iy + inc/3 + 2, str8);
|
||||
const char *str8 = codepoint_to_utf8(g);
|
||||
editor_glyphs(ix + inc/8, iy + inc/3 + 2, selected || hovering ? FONT_COLOR1 FONT_H1 : FONT_COLOR2 FONT_H1, str8);
|
||||
ix += incw;
|
||||
iy += inch;
|
||||
}
|
||||
|
@ -251,13 +251,13 @@ int lit_edit(lit *obj) {
|
|||
ICON_MDI_WEATHER_SUNNY // directional
|
||||
ICON_MDI_LIGHTBULB_FLUORESCENT_TUBE_OUTLINE
|
||||
;
|
||||
// editor_glyphstr(obj->pos.x+16,obj->pos.y-32,all_icons);
|
||||
// editor_glyphs(obj->pos.x+16,obj->pos.y-32,all_icons);
|
||||
if( editor_selected(obj) ) {
|
||||
obj->pos.x += input(KEY_RIGHT) - input(KEY_LEFT);
|
||||
obj->pos.y += input(KEY_DOWN) - input(KEY_UP);
|
||||
obj->type = (obj->type + !!input_down(KEY_SPACE)) % 4;
|
||||
}
|
||||
editor_glyphstr(obj->pos.x,obj->pos.y,lit_icon(obj));
|
||||
editor_glyphs(obj->pos.x,obj->pos.y,0,lit_icon(obj));
|
||||
|
||||
|
||||
|
||||
|
@ -331,7 +331,7 @@ int kid_edit(kid *obj) {
|
|||
obj->pos.x += input(KEY_RIGHT) - input(KEY_LEFT);
|
||||
obj->pos.y += input(KEY_DOWN) - input(KEY_UP);
|
||||
|
||||
editor_glyphstr(obj->pos.x+16,obj->pos.y-16,ICON_MD_VIDEOGAME_ASSET);
|
||||
editor_glyphs(obj->pos.x+16,obj->pos.y-16,0,ICON_MD_VIDEOGAME_ASSET);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -474,9 +474,9 @@ int main(){
|
|||
|
||||
int choice1 = editor_toolbar(window_width()-32, ui_has_menubar() ? 34 : 0, 0, 32,
|
||||
ICON_MD_VISIBILITY
|
||||
ICON_MDI_ORBIT// ICON_MD_360
|
||||
ICON_MD_ZOOM_IN // ICON_MD_ZOOM_OUT_MAP
|
||||
ICON_MD_GRID_ON ); // ICON_MDI_LOUPE ICON_MDI_GRID );
|
||||
ICON_MD_360 // ICON_MDI_ORBIT
|
||||
ICON_MD_LOUPE // ZOOM_OUT_MAP // ICON_MD_ZOOM_IN
|
||||
ICON_MD_GRID_ON ); // ICON_MDI_GRID );
|
||||
int choice2 = editor_toolbar(window_width()-32*2, ui_has_menubar() ? 34 : 0, -32, 0, ICON_MD_SQUARE_FOOT );
|
||||
|
||||
if( choice1 > 0 ) { // clicked[>0]
|
||||
|
|
|
@ -18056,6 +18056,7 @@ typedef struct atlas_slice_frame_t {
|
|||
vec4 bounds;
|
||||
bool has_9slice;
|
||||
vec4 core;
|
||||
vec2 pivot;
|
||||
} atlas_slice_frame_t;
|
||||
|
||||
typedef struct atlas_slice_t {
|
||||
|
@ -18116,13 +18117,15 @@ API void sprite_setanim(sprite_t *s, unsigned name);
|
|||
// game ui
|
||||
|
||||
typedef struct guiskin_t {
|
||||
void (*draw_rect_func)(void* userdata, const char *skin, vec4 rect);
|
||||
void (*drawrect)(void* userdata, const char *skin, vec4 rect);
|
||||
void (*getskinsize)(void* userdata, const char *skin, vec2 *size);
|
||||
void (*free)(void* userdata);
|
||||
void *userdata;
|
||||
} guiskin_t;
|
||||
|
||||
API void gui_pushskin(guiskin_t skin);
|
||||
API void* gui_userdata();
|
||||
API vec2 gui_getskinsize(const char *skin);
|
||||
// --
|
||||
API void gui_panel(int id, vec4 rect, const char *skin);
|
||||
API bool gui_button(int id, vec4 rect, const char *skin);
|
||||
|
@ -18724,8 +18727,8 @@ API vec3 editor_pick(float mouse_x, float mouse_y);
|
|||
API char* editor_path(const char *path);
|
||||
|
||||
API void editor_setmouse(int x, int y);
|
||||
API vec2 editor_glyph(int x, int y, unsigned cp);
|
||||
API vec2 editor_glyphstr(int x, int y, const char *utf8);
|
||||
API vec2 editor_glyph(int x, int y, const char *style, unsigned codepoint);
|
||||
API vec2 editor_glyphs(int x, int y, const char *style, const char *utf8);
|
||||
API void editor_gizmos(int dim);
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
@ -357862,6 +357865,7 @@ static const unsigned table_middle_east[] = {
|
|||
static const unsigned table_emoji[] = {
|
||||
// 0xE000, 0xEB4C, // Private use (emojis)
|
||||
0xE000, 0xF8FF, // Private use (emojis+webfonts)
|
||||
0xF0001,0xF1CC7,// Private use (icon mdi)
|
||||
0
|
||||
};
|
||||
|
||||
|
@ -358049,6 +358053,7 @@ typedef struct font_t {
|
|||
unsigned num_glyphs;
|
||||
unsigned *cp2iter;
|
||||
unsigned *iter2cp;
|
||||
unsigned begin; // first glyph. used in cp2iter table to clamp into a lesser range
|
||||
|
||||
// font info and data
|
||||
int height; // bitmap height
|
||||
|
@ -358145,7 +358150,8 @@ void font_face_from_mem(const char *tag, const void *ttf_data, unsigned ttf_len,
|
|||
if( font_size <= 0 || font_size > 72 ) return;
|
||||
if( !ttf_data || !ttf_len ) return;
|
||||
|
||||
flags |= FONT_ASCII; // ensure this minimal range [0020-00FF] is always in
|
||||
if(!(flags & FONT_EM))
|
||||
flags |= FONT_ASCII; // ensure this minimal range [0020-00FF] is almost always in
|
||||
|
||||
font_t *f = &fonts[index];
|
||||
f->initialized = 1;
|
||||
|
@ -358205,12 +358211,13 @@ void font_face_from_mem(const char *tag, const void *ttf_data, unsigned ttf_len,
|
|||
// pack and create bitmap
|
||||
unsigned char *bitmap = (unsigned char*)MALLOC(f->height*f->width);
|
||||
|
||||
int charCount = 0xFFFF;
|
||||
int charCount = *array_back(sorted) - sorted[0] + 1; // 0xEFFFF;
|
||||
f->begin = sorted[0];
|
||||
f->cdata = (stbtt_packedchar*)CALLOC(1, sizeof(stbtt_packedchar) * charCount);
|
||||
f->iter2cp = (unsigned*)CALLOC( 1, sizeof(unsigned) * charCount );
|
||||
for( int i = 0; i < charCount; ++i ) f->iter2cp[i] = 0xFFFD; // default invalid glyph
|
||||
f->cp2iter = (unsigned*)CALLOC( 1, sizeof(unsigned) * charCount );
|
||||
for( int i = 0; i < charCount; ++i ) f->cp2iter[i] = 0xFFFD; // default invalid glyph
|
||||
f->iter2cp = (unsigned*)MALLOC( sizeof(unsigned) * charCount );
|
||||
f->cp2iter = (unsigned*)MALLOC( sizeof(unsigned) * charCount );
|
||||
for( int i = 0; i < charCount; ++i )
|
||||
f->iter2cp[i] = f->cp2iter[i] = 0xFFFD; // default invalid glyph
|
||||
|
||||
stbtt_pack_context pc;
|
||||
if( !stbtt_PackBegin(&pc, bitmap, f->width, f->height, 0, 1, NULL) ) {
|
||||
|
@ -358224,11 +358231,11 @@ void font_face_from_mem(const char *tag, const void *ttf_data, unsigned ttf_len,
|
|||
while( i < (num-1) && (sorted[i+1]-sorted[i]) == 1 ) end = sorted[++i];
|
||||
//printf("(%d,%d)", (unsigned)begin, (unsigned)end);
|
||||
|
||||
if( stbtt_PackFontRange(&pc, ttf_data, 0, f->font_size, begin, end - begin + 1, (stbtt_packedchar*)f->cdata + begin) ) {
|
||||
for( int j = begin; j <= end; ++j ) {
|
||||
if( stbtt_PackFontRange(&pc, ttf_data, 0, f->font_size, begin, end - begin + 1, (stbtt_packedchar*)f->cdata + begin - f->begin) ) {
|
||||
for( uint64_t cp = begin; cp <= end; ++cp ) {
|
||||
// unicode->index runtime lookup
|
||||
f->cp2iter[ j ] = count;
|
||||
f->iter2cp[ count++ ] = j;
|
||||
f->cp2iter[ cp - f->begin ] = count;
|
||||
f->iter2cp[ count++ ] = cp;
|
||||
}
|
||||
} else {
|
||||
PRINTF("!Failed to pack atlas font. Likely out of texture mem.");
|
||||
|
@ -358260,7 +358267,7 @@ void font_face_from_mem(const char *tag, const void *ttf_data, unsigned ttf_len,
|
|||
for (int i = 0; i < f->num_glyphs; i++) {
|
||||
int cp = f->iter2cp[i];
|
||||
if( cp == 0xFFFD ) continue;
|
||||
stbtt_packedchar *cd = &f->cdata[ cp ];
|
||||
stbtt_packedchar *cd = &f->cdata[ cp - f->begin ];
|
||||
if (cd->y1 > max_y1) {
|
||||
max_y1 = cd->y1;
|
||||
}
|
||||
|
@ -358327,8 +358334,8 @@ void font_face_from_mem(const char *tag, const void *ttf_data, unsigned ttf_len,
|
|||
unsigned cp = f->iter2cp[ i ];
|
||||
if(cp == 0xFFFD) continue;
|
||||
|
||||
stbtt_packedchar *cd = &f->cdata[ cp ];
|
||||
// if(cd->x1==cd->x0) { f->iter2cp[i] = f->cp2iter[cp] = 0xFFFD; continue; }
|
||||
stbtt_packedchar *cd = &f->cdata[ cp - f->begin ];
|
||||
// if(cd->x1==cd->x0) { f->iter2cp[i] = f->cp2iter[cp - f->begin] = 0xFFFD; continue; }
|
||||
|
||||
int k1 = 0*f->num_glyphs + count;
|
||||
int k2 = 1*f->num_glyphs + count; ++count;
|
||||
|
@ -358532,7 +358539,7 @@ vec2 font_draw_ex(const char *text, vec2 offset, const char *col, void (*draw_cm
|
|||
}
|
||||
|
||||
// convert to vbo data
|
||||
int cp = ch; // f->cp2iter[ch];
|
||||
int cp = ch - f->begin; // f->cp2iter[ch - f->begin];
|
||||
//if(cp == 0xFFFD) continue;
|
||||
//if(cp > f->num_glyphs) cp = 0xFFFD;
|
||||
|
||||
|
@ -358948,6 +358955,12 @@ void *gui_userdata() {
|
|||
return last_skin->userdata;
|
||||
}
|
||||
|
||||
vec2 gui_getskinsize(const char *skin) {
|
||||
vec2 size={0};
|
||||
if (last_skin->getskinsize) last_skin->getskinsize(last_skin->userdata, skin, &size);
|
||||
return size;
|
||||
}
|
||||
|
||||
static
|
||||
gui_state_t *gui_getstate(int id) {
|
||||
if (!ctl_states) map_init(ctl_states, less_int, hash_int);
|
||||
|
@ -358972,13 +358985,13 @@ bool (gui_button)(int id, vec4 r, const char *skin) {
|
|||
}
|
||||
|
||||
char *btn = va("%s%s", skin?skin:"button", entry->held?"_press":entry->hover?"_hover":"");
|
||||
if (last_skin->draw_rect_func) last_skin->draw_rect_func(last_skin->userdata, btn, r);
|
||||
if (last_skin->drawrect) last_skin->drawrect(last_skin->userdata, btn, r);
|
||||
|
||||
return was_clicked;
|
||||
}
|
||||
|
||||
void (gui_panel)(int id, vec4 r, const char *skin) {
|
||||
if (last_skin->draw_rect_func) last_skin->draw_rect_func(last_skin->userdata, skin?skin:"panel", r);
|
||||
if (last_skin->drawrect) last_skin->drawrect(last_skin->userdata, skin?skin:"panel", r);
|
||||
}
|
||||
|
||||
/* skinned */
|
||||
|
@ -359006,15 +359019,25 @@ void skinned_draw_missing_rect(vec4 r) {
|
|||
|
||||
static
|
||||
void skinned_draw_sprite(float scale, atlas_t *a, atlas_slice_frame_t *f, vec4 r) {
|
||||
vec4 outer = f->bounds;
|
||||
r.x -= f->pivot.x*scale;
|
||||
r.y -= f->pivot.y*scale;
|
||||
r.z += r.x;
|
||||
r.w += r.y;
|
||||
|
||||
// Ensure dest rectangle is large enough to render the whole element
|
||||
if ((r.z-r.x) < (outer.z-outer.x) * scale) {
|
||||
r.z = r.x + (outer.z-outer.x) * scale;
|
||||
}
|
||||
if ((r.w-r.y) < (outer.w-outer.y) * scale) {
|
||||
r.w = r.y + (outer.w-outer.y) * scale;
|
||||
}
|
||||
|
||||
if (!f->has_9slice) {
|
||||
gui_drawrect(a->tex, v42v2(f->bounds), 0xFFFFFFFF, v42v2(r));
|
||||
return;
|
||||
}
|
||||
|
||||
r.z += r.x;
|
||||
r.w += r.y;
|
||||
|
||||
vec4 outer = f->bounds;
|
||||
vec4 core = f->core;
|
||||
core.x += outer.x;
|
||||
core.y += outer.y;
|
||||
|
@ -359034,14 +359057,6 @@ void skinned_draw_sprite(float scale, atlas_t *a, atlas_slice_frame_t *f, vec4 r
|
|||
vec4 bottom_middle_slice = {core.x, core.w, core.z, outer.w};
|
||||
vec4 bottom_right_slice = {core.z, core.w, outer.z, outer.w};
|
||||
|
||||
// Ensure dest rectangle is large enough to render the whole element
|
||||
if ((r.z-r.x) < (outer.z-outer.x) * scale) {
|
||||
r.z = r.x + (outer.z-outer.x) * scale;
|
||||
}
|
||||
if ((r.w-r.y) < (outer.w-outer.y) * scale) {
|
||||
r.w = r.y + (outer.w-outer.y) * scale;
|
||||
}
|
||||
|
||||
vec4 top_left = {r.x, r.y, r.x + (core.x - outer.x) * scale, r.y + (core.y - outer.y) * scale};
|
||||
vec4 top_right = {r.z - (outer.z - core.z) * scale, r.y, r.z, r.y + (core.y - outer.y) * scale};
|
||||
vec4 bottom_left = {r.x, r.w - (outer.w - core.w) * scale, r.x + (core.x - outer.x) * scale, r.w};
|
||||
|
@ -359074,13 +359089,24 @@ void skinned_draw_rect(void* userdata, const char *skin, vec4 r) {
|
|||
else skinned_draw_sprite(a->scale, &a->atlas, f, r);
|
||||
}
|
||||
|
||||
void skinned_getskinsize(void *userdata, const char *skin, vec2 *size) {
|
||||
skinned_t *a = C_CAST(skinned_t*, userdata);
|
||||
|
||||
atlas_slice_frame_t *f = skinned_getsliceframe(&a->atlas, skin);
|
||||
if (f) {
|
||||
size->x = (f->bounds.z-f->bounds.x)*a->scale;
|
||||
size->y = (f->bounds.w-f->bounds.y)*a->scale;
|
||||
}
|
||||
}
|
||||
|
||||
guiskin_t gui_skinned(const char *inifile, float scale) {
|
||||
skinned_t *a = REALLOC(0, sizeof(skinned_t));
|
||||
a->atlas = atlas_create(inifile, 0);
|
||||
a->scale = scale?scale:1.0f;
|
||||
guiskin_t skin={0};
|
||||
skin.userdata = a;
|
||||
skin.draw_rect_func = skinned_draw_rect;
|
||||
skin.drawrect = skinned_draw_rect;
|
||||
skin.getskinsize = skinned_getskinsize;
|
||||
skin.free = skinned_free;
|
||||
return skin;
|
||||
}
|
||||
|
@ -371040,6 +371066,14 @@ atlas_t atlas_create(const char *inifile, unsigned flags) {
|
|||
|
||||
a.slice_frames[index].core = vec4(x,y,x+z,y+w);
|
||||
}
|
||||
else if ( strend(k, ".sl_pivot") ) {
|
||||
array_reserve_(a.slice_frames, index);
|
||||
|
||||
float x,y;
|
||||
sscanf(v, "%f,%f", &x, &y);
|
||||
|
||||
a.slice_frames[index].pivot = vec2(x,y);
|
||||
}
|
||||
else if( strend(k, ".frames") ) {
|
||||
array_reserve_(a.anims, index);
|
||||
|
||||
|
@ -377149,27 +377183,31 @@ void editor_setmouse(int x, int y) {
|
|||
glfwSetCursorPos( window_handle(), x, y );
|
||||
}
|
||||
|
||||
vec2 editor_glyph(int x, int y, unsigned cp) {
|
||||
vec2 editor_glyph(int x, int y, const char *style, unsigned codepoint) {
|
||||
do_once {
|
||||
// style: atlas size, unicode ranges and 6 font faces max
|
||||
do_once font_face(FONT_FACE2, "MaterialIconsSharp-Regular.otf", 24.f, FONT_EM|FONT_2048);
|
||||
do_once font_face(FONT_FACE3, "materialdesignicons-webfont.ttf", 24.f, FONT_EM|FONT_2048); // {0xF68C /*ICON_MDI_MIN*/, 0xF1CC7/*ICON_MDI_MAX*/, 0}},
|
||||
font_face(FONT_FACE2, "MaterialIconsSharp-Regular.otf", 24.f, FONT_EM|FONT_2048);
|
||||
font_face(FONT_FACE3, "materialdesignicons-webfont.ttf", 24.f, FONT_EM|FONT_2048); // {0xF68C /*ICON_MDI_MIN*/, 0xF1CC7/*ICON_MDI_MAX*/, 0}},
|
||||
// style: 10 colors max
|
||||
do_once font_color(FONT_COLOR1, WHITE);
|
||||
do_once font_color(FONT_COLOR2, RGBX(0xE8F1FF,128)); // GRAY);
|
||||
do_once font_color(FONT_COLOR3, YELLOW);
|
||||
do_once font_color(FONT_COLOR4, ORANGE);
|
||||
do_once font_color(FONT_COLOR5, CYAN);
|
||||
const char *sym = codepoint_to_utf8(cp);
|
||||
font_goto(x,y);
|
||||
return font_print(va("%s" FONT_H1 "%s", cp >= ICON_MDI_MIN ? FONT_FACE3 : FONT_FACE2, sym));
|
||||
font_color(FONT_COLOR1, WHITE);
|
||||
font_color(FONT_COLOR2, RGBX(0xE8F1FF,128)); // GRAY);
|
||||
font_color(FONT_COLOR3, YELLOW);
|
||||
font_color(FONT_COLOR4, ORANGE);
|
||||
font_color(FONT_COLOR5, CYAN);
|
||||
}
|
||||
|
||||
vec2 editor_glyphstr(int x, int y, const char *utf8) {
|
||||
vec2 dim = {x,y};
|
||||
font_goto(x,y);
|
||||
vec2 pos = {x,y};
|
||||
const char *sym = codepoint_to_utf8(codepoint);
|
||||
return add2(pos, font_print(va("%s%s%s", style ? style : "", codepoint >= ICON_MDI_MIN ? FONT_FACE3 : FONT_FACE2, sym)));
|
||||
}
|
||||
|
||||
vec2 editor_glyphs(int x, int y, const char *style, const char *utf8) {
|
||||
vec2 pos = {x,y};
|
||||
array(unsigned) codepoints = string32(utf8);
|
||||
for( int i = 0, end = array_count(codepoints); i < end; ++i)
|
||||
add2(dim, editor_glyph(dim.x,dim.y,codepoints[i]));
|
||||
return dim;
|
||||
pos = add2(pos, editor_glyph(pos.x,pos.y,style,codepoints[i]));
|
||||
return pos;
|
||||
}
|
||||
|
||||
void editor_frame( void (*game)(unsigned, float, double) ) {
|
||||
|
|
|
@ -1148,7 +1148,7 @@ ase_t* cute_aseprite_load_from_memory(const void* memory, int size, void* mem_ct
|
|||
last_udata->has_text = 1;
|
||||
last_udata->text = s_read_string(s);
|
||||
}
|
||||
if (flags & 2) {
|
||||
if (flags & 2) { //< @zpl-zak: removed else
|
||||
last_udata->color.r = s_read_uint8(s);
|
||||
last_udata->color.g = s_read_uint8(s);
|
||||
last_udata->color.b = s_read_uint8(s);
|
||||
|
@ -1178,7 +1178,8 @@ ase_t* cute_aseprite_load_from_memory(const void* memory, int size, void* mem_ct
|
|||
slice.center_y = (int)s_read_int32(s);
|
||||
slice.center_w = (int)s_read_uint32(s);
|
||||
slice.center_h = (int)s_read_uint32(s);
|
||||
} else if (flags & 2) {
|
||||
}
|
||||
if (flags & 2) {
|
||||
// Has pivot information.
|
||||
slice.has_pivot = 1;
|
||||
slice.pivot_x = (int)s_read_int32(s);
|
||||
|
|
|
@ -700,7 +700,8 @@ atlas_t* atlas_loadfiles(array(char*) files, atlas_flags flags)
|
|||
strcatf(&atlas_slices, "[%d].sl_9slice=%d\n", slice_idx, slice->has_center_as_9_slice);
|
||||
if (slice->has_center_as_9_slice)
|
||||
strcatf(&atlas_slices, "[%d].sl_core=%d,%d,%d,%d\n", slice_idx, slice->center_x, slice->center_y, slice->center_w, slice->center_h);
|
||||
|
||||
if (slice->has_pivot)
|
||||
strcatf(&atlas_slices, "[%d].sl_pivot=%d,%d\n", slice_idx, slice->pivot_x, slice->pivot_y);
|
||||
slice_name = slice->name;
|
||||
++slice_frame_idx;
|
||||
}
|
||||
|
|
|
@ -511,27 +511,31 @@ void editor_setmouse(int x, int y) {
|
|||
glfwSetCursorPos( window_handle(), x, y );
|
||||
}
|
||||
|
||||
vec2 editor_glyph(int x, int y, unsigned cp) {
|
||||
vec2 editor_glyph(int x, int y, const char *style, unsigned codepoint) {
|
||||
do_once {
|
||||
// style: atlas size, unicode ranges and 6 font faces max
|
||||
do_once font_face(FONT_FACE2, "MaterialIconsSharp-Regular.otf", 24.f, FONT_EM|FONT_2048);
|
||||
do_once font_face(FONT_FACE3, "materialdesignicons-webfont.ttf", 24.f, FONT_EM|FONT_2048); // {0xF68C /*ICON_MDI_MIN*/, 0xF1CC7/*ICON_MDI_MAX*/, 0}},
|
||||
font_face(FONT_FACE2, "MaterialIconsSharp-Regular.otf", 24.f, FONT_EM|FONT_2048);
|
||||
font_face(FONT_FACE3, "materialdesignicons-webfont.ttf", 24.f, FONT_EM|FONT_2048); // {0xF68C /*ICON_MDI_MIN*/, 0xF1CC7/*ICON_MDI_MAX*/, 0}},
|
||||
// style: 10 colors max
|
||||
do_once font_color(FONT_COLOR1, WHITE);
|
||||
do_once font_color(FONT_COLOR2, RGBX(0xE8F1FF,128)); // GRAY);
|
||||
do_once font_color(FONT_COLOR3, YELLOW);
|
||||
do_once font_color(FONT_COLOR4, ORANGE);
|
||||
do_once font_color(FONT_COLOR5, CYAN);
|
||||
const char *sym = codepoint_to_utf8(cp);
|
||||
font_goto(x,y);
|
||||
return font_print(va("%s" FONT_H1 "%s", cp >= ICON_MDI_MIN ? FONT_FACE3 : FONT_FACE2, sym));
|
||||
font_color(FONT_COLOR1, WHITE);
|
||||
font_color(FONT_COLOR2, RGBX(0xE8F1FF,128)); // GRAY);
|
||||
font_color(FONT_COLOR3, YELLOW);
|
||||
font_color(FONT_COLOR4, ORANGE);
|
||||
font_color(FONT_COLOR5, CYAN);
|
||||
}
|
||||
|
||||
vec2 editor_glyphstr(int x, int y, const char *utf8) {
|
||||
vec2 dim = {x,y};
|
||||
font_goto(x,y);
|
||||
vec2 pos = {x,y};
|
||||
const char *sym = codepoint_to_utf8(codepoint);
|
||||
return add2(pos, font_print(va("%s%s%s", style ? style : "", codepoint >= ICON_MDI_MIN ? FONT_FACE3 : FONT_FACE2, sym)));
|
||||
}
|
||||
|
||||
vec2 editor_glyphs(int x, int y, const char *style, const char *utf8) {
|
||||
vec2 pos = {x,y};
|
||||
array(unsigned) codepoints = string32(utf8);
|
||||
for( int i = 0, end = array_count(codepoints); i < end; ++i)
|
||||
add2(dim, editor_glyph(dim.x,dim.y,codepoints[i]));
|
||||
return dim;
|
||||
pos = add2(pos, editor_glyph(pos.x,pos.y,style,codepoints[i]));
|
||||
return pos;
|
||||
}
|
||||
|
||||
void editor_frame( void (*game)(unsigned, float, double) ) {
|
||||
|
|
|
@ -90,8 +90,8 @@ API vec3 editor_pick(float mouse_x, float mouse_y);
|
|||
API char* editor_path(const char *path);
|
||||
|
||||
API void editor_setmouse(int x, int y);
|
||||
API vec2 editor_glyph(int x, int y, unsigned cp);
|
||||
API vec2 editor_glyphstr(int x, int y, const char *utf8);
|
||||
API vec2 editor_glyph(int x, int y, const char *style, unsigned codepoint);
|
||||
API vec2 editor_glyphs(int x, int y, const char *style, const char *utf8);
|
||||
API void editor_gizmos(int dim);
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
|
|
@ -1388,6 +1388,7 @@ static const unsigned table_middle_east[] = {
|
|||
static const unsigned table_emoji[] = {
|
||||
// 0xE000, 0xEB4C, // Private use (emojis)
|
||||
0xE000, 0xF8FF, // Private use (emojis+webfonts)
|
||||
0xF0001,0xF1CC7,// Private use (icon mdi)
|
||||
0
|
||||
};
|
||||
|
||||
|
@ -1575,6 +1576,7 @@ typedef struct font_t {
|
|||
unsigned num_glyphs;
|
||||
unsigned *cp2iter;
|
||||
unsigned *iter2cp;
|
||||
unsigned begin; // first glyph. used in cp2iter table to clamp into a lesser range
|
||||
|
||||
// font info and data
|
||||
int height; // bitmap height
|
||||
|
@ -1671,7 +1673,8 @@ void font_face_from_mem(const char *tag, const void *ttf_data, unsigned ttf_len,
|
|||
if( font_size <= 0 || font_size > 72 ) return;
|
||||
if( !ttf_data || !ttf_len ) return;
|
||||
|
||||
flags |= FONT_ASCII; // ensure this minimal range [0020-00FF] is always in
|
||||
if(!(flags & FONT_EM))
|
||||
flags |= FONT_ASCII; // ensure this minimal range [0020-00FF] is almost always in
|
||||
|
||||
font_t *f = &fonts[index];
|
||||
f->initialized = 1;
|
||||
|
@ -1731,12 +1734,13 @@ void font_face_from_mem(const char *tag, const void *ttf_data, unsigned ttf_len,
|
|||
// pack and create bitmap
|
||||
unsigned char *bitmap = (unsigned char*)MALLOC(f->height*f->width);
|
||||
|
||||
int charCount = 0xFFFF;
|
||||
int charCount = *array_back(sorted) - sorted[0] + 1; // 0xEFFFF;
|
||||
f->begin = sorted[0];
|
||||
f->cdata = (stbtt_packedchar*)CALLOC(1, sizeof(stbtt_packedchar) * charCount);
|
||||
f->iter2cp = (unsigned*)CALLOC( 1, sizeof(unsigned) * charCount );
|
||||
for( int i = 0; i < charCount; ++i ) f->iter2cp[i] = 0xFFFD; // default invalid glyph
|
||||
f->cp2iter = (unsigned*)CALLOC( 1, sizeof(unsigned) * charCount );
|
||||
for( int i = 0; i < charCount; ++i ) f->cp2iter[i] = 0xFFFD; // default invalid glyph
|
||||
f->iter2cp = (unsigned*)MALLOC( sizeof(unsigned) * charCount );
|
||||
f->cp2iter = (unsigned*)MALLOC( sizeof(unsigned) * charCount );
|
||||
for( int i = 0; i < charCount; ++i )
|
||||
f->iter2cp[i] = f->cp2iter[i] = 0xFFFD; // default invalid glyph
|
||||
|
||||
stbtt_pack_context pc;
|
||||
if( !stbtt_PackBegin(&pc, bitmap, f->width, f->height, 0, 1, NULL) ) {
|
||||
|
@ -1750,11 +1754,11 @@ void font_face_from_mem(const char *tag, const void *ttf_data, unsigned ttf_len,
|
|||
while( i < (num-1) && (sorted[i+1]-sorted[i]) == 1 ) end = sorted[++i];
|
||||
//printf("(%d,%d)", (unsigned)begin, (unsigned)end);
|
||||
|
||||
if( stbtt_PackFontRange(&pc, ttf_data, 0, f->font_size, begin, end - begin + 1, (stbtt_packedchar*)f->cdata + begin) ) {
|
||||
for( int j = begin; j <= end; ++j ) {
|
||||
if( stbtt_PackFontRange(&pc, ttf_data, 0, f->font_size, begin, end - begin + 1, (stbtt_packedchar*)f->cdata + begin - f->begin) ) {
|
||||
for( uint64_t cp = begin; cp <= end; ++cp ) {
|
||||
// unicode->index runtime lookup
|
||||
f->cp2iter[ j ] = count;
|
||||
f->iter2cp[ count++ ] = j;
|
||||
f->cp2iter[ cp - f->begin ] = count;
|
||||
f->iter2cp[ count++ ] = cp;
|
||||
}
|
||||
} else {
|
||||
PRINTF("!Failed to pack atlas font. Likely out of texture mem.");
|
||||
|
@ -1786,7 +1790,7 @@ void font_face_from_mem(const char *tag, const void *ttf_data, unsigned ttf_len,
|
|||
for (int i = 0; i < f->num_glyphs; i++) {
|
||||
int cp = f->iter2cp[i];
|
||||
if( cp == 0xFFFD ) continue;
|
||||
stbtt_packedchar *cd = &f->cdata[ cp ];
|
||||
stbtt_packedchar *cd = &f->cdata[ cp - f->begin ];
|
||||
if (cd->y1 > max_y1) {
|
||||
max_y1 = cd->y1;
|
||||
}
|
||||
|
@ -1853,8 +1857,8 @@ void font_face_from_mem(const char *tag, const void *ttf_data, unsigned ttf_len,
|
|||
unsigned cp = f->iter2cp[ i ];
|
||||
if(cp == 0xFFFD) continue;
|
||||
|
||||
stbtt_packedchar *cd = &f->cdata[ cp ];
|
||||
// if(cd->x1==cd->x0) { f->iter2cp[i] = f->cp2iter[cp] = 0xFFFD; continue; }
|
||||
stbtt_packedchar *cd = &f->cdata[ cp - f->begin ];
|
||||
// if(cd->x1==cd->x0) { f->iter2cp[i] = f->cp2iter[cp - f->begin] = 0xFFFD; continue; }
|
||||
|
||||
int k1 = 0*f->num_glyphs + count;
|
||||
int k2 = 1*f->num_glyphs + count; ++count;
|
||||
|
@ -2058,7 +2062,7 @@ vec2 font_draw_ex(const char *text, vec2 offset, const char *col, void (*draw_cm
|
|||
}
|
||||
|
||||
// convert to vbo data
|
||||
int cp = ch; // f->cp2iter[ch];
|
||||
int cp = ch - f->begin; // f->cp2iter[ch - f->begin];
|
||||
//if(cp == 0xFFFD) continue;
|
||||
//if(cp > f->num_glyphs) cp = 0xFFFD;
|
||||
|
||||
|
|
|
@ -118,6 +118,12 @@ void *gui_userdata() {
|
|||
return last_skin->userdata;
|
||||
}
|
||||
|
||||
vec2 gui_getskinsize(const char *skin) {
|
||||
vec2 size={0};
|
||||
if (last_skin->getskinsize) last_skin->getskinsize(last_skin->userdata, skin, &size);
|
||||
return size;
|
||||
}
|
||||
|
||||
static
|
||||
gui_state_t *gui_getstate(int id) {
|
||||
if (!ctl_states) map_init(ctl_states, less_int, hash_int);
|
||||
|
@ -142,13 +148,13 @@ bool (gui_button)(int id, vec4 r, const char *skin) {
|
|||
}
|
||||
|
||||
char *btn = va("%s%s", skin?skin:"button", entry->held?"_press":entry->hover?"_hover":"");
|
||||
if (last_skin->draw_rect_func) last_skin->draw_rect_func(last_skin->userdata, btn, r);
|
||||
if (last_skin->drawrect) last_skin->drawrect(last_skin->userdata, btn, r);
|
||||
|
||||
return was_clicked;
|
||||
}
|
||||
|
||||
void (gui_panel)(int id, vec4 r, const char *skin) {
|
||||
if (last_skin->draw_rect_func) last_skin->draw_rect_func(last_skin->userdata, skin?skin:"panel", r);
|
||||
if (last_skin->drawrect) last_skin->drawrect(last_skin->userdata, skin?skin:"panel", r);
|
||||
}
|
||||
|
||||
/* skinned */
|
||||
|
@ -176,15 +182,25 @@ void skinned_draw_missing_rect(vec4 r) {
|
|||
|
||||
static
|
||||
void skinned_draw_sprite(float scale, atlas_t *a, atlas_slice_frame_t *f, vec4 r) {
|
||||
vec4 outer = f->bounds;
|
||||
r.x -= f->pivot.x*scale;
|
||||
r.y -= f->pivot.y*scale;
|
||||
r.z += r.x;
|
||||
r.w += r.y;
|
||||
|
||||
// Ensure dest rectangle is large enough to render the whole element
|
||||
if ((r.z-r.x) < (outer.z-outer.x) * scale) {
|
||||
r.z = r.x + (outer.z-outer.x) * scale;
|
||||
}
|
||||
if ((r.w-r.y) < (outer.w-outer.y) * scale) {
|
||||
r.w = r.y + (outer.w-outer.y) * scale;
|
||||
}
|
||||
|
||||
if (!f->has_9slice) {
|
||||
gui_drawrect(a->tex, v42v2(f->bounds), 0xFFFFFFFF, v42v2(r));
|
||||
return;
|
||||
}
|
||||
|
||||
r.z += r.x;
|
||||
r.w += r.y;
|
||||
|
||||
vec4 outer = f->bounds;
|
||||
vec4 core = f->core;
|
||||
core.x += outer.x;
|
||||
core.y += outer.y;
|
||||
|
@ -204,14 +220,6 @@ void skinned_draw_sprite(float scale, atlas_t *a, atlas_slice_frame_t *f, vec4 r
|
|||
vec4 bottom_middle_slice = {core.x, core.w, core.z, outer.w};
|
||||
vec4 bottom_right_slice = {core.z, core.w, outer.z, outer.w};
|
||||
|
||||
// Ensure dest rectangle is large enough to render the whole element
|
||||
if ((r.z-r.x) < (outer.z-outer.x) * scale) {
|
||||
r.z = r.x + (outer.z-outer.x) * scale;
|
||||
}
|
||||
if ((r.w-r.y) < (outer.w-outer.y) * scale) {
|
||||
r.w = r.y + (outer.w-outer.y) * scale;
|
||||
}
|
||||
|
||||
vec4 top_left = {r.x, r.y, r.x + (core.x - outer.x) * scale, r.y + (core.y - outer.y) * scale};
|
||||
vec4 top_right = {r.z - (outer.z - core.z) * scale, r.y, r.z, r.y + (core.y - outer.y) * scale};
|
||||
vec4 bottom_left = {r.x, r.w - (outer.w - core.w) * scale, r.x + (core.x - outer.x) * scale, r.w};
|
||||
|
@ -244,13 +252,24 @@ void skinned_draw_rect(void* userdata, const char *skin, vec4 r) {
|
|||
else skinned_draw_sprite(a->scale, &a->atlas, f, r);
|
||||
}
|
||||
|
||||
void skinned_getskinsize(void *userdata, const char *skin, vec2 *size) {
|
||||
skinned_t *a = C_CAST(skinned_t*, userdata);
|
||||
|
||||
atlas_slice_frame_t *f = skinned_getsliceframe(&a->atlas, skin);
|
||||
if (f) {
|
||||
size->x = (f->bounds.z-f->bounds.x)*a->scale;
|
||||
size->y = (f->bounds.w-f->bounds.y)*a->scale;
|
||||
}
|
||||
}
|
||||
|
||||
guiskin_t gui_skinned(const char *inifile, float scale) {
|
||||
skinned_t *a = REALLOC(0, sizeof(skinned_t));
|
||||
a->atlas = atlas_create(inifile, 0);
|
||||
a->scale = scale?scale:1.0f;
|
||||
guiskin_t skin={0};
|
||||
skin.userdata = a;
|
||||
skin.draw_rect_func = skinned_draw_rect;
|
||||
skin.drawrect = skinned_draw_rect;
|
||||
skin.getskinsize = skinned_getskinsize;
|
||||
skin.free = skinned_free;
|
||||
return skin;
|
||||
}
|
||||
|
|
|
@ -2,13 +2,15 @@
|
|||
// game ui
|
||||
|
||||
typedef struct guiskin_t {
|
||||
void (*draw_rect_func)(void* userdata, const char *skin, vec4 rect);
|
||||
void (*drawrect)(void* userdata, const char *skin, vec4 rect);
|
||||
void (*getskinsize)(void* userdata, const char *skin, vec2 *size);
|
||||
void (*free)(void* userdata);
|
||||
void *userdata;
|
||||
} guiskin_t;
|
||||
|
||||
API void gui_pushskin(guiskin_t skin);
|
||||
API void* gui_userdata();
|
||||
API vec2 gui_getskinsize(const char *skin);
|
||||
// --
|
||||
API void gui_panel(int id, vec4 rect, const char *skin);
|
||||
API bool gui_button(int id, vec4 rect, const char *skin);
|
||||
|
|
|
@ -1277,6 +1277,14 @@ atlas_t atlas_create(const char *inifile, unsigned flags) {
|
|||
|
||||
a.slice_frames[index].core = vec4(x,y,x+z,y+w);
|
||||
}
|
||||
else if ( strend(k, ".sl_pivot") ) {
|
||||
array_reserve_(a.slice_frames, index);
|
||||
|
||||
float x,y;
|
||||
sscanf(v, "%f,%f", &x, &y);
|
||||
|
||||
a.slice_frames[index].pivot = vec2(x,y);
|
||||
}
|
||||
else if( strend(k, ".frames") ) {
|
||||
array_reserve_(a.anims, index);
|
||||
|
||||
|
|
|
@ -101,6 +101,7 @@ typedef struct atlas_slice_frame_t {
|
|||
vec4 bounds;
|
||||
bool has_9slice;
|
||||
vec4 core;
|
||||
vec2 pivot;
|
||||
} atlas_slice_frame_t;
|
||||
|
||||
typedef struct atlas_slice_t {
|
||||
|
|
123
engine/v4k.c
123
engine/v4k.c
|
@ -10038,6 +10038,7 @@ static const unsigned table_middle_east[] = {
|
|||
static const unsigned table_emoji[] = {
|
||||
// 0xE000, 0xEB4C, // Private use (emojis)
|
||||
0xE000, 0xF8FF, // Private use (emojis+webfonts)
|
||||
0xF0001,0xF1CC7,// Private use (icon mdi)
|
||||
0
|
||||
};
|
||||
|
||||
|
@ -10225,6 +10226,7 @@ typedef struct font_t {
|
|||
unsigned num_glyphs;
|
||||
unsigned *cp2iter;
|
||||
unsigned *iter2cp;
|
||||
unsigned begin; // first glyph. used in cp2iter table to clamp into a lesser range
|
||||
|
||||
// font info and data
|
||||
int height; // bitmap height
|
||||
|
@ -10321,7 +10323,8 @@ void font_face_from_mem(const char *tag, const void *ttf_data, unsigned ttf_len,
|
|||
if( font_size <= 0 || font_size > 72 ) return;
|
||||
if( !ttf_data || !ttf_len ) return;
|
||||
|
||||
flags |= FONT_ASCII; // ensure this minimal range [0020-00FF] is always in
|
||||
if(!(flags & FONT_EM))
|
||||
flags |= FONT_ASCII; // ensure this minimal range [0020-00FF] is almost always in
|
||||
|
||||
font_t *f = &fonts[index];
|
||||
f->initialized = 1;
|
||||
|
@ -10381,12 +10384,13 @@ void font_face_from_mem(const char *tag, const void *ttf_data, unsigned ttf_len,
|
|||
// pack and create bitmap
|
||||
unsigned char *bitmap = (unsigned char*)MALLOC(f->height*f->width);
|
||||
|
||||
int charCount = 0xFFFF;
|
||||
int charCount = *array_back(sorted) - sorted[0] + 1; // 0xEFFFF;
|
||||
f->begin = sorted[0];
|
||||
f->cdata = (stbtt_packedchar*)CALLOC(1, sizeof(stbtt_packedchar) * charCount);
|
||||
f->iter2cp = (unsigned*)CALLOC( 1, sizeof(unsigned) * charCount );
|
||||
for( int i = 0; i < charCount; ++i ) f->iter2cp[i] = 0xFFFD; // default invalid glyph
|
||||
f->cp2iter = (unsigned*)CALLOC( 1, sizeof(unsigned) * charCount );
|
||||
for( int i = 0; i < charCount; ++i ) f->cp2iter[i] = 0xFFFD; // default invalid glyph
|
||||
f->iter2cp = (unsigned*)MALLOC( sizeof(unsigned) * charCount );
|
||||
f->cp2iter = (unsigned*)MALLOC( sizeof(unsigned) * charCount );
|
||||
for( int i = 0; i < charCount; ++i )
|
||||
f->iter2cp[i] = f->cp2iter[i] = 0xFFFD; // default invalid glyph
|
||||
|
||||
stbtt_pack_context pc;
|
||||
if( !stbtt_PackBegin(&pc, bitmap, f->width, f->height, 0, 1, NULL) ) {
|
||||
|
@ -10400,11 +10404,11 @@ void font_face_from_mem(const char *tag, const void *ttf_data, unsigned ttf_len,
|
|||
while( i < (num-1) && (sorted[i+1]-sorted[i]) == 1 ) end = sorted[++i];
|
||||
//printf("(%d,%d)", (unsigned)begin, (unsigned)end);
|
||||
|
||||
if( stbtt_PackFontRange(&pc, ttf_data, 0, f->font_size, begin, end - begin + 1, (stbtt_packedchar*)f->cdata + begin) ) {
|
||||
for( int j = begin; j <= end; ++j ) {
|
||||
if( stbtt_PackFontRange(&pc, ttf_data, 0, f->font_size, begin, end - begin + 1, (stbtt_packedchar*)f->cdata + begin - f->begin) ) {
|
||||
for( uint64_t cp = begin; cp <= end; ++cp ) {
|
||||
// unicode->index runtime lookup
|
||||
f->cp2iter[ j ] = count;
|
||||
f->iter2cp[ count++ ] = j;
|
||||
f->cp2iter[ cp - f->begin ] = count;
|
||||
f->iter2cp[ count++ ] = cp;
|
||||
}
|
||||
} else {
|
||||
PRINTF("!Failed to pack atlas font. Likely out of texture mem.");
|
||||
|
@ -10436,7 +10440,7 @@ void font_face_from_mem(const char *tag, const void *ttf_data, unsigned ttf_len,
|
|||
for (int i = 0; i < f->num_glyphs; i++) {
|
||||
int cp = f->iter2cp[i];
|
||||
if( cp == 0xFFFD ) continue;
|
||||
stbtt_packedchar *cd = &f->cdata[ cp ];
|
||||
stbtt_packedchar *cd = &f->cdata[ cp - f->begin ];
|
||||
if (cd->y1 > max_y1) {
|
||||
max_y1 = cd->y1;
|
||||
}
|
||||
|
@ -10503,8 +10507,8 @@ void font_face_from_mem(const char *tag, const void *ttf_data, unsigned ttf_len,
|
|||
unsigned cp = f->iter2cp[ i ];
|
||||
if(cp == 0xFFFD) continue;
|
||||
|
||||
stbtt_packedchar *cd = &f->cdata[ cp ];
|
||||
// if(cd->x1==cd->x0) { f->iter2cp[i] = f->cp2iter[cp] = 0xFFFD; continue; }
|
||||
stbtt_packedchar *cd = &f->cdata[ cp - f->begin ];
|
||||
// if(cd->x1==cd->x0) { f->iter2cp[i] = f->cp2iter[cp - f->begin] = 0xFFFD; continue; }
|
||||
|
||||
int k1 = 0*f->num_glyphs + count;
|
||||
int k2 = 1*f->num_glyphs + count; ++count;
|
||||
|
@ -10708,7 +10712,7 @@ vec2 font_draw_ex(const char *text, vec2 offset, const char *col, void (*draw_cm
|
|||
}
|
||||
|
||||
// convert to vbo data
|
||||
int cp = ch; // f->cp2iter[ch];
|
||||
int cp = ch - f->begin; // f->cp2iter[ch - f->begin];
|
||||
//if(cp == 0xFFFD) continue;
|
||||
//if(cp > f->num_glyphs) cp = 0xFFFD;
|
||||
|
||||
|
@ -11124,6 +11128,12 @@ void *gui_userdata() {
|
|||
return last_skin->userdata;
|
||||
}
|
||||
|
||||
vec2 gui_getskinsize(const char *skin) {
|
||||
vec2 size={0};
|
||||
if (last_skin->getskinsize) last_skin->getskinsize(last_skin->userdata, skin, &size);
|
||||
return size;
|
||||
}
|
||||
|
||||
static
|
||||
gui_state_t *gui_getstate(int id) {
|
||||
if (!ctl_states) map_init(ctl_states, less_int, hash_int);
|
||||
|
@ -11148,13 +11158,13 @@ bool (gui_button)(int id, vec4 r, const char *skin) {
|
|||
}
|
||||
|
||||
char *btn = va("%s%s", skin?skin:"button", entry->held?"_press":entry->hover?"_hover":"");
|
||||
if (last_skin->draw_rect_func) last_skin->draw_rect_func(last_skin->userdata, btn, r);
|
||||
if (last_skin->drawrect) last_skin->drawrect(last_skin->userdata, btn, r);
|
||||
|
||||
return was_clicked;
|
||||
}
|
||||
|
||||
void (gui_panel)(int id, vec4 r, const char *skin) {
|
||||
if (last_skin->draw_rect_func) last_skin->draw_rect_func(last_skin->userdata, skin?skin:"panel", r);
|
||||
if (last_skin->drawrect) last_skin->drawrect(last_skin->userdata, skin?skin:"panel", r);
|
||||
}
|
||||
|
||||
/* skinned */
|
||||
|
@ -11182,15 +11192,25 @@ void skinned_draw_missing_rect(vec4 r) {
|
|||
|
||||
static
|
||||
void skinned_draw_sprite(float scale, atlas_t *a, atlas_slice_frame_t *f, vec4 r) {
|
||||
vec4 outer = f->bounds;
|
||||
r.x -= f->pivot.x*scale;
|
||||
r.y -= f->pivot.y*scale;
|
||||
r.z += r.x;
|
||||
r.w += r.y;
|
||||
|
||||
// Ensure dest rectangle is large enough to render the whole element
|
||||
if ((r.z-r.x) < (outer.z-outer.x) * scale) {
|
||||
r.z = r.x + (outer.z-outer.x) * scale;
|
||||
}
|
||||
if ((r.w-r.y) < (outer.w-outer.y) * scale) {
|
||||
r.w = r.y + (outer.w-outer.y) * scale;
|
||||
}
|
||||
|
||||
if (!f->has_9slice) {
|
||||
gui_drawrect(a->tex, v42v2(f->bounds), 0xFFFFFFFF, v42v2(r));
|
||||
return;
|
||||
}
|
||||
|
||||
r.z += r.x;
|
||||
r.w += r.y;
|
||||
|
||||
vec4 outer = f->bounds;
|
||||
vec4 core = f->core;
|
||||
core.x += outer.x;
|
||||
core.y += outer.y;
|
||||
|
@ -11210,14 +11230,6 @@ void skinned_draw_sprite(float scale, atlas_t *a, atlas_slice_frame_t *f, vec4 r
|
|||
vec4 bottom_middle_slice = {core.x, core.w, core.z, outer.w};
|
||||
vec4 bottom_right_slice = {core.z, core.w, outer.z, outer.w};
|
||||
|
||||
// Ensure dest rectangle is large enough to render the whole element
|
||||
if ((r.z-r.x) < (outer.z-outer.x) * scale) {
|
||||
r.z = r.x + (outer.z-outer.x) * scale;
|
||||
}
|
||||
if ((r.w-r.y) < (outer.w-outer.y) * scale) {
|
||||
r.w = r.y + (outer.w-outer.y) * scale;
|
||||
}
|
||||
|
||||
vec4 top_left = {r.x, r.y, r.x + (core.x - outer.x) * scale, r.y + (core.y - outer.y) * scale};
|
||||
vec4 top_right = {r.z - (outer.z - core.z) * scale, r.y, r.z, r.y + (core.y - outer.y) * scale};
|
||||
vec4 bottom_left = {r.x, r.w - (outer.w - core.w) * scale, r.x + (core.x - outer.x) * scale, r.w};
|
||||
|
@ -11250,13 +11262,24 @@ void skinned_draw_rect(void* userdata, const char *skin, vec4 r) {
|
|||
else skinned_draw_sprite(a->scale, &a->atlas, f, r);
|
||||
}
|
||||
|
||||
void skinned_getskinsize(void *userdata, const char *skin, vec2 *size) {
|
||||
skinned_t *a = C_CAST(skinned_t*, userdata);
|
||||
|
||||
atlas_slice_frame_t *f = skinned_getsliceframe(&a->atlas, skin);
|
||||
if (f) {
|
||||
size->x = (f->bounds.z-f->bounds.x)*a->scale;
|
||||
size->y = (f->bounds.w-f->bounds.y)*a->scale;
|
||||
}
|
||||
}
|
||||
|
||||
guiskin_t gui_skinned(const char *inifile, float scale) {
|
||||
skinned_t *a = REALLOC(0, sizeof(skinned_t));
|
||||
a->atlas = atlas_create(inifile, 0);
|
||||
a->scale = scale?scale:1.0f;
|
||||
guiskin_t skin={0};
|
||||
skin.userdata = a;
|
||||
skin.draw_rect_func = skinned_draw_rect;
|
||||
skin.drawrect = skinned_draw_rect;
|
||||
skin.getskinsize = skinned_getskinsize;
|
||||
skin.free = skinned_free;
|
||||
return skin;
|
||||
}
|
||||
|
@ -23216,6 +23239,14 @@ atlas_t atlas_create(const char *inifile, unsigned flags) {
|
|||
|
||||
a.slice_frames[index].core = vec4(x,y,x+z,y+w);
|
||||
}
|
||||
else if ( strend(k, ".sl_pivot") ) {
|
||||
array_reserve_(a.slice_frames, index);
|
||||
|
||||
float x,y;
|
||||
sscanf(v, "%f,%f", &x, &y);
|
||||
|
||||
a.slice_frames[index].pivot = vec2(x,y);
|
||||
}
|
||||
else if( strend(k, ".frames") ) {
|
||||
array_reserve_(a.anims, index);
|
||||
|
||||
|
@ -29325,27 +29356,31 @@ void editor_setmouse(int x, int y) {
|
|||
glfwSetCursorPos( window_handle(), x, y );
|
||||
}
|
||||
|
||||
vec2 editor_glyph(int x, int y, unsigned cp) {
|
||||
vec2 editor_glyph(int x, int y, const char *style, unsigned codepoint) {
|
||||
do_once {
|
||||
// style: atlas size, unicode ranges and 6 font faces max
|
||||
do_once font_face(FONT_FACE2, "MaterialIconsSharp-Regular.otf", 24.f, FONT_EM|FONT_2048);
|
||||
do_once font_face(FONT_FACE3, "materialdesignicons-webfont.ttf", 24.f, FONT_EM|FONT_2048); // {0xF68C /*ICON_MDI_MIN*/, 0xF1CC7/*ICON_MDI_MAX*/, 0}},
|
||||
font_face(FONT_FACE2, "MaterialIconsSharp-Regular.otf", 24.f, FONT_EM|FONT_2048);
|
||||
font_face(FONT_FACE3, "materialdesignicons-webfont.ttf", 24.f, FONT_EM|FONT_2048); // {0xF68C /*ICON_MDI_MIN*/, 0xF1CC7/*ICON_MDI_MAX*/, 0}},
|
||||
// style: 10 colors max
|
||||
do_once font_color(FONT_COLOR1, WHITE);
|
||||
do_once font_color(FONT_COLOR2, RGBX(0xE8F1FF,128)); // GRAY);
|
||||
do_once font_color(FONT_COLOR3, YELLOW);
|
||||
do_once font_color(FONT_COLOR4, ORANGE);
|
||||
do_once font_color(FONT_COLOR5, CYAN);
|
||||
const char *sym = codepoint_to_utf8(cp);
|
||||
font_goto(x,y);
|
||||
return font_print(va("%s" FONT_H1 "%s", cp >= ICON_MDI_MIN ? FONT_FACE3 : FONT_FACE2, sym));
|
||||
font_color(FONT_COLOR1, WHITE);
|
||||
font_color(FONT_COLOR2, RGBX(0xE8F1FF,128)); // GRAY);
|
||||
font_color(FONT_COLOR3, YELLOW);
|
||||
font_color(FONT_COLOR4, ORANGE);
|
||||
font_color(FONT_COLOR5, CYAN);
|
||||
}
|
||||
|
||||
vec2 editor_glyphstr(int x, int y, const char *utf8) {
|
||||
vec2 dim = {x,y};
|
||||
font_goto(x,y);
|
||||
vec2 pos = {x,y};
|
||||
const char *sym = codepoint_to_utf8(codepoint);
|
||||
return add2(pos, font_print(va("%s%s%s", style ? style : "", codepoint >= ICON_MDI_MIN ? FONT_FACE3 : FONT_FACE2, sym)));
|
||||
}
|
||||
|
||||
vec2 editor_glyphs(int x, int y, const char *style, const char *utf8) {
|
||||
vec2 pos = {x,y};
|
||||
array(unsigned) codepoints = string32(utf8);
|
||||
for( int i = 0, end = array_count(codepoints); i < end; ++i)
|
||||
add2(dim, editor_glyph(dim.x,dim.y,codepoints[i]));
|
||||
return dim;
|
||||
pos = add2(pos, editor_glyph(pos.x,pos.y,style,codepoints[i]));
|
||||
return pos;
|
||||
}
|
||||
|
||||
void editor_frame( void (*game)(unsigned, float, double) ) {
|
||||
|
|
|
@ -4123,6 +4123,7 @@ typedef struct atlas_slice_frame_t {
|
|||
vec4 bounds;
|
||||
bool has_9slice;
|
||||
vec4 core;
|
||||
vec2 pivot;
|
||||
} atlas_slice_frame_t;
|
||||
|
||||
typedef struct atlas_slice_t {
|
||||
|
@ -4183,13 +4184,15 @@ API void sprite_setanim(sprite_t *s, unsigned name);
|
|||
// game ui
|
||||
|
||||
typedef struct guiskin_t {
|
||||
void (*draw_rect_func)(void* userdata, const char *skin, vec4 rect);
|
||||
void (*drawrect)(void* userdata, const char *skin, vec4 rect);
|
||||
void (*getskinsize)(void* userdata, const char *skin, vec2 *size);
|
||||
void (*free)(void* userdata);
|
||||
void *userdata;
|
||||
} guiskin_t;
|
||||
|
||||
API void gui_pushskin(guiskin_t skin);
|
||||
API void* gui_userdata();
|
||||
API vec2 gui_getskinsize(const char *skin);
|
||||
// --
|
||||
API void gui_panel(int id, vec4 rect, const char *skin);
|
||||
API bool gui_button(int id, vec4 rect, const char *skin);
|
||||
|
@ -4791,8 +4794,8 @@ API vec3 editor_pick(float mouse_x, float mouse_y);
|
|||
API char* editor_path(const char *path);
|
||||
|
||||
API void editor_setmouse(int x, int y);
|
||||
API vec2 editor_glyph(int x, int y, unsigned cp);
|
||||
API vec2 editor_glyphstr(int x, int y, const char *utf8);
|
||||
API vec2 editor_glyph(int x, int y, const char *style, unsigned codepoint);
|
||||
API vec2 editor_glyphs(int x, int y, const char *style, const char *utf8);
|
||||
API void editor_gizmos(int dim);
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue