main
Dominik Madarász 2023-12-01 23:12:02 +01:00
parent 36309b841c
commit f61b4c6653
16 changed files with 120 additions and 110 deletions

View File

@ -322,6 +322,7 @@ if "%1"=="fwk" (
git fetch git fetch
git reset --hard origin/main git reset --hard origin/main
popd popd
call make.bat split
call MAKE.bat fwk_prep call MAKE.bat fwk_prep
start "" fwk_diff.WinMerge start "" fwk_diff.WinMerge
exit /b exit /b
@ -338,12 +339,12 @@ if "%1"=="gwk" (
copy/y ..\fwk-mirror\engine\fwk _fwk\engine\fwk copy/y ..\fwk-mirror\engine\fwk _fwk\engine\fwk
copy/y ..\fwk-mirror\engine\split\*.inl _fwk\engine\split\ copy/y ..\fwk-mirror\engine\split\*.inl _fwk\engine\split\
rem copy/y ..\fwk-mirror\engine\split\3rd_*.c _fwk\engine\split\ rem copy/y ..\fwk-mirror\engine\split\3rd_*.c _fwk\engine\split\
make back
exit /b exit /b
) )
if "%1"=="fwk_prep" ( if "%1"=="fwk_prep" (
call make.bat split
if not exist "_fwk" mkdir "_fwk" if not exist "_fwk" mkdir "_fwk"
if not exist "_fwk\demos" mkdir "_fwk\demos" if not exist "_fwk\demos" mkdir "_fwk\demos"
if not exist "_fwk\tools" mkdir "_fwk\tools" if not exist "_fwk\tools" mkdir "_fwk\tools"
@ -453,8 +454,8 @@ if "%1"=="back" (
rem tools\fwkren.exe tools\cook.ini to rem tools\fwkren.exe tools\cook.ini to
call make.bat join rem call make.bat join
call make.bat amalgamation rem call make.bat amalgamation
echo All done. echo All done.
endlocal endlocal

View File

@ -3222,7 +3222,7 @@ int u_coefficients_sh;
size_t strlcpy(char *dst, const char *src, size_t dstcap); size_t strlcpy(char *dst, const char *src, size_t dstcap);
char** strsplit(const char *string, const char *delimiters); char** strsplit(const char *string, const char *delimiters);
char* strjoin(char** list, const char *separator); char* strjoin(char** list, const char *separator);
char * string8(const wchar_t *str); char* string8(const wchar_t *str);
uint32_t* string32( const char *utf8 ); uint32_t* string32( const char *utf8 );
const char* codepoint_to_utf8(unsigned cp); const char* codepoint_to_utf8(unsigned cp);
unsigned intern( const char *string ); unsigned intern( const char *string );
@ -3341,7 +3341,7 @@ unsigned play;
bool paused; bool paused;
struct atlas_t *a; struct atlas_t *a;
} sprite_t; } sprite_t;
enum { OBJTYPE_sprite_t = 10 }; typedef struct { unsigned static_assert_on_L__LINE__ : !!(10 <= 255); } static_assert_on_Lconcat(_L,3959)___COUNTER__; typedef struct { unsigned static_assert_on_L__LINE__ : !!(sizeof(sprite_t)); } static_assert_on_Lconcat(_L,3959)___COUNTER__;; enum { OBJTYPE_sprite_t = 10 }; typedef struct { unsigned static_assert_on_L__LINE__ : !!(10 <= 255); } static_assert_on_Lconcat(_L,3962)___COUNTER__; typedef struct { unsigned static_assert_on_L__LINE__ : !!(sizeof(sprite_t)); } static_assert_on_Lconcat(_L,3962)___COUNTER__;;
void sprite_ctor(sprite_t *s); void sprite_ctor(sprite_t *s);
void sprite_dtor(sprite_t *s); void sprite_dtor(sprite_t *s);
void sprite_tick(sprite_t *s); void sprite_tick(sprite_t *s);

View File

@ -14068,6 +14068,10 @@ extern "C" {
#define COOK_DISABLED 0 // ifdef(nocook, 1, 0) ///+ #define COOK_DISABLED 0 // ifdef(nocook, 1, 0) ///+
#endif #endif
#ifndef ENABLE_RPMALLOC
#define ENABLE_RPMALLOC 0 // ifdef(tcc, 0, 1) // forbidden on tcc because of lacking TLS support
#endif
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// if/n/def hell // if/n/def hell
@ -15368,7 +15372,6 @@ API extern int (*obj_init[256])(); ///-
API extern int (*obj_quit[256])(); ///- API extern int (*obj_quit[256])(); ///-
API extern int (*obj_tick[256])(); ///- API extern int (*obj_tick[256])(); ///-
API extern int (*obj_draw[256])(); ///- API extern int (*obj_draw[256])(); ///-
API extern int (*obj_lerp[256])(); ///- API extern int (*obj_lerp[256])(); ///-
API extern int (*obj_aabb[256])(); ///- API extern int (*obj_aabb[256])(); ///-
@ -15376,7 +15379,7 @@ API extern int (*obj_edit[256])(); ///-
API extern int (*obj_menu[256])(); ///- API extern int (*obj_menu[256])(); ///-
API extern char* (*obj_icon[256])(); ///- API extern char* (*obj_icon[256])(); ///-
API extern const char*OBJTYPES[256]; /// - API extern const char*OBJTYPES[256]; ///-
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// core // core
@ -17735,7 +17738,7 @@ typedef struct camera_t {
vec2 last_look; vec3 last_move; // used for friction and damping vec2 last_look; vec3 last_move; // used for friction and damping
bool damping; bool damping;
bool orthographic; // 0 perspective, 1 orthographic; when ortho: dimetric[if pitch == -30o], isometric[if pitch == 35.264o] bool orthographic; // 0 perspective, 1 orthographic; when ortho: dimetric[if pitch == -30º], isometric[if pitch == 35.264º]
float distance; // distance to pivot, when orbiting float distance; // distance to pivot, when orbiting
// vec2 polarity = { +1,-1 }; // @todo // vec2 polarity = { +1,-1 }; // @todo
// vec2 sensitivity = { 2,2 }; // @todo // vec2 sensitivity = { 2,2 }; // @todo
@ -17935,7 +17938,7 @@ API array(char*) strsplit(const char *string, const char *delimiters);
/// > char *joint = strjoin(tokens, "+"); // joint="hello+world" /// > char *joint = strjoin(tokens, "+"); // joint="hello+world"
API char* strjoin(array(char*) list, const char *separator); API char* strjoin(array(char*) list, const char *separator);
API char * string8(const wchar_t *str); /// convert from wchar16(win) to utf8/ascii API char* string8(const wchar_t *str); /// convert from wchar16(win) to utf8/ascii
API array(uint32_t) string32( const char *utf8 ); /// convert from utf8 to utf32 API array(uint32_t) string32( const char *utf8 ); /// convert from utf8 to utf32
API const char* codepoint_to_utf8(unsigned cp); API const char* codepoint_to_utf8(unsigned cp);
@ -241313,7 +241316,7 @@ static char *ui_filter = 0;
// - rlyeh, public domain // - rlyeh, public domain
// //
// changelog: // changelog:
// - ported to FWK api // - ported to V4K api
// - namespaced symbols // - namespaced symbols
// - diverse win32 fixes // - diverse win32 fixes
// - adaptive cols/rows // - adaptive cols/rows
@ -241490,7 +241493,7 @@ static void browser_reload_directory_content(struct browser *browser, const char
// remove last '/' if present. ok to overwrite absolute var, file_*() API returns writeable strings. // remove last '/' if present. ok to overwrite absolute var, file_*() API returns writeable strings.
char *dir = absolute; if( dir[ strlen(dir) - 1 ] == '/' ) dir[ strlen(dir) - 1 ] = '\0'; char *dir = absolute; if( dir[ strlen(dir) - 1 ] == '/' ) dir[ strlen(dir) - 1 ] = '\0';
dir = file_name(dir); // /home/rlyeh/prj/fwk/art -> art dir = file_name(dir); // /home/rlyeh/prj/v4k/art -> art
BROWSER_PRINTF("%s\n", dir); BROWSER_PRINTF("%s\n", dir);
if( dir[0] != '.' ) // skip special files, folders and internal files like .git or .art.zip if( dir[0] != '.' ) // skip special files, folders and internal files like .git or .art.zip
@ -348635,7 +348638,7 @@ static lm_bool lm_integrateHemisphereBatch(lm_context *ctx)
int sx = ctx->hemisphere.storage.writePosition.x + x; int sx = ctx->hemisphere.storage.writePosition.x + x;
unsigned int hemiIndex = y * ctx->hemisphere.fbHemiCountX + x; unsigned int hemiIndex = y * ctx->hemisphere.fbHemiCountX + x;
ctx->hemisphere.storage.toLightmapLocation[sy * ctx->hemisphere.storage.width + sx] = ctx->hemisphere.storage.toLightmapLocation[sy * ctx->hemisphere.storage.width + sx] =
(hemiIndex >= ctx->hemisphere.fbHemiIndex) ? (hemiIndex >= ctx->hemisphere.fbHemiIndex) ?
lm_i2(-1, -1) : lm_i2(-1, -1) :
ctx->hemisphere.fbHemiToLightmapLocation[hemiIndex]; ctx->hemisphere.fbHemiToLightmapLocation[hemiIndex];
} }
@ -356614,8 +356617,8 @@ void cook_stop() {
int cook_progress() { int cook_progress() {
int count = 0, sum = 0; int count = 0, sum = 0;
for( int i = 0, end = cook_jobs(); i < end; ++i ) { for( int i = 0, end = cook_jobs(); i < end; ++i ) {
sum += jobs[i].progress; sum += jobs[i].progress;
++count; ++count;
} }
return cook_jobs() ? sum / (count+!count) : 100; return cook_jobs() ? sum / (count+!count) : 100;
} }
@ -360823,7 +360826,7 @@ vec2 gui_getskinsize(const char *skin, const char *fallback) {
bool gui_ismouseinrect(const char *skin, const char *fallback, vec4 rect) { bool gui_ismouseinrect(const char *skin, const char *fallback, vec4 rect) {
if (last_skin->ismouseinrect) return last_skin->ismouseinrect(last_skin->userdata, skin, fallback, rect); if (last_skin->ismouseinrect) return last_skin->ismouseinrect(last_skin->userdata, skin, fallback, rect);
return false; return false;
} }
vec4 gui_getscissorrect(const char *skin, const char *fallback, vec4 rect) { vec4 gui_getscissorrect(const char *skin, const char *fallback, vec4 rect) {
@ -361003,7 +361006,7 @@ void skinned_free(void* userdata) {
static static
atlas_slice_frame_t *skinned_getsliceframe(atlas_t *a, const char *name) { atlas_slice_frame_t *skinned_getsliceframe(atlas_t *a, const char *name) {
if (!name) return NULL; if (!name) return NULL;
for (int i = 0; i < array_count(a->slices); i++) for (int i = 0; i < array_count(a->slices); i++)
if (!strcmp(quark_string(&a->db, a->slices[i].name), name)) if (!strcmp(quark_string(&a->db, a->slices[i].name), name))
return &a->slice_frames[a->slices[i].frames[0]]; return &a->slice_frames[a->slices[i].frames[0]];
// PRINTF("slice name: '%s' is missing in atlas!\n", name); // PRINTF("slice name: '%s' is missing in atlas!\n", name);
@ -371557,8 +371560,8 @@ void camera_orbit( camera_t *cam, float yaw, float pitch, float inc_distance ) {
cam->pitch += _mouse.y; cam->pitch += _mouse.y;
cam->distance += _mouse.z; cam->distance += _mouse.z;
// look: limit pitch angle [-89..89] // look: limit pitch angle [-89..89]
cam->pitch = cam->pitch > 89 ? 89 : cam->pitch < -89 ? -89 : cam->pitch; cam->pitch = cam->pitch > 89 ? 89 : cam->pitch < -89 ? -89 : cam->pitch;
// compute view matrix // compute view matrix
float x = rad(cam->yaw), y = rad(-cam->pitch), cx = cosf(x), cy = cosf(y), sx = sinf(x), sy = sinf(y); float x = rad(cam->yaw), y = rad(-cam->pitch), cx = cosf(x), cy = cosf(y), sx = sinf(x), sy = sinf(y);
@ -378856,10 +378859,10 @@ void v4k_init() {
// - network replication can be done by external tools by comparing the filesystems and by sending the resulting diff zipped // - network replication can be done by external tools by comparing the filesystems and by sending the resulting diff zipped
// //
// ## Editor roadmap // ## Editor roadmap
// - Gizmos?, scene tree, property editor?, load/save?, undo/redo?, copy/paste, on/off (vis,tick,ddraw,log), vcs. // - Gizmos✱, scene tree, property editor✱, load/save✱, undo/redo✱, copy/paste, on/off (vis,tick,ddraw,log), vcs.
// - Scenenode pass: node singleton display, node console, node labels, node outlines?.<!-- node == gameobj ? --> // - Scenenode pass: node singleton display, node console, node labels, node outlines.<!-- node == gameobj ? -->
// - Render pass: billboards?, materials, un/lit, cast shadows, wireframe, skybox?/mie?, fog/atmosphere // - Render pass: billboards✱, materials, un/lit, cast shadows, wireframe, skybox✱/mie✱, fog/atmosphere
// - Level pass: volumes, triggers, platforms, level streaming, collide?, physics // - Level pass: volumes, triggers, platforms, level streaming, collide, physics
// - Edit pass: Procedural content, brushes, noise and CSG. // - Edit pass: Procedural content, brushes, noise and CSG.
// - GUI pass: timeline and data tracks, node graphs. <!-- worthy: will be reused into materials, animgraphs and blueprints --> // - GUI pass: timeline and data tracks, node graphs. <!-- worthy: will be reused into materials, animgraphs and blueprints -->
@ -379044,20 +379047,20 @@ int editor_filter() {
if (nk_begin(ui_ctx, "Filter", nk_rect(window_width()-window_width()*0.33,32, window_width()*0.33, 40), if (nk_begin(ui_ctx, "Filter", nk_rect(window_width()-window_width()*0.33,32, window_width()*0.33, 40),
NK_WINDOW_NO_SCROLLBAR)) { NK_WINDOW_NO_SCROLLBAR)) {
char *bak = ui_filter; ui_filter = 0; char *bak = ui_filter; ui_filter = 0;
ui_string(ICON_MD_CLOSE " Filter " ICON_MD_SEARCH, &bak); ui_string(ICON_MD_CLOSE " Filter " ICON_MD_SEARCH, &bak);
ui_filter = bak; ui_filter = bak;
if( input(KEY_ESC) || ( ui_label_icon_clicked_L.x > 0 && ui_label_icon_clicked_L.x <= 24 )) { if( input(KEY_ESC) || ( ui_label_icon_clicked_L.x > 0 && ui_label_icon_clicked_L.x <= 24 )) {
if( ui_filter ) ui_filter[0] = '\0'; if( ui_filter ) ui_filter[0] = '\0';
editor.filter = 0; editor.filter = 0;
} }
} }
nk_end(ui_ctx); nk_end(ui_ctx);
} }
return editor.filter; return editor.filter;
} }
static static
int editor_select_(void *o, const char *mask) { int editor_select_(void *o, const char *mask) {
@ -379081,7 +379084,7 @@ void editor_unselect() { // same than editor_select("!**");
for each_map_ptr(*editor_selected_map(), void*,o, int, k) { for each_map_ptr(*editor_selected_map(), void*,o, int, k) {
if( *k ) *k = 0; if( *k ) *k = 0;
} }
} }
void editor_select_aabb(aabb box) { void editor_select_aabb(aabb box) {
int is_inv = input_held(KEY_CTRL); int is_inv = input_held(KEY_CTRL);
@ -379121,8 +379124,8 @@ void editor_selectgroup(obj *first, obj *last) {
editor_selectgroup_(o, first, last); editor_selectgroup_(o, first, last);
} }
} }
}
} }
}
static obj *find_any_selected_(obj *o) { static obj *find_any_selected_(obj *o) {
if( editor_selected(o) ) return o; if( editor_selected(o) ) return o;
@ -379138,7 +379141,7 @@ void* editor_first_selected() {
obj *oo = find_any_selected_(o); obj *oo = find_any_selected_(o);
// if( oo ) printf("1st found: %s\n", obj_name(oo)); // if( oo ) printf("1st found: %s\n", obj_name(oo));
if( oo ) return oo; if( oo ) return oo;
} }
return 0; return 0;
} }
@ -379149,7 +379152,7 @@ static obj *find_last_selected_(obj *o) {
obj *ooo = find_last_selected_(oo); obj *ooo = find_last_selected_(oo);
if( ooo ) if( ooo )
last = ooo; last = ooo;
} }
return last; return last;
} }
void* editor_last_selected() { void* editor_last_selected() {
@ -379158,7 +379161,7 @@ void* editor_last_selected() {
obj *oo = find_last_selected_(o); obj *oo = find_last_selected_(o);
// if( oo ) printf("last found: %s\n", obj_name(oo)); // if( oo ) printf("last found: %s\n", obj_name(oo));
if( oo ) last = oo; if( oo ) last = oo;
} }
return last; return last;
} }
@ -379168,7 +379171,7 @@ void editor_addtoworld(obj *o) {
set_find_or_add(editor.world, o); set_find_or_add(editor.world, o);
for each_objchild(o, obj*, oo) { for each_objchild(o, obj*, oo) {
editor_addtoworld(oo); editor_addtoworld(oo);
} }
} }
void editor_watch(const void *o) { void editor_watch(const void *o) {
@ -379349,9 +379352,9 @@ void editor_pump() {
if( (*cmd)[0] ) { if( (*cmd)[0] ) {
(*cmd)[0] = '\0'; strcatf(&(*cmd), "\1%s\n", "Ok\n"); (*cmd)[0] = '\0'; (*cmd)[0] = '\0'; strcatf(&(*cmd), "\1%s\n", "Ok\n"); (*cmd)[0] = '\0';
}
} }
} }
}
} }
} }
@ -379500,8 +379503,8 @@ void editor_frame( void (*game)(unsigned, float, double) ) {
for each_set_ptr(editor.world,obj*,o) { for each_set_ptr(editor.world,obj*,o) {
if( obj_hasmethod(*o,edit) ) { if( obj_hasmethod(*o,edit) ) {
obj_edit(*o); obj_edit(*o);
}
} }
}
// draw silhouettes // draw silhouettes
sprite_flush(); sprite_flush();
@ -379513,8 +379516,8 @@ void editor_frame( void (*game)(unsigned, float, double) ) {
} }
if( obj_hasmethod(*o,edit) ) { if( obj_hasmethod(*o,edit) ) {
obj_edit(*o); obj_edit(*o);
} }
} }
sprite_flush(); sprite_flush();
fx_end(); fx_end();
@ -379572,9 +379575,9 @@ void editor_frame( void (*game)(unsigned, float, double) ) {
editor_end(EDITOR_WINDOW_NK_SMALL); editor_end(EDITOR_WINDOW_NK_SMALL);
} else { } else {
editor_setpopup(o, 0); editor_setpopup(o, 0);
}
}
} }
}
}
// draw subeditors // draw subeditors

