[win32 build/link]

- Build milepost as a dynamic library
- Add import/export directives to public API symbols
- Change example build scripts accordingly
This commit is contained in:
martinfouilleul 2023-02-21 18:43:30 +01:00
parent dc2961f513
commit 665c63c3d0
20 changed files with 2529 additions and 2519 deletions

View File

@ -6,5 +6,6 @@ set glsl_shaders=src\glsl_shaders\common.glsl src\glsl_shaders\blit_vertex.glsl
call python3 scripts\embed_text.py %glsl_shaders% --prefix=glsl_ --output src\glsl_shaders.h call python3 scripts\embed_text.py %glsl_shaders% --prefix=glsl_ --output src\glsl_shaders.h
set INCLUDES=/I src /I src/util /I src/platform /I ext /I ext/angle_headers set INCLUDES=/I src /I src/util /I src/platform /I ext /I ext/angle_headers
cl /we4013 /Zi /Zc:preprocessor /std:c11 %INCLUDES% /c /Fo:bin/milepost.obj src/milepost.c set LIBS=user32.lib opengl32.lib gdi32.lib shcore.lib /LIBPATH:./bin libEGL.dll.lib libGLESv2.dll.lib
lib bin/milepost.obj /OUT:bin/milepost.lib
cl /we4013 /Zi /Zc:preprocessor /DMP_BUILD_DLL /std:c11 %INCLUDES% src/milepost.c /Fo:bin/milepost.o /LD /link %LIBS% /OUT:bin/milepost.dll /IMPLIB:bin/milepost.dll.lib

View File

@ -1,4 +1,4 @@
set INCLUDES=/I ..\..\src /I ..\..\src\util /I ..\..\src\platform /I ../../ext /I ../../ext/angle_headers set INCLUDES=/I ..\..\src /I ..\..\src\util /I ..\..\src\platform /I ../../ext /I ../../ext/angle_headers
cl /we4013 /Zi /Zc:preprocessor /std:c11 %INCLUDES% main.c /link /LIBPATH:../../bin milepost.lib user32.lib opengl32.lib gdi32.lib shcore.lib /out:../../bin/example_canvas.exe cl /we4013 /Zi /Zc:preprocessor /std:c11 %INCLUDES% main.c /link /LIBPATH:../../bin milepost.dll.lib /out:../../bin/example_canvas.exe

View File

@ -1,4 +1,4 @@
set INCLUDES=/I ..\..\src /I ..\..\src\util /I ..\..\src\platform /I ../../ext set INCLUDES=/I ..\..\src /I ..\..\src\util /I ..\..\src\platform /I ../../ext
cl /we4013 /Zi /Zc:preprocessor /std:c11 %INCLUDES% main.c /link /LIBPATH:../../bin milepost.lib user32.lib opengl32.lib gdi32.lib shcore.lib /out:../../bin/perf_text.exe cl /we4013 /Zi /Zc:preprocessor /std:c11 %INCLUDES% main.c /link /LIBPATH:../../bin milepost.dll.lib /out:../../bin/perf_text.exe

View File

@ -1,3 +1,3 @@
set INCLUDES=/I ..\..\src /I ..\..\src\util /I ..\..\src\platform /I ../../ext set INCLUDES=/I ..\..\src /I ..\..\src\util /I ..\..\src\platform /I ../../ext
cl /we4013 /Zi /Zc:preprocessor /DMG_IMPLEMENTS_BACKEND_GL /std:c11 %INCLUDES% main.c /link /LIBPATH:../../bin milepost.lib user32.lib opengl32.lib gdi32.lib shcore.lib /LIBPATH:../../bin libEGL.dll.lib libGLESv2.dll.lib /out:../../bin/example_gl_triangle.exe cl /we4013 /Zi /Zc:preprocessor /std:c11 %INCLUDES% main.c /link /LIBPATH:../../bin milepost.dll.lib /out:../../bin/example_gl_triangle.exe

View File

@ -1,3 +1,3 @@
set INCLUDES=/I ..\..\src /I ..\..\src\util /I ..\..\src\platform /I ../../ext /I ../../ext/angle_headers set INCLUDES=/I ..\..\src /I ..\..\src\util /I ..\..\src\platform /I ../../ext /I ../../ext/angle_headers
cl /we4013 /Zi /Zc:preprocessor /std:c11 %INCLUDES% main.c /link /LIBPATH:../../bin milepost.lib /LIBPATH:../../bin libEGL.dll.lib libGLESv2.dll.lib user32.lib opengl32.lib gdi32.lib shcore.lib /out:../../bin/example_gles_triangle.exe cl /we4013 /Zi /Zc:preprocessor /std:c11 %INCLUDES% main.c /link /LIBPATH:../../bin milepost.dll.lib /out:../../bin/example_gles_triangle.exe

View File

@ -96,12 +96,13 @@ for func in glall:
f.write('\t' + 'PFN' + func.upper() + 'PROC ' + remove_prefix(func, 'gl') + ';\n') f.write('\t' + 'PFN' + func.upper() + 'PROC ' + remove_prefix(func, 'gl') + ';\n')
f.write('} mg_gl_api;\n\n') f.write('} mg_gl_api;\n\n')
f.write('extern mp_thread_local mg_gl_api* __mgGLAPI;\n\n');
# generate interface macros # generate interface macros
# TODO guard for different api/versions and only #define functions present in desired version # TODO guard for different api/versions and only #define functions present in desired version
f.write("MP_API mg_gl_api* mg_gl_get_api(void);\n\n")
for func in glall: for func in glall:
f.write('#define ' + func + ' __mgGLAPI->' + remove_prefix(func, 'gl') + '\n') f.write('#define ' + func + ' mg_gl_get_api()->' + remove_prefix(func, 'gl') + '\n')
emit_end_guard(f, apiName) emit_end_guard(f, apiName)
f.close() f.close()
@ -124,8 +125,8 @@ f.write("void mg_gl_load_gl43(mg_gl_api* api, mg_gl_load_proc loadProc);\n")
f.write("void mg_gl_load_gles31(mg_gl_api* api, mg_gl_load_proc loadProc);\n") f.write("void mg_gl_load_gles31(mg_gl_api* api, mg_gl_load_proc loadProc);\n")
f.write("void mg_gl_load_gles32(mg_gl_api* api, mg_gl_load_proc loadProc);\n\n") f.write("void mg_gl_load_gles32(mg_gl_api* api, mg_gl_load_proc loadProc);\n\n")
f.write("void mg_gl_select_api(mg_gl_api* api);\n") f.write("void mg_gl_select_api(mg_gl_api* api);\n\n")
f.write("mg_gl_api* mg_gl_get_api(void);\n\n")
emit_end_guard(f, loaderName) emit_end_guard(f, loaderName)
f.close() f.close()

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
* *
* @file: gl_loader.c * @file: gl_loader.c
* @note: auto-generated by glapi.py from gl.xml * @note: auto-generated by glapi.py from gl.xml
* @date: 20/022023 * @date: 21/022023
* *
*********************************************************/ *********************************************************/
#include"gl_loader.h" #include"gl_loader.h"

View File

@ -2,7 +2,7 @@
* *
* @file: gl_loader.h * @file: gl_loader.h
* @note: auto-generated by glapi.py from gl.xml * @note: auto-generated by glapi.py from gl.xml
* @date: 20/022023 * @date: 21/022023
* *
*********************************************************/ *********************************************************/
#ifndef __GL_LOADER_H__ #ifndef __GL_LOADER_H__
@ -18,6 +18,5 @@ void mg_gl_load_gles31(mg_gl_api* api, mg_gl_load_proc loadProc);
void mg_gl_load_gles32(mg_gl_api* api, mg_gl_load_proc loadProc); void mg_gl_load_gles32(mg_gl_api* api, mg_gl_load_proc loadProc);
void mg_gl_select_api(mg_gl_api* api); void mg_gl_select_api(mg_gl_api* api);
mg_gl_api* mg_gl_get_api(void);
#endif // __GL_LOADER_H__ #endif // __GL_LOADER_H__

View File