View File

@ -751,7 +751,7 @@ static lm_bool lm_integrateHemisphereBatch(lm_context *ctx)
int sx = ctx->hemisphere.storage.writePosition.x + x; int sx = ctx->hemisphere.storage.writePosition.x + x;
unsigned int hemiIndex = y * ctx->hemisphere.fbHemiCountX + x; unsigned int hemiIndex = y * ctx->hemisphere.fbHemiCountX + x;
ctx->hemisphere.storage.toLightmapLocation[sy * ctx->hemisphere.storage.width + sx] = ctx->hemisphere.storage.toLightmapLocation[sy * ctx->hemisphere.storage.width + sx] =
(hemiIndex >= ctx->hemisphere.fbHemiIndex) ? (hemiIndex >= ctx->hemisphere.fbHemiIndex) ?
lm_i2(-1, -1) : lm_i2(-1, -1) :
ctx->hemisphere.fbHemiToLightmapLocation[hemiIndex]; ctx->hemisphere.fbHemiToLightmapLocation[hemiIndex];
} }

View File

@ -2,7 +2,7 @@
// - rlyeh, public domain // - rlyeh, public domain
// //
// changelog: // changelog:
// - ported to FWK api // - ported to V4K api
// - namespaced symbols // - namespaced symbols
// - diverse win32 fixes // - diverse win32 fixes
// - adaptive cols/rows // - adaptive cols/rows
@ -179,7 +179,7 @@ static void browser_reload_directory_content(struct browser *browser, const char
// remove last '/' if present. ok to overwrite absolute var, file_*() API returns writeable strings. // remove last '/' if present. ok to overwrite absolute var, file_*() API returns writeable strings.
char *dir = absolute; if( dir[ strlen(dir) - 1 ] == '/' ) dir[ strlen(dir) - 1 ] = '\0'; char *dir = absolute; if( dir[ strlen(dir) - 1 ] == '/' ) dir[ strlen(dir) - 1 ] = '\0';
dir = file_name(dir); // /home/rlyeh/prj/fwk/art -> art dir = file_name(dir); // /home/rlyeh/prj/v4k/art -> art
BROWSER_PRINTF("%s\n", dir); BROWSER_PRINTF("%s\n", dir);
if( dir[0] != '.' ) // skip special files, folders and internal files like .git or .art.zip if( dir[0] != '.' ) // skip special files, folders and internal files like .git or .art.zip

View File

@ -37,6 +37,10 @@
#define COOK_DISABLED 0 // ifdef(nocook, 1, 0) ///+ #define COOK_DISABLED 0 // ifdef(nocook, 1, 0) ///+
#endif #endif
#ifndef ENABLE_RPMALLOC
#define ENABLE_RPMALLOC 0 // ifdef(tcc, 0, 1) // forbidden on tcc because of lacking TLS support
#endif
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// if/n/def hell // if/n/def hell

View File

@ -830,8 +830,8 @@ void cook_stop() {
int cook_progress() { int cook_progress() {
int count = 0, sum = 0; int count = 0, sum = 0;
for( int i = 0, end = cook_jobs(); i < end; ++i ) { for( int i = 0, end = cook_jobs(); i < end; ++i ) {
sum += jobs[i].progress; sum += jobs[i].progress;
++count; ++count;
} }
return cook_jobs() ? sum / (count+!count) : 100; return cook_jobs() ? sum / (count+!count) : 100;
} }

View File

@ -6,10 +6,10 @@
// - network replication can be done by external tools by comparing the filesystems and by sending the resulting diff zipped // - network replication can be done by external tools by comparing the filesystems and by sending the resulting diff zipped
// //
// ## Editor roadmap // ## Editor roadmap
// - Gizmos?, scene tree, property editor?, load/save?, undo/redo?, copy/paste, on/off (vis,tick,ddraw,log), vcs. // - Gizmos✱, scene tree, property editor✱, load/save✱, undo/redo✱, copy/paste, on/off (vis,tick,ddraw,log), vcs.
// - Scenenode pass: node singleton display, node console, node labels, node outlines?.<!-- node == gameobj ? --> // - Scenenode pass: node singleton display, node console, node labels, node outlines.<!-- node == gameobj ? -->
// - Render pass: billboards?, materials, un/lit, cast shadows, wireframe, skybox?/mie?, fog/atmosphere // - Render pass: billboards✱, materials, un/lit, cast shadows, wireframe, skybox✱/mie✱, fog/atmosphere
// - Level pass: volumes, triggers, platforms, level streaming, collide?, physics // - Level pass: volumes, triggers, platforms, level streaming, collide, physics
// - Edit pass: Procedural content, brushes, noise and CSG. // - Edit pass: Procedural content, brushes, noise and CSG.
// - GUI pass: timeline and data tracks, node graphs. <!-- worthy: will be reused into materials, animgraphs and blueprints --> // - GUI pass: timeline and data tracks, node graphs. <!-- worthy: will be reused into materials, animgraphs and blueprints -->
@ -194,20 +194,20 @@ int editor_filter() {
if (nk_begin(ui_ctx, "Filter", nk_rect(window_width()-window_width()*0.33,32, window_width()*0.33, 40), if (nk_begin(ui_ctx, "Filter", nk_rect(window_width()-window_width()*0.33,32, window_width()*0.33, 40),
NK_WINDOW_NO_SCROLLBAR)) { NK_WINDOW_NO_SCROLLBAR)) {
char *bak = ui_filter; ui_filter = 0; char *bak = ui_filter; ui_filter = 0;
ui_string(ICON_MD_CLOSE " Filter " ICON_MD_SEARCH, &bak); ui_string(ICON_MD_CLOSE " Filter " ICON_MD_SEARCH, &bak);
ui_filter = bak; ui_filter = bak;
if( input(KEY_ESC) || ( ui_label_icon_clicked_L.x > 0 && ui_label_icon_clicked_L.x <= 24 )) { if( input(KEY_ESC) || ( ui_label_icon_clicked_L.x > 0 && ui_label_icon_clicked_L.x <= 24 )) {
if( ui_filter ) ui_filter[0] = '\0'; if( ui_filter ) ui_filter[0] = '\0';
editor.filter = 0; editor.filter = 0;
} }
} }
nk_end(ui_ctx); nk_end(ui_ctx);
} }
return editor.filter; return editor.filter;
} }
static static
int editor_select_(void *o, const char *mask) { int editor_select_(void *o, const char *mask) {
@ -231,7 +231,7 @@ void editor_unselect() { // same than editor_select("!**");
for each_map_ptr(*editor_selected_map(), void*,o, int, k) { for each_map_ptr(*editor_selected_map(), void*,o, int, k) {
if( *k ) *k = 0; if( *k ) *k = 0;
} }
} }
void editor_select_aabb(aabb box) { void editor_select_aabb(aabb box) {
int is_inv = input_held(KEY_CTRL); int is_inv = input_held(KEY_CTRL);
@ -271,8 +271,8 @@ void editor_selectgroup(obj *first, obj *last) {
editor_selectgroup_(o, first, last); editor_selectgroup_(o, first, last);
} }
} }
}
} }
}
static obj *find_any_selected_(obj *o) { static obj *find_any_selected_(obj *o) {
if( editor_selected(o) ) return o; if( editor_selected(o) ) return o;
@ -288,7 +288,7 @@ void* editor_first_selected() {
obj *oo = find_any_selected_(o); obj *oo = find_any_selected_(o);
// if( oo ) printf("1st found: %s\n", obj_name(oo)); // if( oo ) printf("1st found: %s\n", obj_name(oo));
if( oo ) return oo; if( oo ) return oo;
} }
return 0; return 0;
} }
@ -299,7 +299,7 @@ static obj *find_last_selected_(obj *o) {
obj *ooo = find_last_selected_(oo); obj *ooo = find_last_selected_(oo);
if( ooo ) if( ooo )
last = ooo; last = ooo;
} }
return last; return last;
} }
void* editor_last_selected() { void* editor_last_selected() {
@ -308,7 +308,7 @@ void* editor_last_selected() {
obj *oo = find_last_selected_(o); obj *oo = find_last_selected_(o);
// if( oo ) printf("last found: %s\n", obj_name(oo)); // if( oo ) printf("last found: %s\n", obj_name(oo));
if( oo ) last = oo; if( oo ) last = oo;
} }
return last; return last;
} }
@ -318,7 +318,7 @@ void editor_addtoworld(obj *o) {
set_find_or_add(editor.world, o); set_find_or_add(editor.world, o);
for each_objchild(o, obj*, oo) { for each_objchild(o, obj*, oo) {
editor_addtoworld(oo); editor_addtoworld(oo);
} }
} }
void editor_watch(const void *o) { void editor_watch(const void *o) {
@ -499,9 +499,9 @@ void editor_pump() {
if( (*cmd)[0] ) { if( (*cmd)[0] ) {
(*cmd)[0] = '\0'; strcatf(&(*cmd), "\1%s\n", "Ok\n"); (*cmd)[0] = '\0'; (*cmd)[0] = '\0'; strcatf(&(*cmd), "\1%s\n", "Ok\n"); (*cmd)[0] = '\0';
}
} }
} }
}
} }
} }
@ -650,8 +650,8 @@ void editor_frame( void (*game)(unsigned, float, double) ) {
for each_set_ptr(editor.world,obj*,o) { for each_set_ptr(editor.world,obj*,o) {
if( obj_hasmethod(*o,edit) ) { if( obj_hasmethod(*o,edit) ) {
obj_edit(*o); obj_edit(*o);
}
} }
}
// draw silhouettes // draw silhouettes
sprite_flush(); sprite_flush();
@ -663,8 +663,8 @@ void editor_frame( void (*game)(unsigned, float, double) ) {
} }
if( obj_hasmethod(*o,edit) ) { if( obj_hasmethod(*o,edit) ) {
obj_edit(*o); obj_edit(*o);
} }
} }
sprite_flush(); sprite_flush();
fx_end(); fx_end();
@ -722,9 +722,9 @@ void editor_frame( void (*game)(unsigned, float, double) ) {
editor_end(EDITOR_WINDOW_NK_SMALL); editor_end(EDITOR_WINDOW_NK_SMALL);
} else { } else {
editor_setpopup(o, 0); editor_setpopup(o, 0);
}
}
} }
}
}
// draw subeditors // draw subeditors

View File

@ -126,7 +126,7 @@ vec2 gui_getskinsize(const char *skin, const char *fallback) {
bool gui_ismouseinrect(const char *skin, const char *fallback, vec4 rect) { bool gui_ismouseinrect(const char *skin, const char *fallback, vec4 rect) {
if (last_skin->ismouseinrect) return last_skin->ismouseinrect(last_skin->userdata, skin, fallback, rect); if (last_skin->ismouseinrect) return last_skin->ismouseinrect(last_skin->userdata, skin, fallback, rect);
return false; return false;
} }
vec4 gui_getscissorrect(const char *skin, const char *fallback, vec4 rect) { vec4 gui_getscissorrect(const char *skin, const char *fallback, vec4 rect) {
@ -306,7 +306,7 @@ void skinned_free(void* userdata) {
static static
atlas_slice_frame_t *skinned_getsliceframe(atlas_t *a, const char *name) { atlas_slice_frame_t *skinned_getsliceframe(atlas_t *a, const char *name) {
if (!name) return NULL; if (!name) return NULL;
for (int i = 0; i < array_count(a->slices); i++) for (int i = 0; i < array_count(a->slices); i++)
if (!strcmp(quark_string(&a->db, a->slices[i].name), name)) if (!strcmp(quark_string(&a->db, a->slices[i].name), name))
return &a->slice_frames[a->slices[i].frames[0]]; return &a->slice_frames[a->slices[i].frames[0]];
// PRINTF("slice name: '%s' is missing in atlas!\n", name); // PRINTF("slice name: '%s' is missing in atlas!\n", name);

View File

@ -208,7 +208,6 @@ API extern int (*obj_init[256])(); ///-
API extern int (*obj_quit[256])(); ///- API extern int (*obj_quit[256])(); ///-
API extern int (*obj_tick[256])(); ///- API extern int (*obj_tick[256])(); ///-
API extern int (*obj_draw[256])(); ///- API extern int (*obj_draw[256])(); ///-
API extern int (*obj_lerp[256])(); ///- API extern int (*obj_lerp[256])(); ///-
API extern int (*obj_aabb[256])(); ///- API extern int (*obj_aabb[256])(); ///-
@ -216,7 +215,7 @@ API extern int (*obj_edit[256])(); ///-
API extern int (*obj_menu[256])(); ///- API extern int (*obj_menu[256])(); ///-
API extern char* (*obj_icon[256])(); ///- API extern char* (*obj_icon[256])(); ///-
API extern const char*OBJTYPES[256]; /// - API extern const char*OBJTYPES[256]; ///-
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// core // core

View File

@ -156,8 +156,8 @@ void camera_orbit( camera_t *cam, float yaw, float pitch, float inc_distance ) {
cam->pitch += _mouse.y; cam->pitch += _mouse.y;
cam->distance += _mouse.z; cam->distance += _mouse.z;
// look: limit pitch angle [-89..89] // look: limit pitch angle [-89..89]
cam->pitch = cam->pitch > 89 ? 89 : cam->pitch < -89 ? -89 : cam->pitch; cam->pitch = cam->pitch > 89 ? 89 : cam->pitch < -89 ? -89 : cam->pitch;
// compute view matrix // compute view matrix
float x = rad(cam->yaw), y = rad(-cam->pitch), cx = cosf(x), cy = cosf(y), sx = sinf(x), sy = sinf(y); float x = rad(cam->yaw), y = rad(-cam->pitch), cx = cosf(x), cy = cosf(y), sx = sinf(x), sy = sinf(y);

View File

@ -15,7 +15,7 @@ typedef struct camera_t {
vec2 last_look; vec3 last_move; // used for friction and damping vec2 last_look; vec3 last_move; // used for friction and damping
bool damping; bool damping;
bool orthographic; // 0 perspective, 1 orthographic; when ortho: dimetric[if pitch == -30o], isometric[if pitch == 35.264o] bool orthographic; // 0 perspective, 1 orthographic; when ortho: dimetric[if pitch == -30º], isometric[if pitch == 35.264º]
float distance; // distance to pivot, when orbiting float distance; // distance to pivot, when orbiting
// vec2 polarity = { +1,-1 }; // @todo // vec2 polarity = { +1,-1 }; // @todo
// vec2 sensitivity = { 2,2 }; // @todo // vec2 sensitivity = { 2,2 }; // @todo

View File

@ -73,7 +73,7 @@ API array(char*) strsplit(const char *string, const char *delimiters);
/// > char *joint = strjoin(tokens, "+"); // joint="hello+world" /// > char *joint = strjoin(tokens, "+"); // joint="hello+world"
API char* strjoin(array(char*) list, const char *separator); API char* strjoin(array(char*) list, const char *separator);
API char * string8(const wchar_t *str); /// convert from wchar16(win) to utf8/ascii API char* string8(const wchar_t *str); /// convert from wchar16(win) to utf8/ascii
API array(uint32_t) string32( const char *utf8 ); /// convert from utf8 to utf32 API array(uint32_t) string32( const char *utf8 ); /// convert from utf8 to utf32
API const char* codepoint_to_utf8(unsigned cp); API const char* codepoint_to_utf8(unsigned cp);

View File

@ -222477,7 +222477,7 @@ static char *ui_filter = 0;
// - rlyeh, public domain // - rlyeh, public domain
// //
// changelog: // changelog:
// - ported to FWK api // - ported to V4K api
// - namespaced symbols // - namespaced symbols
// - diverse win32 fixes // - diverse win32 fixes
// - adaptive cols/rows // - adaptive cols/rows
@ -222654,7 +222654,7 @@ static void browser_reload_directory_content(struct browser *browser, const char
// remove last '/' if present. ok to overwrite absolute var, file_*() API returns writeable strings. // remove last '/' if present. ok to overwrite absolute var, file_*() API returns writeable strings.
char *dir = absolute; if( dir[ strlen(dir) - 1 ] == '/' ) dir[ strlen(dir) - 1 ] = '\0'; char *dir = absolute; if( dir[ strlen(dir) - 1 ] == '/' ) dir[ strlen(dir) - 1 ] = '\0';
dir = file_name(dir); // /home/rlyeh/prj/fwk/art -> art dir = file_name(dir); // /home/rlyeh/prj/v4k/art -> art
BROWSER_PRINTF("%s\n", dir); BROWSER_PRINTF("%s\n", dir);
if( dir[0] != '.' ) // skip special files, folders and internal files like .git or .art.zip if( dir[0] != '.' ) // skip special files, folders and internal files like .git or .art.zip
@ -329799,7 +329799,7 @@ static lm_bool lm_integrateHemisphereBatch(lm_context *ctx)
int sx = ctx->hemisphere.storage.writePosition.x + x; int sx = ctx->hemisphere.storage.writePosition.x + x;
unsigned int hemiIndex = y * ctx->hemisphere.fbHemiCountX + x; unsigned int hemiIndex = y * ctx->hemisphere.fbHemiCountX + x;
ctx->hemisphere.storage.toLightmapLocation[sy * ctx->hemisphere.storage.width + sx] = ctx->hemisphere.storage.toLightmapLocation[sy * ctx->hemisphere.storage.width + sx] =
(hemiIndex >= ctx->hemisphere.fbHemiIndex) ? (hemiIndex >= ctx->hemisphere.fbHemiIndex) ?
lm_i2(-1, -1) : lm_i2(-1, -1) :
ctx->hemisphere.fbHemiToLightmapLocation[hemiIndex]; ctx->hemisphere.fbHemiToLightmapLocation[hemiIndex];
} }

View File

@ -6946,8 +6946,8 @@ void cook_stop() {
int cook_progress() { int cook_progress() {
int count = 0, sum = 0; int count = 0, sum = 0;
for( int i = 0, end = cook_jobs(); i < end; ++i ) { for( int i = 0, end = cook_jobs(); i < end; ++i ) {
sum += jobs[i].progress; sum += jobs[i].progress;
++count; ++count;
} }
return cook_jobs() ? sum / (count+!count) : 100; return cook_jobs() ? sum / (count+!count) : 100;
} }
@ -11155,7 +11155,7 @@ vec2 gui_getskinsize(const char *skin, const char *fallback) {
bool gui_ismouseinrect(const char *skin, const char *fallback, vec4 rect) { bool gui_ismouseinrect(const char *skin, const char *fallback, vec4 rect) {
if (last_skin->ismouseinrect) return last_skin->ismouseinrect(last_skin->userdata, skin, fallback, rect); if (last_skin->ismouseinrect) return last_skin->ismouseinrect(last_skin->userdata, skin, fallback, rect);
return false; return false;
} }
vec4 gui_getscissorrect(const char *skin, const char *fallback, vec4 rect) { vec4 gui_getscissorrect(const char *skin, const char *fallback, vec4 rect) {
@ -11335,7 +11335,7 @@ void skinned_free(void* userdata) {
static static
atlas_slice_frame_t *skinned_getsliceframe(atlas_t *a, const char *name) { atlas_slice_frame_t *skinned_getsliceframe(atlas_t *a, const char *name) {
if (!name) return NULL; if (!name) return NULL;
for (int i = 0; i < array_count(a->slices); i++) for (int i = 0; i < array_count(a->slices); i++)
if (!strcmp(quark_string(&a->db, a->slices[i].name), name)) if (!strcmp(quark_string(&a->db, a->slices[i].name), name))
return &a->slice_frames[a->slices[i].frames[0]]; return &a->slice_frames[a->slices[i].frames[0]];
// PRINTF("slice name: '%s' is missing in atlas!\n", name); // PRINTF("slice name: '%s' is missing in atlas!\n", name);
@ -21889,8 +21889,8 @@ void camera_orbit( camera_t *cam, float yaw, float pitch, float inc_distance ) {
cam->pitch += _mouse.y; cam->pitch += _mouse.y;
cam->distance += _mouse.z; cam->distance += _mouse.z;
// look: limit pitch angle [-89..89] // look: limit pitch angle [-89..89]
cam->pitch = cam->pitch > 89 ? 89 : cam->pitch < -89 ? -89 : cam->pitch; cam->pitch = cam->pitch > 89 ? 89 : cam->pitch < -89 ? -89 : cam->pitch;
// compute view matrix // compute view matrix
float x = rad(cam->yaw), y = rad(-cam->pitch), cx = cosf(x), cy = cosf(y), sx = sinf(x), sy = sinf(y); float x = rad(cam->yaw), y = rad(-cam->pitch), cx = cosf(x), cy = cosf(y), sx = sinf(x), sy = sinf(y);
@ -29188,10 +29188,10 @@ void v4k_init() {
// - network replication can be done by external tools by comparing the filesystems and by sending the resulting diff zipped // - network replication can be done by external tools by comparing the filesystems and by sending the resulting diff zipped
// //
// ## Editor roadmap // ## Editor roadmap
// - Gizmos?, scene tree, property editor?, load/save?, undo/redo?, copy/paste, on/off (vis,tick,ddraw,log), vcs. // - Gizmos✱, scene tree, property editor✱, load/save✱, undo/redo✱, copy/paste, on/off (vis,tick,ddraw,log), vcs.
// - Scenenode pass: node singleton display, node console, node labels, node outlines?.<!-- node == gameobj ? --> // - Scenenode pass: node singleton display, node console, node labels, node outlines.<!-- node == gameobj ? -->
// - Render pass: billboards?, materials, un/lit, cast shadows, wireframe, skybox?/mie?, fog/atmosphere // - Render pass: billboards✱, materials, un/lit, cast shadows, wireframe, skybox✱/mie✱, fog/atmosphere
// - Level pass: volumes, triggers, platforms, level streaming, collide?, physics // - Level pass: volumes, triggers, platforms, level streaming, collide, physics
// - Edit pass: Procedural content, brushes, noise and CSG. // - Edit pass: Procedural content, brushes, noise and CSG.
// - GUI pass: timeline and data tracks, node graphs. <!-- worthy: will be reused into materials, animgraphs and blueprints --> // - GUI pass: timeline and data tracks, node graphs. <!-- worthy: will be reused into materials, animgraphs and blueprints -->
@ -29376,20 +29376,20 @@ int editor_filter() {
if (nk_begin(ui_ctx, "Filter", nk_rect(window_width()-window_width()*0.33,32, window_width()*0.33, 40), if (nk_begin(ui_ctx, "Filter", nk_rect(window_width()-window_width()*0.33,32, window_width()*0.33, 40),
NK_WINDOW_NO_SCROLLBAR)) { NK_WINDOW_NO_SCROLLBAR)) {
char *bak = ui_filter; ui_filter = 0; char *bak = ui_filter; ui_filter = 0;
ui_string(ICON_MD_CLOSE " Filter " ICON_MD_SEARCH, &bak); ui_string(ICON_MD_CLOSE " Filter " ICON_MD_SEARCH, &bak);
ui_filter = bak; ui_filter = bak;
if( input(KEY_ESC) || ( ui_label_icon_clicked_L.x > 0 && ui_label_icon_clicked_L.x <= 24 )) { if( input(KEY_ESC) || ( ui_label_icon_clicked_L.x > 0 && ui_label_icon_clicked_L.x <= 24 )) {
if( ui_filter ) ui_filter[0] = '\0'; if( ui_filter ) ui_filter[0] = '\0';
editor.filter = 0; editor.filter = 0;
} }
} }
nk_end(ui_ctx); nk_end(ui_ctx);
} }
return editor.filter; return editor.filter;
} }
static static
int editor_select_(void *o, const char *mask) { int editor_select_(void *o, const char *mask) {
@ -29413,7 +29413,7 @@ void editor_unselect() { // same than editor_select("!**");
for each_map_ptr(*editor_selected_map(), void*,o, int, k) { for each_map_ptr(*editor_selected_map(), void*,o, int, k) {
if( *k ) *k = 0; if( *k ) *k = 0;
} }
} }
void editor_select_aabb(aabb box) { void editor_select_aabb(aabb box) {
int is_inv = input_held(KEY_CTRL); int is_inv = input_held(KEY_CTRL);
@ -29453,8 +29453,8 @@ void editor_selectgroup(obj *first, obj *last) {
editor_selectgroup_(o, first, last); editor_selectgroup_(o, first, last);
} }
} }
}
} }
}
static obj *find_any_selected_(obj *o) { static obj *find_any_selected_(obj *o) {
if( editor_selected(o) ) return o; if( editor_selected(o) ) return o;
@ -29470,7 +29470,7 @@ void* editor_first_selected() {
obj *oo = find_any_selected_(o); obj *oo = find_any_selected_(o);
// if( oo ) printf("1st found: %s\n", obj_name(oo)); // if( oo ) printf("1st found: %s\n", obj_name(oo));
if( oo ) return oo; if( oo ) return oo;
} }
return 0; return 0;
} }
@ -29481,7 +29481,7 @@ static obj *find_last_selected_(obj *o) {
obj *ooo = find_last_selected_(oo); obj *ooo = find_last_selected_(oo);
if( ooo ) if( ooo )
last = ooo; last = ooo;
} }
return last; return last;
} }
void* editor_last_selected() { void* editor_last_selected() {
@ -29490,7 +29490,7 @@ void* editor_last_selected() {
obj *oo = find_last_selected_(o); obj *oo = find_last_selected_(o);
// if( oo ) printf("last found: %s\n", obj_name(oo)); // if( oo ) printf("last found: %s\n", obj_name(oo));
if( oo ) last = oo; if( oo ) last = oo;
} }
return last; return last;
} }
@ -29500,7 +29500,7 @@ void editor_addtoworld(obj *o) {
set_find_or_add(editor.world, o); set_find_or_add(editor.world, o);
for each_objchild(o, obj*, oo) { for each_objchild(o, obj*, oo) {
editor_addtoworld(oo); editor_addtoworld(oo);
} }
} }
void editor_watch(const void *o) { void editor_watch(const void *o) {
@ -29681,9 +29681,9 @@ void editor_pump() {
if( (*cmd)[0] ) { if( (*cmd)[0] ) {
(*cmd)[0] = '\0'; strcatf(&(*cmd), "\1%s\n", "Ok\n"); (*cmd)[0] = '\0'; (*cmd)[0] = '\0'; strcatf(&(*cmd), "\1%s\n", "Ok\n"); (*cmd)[0] = '\0';
}
} }
} }
}
} }
} }
@ -29832,8 +29832,8 @@ void editor_frame( void (*game)(unsigned, float, double) ) {
for each_set_ptr(editor.world,obj*,o) { for each_set_ptr(editor.world,obj*,o) {
if( obj_hasmethod(*o,edit) ) { if( obj_hasmethod(*o,edit) ) {
obj_edit(*o); obj_edit(*o);
}
} }
}
// draw silhouettes // draw silhouettes
sprite_flush(); sprite_flush();
@ -29845,8 +29845,8 @@ void editor_frame( void (*game)(unsigned, float, double) ) {
} }
if( obj_hasmethod(*o,edit) ) { if( obj_hasmethod(*o,edit) ) {
obj_edit(*o); obj_edit(*o);
} }
} }
sprite_flush(); sprite_flush();
fx_end(); fx_end();
@ -29904,9 +29904,9 @@ void editor_frame( void (*game)(unsigned, float, double) ) {
editor_end(EDITOR_WINDOW_NK_SMALL); editor_end(EDITOR_WINDOW_NK_SMALL);
} else { } else {
editor_setpopup(o, 0); editor_setpopup(o, 0);
}
}
} }
}
}
// draw subeditors // draw subeditors