@ -79,27 +79,27 @@ typedef enum {
//TODO: add MG_INCLUDE_OPENGL/GLES/etc, once we know how we make different gl versions co-exist //TODO: add MG_INCLUDE_OPENGL/GLES/etc, once we know how we make different gl versions co-exist
bool mg_is_surface_backend_available(mg_backend_id id); MP_API bool mg_is_surface_backend_available(mg_backend_id id);
bool mg_is_canvas_backend_available(mg_backend_id id); MP_API bool mg_is_canvas_backend_available(mg_backend_id id);
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
//NOTE(martin): graphics surface //NOTE(martin): graphics surface
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
typedef struct mg_surface { u64 h; } mg_surface; typedef struct mg_surface { u64 h; } mg_surface;
mg_surface mg_surface_nil(); MP_API mg_surface mg_surface_nil();
bool mg_surface_is_nil(mg_surface surface); MP_API bool mg_surface_is_nil(mg_surface surface);
mg_surface mg_surface_create_for_window(mp_window window, mg_backend_id backend); MP_API mg_surface mg_surface_create_for_window(mp_window window, mg_backend_id backend);
void mg_surface_destroy(mg_surface surface); MP_API void mg_surface_destroy(mg_surface surface);
void mg_surface_prepare(mg_surface surface); MP_API void mg_surface_prepare(mg_surface surface);
void mg_surface_present(mg_surface surface); MP_API void mg_surface_present(mg_surface surface);
void mg_surface_swap_interval(mg_surface surface, int swap); MP_API void mg_surface_swap_interval(mg_surface surface, int swap);
vec2 mg_surface_contents_scaling(mg_surface surface); MP_API vec2 mg_surface_contents_scaling(mg_surface surface);
mp_rect mg_surface_get_frame(mg_surface surface); MP_API mp_rect mg_surface_get_frame(mg_surface surface);
void mg_surface_set_frame(mg_surface surface, mp_rect frame); MP_API void mg_surface_set_frame(mg_surface surface, mp_rect frame);
bool mg_surface_get_hidden(mg_surface surface); MP_API bool mg_surface_get_hidden(mg_surface surface);
void mg_surface_set_hidden(mg_surface surface, bool hidden); MP_API void mg_surface_set_hidden(mg_surface surface, bool hidden);
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
@ -161,128 +161,128 @@ typedef struct mg_text_extents
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
//NOTE(martin): graphics canvas //NOTE(martin): graphics canvas
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
mg_canvas mg_canvas_nil(); MP_API mg_canvas mg_canvas_nil();
bool mg_canvas_is_nil(mg_canvas canvas); MP_API bool mg_canvas_is_nil(mg_canvas canvas);
mg_canvas mg_canvas_create(mg_surface surface); MP_API mg_canvas mg_canvas_create(mg_surface surface);
void mg_canvas_destroy(mg_canvas canvas); MP_API void mg_canvas_destroy(mg_canvas canvas);
mg_canvas mg_canvas_set_current(mg_canvas canvas); MP_API mg_canvas mg_canvas_set_current(mg_canvas canvas);
void mg_flush(); MP_API void mg_flush();
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
//NOTE(martin): transform, viewport and clipping //NOTE(martin): transform, viewport and clipping
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
void mg_viewport(mp_rect viewPort); MP_API void mg_viewport(mp_rect viewPort);
void mg_matrix_push(mg_mat2x3 matrix); MP_API void mg_matrix_push(mg_mat2x3 matrix);
void mg_matrix_pop(); MP_API void mg_matrix_pop();
void mg_clip_push(f32 x, f32 y, f32 w, f32 h); MP_API void mg_clip_push(f32 x, f32 y, f32 w, f32 h);
void mg_clip_pop(); MP_API void mg_clip_pop();
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
//NOTE(martin): graphics attributes setting/getting //NOTE(martin): graphics attributes setting/getting
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
void mg_set_color(mg_color color); MP_API void mg_set_color(mg_color color);
void mg_set_color_rgba(f32 r, f32 g, f32 b, f32 a); MP_API void mg_set_color_rgba(f32 r, f32 g, f32 b, f32 a);
void mg_set_width(f32 width); MP_API void mg_set_width(f32 width);
void mg_set_tolerance(f32 tolerance); MP_API void mg_set_tolerance(f32 tolerance);
void mg_set_joint(mg_joint_type joint); MP_API void mg_set_joint(mg_joint_type joint);
void mg_set_max_joint_excursion(f32 maxJointExcursion); MP_API void mg_set_max_joint_excursion(f32 maxJointExcursion);
void mg_set_cap(mg_cap_type cap); MP_API void mg_set_cap(mg_cap_type cap);
void mg_set_font(mg_font font); MP_API void mg_set_font(mg_font font);
void mg_set_font_size(f32 size); MP_API void mg_set_font_size(f32 size);
void mg_set_text_flip(bool flip); MP_API void mg_set_text_flip(bool flip);
mg_color mg_get_color(); MP_API mg_color mg_get_color();
f32 mg_get_width(); MP_API f32 mg_get_width();
f32 mg_get_tolerance(); MP_API f32 mg_get_tolerance();
mg_joint_type mg_get_joint(); MP_API mg_joint_type mg_get_joint();
f32 mg_get_max_joint_excursion(); MP_API f32 mg_get_max_joint_excursion();
mg_cap_type mg_get_cap(); MP_API mg_cap_type mg_get_cap();
mg_font mg_get_font(); MP_API mg_font mg_get_font();
f32 mg_get_font_size(); MP_API f32 mg_get_font_size();
bool mg_get_text_flip(); MP_API bool mg_get_text_flip();
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
//NOTE(martin): path construction //NOTE(martin): path construction
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
vec2 mg_get_position(); MP_API vec2 mg_get_position();
void mg_move_to(f32 x, f32 y); MP_API void mg_move_to(f32 x, f32 y);
void mg_line_to(f32 x, f32 y); MP_API void mg_line_to(f32 x, f32 y);
void mg_quadratic_to(f32 x1, f32 y1, f32 x2, f32 y2); MP_API void mg_quadratic_to(f32 x1, f32 y1, f32 x2, f32 y2);
void mg_cubic_to(f32 x1, f32 y1, f32 x2, f32 y2, f32 x3, f32 y3); MP_API void mg_cubic_to(f32 x1, f32 y1, f32 x2, f32 y2, f32 x3, f32 y3);
void mg_close_path(); MP_API void mg_close_path();
mp_rect mg_glyph_outlines(str32 glyphIndices); MP_API mp_rect mg_glyph_outlines(str32 glyphIndices);
void mg_codepoints_outlines(str32 string); MP_API void mg_codepoints_outlines(str32 string);
void mg_text_outlines(str8 string); MP_API void mg_text_outlines(str8 string);
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
//NOTE(martin): clear/fill/stroke //NOTE(martin): clear/fill/stroke
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
void mg_clear(); MP_API void mg_clear();
void mg_fill(); MP_API void mg_fill();
void mg_stroke(); MP_API void mg_stroke();
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
//NOTE(martin): 'fast' shapes primitives //NOTE(martin): 'fast' shapes primitives
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
void mg_rectangle_fill(f32 x, f32 y, f32 w, f32 h); MP_API void mg_rectangle_fill(f32 x, f32 y, f32 w, f32 h);
void mg_rectangle_stroke(f32 x, f32 y, f32 w, f32 h); MP_API void mg_rectangle_stroke(f32 x, f32 y, f32 w, f32 h);
void mg_rounded_rectangle_fill(f32 x, f32 y, f32 w, f32 h, f32 r); MP_API void mg_rounded_rectangle_fill(f32 x, f32 y, f32 w, f32 h, f32 r);
void mg_rounded_rectangle_stroke(f32 x, f32 y, f32 w, f32 h, f32 r); MP_API void mg_rounded_rectangle_stroke(f32 x, f32 y, f32 w, f32 h, f32 r);
void mg_ellipse_fill(f32 x, f32 y, f32 rx, f32 ry); MP_API void mg_ellipse_fill(f32 x, f32 y, f32 rx, f32 ry);
void mg_ellipse_stroke(f32 x, f32 y, f32 rx, f32 ry); MP_API void mg_ellipse_stroke(f32 x, f32 y, f32 rx, f32 ry);
void mg_circle_fill(f32 x, f32 y, f32 r); MP_API void mg_circle_fill(f32 x, f32 y, f32 r);
void mg_circle_stroke(f32 x, f32 y, f32 r); MP_API void mg_circle_stroke(f32 x, f32 y, f32 r);
void mg_arc(f32 x, f32 y, f32 r, f32 arcAngle, f32 startAngle); MP_API void mg_arc(f32 x, f32 y, f32 r, f32 arcAngle, f32 startAngle);
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
//NOTE(martin): fonts //NOTE(martin): fonts
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
mg_font mg_font_nil(); MP_API mg_font mg_font_nil();
mg_font mg_font_create_from_memory(u32 size, byte* buffer, u32 rangeCount, unicode_range* ranges); MP_API mg_font mg_font_create_from_memory(u32 size, byte* buffer, u32 rangeCount, unicode_range* ranges);
void mg_font_destroy(mg_font font); MP_API void mg_font_destroy(mg_font font);
//NOTE(martin): the following int valued functions return -1 if font is invalid or codepoint is not present in font// //NOTE(martin): the following int valued functions return -1 if font is invalid or codepoint is not present in font//
//TODO(martin): add enum error codes //TODO(martin): add enum error codes
mg_font_extents mg_font_get_extents(mg_font font); MP_API mg_font_extents mg_font_get_extents(mg_font font);
mg_font_extents mg_font_get_scaled_extents(mg_font font, f32 emSize); MP_API mg_font_extents mg_font_get_scaled_extents(mg_font font, f32 emSize);
f32 mg_font_get_scale_for_em_pixels(mg_font font, f32 emSize); MP_API f32 mg_font_get_scale_for_em_pixels(mg_font font, f32 emSize);
//NOTE(martin): if you need to process more than one codepoint, first convert your codepoints to glyph indices, then use the //NOTE(martin): if you need to process more than one codepoint, first convert your codepoints to glyph indices, then use the
// glyph index versions of the functions, which can take an array of glyph indices. // glyph index versions of the functions, which can take an array of glyph indices.
str32 mg_font_get_glyph_indices(mg_font font, str32 codePoints, str32 backing); MP_API str32 mg_font_get_glyph_indices(mg_font font, str32 codePoints, str32 backing);
str32 mg_font_push_glyph_indices(mg_font font, mem_arena* arena, str32 codePoints); MP_API str32 mg_font_push_glyph_indices(mg_font font, mem_arena* arena, str32 codePoints);
u32 mg_font_get_glyph_index(mg_font font, utf32 codePoint); MP_API u32 mg_font_get_glyph_index(mg_font font, utf32 codePoint);
int mg_font_get_codepoint_extents(mg_font font, utf32 codePoint, mg_text_extents* outExtents); MP_API int mg_font_get_codepoint_extents(mg_font font, utf32 codePoint, mg_text_extents* outExtents);
int mg_font_get_glyph_extents(mg_font font, str32 glyphIndices, mg_text_extents* outExtents); MP_API int mg_font_get_glyph_extents(mg_font font, str32 glyphIndices, mg_text_extents* outExtents);
mp_rect mg_text_bounding_box_utf32(mg_font font, f32 fontSize, str32 text); MP_API mp_rect mg_text_bounding_box_utf32(mg_font font, f32 fontSize, str32 text);
mp_rect mg_text_bounding_box(mg_font font, f32 fontSize, str8 text); MP_API mp_rect mg_text_bounding_box(mg_font font, f32 fontSize, str8 text);
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
//NOTE(martin): images //NOTE(martin): images
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
typedef struct mg_image { u64 h; } mg_image; typedef struct mg_image { u64 h; } mg_image;
mg_image mg_image_nil(); MP_API mg_image mg_image_nil();
bool mg_image_equal(mg_image a, mg_image b); MP_API bool mg_image_equal(mg_image a, mg_image b);
mg_image mg_image_create_from_rgba8(u32 width, u32 height, u8* pixels); MP_API mg_image mg_image_create_from_rgba8(u32 width, u32 height, u8* pixels);
mg_image mg_image_create_from_data(str8 data, bool flip); MP_API mg_image mg_image_create_from_data(str8 data, bool flip);
mg_image mg_image_create_from_file(str8 path, bool flip); MP_API mg_image mg_image_create_from_file(str8 path, bool flip);
void mg_image_drestroy(mg_image image); MP_API void mg_image_drestroy(mg_image image);
vec2 mg_image_size(mg_image image); MP_API vec2 mg_image_size(mg_image image);
void mg_image_draw(mg_image image, mp_rect rect); MP_API void mg_image_draw(mg_image image, mp_rect rect);
void mg_rounded_image_draw(mg_image image, mp_rect rect, f32 roundness); MP_API void mg_rounded_image_draw(mg_image image, mp_rect rect, f32 roundness);
#endif //__GRAPHICS_H_ #endif //__GRAPHICS_H_

View File

@ -1,398 +1,398 @@
/************************************************************//** /************************************************************//**
* *
* @file: platform_app.h * @file: platform_app.h
* @author: Martin Fouilleul * @author: Martin Fouilleul
* @date: 16/05/2020 * @date: 16/05/2020
* @revision: * @revision:
* *
*****************************************************************/ *****************************************************************/
#ifndef __PLATFORM_APP_H_ #ifndef __PLATFORM_APP_H_
#define __PLATFORM_APP_H_ #define __PLATFORM_APP_H_
#include"typedefs.h" #include"typedefs.h"
#include"utf8.h" #include"utf8.h"
#include"lists.h" #include"lists.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// Typedefs, enums and constants // Typedefs, enums and constants
//-------------------------------------------------------------------- //--------------------------------------------------------------------
typedef struct mp_window { u64 h; } mp_window; typedef struct mp_window { u64 h; } mp_window;
typedef enum { MP_MOUSE_CURSOR_ARROW, typedef enum { MP_MOUSE_CURSOR_ARROW,
MP_MOUSE_CURSOR_RESIZE_0, MP_MOUSE_CURSOR_RESIZE_0,
MP_MOUSE_CURSOR_RESIZE_90, MP_MOUSE_CURSOR_RESIZE_90,
MP_MOUSE_CURSOR_RESIZE_45, MP_MOUSE_CURSOR_RESIZE_45,
MP_MOUSE_CURSOR_RESIZE_135, MP_MOUSE_CURSOR_RESIZE_135,
MP_MOUSE_CURSOR_TEXT } mp_mouse_cursor; MP_MOUSE_CURSOR_TEXT } mp_mouse_cursor;
typedef i32 mp_window_style; typedef i32 mp_window_style;
static const mp_window_style MP_WINDOW_STYLE_NO_TITLE = 0x01<<0, static const mp_window_style MP_WINDOW_STYLE_NO_TITLE = 0x01<<0,
MP_WINDOW_STYLE_FIXED_SIZE = 0x01<<1, MP_WINDOW_STYLE_FIXED_SIZE = 0x01<<1,
MP_WINDOW_STYLE_NO_CLOSE = 0x01<<2, MP_WINDOW_STYLE_NO_CLOSE = 0x01<<2,
MP_WINDOW_STYLE_NO_MINIFY = 0x01<<3, MP_WINDOW_STYLE_NO_MINIFY = 0x01<<3,
MP_WINDOW_STYLE_NO_FOCUS = 0x01<<4, MP_WINDOW_STYLE_NO_FOCUS = 0x01<<4,
MP_WINDOW_STYLE_FLOAT = 0x01<<5, MP_WINDOW_STYLE_FLOAT = 0x01<<5,
MP_WINDOW_STYLE_POPUPMENU = 0x01<<6, MP_WINDOW_STYLE_POPUPMENU = 0x01<<6,
MP_WINDOW_STYLE_NO_BUTTONS = 0x01<<7; MP_WINDOW_STYLE_NO_BUTTONS = 0x01<<7;
typedef enum { MP_EVENT_NONE, typedef enum { MP_EVENT_NONE,
MP_EVENT_KEYBOARD_MODS, //TODO: remove, keep only key? MP_EVENT_KEYBOARD_MODS, //TODO: remove, keep only key?
MP_EVENT_KEYBOARD_KEY, MP_EVENT_KEYBOARD_KEY,
MP_EVENT_KEYBOARD_CHAR, MP_EVENT_KEYBOARD_CHAR,
MP_EVENT_MOUSE_BUTTON, MP_EVENT_MOUSE_BUTTON,
MP_EVENT_MOUSE_MOVE, MP_EVENT_MOUSE_MOVE,
MP_EVENT_MOUSE_WHEEL, MP_EVENT_MOUSE_WHEEL,
MP_EVENT_MOUSE_ENTER, MP_EVENT_MOUSE_ENTER,
MP_EVENT_MOUSE_LEAVE, MP_EVENT_MOUSE_LEAVE,
MP_EVENT_WINDOW_RESIZE, MP_EVENT_WINDOW_RESIZE,
MP_EVENT_WINDOW_MOVE, MP_EVENT_WINDOW_MOVE,
MP_EVENT_WINDOW_FOCUS, MP_EVENT_WINDOW_FOCUS,
MP_EVENT_WINDOW_UNFOCUS, MP_EVENT_WINDOW_UNFOCUS,
MP_EVENT_WINDOW_HIDE, // rename to minimize? MP_EVENT_WINDOW_HIDE, // rename to minimize?
MP_EVENT_WINDOW_SHOW, // rename to restore? MP_EVENT_WINDOW_SHOW, // rename to restore?
MP_EVENT_WINDOW_CLOSE, MP_EVENT_WINDOW_CLOSE,
MP_EVENT_PATHDROP, MP_EVENT_PATHDROP,
MP_EVENT_FRAME, MP_EVENT_FRAME,
MP_EVENT_QUIT } mp_event_type; MP_EVENT_QUIT } mp_event_type;
typedef enum { MP_KEY_NO_ACTION, typedef enum { MP_KEY_NO_ACTION,
MP_KEY_PRESS, MP_KEY_PRESS,
MP_KEY_RELEASE, MP_KEY_RELEASE,
MP_KEY_REPEAT } mp_key_action; MP_KEY_REPEAT } mp_key_action;
typedef enum { MP_KEY_UNKNOWN = 0, typedef enum { MP_KEY_UNKNOWN = 0,
MP_KEY_SPACE = 32, MP_KEY_SPACE = 32,
MP_KEY_APOSTROPHE = 39, /* ' */ MP_KEY_APOSTROPHE = 39, /* ' */
MP_KEY_COMMA = 44, /* , */ MP_KEY_COMMA = 44, /* , */
MP_KEY_MINUS = 45, // - MP_KEY_MINUS = 45, // -
MP_KEY_PERIOD = 46, // . MP_KEY_PERIOD = 46, // .
MP_KEY_SLASH = 47, // / MP_KEY_SLASH = 47, // /
MP_KEY_0 = 48, MP_KEY_0 = 48,
MP_KEY_1 = 49, MP_KEY_1 = 49,
MP_KEY_2 = 50, MP_KEY_2 = 50,
MP_KEY_3 = 51, MP_KEY_3 = 51,
MP_KEY_4 = 52, MP_KEY_4 = 52,
MP_KEY_5 = 53, MP_KEY_5 = 53,
MP_KEY_6 = 54, MP_KEY_6 = 54,
MP_KEY_7 = 55, MP_KEY_7 = 55,
MP_KEY_8 = 56, MP_KEY_8 = 56,
MP_KEY_9 = 57, MP_KEY_9 = 57,
MP_KEY_SEMICOLON = 59, // ; MP_KEY_SEMICOLON = 59, // ;
MP_KEY_EQUAL = 61, // = MP_KEY_EQUAL = 61, // =
MP_KEY_A = 65, MP_KEY_A = 65,
MP_KEY_B = 66, MP_KEY_B = 66,
MP_KEY_C = 67, MP_KEY_C = 67,
MP_KEY_D = 68, MP_KEY_D = 68,
MP_KEY_E = 69, MP_KEY_E = 69,
MP_KEY_F = 70, MP_KEY_F = 70,
MP_KEY_G = 71, MP_KEY_G = 71,
MP_KEY_H = 72, MP_KEY_H = 72,
MP_KEY_I = 73, MP_KEY_I = 73,
MP_KEY_J = 74, MP_KEY_J = 74,
MP_KEY_K = 75, MP_KEY_K = 75,
MP_KEY_L = 76, MP_KEY_L = 76,
MP_KEY_M = 77, MP_KEY_M = 77,
MP_KEY_N = 78, MP_KEY_N = 78,
MP_KEY_O = 79, MP_KEY_O = 79,
MP_KEY_P = 80, MP_KEY_P = 80,
MP_KEY_Q = 81, MP_KEY_Q = 81,
MP_KEY_R = 82, MP_KEY_R = 82,
MP_KEY_S = 83, MP_KEY_S = 83,
MP_KEY_T = 84, MP_KEY_T = 84,
MP_KEY_U = 85, MP_KEY_U = 85,
MP_KEY_V = 86, MP_KEY_V = 86,
MP_KEY_W = 87, MP_KEY_W = 87,
MP_KEY_X = 88, MP_KEY_X = 88,
MP_KEY_Y = 89, MP_KEY_Y = 89,
MP_KEY_Z = 90, MP_KEY_Z = 90,
MP_KEY_LEFT_BRACKET = 91, // [ MP_KEY_LEFT_BRACKET = 91, // [
MP_KEY_BACKSLASH = 92, // \ */ MP_KEY_BACKSLASH = 92, // \ */
MP_KEY_RIGHT_BRACKET = 93, // ] MP_KEY_RIGHT_BRACKET = 93, // ]
MP_KEY_GRAVE_ACCENT = 96, // ` MP_KEY_GRAVE_ACCENT = 96, // `
MP_KEY_WORLD_1 = 161, // non-US #1 MP_KEY_WORLD_1 = 161, // non-US #1
MP_KEY_WORLD_2 = 162, // non-US #2 MP_KEY_WORLD_2 = 162, // non-US #2
MP_KEY_ESCAPE = 256, MP_KEY_ESCAPE = 256,
MP_KEY_ENTER = 257, MP_KEY_ENTER = 257,
MP_KEY_TAB = 258, MP_KEY_TAB = 258,
MP_KEY_BACKSPACE = 259, MP_KEY_BACKSPACE = 259,
MP_KEY_INSERT = 260, MP_KEY_INSERT = 260,
MP_KEY_DELETE = 261, MP_KEY_DELETE = 261,
MP_KEY_RIGHT = 262, MP_KEY_RIGHT = 262,
MP_KEY_LEFT = 263, MP_KEY_LEFT = 263,
MP_KEY_DOWN = 264, MP_KEY_DOWN = 264,
MP_KEY_UP = 265, MP_KEY_UP = 265,
MP_KEY_PAGE_UP = 266, MP_KEY_PAGE_UP = 266,
MP_KEY_PAGE_DOWN = 267, MP_KEY_PAGE_DOWN = 267,
MP_KEY_HOME = 268, MP_KEY_HOME = 268,
MP_KEY_END = 269, MP_KEY_END = 269,
MP_KEY_CAPS_LOCK = 280, MP_KEY_CAPS_LOCK = 280,
MP_KEY_SCROLL_LOCK = 281, MP_KEY_SCROLL_LOCK = 281,
MP_KEY_NUM_LOCK = 282, MP_KEY_NUM_LOCK = 282,
MP_KEY_PRINT_SCREEN = 283, MP_KEY_PRINT_SCREEN = 283,
MP_KEY_PAUSE = 284, MP_KEY_PAUSE = 284,
MP_KEY_F1 = 290, MP_KEY_F1 = 290,
MP_KEY_F2 = 291, MP_KEY_F2 = 291,
MP_KEY_F3 = 292, MP_KEY_F3 = 292,
MP_KEY_F4 = 293, MP_KEY_F4 = 293,
MP_KEY_F5 = 294, MP_KEY_F5 = 294,
MP_KEY_F6 = 295, MP_KEY_F6 = 295,
MP_KEY_F7 = 296, MP_KEY_F7 = 296,
MP_KEY_F8 = 297, MP_KEY_F8 = 297,
MP_KEY_F9 = 298, MP_KEY_F9 = 298,
MP_KEY_F10 = 299, MP_KEY_F10 = 299,
MP_KEY_F11 = 300, MP_KEY_F11 = 300,
MP_KEY_F12 = 301, MP_KEY_F12 = 301,
MP_KEY_F13 = 302, MP_KEY_F13 = 302,
MP_KEY_F14 = 303, MP_KEY_F14 = 303,
MP_KEY_F15 = 304, MP_KEY_F15 = 304,
MP_KEY_F16 = 305, MP_KEY_F16 = 305,
MP_KEY_F17 = 306, MP_KEY_F17 = 306,
MP_KEY_F18 = 307, MP_KEY_F18 = 307,
MP_KEY_F19 = 308, MP_KEY_F19 = 308,
MP_KEY_F20 = 309, MP_KEY_F20 = 309,
MP_KEY_F21 = 310, MP_KEY_F21 = 310,
MP_KEY_F22 = 311, MP_KEY_F22 = 311,
MP_KEY_F23 = 312, MP_KEY_F23 = 312,
MP_KEY_F24 = 313, MP_KEY_F24 = 313,
MP_KEY_F25 = 314, MP_KEY_F25 = 314,
MP_KEY_KP_0 = 320, MP_KEY_KP_0 = 320,
MP_KEY_KP_1 = 321, MP_KEY_KP_1 = 321,
MP_KEY_KP_2 = 322, MP_KEY_KP_2 = 322,
MP_KEY_KP_3 = 323, MP_KEY_KP_3 = 323,
MP_KEY_KP_4 = 324, MP_KEY_KP_4 = 324,
MP_KEY_KP_5 = 325, MP_KEY_KP_5 = 325,
MP_KEY_KP_6 = 326, MP_KEY_KP_6 = 326,
MP_KEY_KP_7 = 327, MP_KEY_KP_7 = 327,
MP_KEY_KP_8 = 328, MP_KEY_KP_8 = 328,
MP_KEY_KP_9 = 329, MP_KEY_KP_9 = 329,
MP_KEY_KP_DECIMAL = 330, MP_KEY_KP_DECIMAL = 330,
MP_KEY_KP_DIVIDE = 331, MP_KEY_KP_DIVIDE = 331,
MP_KEY_KP_MULTIPLY = 332, MP_KEY_KP_MULTIPLY = 332,
MP_KEY_KP_SUBTRACT = 333, MP_KEY_KP_SUBTRACT = 333,
MP_KEY_KP_ADD = 334, MP_KEY_KP_ADD = 334,
MP_KEY_KP_ENTER = 335, MP_KEY_KP_ENTER = 335,
MP_KEY_KP_EQUAL = 336, MP_KEY_KP_EQUAL = 336,
MP_KEY_LEFT_SHIFT = 340, MP_KEY_LEFT_SHIFT = 340,
MP_KEY_LEFT_CONTROL = 341, MP_KEY_LEFT_CONTROL = 341,
MP_KEY_LEFT_ALT = 342, MP_KEY_LEFT_ALT = 342,
MP_KEY_LEFT_SUPER = 343, MP_KEY_LEFT_SUPER = 343,
MP_KEY_RIGHT_SHIFT = 344, MP_KEY_RIGHT_SHIFT = 344,
MP_KEY_RIGHT_CONTROL = 345, MP_KEY_RIGHT_CONTROL = 345,
MP_KEY_RIGHT_ALT = 346, MP_KEY_RIGHT_ALT = 346,
MP_KEY_RIGHT_SUPER = 347, MP_KEY_RIGHT_SUPER = 347,
MP_KEY_MENU = 348, MP_KEY_MENU = 348,
MP_KEY_COUNT } mp_key_code; MP_KEY_COUNT } mp_key_code;
typedef enum { typedef enum {
MP_KEYMOD_NONE = 0x00, MP_KEYMOD_NONE = 0x00,
MP_KEYMOD_ALT = 0x01, MP_KEYMOD_ALT = 0x01,
MP_KEYMOD_SHIFT = 0x02, MP_KEYMOD_SHIFT = 0x02,
MP_KEYMOD_CTRL = 0x04, MP_KEYMOD_CTRL = 0x04,
MP_KEYMOD_CMD = 0x08 } mp_key_mods; MP_KEYMOD_CMD = 0x08 } mp_key_mods;
typedef enum { typedef enum {
MP_MOUSE_LEFT = 0x00, MP_MOUSE_LEFT = 0x00,
MP_MOUSE_RIGHT = 0x01, MP_MOUSE_RIGHT = 0x01,
MP_MOUSE_MIDDLE = 0x02, MP_MOUSE_MIDDLE = 0x02,
MP_MOUSE_EXT1 = 0x03, MP_MOUSE_EXT1 = 0x03,
MP_MOUSE_EXT2 = 0x04, MP_MOUSE_EXT2 = 0x04,
MP_MOUSE_BUTTON_COUNT } mp_mouse_button; MP_MOUSE_BUTTON_COUNT } mp_mouse_button;
typedef struct mp_key_event // keyboard and mouse buttons input typedef struct mp_key_event // keyboard and mouse buttons input
{ {
mp_key_action action; mp_key_action action;
i32 code; i32 code;
mp_key_mods mods; mp_key_mods mods;
char label[8]; char label[8];
u8 labelLen; u8 labelLen;
int clickCount; int clickCount;
} mp_key_event; } mp_key_event;
typedef struct mp_char_event // character input typedef struct mp_char_event // character input
{ {
utf32 codepoint; utf32 codepoint;
char sequence[8]; char sequence[8];
u8 seqLen; u8 seqLen;
} mp_char_event; } mp_char_event;
typedef struct mp_move_event // mouse move/scroll typedef struct mp_move_event // mouse move/scroll
{ {
f32 x; f32 x;
f32 y; f32 y;
f32 deltaX; f32 deltaX;
f32 deltaY; f32 deltaY;
mp_key_mods mods; mp_key_mods mods;
} mp_move_event; } mp_move_event;
typedef struct mp_frame_event // window resize / move typedef struct mp_frame_event // window resize / move
{ {
mp_rect rect; mp_rect rect;
} mp_frame_event; } mp_frame_event;
typedef struct mp_event typedef struct mp_event
{ {
//TODO clipboard and path drop //TODO clipboard and path drop
mp_window window; mp_window window;
mp_event_type type; mp_event_type type;
union union
{ {
mp_key_event key; mp_key_event key;
mp_char_event character; mp_char_event character;
mp_move_event move; mp_move_event move;
mp_frame_event frame; mp_frame_event frame;
str8 path; str8 path;
}; };
//TODO(martin): chain externally ? //TODO(martin): chain externally ?
list_elt list; list_elt list;
} mp_event; } mp_event;
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// app management // app management
//-------------------------------------------------------------------- //--------------------------------------------------------------------
void mp_init(); MP_API void mp_init(void);
void mp_terminate(); MP_API void mp_terminate(void);
bool mp_should_quit(); MP_API bool mp_should_quit(void);
void mp_cancel_quit(); MP_API void mp_cancel_quit(void);
void mp_request_quit(); MP_API void mp_request_quit(void);
void mp_set_cursor(mp_mouse_cursor cursor); MP_API void mp_set_cursor(mp_mouse_cursor cursor);
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// Main loop and events handling // Main loop and events handling
//-------------------------------------------------------------------- //--------------------------------------------------------------------
void mp_pump_events(f64 timeout); MP_API void mp_pump_events(f64 timeout);
bool mp_next_event(mp_event* event); MP_API bool mp_next_event(mp_event* event);
typedef void(*mp_live_resize_callback)(mp_event event, void* data); typedef void(*mp_live_resize_callback)(mp_event event, void* data);
void mp_set_live_resize_callback(mp_live_resize_callback callback, void* data); MP_API void mp_set_live_resize_callback(mp_live_resize_callback callback, void* data);
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// window management // window management
//-------------------------------------------------------------------- //--------------------------------------------------------------------
bool mp_window_handle_is_null(mp_window window); MP_API bool mp_window_handle_is_null(mp_window window);
mp_window mp_window_null_handle(); MP_API mp_window mp_window_null_handle(void);
mp_window mp_window_create(mp_rect contentRect, const char* title, mp_window_style style); MP_API mp_window mp_window_create(mp_rect contentRect, const char* title, mp_window_style style);
void mp_window_destroy(mp_window window); MP_API void mp_window_destroy(mp_window window);
void* mp_window_native_pointer(mp_window window); MP_API void* mp_window_native_pointer(mp_window window);
bool mp_window_should_close(mp_window window); MP_API bool mp_window_should_close(mp_window window);
void mp_window_request_close(mp_window window); MP_API void mp_window_request_close(mp_window window);
void mp_window_cancel_close(mp_window window); MP_API void mp_window_cancel_close(mp_window window);
bool mp_window_is_hidden(mp_window window); MP_API bool mp_window_is_hidden(mp_window window);
void mp_window_hide(mp_window window); MP_API void mp_window_hide(mp_window window);
void mp_window_show(mp_window window); MP_API void mp_window_show(mp_window window);
bool mp_window_is_minimized(mp_window window); MP_API bool mp_window_is_minimized(mp_window window);
bool mp_window_is_maximized(mp_window window); MP_API bool mp_window_is_maximized(mp_window window);
void mp_window_minimize(mp_window window); MP_API void mp_window_minimize(mp_window window);
void mp_window_maximize(mp_window window); MP_API void mp_window_maximize(mp_window window);
void mp_window_restore(mp_window window); MP_API void mp_window_restore(mp_window window);
bool mp_window_has_focus(mp_window window); MP_API bool mp_window_has_focus(mp_window window);
void mp_window_focus(mp_window window); MP_API void mp_window_focus(mp_window window);
void mp_window_unfocus(mp_window window); MP_API void mp_window_unfocus(mp_window window);
void mp_window_send_to_back(mp_window window); MP_API void mp_window_send_to_back(mp_window window);
void mp_window_bring_to_front(mp_window window); MP_API void mp_window_bring_to_front(mp_window window);
mp_rect mp_window_get_content_rect(mp_window window); MP_API mp_rect mp_window_get_content_rect(mp_window window);
mp_rect mp_window_get_frame_rect(mp_window window); MP_API mp_rect mp_window_get_frame_rect(mp_window window);
void mp_window_set_content_rect(mp_window window, mp_rect contentRect); MP_API void mp_window_set_content_rect(mp_window window, mp_rect contentRect);
void mp_window_set_frame_rect(mp_window window, mp_rect frameRect); MP_API void mp_window_set_frame_rect(mp_window window, mp_rect frameRect);
void mp_window_center(mp_window window); MP_API void mp_window_center(mp_window window);
mp_rect mp_window_content_rect_for_frame_rect(mp_rect frameRect, mp_window_style style); MP_API mp_rect mp_window_content_rect_for_frame_rect(mp_rect frameRect, mp_window_style style);
mp_rect mp_window_frame_rect_for_content_rect(mp_rect contentRect, mp_window_style style); MP_API mp_rect mp_window_frame_rect_for_content_rect(mp_rect contentRect, mp_window_style style);
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// Input state polling // Input state polling
//-------------------------------------------------------------------- //--------------------------------------------------------------------
bool mp_input_key_down(mp_key_code key); MP_API bool mp_input_key_down(mp_key_code key);
bool mp_input_key_pressed(mp_key_code key); MP_API bool mp_input_key_pressed(mp_key_code key);
bool mp_input_key_released(mp_key_code key); MP_API bool mp_input_key_released(mp_key_code key);
mp_key_mods mp_input_key_mods(); MP_API mp_key_mods mp_input_key_mods(void);
str8 mp_key_to_label(mp_key_code key); MP_API str8 mp_key_to_label(mp_key_code key);
mp_key_code mp_label_to_key(str8 label); MP_API mp_key_code mp_label_to_key(str8 label);
bool mp_input_mouse_down(mp_mouse_button button); MP_API bool mp_input_mouse_down(mp_mouse_button button);
bool mp_input_mouse_pressed(mp_mouse_button button); MP_API bool mp_input_mouse_pressed(mp_mouse_button button);
bool mp_input_mouse_released(mp_mouse_button button); MP_API bool mp_input_mouse_released(mp_mouse_button button);
bool mp_input_mouse_clicked(mp_mouse_button button); MP_API bool mp_input_mouse_clicked(mp_mouse_button button);
bool mp_input_mouse_double_clicked(mp_mouse_button button); MP_API bool mp_input_mouse_double_clicked(mp_mouse_button button);
vec2 mp_input_mouse_position(); MP_API vec2 mp_input_mouse_position(void);
vec2 mp_input_mouse_delta(); MP_API vec2 mp_input_mouse_delta(void);
vec2 mp_input_mouse_wheel(); MP_API vec2 mp_input_mouse_wheel(void);
str32 mp_input_text_utf32(mem_arena* arena); MP_API str32 mp_input_text_utf32(mem_arena* arena);
str8 mp_input_text_utf8(mem_arena* arena); MP_API str8 mp_input_text_utf8(mem_arena* arena);
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// Clipboard // Clipboard
//-------------------------------------------------------------------- //--------------------------------------------------------------------
void mp_clipboard_clear(); MP_API void mp_clipboard_clear(void);
void mp_clipboard_set_string(str8 string); MP_API void mp_clipboard_set_string(str8 string);
str8 mp_clipboard_get_string(mem_arena* arena); MP_API str8 mp_clipboard_get_string(mem_arena* arena);
str8 mp_clipboard_copy_string(str8 backing); MP_API str8 mp_clipboard_copy_string(str8 backing);
bool mp_clipboard_has_tag(const char* tag); MP_API bool mp_clipboard_has_tag(const char* tag);
void mp_clipboard_set_data_for_tag(const char* tag, str8 data); MP_API void mp_clipboard_set_data_for_tag(const char* tag, str8 data);
str8 mp_clipboard_get_data_for_tag(mem_arena* arena, const char* tag); MP_API str8 mp_clipboard_get_data_for_tag(mem_arena* arena, const char* tag);
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// native open/save/alert windows // native open/save/alert windows
//-------------------------------------------------------------------- //--------------------------------------------------------------------
str8 mp_open_dialog(mem_arena* arena, MP_API str8 mp_open_dialog(mem_arena* arena,
const char* title, const char* title,
const char* defaultPath, const char* defaultPath,
int filterCount, int filterCount,
const char** filters, const char** filters,
bool directory); bool directory);
str8 mp_save_dialog(mem_arena* arena, MP_API str8 mp_save_dialog(mem_arena* arena,
const char* title, const char* title,
const char* defaultPath, const char* defaultPath,
int filterCount, int filterCount,
const char** filters); const char** filters);
int mp_alert_popup(const char* title, MP_API int mp_alert_popup(const char* title,
const char* message, const char* message,
u32 count, u32 count,
const char** options); const char** options);
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// file system stuff... //TODO: move elsewhere // file system stuff... //TODO: move elsewhere
//-------------------------------------------------------------------- //--------------------------------------------------------------------
int mp_file_move(str8 from, str8 to); MP_API int mp_file_move(str8 from, str8 to);
int mp_file_remove(str8 path); MP_API int mp_file_remove(str8 path);
int mp_directory_create(str8 path); MP_API int mp_directory_create(str8 path);
str8 mp_app_get_resource_path(mem_arena* arena, const char* name); MP_API str8 mp_app_get_resource_path(mem_arena* arena, const char* name);
str8 mp_app_get_executable_path(mem_arena* arena); MP_API str8 mp_app_get_executable_path(mem_arena* arena);
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"
#endif #endif
#endif //__PLATFORM_APP_H_ #endif //__PLATFORM_APP_H_

View File

@ -1,85 +1,93 @@
//***************************************************************** //*****************************************************************
// //
// $file: platform.h $ // $file: platform.h $
// $author: Martin Fouilleul $ // $author: Martin Fouilleul $
// $date: 22/12/2022 $ // $date: 22/12/2022 $
// $revision: $ // $revision: $
// $note: (C) 2022 by Martin Fouilleul - all rights reserved $ // $note: (C) 2022 by Martin Fouilleul - all rights reserved $
// //
//***************************************************************** //*****************************************************************
#ifndef __PLATFORM_H_ #ifndef __PLATFORM_H_
#define __PLATFORM_H_ #define __PLATFORM_H_
//----------------------------------------------------------------- //-----------------------------------------------------------------
// Compiler identification // Compiler identification
//----------------------------------------------------------------- //-----------------------------------------------------------------
#if defined(__clang__) #if defined(__clang__)
#define COMPILER_CLANG 1 #define COMPILER_CLANG 1
#if defined(__apple_build_version__) #if defined(__apple_build_version__)
#define COMPILER_CLANG_APPLE 1 #define COMPILER_CLANG_APPLE 1
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
#define COMPILER_CLANG_CL 1 #define COMPILER_CLANG_CL 1
#endif #endif
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
#define COMPILER_CL 1 #define COMPILER_CL 1
#elif defined(__GNUC__) #elif defined(__GNUC__)
#define COMPILER_GCC 1 #define COMPILER_GCC 1
#else #else
#error "Can't identify compiler" #error "Can't identify compiler"
#endif #endif
//----------------------------------------------------------------- //-----------------------------------------------------------------
// OS identification // OS identification
//----------------------------------------------------------------- //-----------------------------------------------------------------
#if defined(_WIN64) #if defined(_WIN64)
#define OS_WIN64 1 #define OS_WIN64 1
#elif defined(_WIN32) #elif defined(_WIN32)
#error "Unsupported OS (32bit only version of Windows)" #error "Unsupported OS (32bit only version of Windows)"
#elif defined(__APPLE__) && defined(__MACH__) #elif defined(__APPLE__) && defined(__MACH__)
#define OS_MACOS 1 #define OS_MACOS 1
#elif defined(__gnu_linux__) #elif defined(__gnu_linux__)
#define OS_LINUX 1 #define OS_LINUX 1
#else #else
#error "Can't identify OS" #error "Can't identify OS"
#endif #endif
//----------------------------------------------------------------- //-----------------------------------------------------------------
// Architecture identification // Architecture identification
//----------------------------------------------------------------- //-----------------------------------------------------------------
#if defined(COMPILER_CL) #if defined(COMPILER_CL)
#if defined(_M_AMD64) #if defined(_M_AMD64)
#define ARCH_X64 1 #define ARCH_X64 1
#elif defined(_M_I86) #elif defined(_M_I86)
#define ARCH_X86 1 #define ARCH_X86 1
#elif defined(_M_ARM64) #elif defined(_M_ARM64)
#define ARCH_ARM64 1 #define ARCH_ARM64 1
#elif defined(_M_ARM) #elif defined(_M_ARM)
#define ARCH_ARM32 1 #define ARCH_ARM32 1
#else #else
#error "Can't identify architecture" #error "Can't identify architecture"
#endif #endif
#else #else
#if defined(__x86_64__) #if defined(__x86_64__)
#define ARCH_X64 1 #define ARCH_X64 1
#elif defined(__i386__) #elif defined(__i386__)
#define ARCH_X86 1 #define ARCH_X86 1
#elif defined(__arm__) #elif defined(__arm__)
#define ARCH_ARM32 1 #define ARCH_ARM32 1
#elif defined(__aarch64__) #elif defined(__aarch64__)
#define ARCH_ARM64 1 #define ARCH_ARM64 1
#else #else
#error "Can't identify architecture" #error "Can't identify architecture"
#endif #endif
#endif #endif
//----------------------------------------------------------------- //-----------------------------------------------------------------
// platform helper macros // platform helper macros
//----------------------------------------------------------------- //-----------------------------------------------------------------
#if defined(COMPILER_CL) #if defined(COMPILER_CL)
#define mp_thread_local __declspec(thread) #if defined(MP_BUILD_DLL)
#elif defined(COMPILER_GCC) || defined(COMPILER_CLANG) #define MP_API __declspec(dllexport)
#define mp_thread_local __thread #else
#endif #define MP_API __declspec(dllimport)
#endif
#endif // __PLATFORM_H_
#define mp_thread_local __declspec(thread)
#elif defined(COMPILER_GCC) || defined(COMPILER_CLANG)
#define MP_API
#define mp_thread_local __thread
#endif
#endif // __PLATFORM_H_

View File

@ -1,34 +1,34 @@
/************************************************************//** /************************************************************//**
* *
* @file: platform_clock.h * @file: platform_clock.h
* @author: Martin Fouilleul * @author: Martin Fouilleul
* @date: 07/03/2019 * @date: 07/03/2019
* @revision: * @revision:
* *
*****************************************************************/ *****************************************************************/
#ifndef __PLATFORM_CLOCK_H_ #ifndef __PLATFORM_CLOCK_H_
#define __PLATFORM_CLOCK_H_ #define __PLATFORM_CLOCK_H_
#include"typedefs.h" #include"typedefs.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif // __cplusplus #endif // __cplusplus
typedef enum { typedef enum {
MP_CLOCK_MONOTONIC, // clock that increment monotonically MP_CLOCK_MONOTONIC, // clock that increment monotonically
MP_CLOCK_UPTIME, // clock that increment monotonically during uptime MP_CLOCK_UPTIME, // clock that increment monotonically during uptime
MP_CLOCK_DATE // clock that is driven by the platform time MP_CLOCK_DATE // clock that is driven by the platform time
} mp_clock_kind; } mp_clock_kind;
void mp_clock_init(); // initialize the clock subsystem MP_API void mp_clock_init(); // initialize the clock subsystem
u64 mp_get_timestamp(mp_clock_kind clock); MP_API u64 mp_get_timestamp(mp_clock_kind clock);
f64 mp_get_time(mp_clock_kind clock); MP_API f64 mp_get_time(mp_clock_kind clock);
void mp_sleep_nanoseconds(u64 nanoseconds); // sleep for a given number of nanoseconds MP_API void mp_sleep_nanoseconds(u64 nanoseconds); // sleep for a given number of nanoseconds
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"
#endif // __cplusplus #endif // __cplusplus
#endif //__PLATFORM_CLOCK_H_ #endif //__PLATFORM_CLOCK_H_

View File

@ -1,97 +1,98 @@
/************************************************************//** /************************************************************//**
* *
* @file: debug_log.h * @file: debug_log.h
* @author: Martin Fouilleul * @author: Martin Fouilleul
* @date: 05/04/2019 * @date: 05/04/2019
* @revision: * @revision:
* *
*****************************************************************/ *****************************************************************/
#ifndef __DEBUG_LOG_H_ #ifndef __DEBUG_LOG_H_
#define __DEBUG_LOG_H_ #define __DEBUG_LOG_H_
#include<stdio.h> #include<stdio.h>
#include"typedefs.h" #include"platform.h"
#include"macro_helpers.h" #include"typedefs.h"
#include"macro_helpers.h"
#ifdef __cplusplus
extern "C" { #ifdef __cplusplus
#endif extern "C" {
//NOTE(martin): the default logging level can be adjusted by defining LOG_DEFAULT_LEVEL. As the name suggest, it is the default, but it #endif
// can be adjusted at runtime with LogLevel() //NOTE(martin): the default logging level can be adjusted by defining LOG_DEFAULT_LEVEL. As the name suggest, it is the default, but it
#ifndef LOG_DEFAULT_LEVEL // can be adjusted at runtime with LogLevel()
#define LOG_DEFAULT_LEVEL LOG_LEVEL_WARNING #ifndef LOG_DEFAULT_LEVEL
#endif #define LOG_DEFAULT_LEVEL LOG_LEVEL_WARNING
#endif
//NOTE(martin): the default output can be adjusted by defining LOG_DEFAULT_OUTPUT. It can be adjusted at runtime with LogOutput()
#ifndef LOG_DEFAULT_OUTPUT //NOTE(martin): the default output can be adjusted by defining LOG_DEFAULT_OUTPUT. It can be adjusted at runtime with LogOutput()
#define LOG_DEFAULT_OUTPUT stdout #ifndef LOG_DEFAULT_OUTPUT
#endif #define LOG_DEFAULT_OUTPUT stdout
#endif
//NOTE(martin): LOG_SUBSYSTEM can be defined in each compilation unit to associate it with a subsystem, like this:
// #define LOG_SUBSYSTEM "name" //NOTE(martin): LOG_SUBSYSTEM can be defined in each compilation unit to associate it with a subsystem, like this:
// #define LOG_SUBSYSTEM "name"
typedef enum { LOG_LEVEL_ERROR,
LOG_LEVEL_WARNING, typedef enum { LOG_LEVEL_ERROR,
LOG_LEVEL_MESSAGE, LOG_LEVEL_WARNING,
LOG_LEVEL_DEBUG, LOG_LEVEL_MESSAGE,
LOG_LEVEL_COUNT } log_level; LOG_LEVEL_DEBUG,
LOG_LEVEL_COUNT } log_level;
void LogGeneric(log_level level,
const char* subsystem, MP_API void LogGeneric(log_level level,
const char* functionName, const char* subsystem,
const char* fileName, const char* functionName,
u32 line, const char* fileName,
const char* msg, u32 line,
...); const char* msg,
...);
void LogOutput(FILE* output);
void LogLevel(log_level level); MP_API void LogOutput(FILE* output);
void LogFilter(const char* subsystem, log_level level); MP_API void LogLevel(log_level level);
MP_API void LogFilter(const char* subsystem, log_level level);
#define LOG_GENERIC(level, func, file, line, msg, ...) LogGeneric(level, LOG_SUBSYSTEM, func, file, line, msg, ##__VA_ARGS__ )
#define LOG_GENERIC(level, func, file, line, msg, ...) LogGeneric(level, LOG_SUBSYSTEM, func, file, line, msg, ##__VA_ARGS__ )
#define LOG_ERROR(msg, ...) LOG_GENERIC(LOG_LEVEL_ERROR, __FUNCTION__, __FILE__, __LINE__, msg, ##__VA_ARGS__ )
#define LOG_ERROR(msg, ...) LOG_GENERIC(LOG_LEVEL_ERROR, __FUNCTION__, __FILE__, __LINE__, msg, ##__VA_ARGS__ )
//NOTE(martin): warnings, messages, and debug info can be enabled in debug mode by defining LOG_COMPILE_XXX, XXX being the max desired log level
// error logging is always compiled //NOTE(martin): warnings, messages, and debug info can be enabled in debug mode by defining LOG_COMPILE_XXX, XXX being the max desired log level
#if defined(LOG_COMPILE_WARNING) || defined(LOG_COMPILE_MESSAGE) || defined(LOG_COMPILE_DEBUG) // error logging is always compiled
#define LOG_WARNING(msg, ...) LOG_GENERIC(LOG_LEVEL_WARNING, __FUNCTION__, __FILE__, __LINE__, msg, ##__VA_ARGS__ ) #if defined(LOG_COMPILE_WARNING) || defined(LOG_COMPILE_MESSAGE) || defined(LOG_COMPILE_DEBUG)
#define LOG_WARNING(msg, ...) LOG_GENERIC(LOG_LEVEL_WARNING, __FUNCTION__, __FILE__, __LINE__, msg, ##__VA_ARGS__ )
#if defined(LOG_COMPILE_MESSAGE) || defined(LOG_COMPILE_DEBUG)
#define LOG_MESSAGE(msg, ...) LOG_GENERIC(LOG_LEVEL_MESSAGE, __FUNCTION__, __FILE__, __LINE__, msg, ##__VA_ARGS__ ) #if defined(LOG_COMPILE_MESSAGE) || defined(LOG_COMPILE_DEBUG)
#define LOG_MESSAGE(msg, ...) LOG_GENERIC(LOG_LEVEL_MESSAGE, __FUNCTION__, __FILE__, __LINE__, msg, ##__VA_ARGS__ )
#if defined(LOG_COMPILE_DEBUG)
#define LOG_DEBUG(msg, ...) LOG_GENERIC(LOG_LEVEL_DEBUG, __FUNCTION__, __FILE__, __LINE__, msg, ##__VA_ARGS__ ) #if defined(LOG_COMPILE_DEBUG)
#else #define LOG_DEBUG(msg, ...) LOG_GENERIC(LOG_LEVEL_DEBUG, __FUNCTION__, __FILE__, __LINE__, msg, ##__VA_ARGS__ )
#define LOG_DEBUG(msg, ...) #else
#endif #define LOG_DEBUG(msg, ...)
#else #endif
#define LOG_MESSAGE(msg, ...) #else
#define LOG_DEBUG(msg, ...) #define LOG_MESSAGE(msg, ...)
#endif #define LOG_DEBUG(msg, ...)
#else #endif
#define LOG_WARNING(msg, ...) #else
#define LOG_MESSAGE(msg, ...) #define LOG_WARNING(msg, ...)
#define LOG_DEBUG(msg, ...) #define LOG_MESSAGE(msg, ...)
#endif #define LOG_DEBUG(msg, ...)
#endif
#ifndef NO_ASSERT
#include<assert.h> #ifndef NO_ASSERT
#define _ASSERT_(x, msg) assert(x && msg) #include<assert.h>
#define ASSERT(x, ...) _ASSERT_(x, #__VA_ARGS__) #define _ASSERT_(x, msg) assert(x && msg)
#define ASSERT(x, ...) _ASSERT_(x, #__VA_ARGS__)
#ifdef DEBUG
#define DEBUG_ASSERT(x, ...) ASSERT(x, ##__VA_ARGS__ ) #ifdef DEBUG
#else #define DEBUG_ASSERT(x, ...) ASSERT(x, ##__VA_ARGS__ )
#define DEBUG_ASSERT(x, ...) #else
#endif #define DEBUG_ASSERT(x, ...)
#else #endif
#define ASSERT(x, ...) #else
#define DEBUG_ASSERT(x, ...) #define ASSERT(x, ...)
#endif #define DEBUG_ASSERT(x, ...)
#endif
#ifdef __cplusplus
} // extern "C" #ifdef __cplusplus
#endif } // extern "C"
#endif
#endif //__DEBUG_LOG_H_
#endif //__DEBUG_LOG_H_

View File

@ -1,29 +1,29 @@
/************************************************************//** /************************************************************//**
* *
* @file: hash.h * @file: hash.h
* @author: Martin Fouilleul * @author: Martin Fouilleul
* @date: 08/08/2022 * @date: 08/08/2022
* @revision: * @revision:
* *
*****************************************************************/ *****************************************************************/
#ifndef __HASH_H_ #ifndef __HASH_H_
#define __HASH_H_ #define __HASH_H_
#include"typedefs.h" #include"typedefs.h"
#include"strings.h" #include"strings.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
u64 mp_hash_aes_u64(u64 x); MP_API u64 mp_hash_aes_u64(u64 x);
u64 mp_hash_aes_u64_x2(u64 x, u64 y); MP_API u64 mp_hash_aes_u64_x2(u64 x, u64 y);
u64 mp_hash_aes_string(str8 string); MP_API u64 mp_hash_aes_string(str8 string);
u64 mp_hash_aes_string_seed(str8 string, u64 seed); MP_API u64 mp_hash_aes_string_seed(str8 string, u64 seed);
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"
#endif #endif
#endif //__HASH_H_ #endif //__HASH_H_

View File

@ -1,106 +1,106 @@
/************************************************************//** /************************************************************//**
* *
* @file: memory.h * @file: memory.h
* @author: Martin Fouilleul * @author: Martin Fouilleul
* @date: 24/10/2019 * @date: 24/10/2019
* @revision: * @revision:
* *
*****************************************************************/ *****************************************************************/
#ifndef __MEMORY_H_ #ifndef __MEMORY_H_
#define __MEMORY_H_ #define __MEMORY_H_
#include"typedefs.h" #include"typedefs.h"
#include"lists.h" #include"lists.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------
//NOTE(martin): base allocator //NOTE(martin): base allocator
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------
typedef void*(*mem_reserve_function)(void* context, u64 size); typedef void*(*mem_reserve_function)(void* context, u64 size);
typedef void(*mem_modify_function)(void* context, void* ptr, u64 size); typedef void(*mem_modify_function)(void* context, void* ptr, u64 size);
typedef struct mem_base_allocator typedef struct mem_base_allocator
{ {
mem_reserve_function reserve; mem_reserve_function reserve;
mem_modify_function commit; mem_modify_function commit;
mem_modify_function decommit; mem_modify_function decommit;
mem_modify_function release; mem_modify_function release;
void* context; void* context;
} mem_base_allocator; } mem_base_allocator;
mem_base_allocator* mem_base_allocator_default(); MP_API mem_base_allocator* mem_base_allocator_default();
#define mem_base_reserve(base, size) base->reserve(base->context, size) #define mem_base_reserve(base, size) base->reserve(base->context, size)
#define mem_base_commit(base, ptr, size) base->commit(base->context, ptr, size) #define mem_base_commit(base, ptr, size) base->commit(base->context, ptr, size)
#define mem_base_decommit(base, ptr, size) base->decommit(base->context, ptr, size) #define mem_base_decommit(base, ptr, size) base->decommit(base->context, ptr, size)
#define mem_base_release(base, ptr, size) base->release(base->context, ptr, size) #define mem_base_release(base, ptr, size) base->release(base->context, ptr, size)
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------
//NOTE(martin): memory arena //NOTE(martin): memory arena
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------
typedef struct mem_arena typedef struct mem_arena
{ {
mem_base_allocator* base; mem_base_allocator* base;
char* ptr; char* ptr;
u64 offset; u64 offset;
u64 committed; u64 committed;
u64 cap; u64 cap;
} mem_arena; } mem_arena;
typedef struct mem_arena_options typedef struct mem_arena_options
{ {
mem_base_allocator* base; mem_base_allocator* base;
u64 reserve; u64 reserve;
} mem_arena_options; } mem_arena_options;
void mem_arena_init(mem_arena* arena); MP_API void mem_arena_init(mem_arena* arena);
void mem_arena_init_with_options(mem_arena* arena, mem_arena_options* options); MP_API void mem_arena_init_with_options(mem_arena* arena, mem_arena_options* options);
void mem_arena_release(mem_arena* arena); MP_API void mem_arena_release(mem_arena* arena);
void* mem_arena_alloc(mem_arena* arena, u64 size); MP_API void* mem_arena_alloc(mem_arena* arena, u64 size);
void mem_arena_clear(mem_arena* arena); MP_API void mem_arena_clear(mem_arena* arena);
#define mem_arena_alloc_type(arena, type) ((type*)mem_arena_alloc(arena, sizeof(type))) #define mem_arena_alloc_type(arena, type) ((type*)mem_arena_alloc(arena, sizeof(type)))
#define mem_arena_alloc_array(arena, type, count) ((type*)mem_arena_alloc(arena, sizeof(type)*(count))) #define mem_arena_alloc_array(arena, type, count) ((type*)mem_arena_alloc(arena, sizeof(type)*(count)))
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------
//NOTE(martin): memory pool //NOTE(martin): memory pool
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------
typedef struct mem_pool typedef struct mem_pool
{ {
mem_arena arena; mem_arena arena;
list_info freeList; list_info freeList;
u64 blockSize; u64 blockSize;
} mem_pool; } mem_pool;
typedef struct mem_pool_options typedef struct mem_pool_options
{ {
mem_base_allocator* base; mem_base_allocator* base;
u64 reserve; u64 reserve;
} mem_pool_options; } mem_pool_options;
void mem_pool_init(mem_pool* pool, u64 blockSize); MP_API void mem_pool_init(mem_pool* pool, u64 blockSize);
void mem_pool_init_with_options(mem_pool* pool, u64 blockSize, mem_pool_options* options); MP_API void mem_pool_init_with_options(mem_pool* pool, u64 blockSize, mem_pool_options* options);
void mem_pool_release(mem_pool* pool); MP_API void mem_pool_release(mem_pool* pool);
void* mem_pool_alloc(mem_pool* pool); MP_API void* mem_pool_alloc(mem_pool* pool);
void mem_pool_recycle(mem_pool* pool, void* ptr); MP_API void mem_pool_recycle(mem_pool* pool, void* ptr);
void mem_pool_clear(mem_pool* pool); MP_API void mem_pool_clear(mem_pool* pool);
#define mem_pool_alloc_type(arena, type) ((type*)mem_pool_alloc(arena)) #define mem_pool_alloc_type(arena, type) ((type*)mem_pool_alloc(arena))
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------
//NOTE(martin): per-thread implicit scratch arena //NOTE(martin): per-thread implicit scratch arena
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------
void mem_scratch_clear(); MP_API void mem_scratch_clear();
mem_arena* mem_scratch(); MP_API mem_arena* mem_scratch();
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"
#endif #endif
#endif //__MEMORY_H_ #endif //__MEMORY_H_

View File

@ -1,113 +1,113 @@
/************************************************************//** /************************************************************//**
* *
* @file: strings.h * @file: strings.h
* @author: Martin Fouilleul * @author: Martin Fouilleul
* @date: 29/05/2021 * @date: 29/05/2021
* @revision: * @revision:
* *
*****************************************************************/ *****************************************************************/
#ifndef __STRINGS_H_ #ifndef __STRINGS_H_
#define __STRINGS_H_ #define __STRINGS_H_
#include"typedefs.h" #include"typedefs.h"
#include"lists.h" #include"lists.h"
#include"memory.h" #include"memory.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// string slices as values // string slices as values
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
typedef struct str8 typedef struct str8
{ {
u64 len; u64 len;
char* ptr; char* ptr;
} str8; } str8;
#define str8_lit(s) ((str8){.len = sizeof(s)-1, .ptr = (char*)(s)}) #define str8_lit(s) ((str8){.len = sizeof(s)-1, .ptr = (char*)(s)})
#define str8_unbox(s) (int)((s).len), ((s).ptr) #define str8_unbox(s) (int)((s).len), ((s).ptr)
str8 str8_from_buffer(u64 len, char* buffer); MP_API str8 str8_from_buffer(u64 len, char* buffer);
str8 str8_from_cstring(char* str); MP_API str8 str8_from_cstring(char* str);
str8 str8_slice(str8 s, u64 start, u64 end); MP_API str8 str8_slice(str8 s, u64 start, u64 end);
str8 str8_push_buffer(mem_arena* arena, u64 len, char* buffer); MP_API str8 str8_push_buffer(mem_arena* arena, u64 len, char* buffer);
str8 str8_push_cstring(mem_arena* arena, const char* str); MP_API str8 str8_push_cstring(mem_arena* arena, const char* str);
str8 str8_push_copy(mem_arena* arena, str8 s); MP_API str8 str8_push_copy(mem_arena* arena, str8 s);
str8 str8_push_slice(mem_arena* arena, str8 s, u64 start, u64 end); MP_API str8 str8_push_slice(mem_arena* arena, str8 s, u64 start, u64 end);
str8 str8_pushfv(mem_arena* arena, const char* format, va_list args); MP_API str8 str8_pushfv(mem_arena* arena, const char* format, va_list args);
str8 str8_pushf(mem_arena* arena, const char* format, ...); MP_API str8 str8_pushf(mem_arena* arena, const char* format, ...);
int str8_cmp(str8 s1, str8 s2); MP_API int str8_cmp(str8 s1, str8 s2);
char* str8_to_cstring(mem_arena* arena, str8 string); MP_API char* str8_to_cstring(mem_arena* arena, str8 string);
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// string lists // string lists
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
typedef struct str8_elt typedef struct str8_elt
{ {
list_elt listElt; list_elt listElt;
str8 string; str8 string;
} str8_elt; } str8_elt;
typedef struct str8_list typedef struct str8_list
{ {
list_info list; list_info list;
u64 eltCount; u64 eltCount;
u64 len; u64 len;
} str8_list; } str8_list;
void str8_list_push(mem_arena* arena, str8_list* list, str8 str); MP_API void str8_list_push(mem_arena* arena, str8_list* list, str8 str);
void str8_list_pushf(mem_arena* arena, str8_list* list, const char* format, ...); MP_API void str8_list_pushf(mem_arena* arena, str8_list* list, const char* format, ...);
str8 str8_list_join(mem_arena* arena, str8_list list); MP_API str8 str8_list_join(mem_arena* arena, str8_list list);
str8_list str8_split(mem_arena* arena, str8 str, str8_list separators); MP_API str8_list str8_split(mem_arena* arena, str8 str, str8_list separators);
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// u32 strings // u32 strings
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
typedef struct str32 typedef struct str32
{ {
u64 len; u64 len;
u32* ptr; u32* ptr;
} str32; } str32;
str32 str32_from_buffer(u64 len, u32* buffer); MP_API str32 str32_from_buffer(u64 len, u32* buffer);
str32 str32_slice(str32 s, u64 start, u64 end); MP_API str32 str32_slice(str32 s, u64 start, u64 end);
str32 str32_push_buffer(mem_arena* arena, u64 len, u32* buffer); MP_API str32 str32_push_buffer(mem_arena* arena, u64 len, u32* buffer);
str32 str32_push_copy(mem_arena* arena, str32 s); MP_API str32 str32_push_copy(mem_arena* arena, str32 s);
str32 str32_push_slice(mem_arena* arena, str32 s, u64 start, u64 end); MP_API str32 str32_push_slice(mem_arena* arena, str32 s, u64 start, u64 end);
typedef struct str32_elt typedef struct str32_elt
{ {
list_elt listElt; list_elt listElt;
str32 string; str32 string;
} str32_elt; } str32_elt;
typedef struct str32_list typedef struct str32_list
{ {
list_info list; list_info list;
u64 eltCount; u64 eltCount;
u64 len; u64 len;
} str32_list; } str32_list;
void str32_list_push(mem_arena* arena, str32_list* list, str32 str); MP_API void str32_list_push(mem_arena* arena, str32_list* list, str32 str);
str32 str32_list_join(mem_arena* arena, str32_list list); MP_API str32 str32_list_join(mem_arena* arena, str32_list list);
str32_list str32_split(mem_arena* arena, str32 str, str32_list separators); MP_API str32_list str32_split(mem_arena* arena, str32 str, str32_list separators);
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Paths helpers // Paths helpers
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
str8 mp_path_directory(str8 fullPath); MP_API str8 mp_path_directory(str8 fullPath);
str8 mp_path_base_name(str8 fullPath); MP_API str8 mp_path_base_name(str8 fullPath);
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"
#endif #endif
#endif //__STRINGS_H_ #endif //__STRINGS_H_

View File

@ -1,283 +1,284 @@
//***************************************************************** //*****************************************************************
// //
// $file: utf8.c $ // $file: utf8.c $
// $author: Martin Fouilleul $ // $author: Martin Fouilleul $
// $date: 05/11/2016 $ // $date: 05/11/2016 $
// $revision: $ // $revision: $
// $note: (C) 2016 by Martin Fouilleul - all rights reserved $ // $note: (C) 2016 by Martin Fouilleul - all rights reserved $
// //
//***************************************************************** //*****************************************************************
#include"utf8.h" #include"utf8.h"
#include<string.h> #include"platform.h"
#include<string.h>
//-----------------------------------------------------------------
// utf-8 gore //-----------------------------------------------------------------
//----------------------------------------------------------------- // utf-8 gore
const u32 offsetsFromUTF8[6] = { //-----------------------------------------------------------------
0x00000000UL, 0x00003080UL, 0x000E2080UL, const u32 offsetsFromUTF8[6] = {
0x03C82080UL, 0xFA082080UL, 0x82082080UL }; 0x00000000UL, 0x00003080UL, 0x000E2080UL,
0x03C82080UL, 0xFA082080UL, 0x82082080UL };
const char trailingBytesForUTF8[256] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, const char trailingBytesForUTF8[256] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
}; 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
};
#define utf8_is_start_byte(c) (((c)&0xc0)!=0x80)
#define utf8_is_start_byte(c) (((c)&0xc0)!=0x80)
//-----------------------------------------------------------------
//NOTE: getting sizes / offsets / indices //-----------------------------------------------------------------
//----------------------------------------------------------------- //NOTE: getting sizes / offsets / indices
//-----------------------------------------------------------------
u32 utf8_size_from_leading_char(char leadingChar)
{ u32 utf8_size_from_leading_char(char leadingChar)
return(trailingBytesForUTF8[(unsigned int)(unsigned char)leadingChar] + 1); {
} return(trailingBytesForUTF8[(unsigned int)(unsigned char)leadingChar] + 1);
}
u32 utf8_codepoint_size(utf32 codePoint)
{ u32 utf8_codepoint_size(utf32 codePoint)
if(codePoint < 0x80) {
{ if(codePoint < 0x80)
return(1); {
} return(1);
if(codePoint < 0x800) }
{ if(codePoint < 0x800)
return(2); {
} return(2);
if(codePoint < 0x10000) }
{ if(codePoint < 0x10000)
return(3); {
} return(3);
if(codePoint < 0x110000) }
{ if(codePoint < 0x110000)
return(4); {
} return(4);
return(0); }
} return(0);
}
u64 utf8_codepoint_count_for_string(str8 string)
{ u64 utf8_codepoint_count_for_string(str8 string)
u64 byteOffset = 0; {
u64 codePointIndex = 0; u64 byteOffset = 0;
for(; u64 codePointIndex = 0;
(byteOffset < string.len) && (string.ptr[byteOffset] != 0); for(;
codePointIndex++) (byteOffset < string.len) && (string.ptr[byteOffset] != 0);
{ codePointIndex++)
utf8_dec decode = utf8_decode_at(string, byteOffset); {
byteOffset += decode.size; utf8_dec decode = utf8_decode_at(string, byteOffset);
} byteOffset += decode.size;
return(codePointIndex); }
} return(codePointIndex);
}
u64 utf8_byte_count_for_codepoints(str32 codePoints)
{ u64 utf8_byte_count_for_codepoints(str32 codePoints)
//NOTE(martin): return the exact number of bytes taken by the encoded {
// version of codePoints. (ie do not attempt to provision //NOTE(martin): return the exact number of bytes taken by the encoded
// for a zero terminator). // version of codePoints. (ie do not attempt to provision
u64 byteCount = 0; // for a zero terminator).
for(u64 i=0; i<codePoints.len; i++) u64 byteCount = 0;
{ for(u64 i=0; i<codePoints.len; i++)
byteCount += utf8_codepoint_size(codePoints.ptr[i]); {
} byteCount += utf8_codepoint_size(codePoints.ptr[i]);
return(byteCount); }
} return(byteCount);
}
u64 utf8_next_offset(str8 string, u64 byteOffset)
{ u64 utf8_next_offset(str8 string, u64 byteOffset)
u64 res = 0; {
if(byteOffset >= string.len) u64 res = 0;
{ if(byteOffset >= string.len)
res = string.len; {
} res = string.len;
else }
{ else
u64 nextOffset = byteOffset + utf8_size_from_leading_char(string.ptr[byteOffset]); {
res = minimum(nextOffset, string.len); u64 nextOffset = byteOffset + utf8_size_from_leading_char(string.ptr[byteOffset]);
} res = minimum(nextOffset, string.len);
return(res); }
} return(res);
}
u64 utf8_prev_offset(str8 string, u64 byteOffset)
{ u64 utf8_prev_offset(str8 string, u64 byteOffset)
u64 res = 0; {
if(byteOffset > string.len) u64 res = 0;
{ if(byteOffset > string.len)
res = string.len; {
} res = string.len;
else if(byteOffset) }
{ else if(byteOffset)
byteOffset--; {
while(byteOffset > 0 && !utf8_is_start_byte(string.ptr[byteOffset])) byteOffset--;
{ while(byteOffset > 0 && !utf8_is_start_byte(string.ptr[byteOffset]))
byteOffset--; {
} byteOffset--;
res = byteOffset; }
} res = byteOffset;
return(res); }
} return(res);
}
//-----------------------------------------------------------------
//NOTE: encoding / decoding //-----------------------------------------------------------------
//----------------------------------------------------------------- //NOTE: encoding / decoding
//-----------------------------------------------------------------
utf8_dec utf8_decode_at(str8 string, u64 offset)
{ utf8_dec utf8_decode_at(str8 string, u64 offset)
//NOTE(martin): get the first codepoint in str, and advance index to the {
// next utf8 character //NOTE(martin): get the first codepoint in str, and advance index to the
//TODO(martin): check for utf-16 surrogate pairs // next utf8 character
utf32 cp = 0; //TODO(martin): check for utf-16 surrogate pairs
u64 sz = 0; utf32 cp = 0;
u64 sz = 0;
if(offset >= string.len || !string.ptr[offset])
{ if(offset >= string.len || !string.ptr[offset])
cp = 0; {
sz = 1; cp = 0;
} sz = 1;
else if( !utf8_is_start_byte(string.ptr[offset])) }
{ else if( !utf8_is_start_byte(string.ptr[offset]))
//NOTE(martin): unexpected continuation or invalid character. {
cp = 0xfffd; //NOTE(martin): unexpected continuation or invalid character.
sz = 1; cp = 0xfffd;
} sz = 1;
else }
{ else
int expectedSize = utf8_size_from_leading_char(string.ptr[offset]); {
do int expectedSize = utf8_size_from_leading_char(string.ptr[offset]);
{ do
/*NOTE(martin): {
we shift 6 bits and add the next byte at each round. /*NOTE(martin):
at the end we have our utf8 codepoint, added to the shifted versions we shift 6 bits and add the next byte at each round.
of the utf8 leading bits for each encoded byte. These values are at the end we have our utf8 codepoint, added to the shifted versions
precomputed in offsetsFromUTF8. of the utf8 leading bits for each encoded byte. These values are
*/ precomputed in offsetsFromUTF8.
unsigned char b = string.ptr[offset]; */
cp <<= 6; unsigned char b = string.ptr[offset];
cp += b; cp <<= 6;
offset += 1; cp += b;
sz++; offset += 1;
sz++;
if(b == 0xc0 || b == 0xc1 || b >= 0xc5)
{ if(b == 0xc0 || b == 0xc1 || b >= 0xc5)
//NOTE(martin): invalid byte encountered {
break; //NOTE(martin): invalid byte encountered
} break;
}
} while( offset < string.len
&& string.ptr[offset] } while( offset < string.len
&& !utf8_is_start_byte(string.ptr[offset]) && string.ptr[offset]
&& sz < expectedSize); && !utf8_is_start_byte(string.ptr[offset])
&& sz < expectedSize);
if(sz != expectedSize)
{ if(sz != expectedSize)
//NOTE(martin): if we encountered an error, we return the replacement codepoint U+FFFD {
cp = 0xfffd; //NOTE(martin): if we encountered an error, we return the replacement codepoint U+FFFD
} cp = 0xfffd;
else }
{ else
cp -= offsetsFromUTF8[sz-1]; {
cp -= offsetsFromUTF8[sz-1];
//NOTE(martin): check for invalid codepoints
if(cp > 0x10ffff || (cp >= 0xd800 && cp <= 0xdfff)) //NOTE(martin): check for invalid codepoints
{ if(cp > 0x10ffff || (cp >= 0xd800 && cp <= 0xdfff))
cp = 0xfffd; {
} cp = 0xfffd;
} }
} }
utf8_dec res = {.codepoint = cp, .size = sz}; }
return(res); utf8_dec res = {.codepoint = cp, .size = sz};
} return(res);
}
utf8_dec utf8_decode(str8 string)
{ utf8_dec utf8_decode(str8 string)
return(utf8_decode_at(string, 0)); {
} return(utf8_decode_at(string, 0));
}
str8 utf8_encode(char* dest, utf32 codePoint)
{ str8 utf8_encode(char* dest, utf32 codePoint)
u64 sz = 0; {
if (codePoint < 0x80) u64 sz = 0;
{ if (codePoint < 0x80)
dest[0] = (char)codePoint; {
sz = 1; dest[0] = (char)codePoint;
} sz = 1;
else if (codePoint < 0x800) }
{ else if (codePoint < 0x800)
dest[0] = (codePoint>>6) | 0xC0; {
dest[1] = (codePoint & 0x3F) | 0x80; dest[0] = (codePoint>>6) | 0xC0;
sz = 2; dest[1] = (codePoint & 0x3F) | 0x80;
} sz = 2;
else if (codePoint < 0x10000) }
{ else if (codePoint < 0x10000)
dest[0] = (codePoint>>12) | 0xE0; {
dest[1] = ((codePoint>>6) & 0x3F) | 0x80; dest[0] = (codePoint>>12) | 0xE0;
dest[2] = (codePoint & 0x3F) | 0x80; dest[1] = ((codePoint>>6) & 0x3F) | 0x80;
sz = 3; dest[2] = (codePoint & 0x3F) | 0x80;
} sz = 3;
else if (codePoint < 0x110000) }
{ else if (codePoint < 0x110000)
dest[0] = (codePoint>>18) | 0xF0; {
dest[1] = ((codePoint>>12) & 0x3F) | 0x80; dest[0] = (codePoint>>18) | 0xF0;
dest[2] = ((codePoint>>6) & 0x3F) | 0x80; dest[1] = ((codePoint>>12) & 0x3F) | 0x80;
dest[3] = (codePoint & 0x3F) | 0x80; dest[2] = ((codePoint>>6) & 0x3F) | 0x80;
sz = 4; dest[3] = (codePoint & 0x3F) | 0x80;
} sz = 4;
str8 res = {.len = sz, .ptr = dest}; }
return(res); str8 res = {.len = sz, .ptr = dest};
} return(res);
}
str32 utf8_to_codepoints(u64 maxCount, utf32* backing, str8 string)
{ str32 utf8_to_codepoints(u64 maxCount, utf32* backing, str8 string)
u64 codePointIndex = 0; {
u64 byteOffset = 0; u64 codePointIndex = 0;
for(; codePointIndex < maxCount && byteOffset < string.len; codePointIndex++) u64 byteOffset = 0;
{ for(; codePointIndex < maxCount && byteOffset < string.len; codePointIndex++)
utf8_dec decode = utf8_decode_at(string, byteOffset); {
backing[codePointIndex] = decode.codepoint; utf8_dec decode = utf8_decode_at(string, byteOffset);
byteOffset += decode.size; backing[codePointIndex] = decode.codepoint;
} byteOffset += decode.size;
str32 res = {.len = codePointIndex, .ptr = backing}; }
return(res); str32 res = {.len = codePointIndex, .ptr = backing};
} return(res);
}
str8 utf8_from_codepoints(u64 maxBytes, char* backing, str32 codePoints)
{ str8 utf8_from_codepoints(u64 maxBytes, char* backing, str32 codePoints)
u64 byteOffset = 0; {
for(u64 codePointIndex = 0; (codePointIndex < codePoints.len); codePointIndex++) u64 byteOffset = 0;
{ for(u64 codePointIndex = 0; (codePointIndex < codePoints.len); codePointIndex++)
utf32 codePoint = codePoints.ptr[codePointIndex]; {
u32 byteCount = utf8_codepoint_size(codePoint); utf32 codePoint = codePoints.ptr[codePointIndex];
if(byteOffset + byteCount > maxBytes) u32 byteCount = utf8_codepoint_size(codePoint);
{ if(byteOffset + byteCount > maxBytes)
break; {
} break;
utf8_encode(backing+byteOffset, codePoint); }
byteOffset += byteCount; utf8_encode(backing+byteOffset, codePoint);
} byteOffset += byteCount;
str8 res = {.len = byteOffset, .ptr = backing}; }
return(res); str8 res = {.len = byteOffset, .ptr = backing};
} return(res);
}
str32 utf8_push_to_codepoints(mem_arena* arena, str8 string)
{ str32 utf8_push_to_codepoints(mem_arena* arena, str8 string)
u64 count = utf8_codepoint_count_for_string(string); {
utf32* backing = mem_arena_alloc_array(arena, utf32, count); u64 count = utf8_codepoint_count_for_string(string);
str32 res = utf8_to_codepoints(count, backing, string); utf32* backing = mem_arena_alloc_array(arena, utf32, count);
return(res); str32 res = utf8_to_codepoints(count, backing, string);
} return(res);
}
str8 utf8_push_from_codepoints(mem_arena* arena, str32 codePoints)
{ str8 utf8_push_from_codepoints(mem_arena* arena, str32 codePoints)
u64 count = utf8_byte_count_for_codepoints(codePoints); {
char* backing = mem_arena_alloc_array(arena, char, count); u64 count = utf8_byte_count_for_codepoints(codePoints);
str8 res = utf8_from_codepoints(count, backing, codePoints); char* backing = mem_arena_alloc_array(arena, char, count);
return(res); str8 res = utf8_from_codepoints(count, backing, codePoints);
} return(res);
}
#define UNICODE_RANGE(start, cnt, name) const unicode_range _cat2_(UNICODE_RANGE_, name) = { .firstCodePoint = start, .count = cnt };
UNICODE_RANGES #define UNICODE_RANGE(start, cnt, name) MP_API extern const unicode_range _cat2_(UNICODE_RANGE_, name) = { .firstCodePoint = start, .count = cnt };
#undef UNICODE_RANGE UNICODE_RANGES
#undef UNICODE_RANGE