View File

@ -135,6 +135,10 @@ extern "C" {
#define COOK_DISABLED 0 // ifdef(nocook, 1, 0) ///+ #define COOK_DISABLED 0 // ifdef(nocook, 1, 0) ///+
#endif #endif
#ifndef ENABLE_RPMALLOC
#define ENABLE_RPMALLOC 0 // ifdef(tcc, 0, 1) // forbidden on tcc because of lacking TLS support
#endif
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// if/n/def hell // if/n/def hell
@ -1435,7 +1439,6 @@ API extern int (*obj_init[256])(); ///-
API extern int (*obj_quit[256])(); ///- API extern int (*obj_quit[256])(); ///-
API extern int (*obj_tick[256])(); ///- API extern int (*obj_tick[256])(); ///-
API extern int (*obj_draw[256])(); ///- API extern int (*obj_draw[256])(); ///-
API extern int (*obj_lerp[256])(); ///- API extern int (*obj_lerp[256])(); ///-
API extern int (*obj_aabb[256])(); ///- API extern int (*obj_aabb[256])(); ///-
@ -1443,7 +1446,7 @@ API extern int (*obj_edit[256])(); ///-
API extern int (*obj_menu[256])(); ///- API extern int (*obj_menu[256])(); ///-
API extern char* (*obj_icon[256])(); ///- API extern char* (*obj_icon[256])(); ///-
API extern const char*OBJTYPES[256]; /// - API extern const char*OBJTYPES[256]; ///-
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// core // core
@ -3802,7 +3805,7 @@ typedef struct camera_t {
vec2 last_look; vec3 last_move; // used for friction and damping vec2 last_look; vec3 last_move; // used for friction and damping
bool damping; bool damping;
bool orthographic; // 0 perspective, 1 orthographic; when ortho: dimetric[if pitch == -30o], isometric[if pitch == 35.264o] bool orthographic; // 0 perspective, 1 orthographic; when ortho: dimetric[if pitch == -30º], isometric[if pitch == 35.264º]
float distance; // distance to pivot, when orbiting float distance; // distance to pivot, when orbiting
// vec2 polarity = { +1,-1 }; // @todo // vec2 polarity = { +1,-1 }; // @todo
// vec2 sensitivity = { 2,2 }; // @todo // vec2 sensitivity = { 2,2 }; // @todo
@ -4002,7 +4005,7 @@ API array(char*) strsplit(const char *string, const char *delimiters);
/// > char *joint = strjoin(tokens, "+"); // joint="hello+world" /// > char *joint = strjoin(tokens, "+"); // joint="hello+world"
API char* strjoin(array(char*) list, const char *separator); API char* strjoin(array(char*) list, const char *separator);
API char * string8(const wchar_t *str); /// convert from wchar16(win) to utf8/ascii API char* string8(const wchar_t *str); /// convert from wchar16(win) to utf8/ascii
API array(uint32_t) string32( const char *utf8 ); /// convert from utf8 to utf32 API array(uint32_t) string32( const char *utf8 ); /// convert from utf8 to utf32
API const char* codepoint_to_utf8(unsigned cp); API const char* codepoint_to_utf8(unsigned cp);