View File

@ -1,202 +1,201 @@
//***************************************************************** //*****************************************************************
// //
// $file: utf8.h $ // $file: utf8.h $
// $author: Martin Fouilleul $ // $author: Martin Fouilleul $
// $date: 05/11/2016 $ // $date: 05/11/2016 $
// $revision: $ // $revision: $
// $note: (C) 2016 by Martin Fouilleul - all rights reserved $ // $note: (C) 2016 by Martin Fouilleul - all rights reserved $
// //
//***************************************************************** //*****************************************************************
#ifndef __UTF8_H_ #ifndef __UTF8_H_
#define __UTF8_H_ #define __UTF8_H_
#include"typedefs.h" #include"typedefs.h"
#include"macro_helpers.h" #include"macro_helpers.h"
#include"strings.h" #include"strings.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
typedef u32 utf32; typedef u32 utf32;
//----------------------------------------------------------------- //-----------------------------------------------------------------
//NOTE: getting sizes / offsets / indices //NOTE: getting sizes / offsets / indices
//----------------------------------------------------------------- //-----------------------------------------------------------------
u32 utf8_size_from_leading_char(char leadingChar); MP_API u32 utf8_size_from_leading_char(char leadingChar);
u32 utf8_codepoint_size(utf32 codePoint); MP_API u32 utf8_codepoint_size(utf32 codePoint);
u64 utf8_codepoint_count_for_string(str8 string); MP_API u64 utf8_codepoint_count_for_string(str8 string);
u64 utf8_byte_count_for_codepoints(str32 codePoints); MP_API u64 utf8_byte_count_for_codepoints(str32 codePoints);
u64 utf8_next_offset(str8 string, u64 byteOffset); MP_API u64 utf8_next_offset(str8 string, u64 byteOffset);
u64 utf8_prev_offset(str8 string, u64 byteOffset); MP_API u64 utf8_prev_offset(str8 string, u64 byteOffset);
//----------------------------------------------------------------- //-----------------------------------------------------------------
//NOTE: encoding / decoding //NOTE: encoding / decoding
//----------------------------------------------------------------- //-----------------------------------------------------------------
typedef struct utf8_dec typedef struct utf8_dec
{ {
utf32 codepoint; //NOTE: decoded codepoint utf32 codepoint; //NOTE: decoded codepoint
u32 size; //NOTE: size of corresponding utf8 sequence u32 size; //NOTE: size of corresponding utf8 sequence
} utf8_dec; } utf8_dec;
utf8_dec utf8_decode(str8 string); //NOTE: decode a single utf8 sequence at start of string MP_API utf8_dec utf8_decode(str8 string); //NOTE: decode a single utf8 sequence at start of string
utf8_dec utf8_decode_at(str8 string, u64 offset); //NOTE: decode a single utf8 sequence starting at byte offset MP_API utf8_dec utf8_decode_at(str8 string, u64 offset); //NOTE: decode a single utf8 sequence starting at byte offset
str8 utf8_encode(char* dst, utf32 codePoint); //NOTE: encode codepoint into backing buffer dst MP_API str8 utf8_encode(char* dst, utf32 codePoint); //NOTE: encode codepoint into backing buffer dst
str32 utf8_to_codepoints(u64 maxCount, utf32* backing, str8 string); MP_API str32 utf8_to_codepoints(u64 maxCount, utf32* backing, str8 string);
str8 utf8_from_codepoints(u64 maxBytes, char* backing, str32 codePoints); MP_API str8 utf8_from_codepoints(u64 maxBytes, char* backing, str32 codePoints);
str32 utf8_push_to_codepoints(mem_arena* arena, str8 string); MP_API str32 utf8_push_to_codepoints(mem_arena* arena, str8 string);
str8 utf8_push_from_codepoints(mem_arena* arena, str32 codePoints); MP_API str8 utf8_push_from_codepoints(mem_arena* arena, str32 codePoints);
//----------------------------------------------------------------- //-----------------------------------------------------------------
// utf8 range struct and X-macros for defining utf8 ranges // utf8 range struct and X-macros for defining utf8 ranges
//----------------------------------------------------------------- //-----------------------------------------------------------------
typedef struct unicode_range typedef struct unicode_range
{ {
utf32 firstCodePoint; utf32 firstCodePoint;
u32 count; u32 count;
} unicode_range; } unicode_range;
//NOTE(martin): range declared here are defined in utf8.cpp //NOTE(martin): range declared here are defined in utf8.cpp
// they can be used by prefixing them with UTF8_RANGE_, as in 'UTF8_RANGE_BASIC_LATIN' // they can be used by prefixing them with UTF8_RANGE_, as in 'UTF8_RANGE_BASIC_LATIN'
#define UNICODE_RANGES \ #define UNICODE_RANGES \
UNICODE_RANGE(0x0000, 127, BASIC_LATIN) \ UNICODE_RANGE(0x0000, 127, BASIC_LATIN) \
UNICODE_RANGE(0x0080, 127, C1_CONTROLS_AND_LATIN_1_SUPPLEMENT) \ UNICODE_RANGE(0x0080, 127, C1_CONTROLS_AND_LATIN_1_SUPPLEMENT) \
UNICODE_RANGE(0x0100, 127, LATIN_EXTENDED_A) \ UNICODE_RANGE(0x0100, 127, LATIN_EXTENDED_A) \
UNICODE_RANGE(0x0180, 207, LATIN_EXTENDED_B) \ UNICODE_RANGE(0x0180, 207, LATIN_EXTENDED_B) \
UNICODE_RANGE(0x0250, 95, IPA_EXTENSIONS) \ UNICODE_RANGE(0x0250, 95, IPA_EXTENSIONS) \
UNICODE_RANGE(0x02b0, 79, SPACING_MODIFIER_LETTERS) \ UNICODE_RANGE(0x02b0, 79, SPACING_MODIFIER_LETTERS) \
UNICODE_RANGE(0x0300, 111, COMBINING_DIACRITICAL_MARKS) \ UNICODE_RANGE(0x0300, 111, COMBINING_DIACRITICAL_MARKS) \
UNICODE_RANGE(0x0370, 143, GREEK_COPTIC) \ UNICODE_RANGE(0x0370, 143, GREEK_COPTIC) \
UNICODE_RANGE(0x0400, 255, CYRILLIC) \ UNICODE_RANGE(0x0400, 255, CYRILLIC) \
UNICODE_RANGE(0x0500, 47, CYRILLIC_SUPPLEMENT) \ UNICODE_RANGE(0x0500, 47, CYRILLIC_SUPPLEMENT) \
UNICODE_RANGE(0x0530, 95, ARMENIAN) \ UNICODE_RANGE(0x0530, 95, ARMENIAN) \
UNICODE_RANGE(0x0590, 111, HEBREW) \ UNICODE_RANGE(0x0590, 111, HEBREW) \
UNICODE_RANGE(0x0600, 255, ARABIC) \ UNICODE_RANGE(0x0600, 255, ARABIC) \
UNICODE_RANGE(0x0700, 79, SYRIAC) \ UNICODE_RANGE(0x0700, 79, SYRIAC) \
UNICODE_RANGE(0x0780, 63, THAANA) \ UNICODE_RANGE(0x0780, 63, THAANA) \
UNICODE_RANGE(0x0900, 127, DEVANAGARI) \ UNICODE_RANGE(0x0900, 127, DEVANAGARI) \
UNICODE_RANGE(0x0980, 127, BENGALI_ASSAMESE) \ UNICODE_RANGE(0x0980, 127, BENGALI_ASSAMESE) \
UNICODE_RANGE(0x0a00, 127, GURMUKHI) \ UNICODE_RANGE(0x0a00, 127, GURMUKHI) \
UNICODE_RANGE(0x0a80, 127, GUJARATI) \ UNICODE_RANGE(0x0a80, 127, GUJARATI) \
UNICODE_RANGE(0x0b00, 127, ORIYA) \ UNICODE_RANGE(0x0b00, 127, ORIYA) \
UNICODE_RANGE(0x0b80, 127, TAMIL) \ UNICODE_RANGE(0x0b80, 127, TAMIL) \
UNICODE_RANGE(0x0c00, 127, TELUGU) \ UNICODE_RANGE(0x0c00, 127, TELUGU) \
UNICODE_RANGE(0x0c80, 127, KANNADA) \ UNICODE_RANGE(0x0c80, 127, KANNADA) \
UNICODE_RANGE(0x0d00, 255, MALAYALAM) \ UNICODE_RANGE(0x0d00, 255, MALAYALAM) \
UNICODE_RANGE(0x0d80, 127, SINHALA) \ UNICODE_RANGE(0x0d80, 127, SINHALA) \
UNICODE_RANGE(0x0e00, 127, THAI) \ UNICODE_RANGE(0x0e00, 127, THAI) \
UNICODE_RANGE(0x0e80, 127, LAO) \ UNICODE_RANGE(0x0e80, 127, LAO) \
UNICODE_RANGE(0x0f00, 255, TIBETAN) \ UNICODE_RANGE(0x0f00, 255, TIBETAN) \
UNICODE_RANGE(0x1000, 159, MYANMAR) \ UNICODE_RANGE(0x1000, 159, MYANMAR) \
UNICODE_RANGE(0x10a0, 95, GEORGIAN) \ UNICODE_RANGE(0x10a0, 95, GEORGIAN) \
UNICODE_RANGE(0x1100, 255, HANGUL_JAMO) \ UNICODE_RANGE(0x1100, 255, HANGUL_JAMO) \
UNICODE_RANGE(0x1200, 383, ETHIOPIC) \ UNICODE_RANGE(0x1200, 383, ETHIOPIC) \
UNICODE_RANGE(0x13a0, 95, CHEROKEE) \ UNICODE_RANGE(0x13a0, 95, CHEROKEE) \
UNICODE_RANGE(0x1400, 639, UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS) \ UNICODE_RANGE(0x1400, 639, UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS) \
UNICODE_RANGE(0x1680, 31, OGHAM) \ UNICODE_RANGE(0x1680, 31, OGHAM) \
UNICODE_RANGE(0x16a0, 95, RUNIC) \ UNICODE_RANGE(0x16a0, 95, RUNIC) \
UNICODE_RANGE(0x1700, 31, TAGALOG) \ UNICODE_RANGE(0x1700, 31, TAGALOG) \
UNICODE_RANGE(0x1720, 31, HANUNOO) \ UNICODE_RANGE(0x1720, 31, HANUNOO) \
UNICODE_RANGE(0x1740, 31, BUHID) \ UNICODE_RANGE(0x1740, 31, BUHID) \
UNICODE_RANGE(0x1760, 31, TAGBANWA) \ UNICODE_RANGE(0x1760, 31, TAGBANWA) \
UNICODE_RANGE(0x1780, 127, KHMER) \ UNICODE_RANGE(0x1780, 127, KHMER) \
UNICODE_RANGE(0x1800, 175, MONGOLIAN) \ UNICODE_RANGE(0x1800, 175, MONGOLIAN) \
UNICODE_RANGE(0x1900, 79, LIMBU) \ UNICODE_RANGE(0x1900, 79, LIMBU) \
UNICODE_RANGE(0x1950, 47, TAI_LE) \ UNICODE_RANGE(0x1950, 47, TAI_LE) \
UNICODE_RANGE(0x19e0, 31, KHMER_SYMBOLS) \ UNICODE_RANGE(0x19e0, 31, KHMER_SYMBOLS) \
UNICODE_RANGE(0x1d00, 127, PHONETIC_EXTENSIONS) \ UNICODE_RANGE(0x1d00, 127, PHONETIC_EXTENSIONS) \
UNICODE_RANGE(0x1e00, 255, LATIN_EXTENDED_ADDITIONAL) \ UNICODE_RANGE(0x1e00, 255, LATIN_EXTENDED_ADDITIONAL) \
UNICODE_RANGE(0x1f00, 255, GREEK_EXTENDED) \ UNICODE_RANGE(0x1f00, 255, GREEK_EXTENDED) \
UNICODE_RANGE(0x2000, 111, GENERAL_PUNCTUATION) \ UNICODE_RANGE(0x2000, 111, GENERAL_PUNCTUATION) \
UNICODE_RANGE(0x2070, 47, SUPERSCRIPTS_AND_SUBSCRIPTS) \ UNICODE_RANGE(0x2070, 47, SUPERSCRIPTS_AND_SUBSCRIPTS) \
UNICODE_RANGE(0x20a0, 47, CURRENCY_SYMBOLS) \ UNICODE_RANGE(0x20a0, 47, CURRENCY_SYMBOLS) \
UNICODE_RANGE(0x20d0, 47, COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS) \ UNICODE_RANGE(0x20d0, 47, COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS) \
UNICODE_RANGE(0x2100, 79, LETTERLIKE_SYMBOLS) \ UNICODE_RANGE(0x2100, 79, LETTERLIKE_SYMBOLS) \
UNICODE_RANGE(0x2150, 63, NUMBER_FORMS) \ UNICODE_RANGE(0x2150, 63, NUMBER_FORMS) \
UNICODE_RANGE(0x2190, 111, ARROWS) \ UNICODE_RANGE(0x2190, 111, ARROWS) \
UNICODE_RANGE(0x2200, 255, MATHEMATICAL_OPERATORS) \ UNICODE_RANGE(0x2200, 255, MATHEMATICAL_OPERATORS) \
UNICODE_RANGE(0x2300, 255, MISCELLANEOUS_TECHNICAL) \ UNICODE_RANGE(0x2300, 255, MISCELLANEOUS_TECHNICAL) \
UNICODE_RANGE(0x2400, 63, CONTROL_PICTURES) \ UNICODE_RANGE(0x2400, 63, CONTROL_PICTURES) \
UNICODE_RANGE(0x2440, 31, OPTICAL_CHARACTER_RECOGNITION) \ UNICODE_RANGE(0x2440, 31, OPTICAL_CHARACTER_RECOGNITION) \
UNICODE_RANGE(0x2460, 159, ENCLOSED_ALPHANUMERICS) \ UNICODE_RANGE(0x2460, 159, ENCLOSED_ALPHANUMERICS) \
UNICODE_RANGE(0x2500, 127, BOX_DRAWING) \ UNICODE_RANGE(0x2500, 127, BOX_DRAWING) \
UNICODE_RANGE(0x2580, 31, BLOCK_ELEMENTS) \ UNICODE_RANGE(0x2580, 31, BLOCK_ELEMENTS) \
UNICODE_RANGE(0x25a0, 95, GEOMETRIC_SHAPES) \ UNICODE_RANGE(0x25a0, 95, GEOMETRIC_SHAPES) \
UNICODE_RANGE(0x2600, 255, MISCELLANEOUS_SYMBOLS) \ UNICODE_RANGE(0x2600, 255, MISCELLANEOUS_SYMBOLS) \
UNICODE_RANGE(0x2700, 191, DINGBATS) \ UNICODE_RANGE(0x2700, 191, DINGBATS) \
UNICODE_RANGE(0x27c0, 47, MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A) \ UNICODE_RANGE(0x27c0, 47, MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A) \
UNICODE_RANGE(0x27f0, 15, SUPPLEMENTAL_ARROWS_A) \ UNICODE_RANGE(0x27f0, 15, SUPPLEMENTAL_ARROWS_A) \
UNICODE_RANGE(0x2800, 255, BRAILLE_PATTERNS) \ UNICODE_RANGE(0x2800, 255, BRAILLE_PATTERNS) \
UNICODE_RANGE(0x2900, 127, SUPPLEMENTAL_ARROWS_B) \ UNICODE_RANGE(0x2900, 127, SUPPLEMENTAL_ARROWS_B) \
UNICODE_RANGE(0x2980, 127, MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B) \ UNICODE_RANGE(0x2980, 127, MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B) \
UNICODE_RANGE(0x2a00, 255, SUPPLEMENTAL_MATHEMATICAL_OPERATORS) \ UNICODE_RANGE(0x2a00, 255, SUPPLEMENTAL_MATHEMATICAL_OPERATORS) \
UNICODE_RANGE(0x2b00, 255, MISCELLANEOUS_SYMBOLS_AND_ARROWS) \ UNICODE_RANGE(0x2b00, 255, MISCELLANEOUS_SYMBOLS_AND_ARROWS) \
UNICODE_RANGE(0x2e80, 127, CJK_RADICALS_SUPPLEMENT) \ UNICODE_RANGE(0x2e80, 127, CJK_RADICALS_SUPPLEMENT) \
UNICODE_RANGE(0x2f00, 223, KANGXI_RADICALS) \ UNICODE_RANGE(0x2f00, 223, KANGXI_RADICALS) \
UNICODE_RANGE(0x2ff0, 15, IDEOGRAPHIC_DESCRIPTION_CHARACTERS) \ UNICODE_RANGE(0x2ff0, 15, IDEOGRAPHIC_DESCRIPTION_CHARACTERS) \
UNICODE_RANGE(0x3000, 63, CJK_SYMBOLS_AND_PUNCTUATION) \ UNICODE_RANGE(0x3000, 63, CJK_SYMBOLS_AND_PUNCTUATION) \
UNICODE_RANGE(0x3040, 95, HIRAGANA) \ UNICODE_RANGE(0x3040, 95, HIRAGANA) \
UNICODE_RANGE(0x30a0, 95, KATAKANA) \ UNICODE_RANGE(0x30a0, 95, KATAKANA) \
UNICODE_RANGE(0x3100, 47, BOPOMOFO) \ UNICODE_RANGE(0x3100, 47, BOPOMOFO) \
UNICODE_RANGE(0x3130, 95, HANGUL_COMPATIBILITY_JAMO) \ UNICODE_RANGE(0x3130, 95, HANGUL_COMPATIBILITY_JAMO) \
UNICODE_RANGE(0x3190, 15, KANBUN_KUNTEN) \ UNICODE_RANGE(0x3190, 15, KANBUN_KUNTEN) \
UNICODE_RANGE(0x31a0, 31, BOPOMOFO_EXTENDED) \ UNICODE_RANGE(0x31a0, 31, BOPOMOFO_EXTENDED) \
UNICODE_RANGE(0x31f0, 15, KATAKANA_PHONETIC_EXTENSIONS) \ UNICODE_RANGE(0x31f0, 15, KATAKANA_PHONETIC_EXTENSIONS) \
UNICODE_RANGE(0x3200, 255, ENCLOSED_CJK_LETTERS_AND_MONTHS) \ UNICODE_RANGE(0x3200, 255, ENCLOSED_CJK_LETTERS_AND_MONTHS) \
UNICODE_RANGE(0x3300, 255, CJK_COMPATIBILITY) \ UNICODE_RANGE(0x3300, 255, CJK_COMPATIBILITY) \
UNICODE_RANGE(0x3400, 6591, CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A) \ UNICODE_RANGE(0x3400, 6591, CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A) \
UNICODE_RANGE(0x4dc0, 63, YIJING_HEXAGRAM_SYMBOLS) \ UNICODE_RANGE(0x4dc0, 63, YIJING_HEXAGRAM_SYMBOLS) \
UNICODE_RANGE(0x4e00, 20911, CJK_UNIFIED_IDEOGRAPHS) \ UNICODE_RANGE(0x4e00, 20911, CJK_UNIFIED_IDEOGRAPHS) \
UNICODE_RANGE(0xa000, 1167, YI_SYLLABLES) \ UNICODE_RANGE(0xa000, 1167, YI_SYLLABLES) \
UNICODE_RANGE(0xa490, 63, YI_RADICALS) \ UNICODE_RANGE(0xa490, 63, YI_RADICALS) \
UNICODE_RANGE(0xac00, 11183, HANGUL_SYLLABLES) \ UNICODE_RANGE(0xac00, 11183, HANGUL_SYLLABLES) \
UNICODE_RANGE(0xd800, 1023, HIGH_SURROGATE_AREA) \ UNICODE_RANGE(0xd800, 1023, HIGH_SURROGATE_AREA) \
UNICODE_RANGE(0xdc00, 1023, LOW_SURROGATE_AREA) \ UNICODE_RANGE(0xdc00, 1023, LOW_SURROGATE_AREA) \
UNICODE_RANGE(0xe000, 6399, PRIVATE_USE_AREA) \ UNICODE_RANGE(0xe000, 6399, PRIVATE_USE_AREA) \
UNICODE_RANGE(0xf900, 511, CJK_COMPATIBILITY_IDEOGRAPHS) \ UNICODE_RANGE(0xf900, 511, CJK_COMPATIBILITY_IDEOGRAPHS) \
UNICODE_RANGE(0xfb00, 79, ALPHABETIC_PRESENTATION_FORMS) \ UNICODE_RANGE(0xfb00, 79, ALPHABETIC_PRESENTATION_FORMS) \
UNICODE_RANGE(0xfb50, 687, ARABIC_PRESENTATION_FORMS_A) \ UNICODE_RANGE(0xfb50, 687, ARABIC_PRESENTATION_FORMS_A) \
UNICODE_RANGE(0xfe00, 15, VARIATION_SELECTORS) \ UNICODE_RANGE(0xfe00, 15, VARIATION_SELECTORS) \
UNICODE_RANGE(0xfe20, 15, COMBINING_HALF_MARKS) \ UNICODE_RANGE(0xfe20, 15, COMBINING_HALF_MARKS) \
UNICODE_RANGE(0xfe30, 31, CJK_COMPATIBILITY_FORMS) \ UNICODE_RANGE(0xfe30, 31, CJK_COMPATIBILITY_FORMS) \
UNICODE_RANGE(0xfe50, 31, SMALL_FORM_VARIANTS) \ UNICODE_RANGE(0xfe50, 31, SMALL_FORM_VARIANTS) \
UNICODE_RANGE(0xfe70, 143, ARABIC_PRESENTATION_FORMS_B) \ UNICODE_RANGE(0xfe70, 143, ARABIC_PRESENTATION_FORMS_B) \
UNICODE_RANGE(0xff00, 239, HALFWIDTH_AND_FULLWIDTH_FORMS) \ UNICODE_RANGE(0xff00, 239, HALFWIDTH_AND_FULLWIDTH_FORMS) \
UNICODE_RANGE(0xfff0, 15, SPECIALS) \ UNICODE_RANGE(0xfff0, 15, SPECIALS) \
UNICODE_RANGE(0x10000, 127, LINEAR_B_SYLLABARY) \ UNICODE_RANGE(0x10000, 127, LINEAR_B_SYLLABARY) \
UNICODE_RANGE(0x10080, 127, LINEAR_B_IDEOGRAMS) \ UNICODE_RANGE(0x10080, 127, LINEAR_B_IDEOGRAMS) \
UNICODE_RANGE(0x10100, 63, AEGEAN_NUMBERS) \ UNICODE_RANGE(0x10100, 63, AEGEAN_NUMBERS) \
UNICODE_RANGE(0x10300, 47, OLD_ITALIC) \ UNICODE_RANGE(0x10300, 47, OLD_ITALIC) \
UNICODE_RANGE(0x10330, 31, GOTHIC) \ UNICODE_RANGE(0x10330, 31, GOTHIC) \
UNICODE_RANGE(0x10380, 31, UGARITIC) \ UNICODE_RANGE(0x10380, 31, UGARITIC) \
UNICODE_RANGE(0x10400, 79, DESERET) \ UNICODE_RANGE(0x10400, 79, DESERET) \
UNICODE_RANGE(0x10450, 47, SHAVIAN) \ UNICODE_RANGE(0x10450, 47, SHAVIAN) \
UNICODE_RANGE(0x10480, 47, OSMANYA) \ UNICODE_RANGE(0x10480, 47, OSMANYA) \
UNICODE_RANGE(0x10800, 63, CYPRIOT_SYLLABARY) \ UNICODE_RANGE(0x10800, 63, CYPRIOT_SYLLABARY) \
UNICODE_RANGE(0x1d000, 255, BYZANTINE_MUSICAL_SYMBOLS) \ UNICODE_RANGE(0x1d000, 255, BYZANTINE_MUSICAL_SYMBOLS) \
UNICODE_RANGE(0x1d100, 255, MUSICAL_SYMBOLS) \ UNICODE_RANGE(0x1d100, 255, MUSICAL_SYMBOLS) \
UNICODE_RANGE(0x1d300, 95, TAI_XUAN_JING_SYMBOLS) \ UNICODE_RANGE(0x1d300, 95, TAI_XUAN_JING_SYMBOLS) \
UNICODE_RANGE(0x1d400, 1023, MATHEMATICAL_ALPHANUMERIC_SYMBOLS) \ UNICODE_RANGE(0x1d400, 1023, MATHEMATICAL_ALPHANUMERIC_SYMBOLS) \
UNICODE_RANGE(0x20000, 42719, CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B) \ UNICODE_RANGE(0x20000, 42719, CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B) \
UNICODE_RANGE(0x2f800, 543, CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT) \ UNICODE_RANGE(0x2f800, 543, CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT) \
UNICODE_RANGE(0xe0000, 127, TAGS) \ UNICODE_RANGE(0xe0000, 127, TAGS) \
UNICODE_RANGE(0xe0100, 239, VARIATION_SELECTORS_SUPPLEMENT) \ UNICODE_RANGE(0xe0100, 239, VARIATION_SELECTORS_SUPPLEMENT) \
UNICODE_RANGE(0xf0000, 65533, SUPPLEMENTARY_PRIVATE_USE_AREA_A) \ UNICODE_RANGE(0xf0000, 65533, SUPPLEMENTARY_PRIVATE_USE_AREA_A) \
UNICODE_RANGE(0x100000, 65533, SUPPLEMENTARY_PRIVATE_USE_AREA_B) UNICODE_RANGE(0x100000, 65533, SUPPLEMENTARY_PRIVATE_USE_AREA_B)
#define UNICODE_RANGE(start, count, name) \
#define UNICODE_RANGE(start, count, name) \ MP_API extern const unicode_range _cat2_(UNICODE_RANGE_, name);
extern const unicode_range _cat2_(UNICODE_RANGE_, name); UNICODE_RANGES
UNICODE_RANGES #undef UNICODE_RANGE
#undef UNICODE_RANGE
#ifdef __cplusplus
#ifdef __cplusplus } // extern "C"
} // extern "C" #endif
#endif
#endif //__UTF8_H_
#endif //__UTF8_H_

View File

@ -16,7 +16,7 @@ Overview
[.] Make linking with libEGL optional, even if EGL backend is compiled in milepost? [.] Make linking with libEGL optional, even if EGL backend is compiled in milepost?
[x] using weak linking on macos [x] using weak linking on macos
[ ] use /DELAYLOAD:lib on windows? [ ] use /DELAYLOAD:lib on windows?
[.] Remove the need for client apps to link with all dependent libs explicitly [x] Remove the need for client apps to link with all dependent libs explicitly
[!] Allow controlling surface overlaying [!] Allow controlling surface overlaying
[!] Sort out contents scaling for high dpi on osx [!] Sort out contents scaling for high dpi on osx