Merge branch 'main' into fix_win32_time_init
This commit is contained in:
		
						commit
						b0e025616c
					
				|  | @ -19,6 +19,9 @@ f32 minf(f32 a, f32 b); | |||
| 
 | ||||
| ORCA_EXPORT void oc_on_init(void) | ||||
| { | ||||
|     oc_runtime_window_set_title(OC_STR8("clock")); | ||||
|     oc_runtime_window_set_size((oc_vec2){ .x = 400, .y = 400 }); | ||||
| 
 | ||||
|     surface = oc_surface_canvas(); | ||||
|     canvas = oc_canvas_create(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -615,6 +615,8 @@ ORCA_EXPORT void oc_on_init() | |||
| { | ||||
|     oc_log_info("Hello, world (from C)"); | ||||
| 
 | ||||
|     oc_runtime_window_set_title(OC_STR8("fluid")); | ||||
| 
 | ||||
|     surface = oc_surface_gles(); | ||||
|     oc_surface_select(surface); | ||||
| 
 | ||||
|  |  | |||
|  | @ -37,6 +37,8 @@ void compile_shader(GLuint shader, const char* source) | |||
| 
 | ||||
| ORCA_EXPORT void oc_on_init(void) | ||||
| { | ||||
|     oc_runtime_window_set_title(OC_STR8("triangle")); | ||||
| 
 | ||||
|     surface = oc_surface_gles(); | ||||
|     oc_surface_select(surface); | ||||
| 
 | ||||
|  |  | |||
|  | @ -69,6 +69,8 @@ oc_str8 loadFile(oc_arena* arena, oc_str8 filename) | |||
| 
 | ||||
| ORCA_EXPORT void oc_on_init(void) | ||||
| { | ||||
|     oc_runtime_window_set_title(OC_STR8("pong")); | ||||
| 
 | ||||
|     surface = oc_surface_canvas(); | ||||
|     canvas = oc_canvas_create(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -10,6 +10,8 @@ oc_arena textArena = { 0 }; | |||
| 
 | ||||
| ORCA_EXPORT void oc_on_init(void) | ||||
| { | ||||
|     oc_runtime_window_set_title(OC_STR8("ui")); | ||||
| 
 | ||||
|     surface = oc_surface_canvas(); | ||||
|     canvas = oc_canvas_create(); | ||||
|     oc_ui_init(&ui); | ||||
|  |  | |||
|  | @ -397,6 +397,7 @@ def gen_all_bindings(): | |||
|     ) | ||||
| 
 | ||||
|     bindgen("core", "src/wasmbind/core_api.json", | ||||
|         guest_stubs="src/wasmbind/core_api_stubs.c", | ||||
|         wasm3_bindings="src/wasmbind/core_api_bind_gen.c", | ||||
|     ) | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										687
									
								
								src/app/app.h
								
								
								
								
							
							
						
						
									
										687
									
								
								src/app/app.h
								
								
								
								
							|  | @ -15,392 +15,399 @@ | |||
| #include "util/utf8.h" | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| extern "C" | ||||
| { | ||||
| extern "C" { | ||||
| #endif | ||||
| 
 | ||||
|     //--------------------------------------------------------------------
 | ||||
|     // Typedefs, enums and constants
 | ||||
|     //--------------------------------------------------------------------
 | ||||
| //--------------------------------------------------------------------
 | ||||
| // Typedefs, enums and constants
 | ||||
| //--------------------------------------------------------------------
 | ||||
| 
 | ||||
|     typedef struct oc_window | ||||
| typedef struct oc_window | ||||
| { | ||||
|     u64 h; | ||||
| } oc_window; | ||||
| 
 | ||||
| typedef enum | ||||
| { | ||||
|     OC_MOUSE_CURSOR_ARROW, | ||||
|     OC_MOUSE_CURSOR_RESIZE_0, | ||||
|     OC_MOUSE_CURSOR_RESIZE_90, | ||||
|     OC_MOUSE_CURSOR_RESIZE_45, | ||||
|     OC_MOUSE_CURSOR_RESIZE_135, | ||||
|     OC_MOUSE_CURSOR_TEXT | ||||
| } oc_mouse_cursor; | ||||
| 
 | ||||
| typedef i32 oc_window_style; | ||||
| static const oc_window_style OC_WINDOW_STYLE_NO_TITLE = 0x01 << 0, | ||||
|                              OC_WINDOW_STYLE_FIXED_SIZE = 0x01 << 1, | ||||
|                              OC_WINDOW_STYLE_NO_CLOSE = 0x01 << 2, | ||||
|                              OC_WINDOW_STYLE_NO_MINIFY = 0x01 << 3, | ||||
|                              OC_WINDOW_STYLE_NO_FOCUS = 0x01 << 4, | ||||
|                              OC_WINDOW_STYLE_FLOAT = 0x01 << 5, | ||||
|                              OC_WINDOW_STYLE_POPUPMENU = 0x01 << 6, | ||||
|                              OC_WINDOW_STYLE_NO_BUTTONS = 0x01 << 7; | ||||
| 
 | ||||
| typedef enum | ||||
| { | ||||
|     OC_EVENT_NONE, | ||||
|     OC_EVENT_KEYBOARD_MODS, //TODO: remove, keep only key?
 | ||||
|     OC_EVENT_KEYBOARD_KEY, | ||||
|     OC_EVENT_KEYBOARD_CHAR, | ||||
|     OC_EVENT_MOUSE_BUTTON, | ||||
|     OC_EVENT_MOUSE_MOVE, | ||||
|     OC_EVENT_MOUSE_WHEEL, | ||||
|     OC_EVENT_MOUSE_ENTER, | ||||
|     OC_EVENT_MOUSE_LEAVE, | ||||
|     OC_EVENT_WINDOW_RESIZE, | ||||
|     OC_EVENT_WINDOW_MOVE, | ||||
|     OC_EVENT_WINDOW_FOCUS, | ||||
|     OC_EVENT_WINDOW_UNFOCUS, | ||||
|     OC_EVENT_WINDOW_HIDE, // rename to minimize?
 | ||||
|     OC_EVENT_WINDOW_SHOW, // rename to restore?
 | ||||
|     OC_EVENT_WINDOW_CLOSE, | ||||
|     OC_EVENT_PATHDROP, | ||||
|     OC_EVENT_FRAME, | ||||
|     OC_EVENT_QUIT | ||||
| } oc_event_type; | ||||
| 
 | ||||
| typedef enum | ||||
| { | ||||
|     OC_KEY_NO_ACTION, | ||||
|     OC_KEY_PRESS, | ||||
|     OC_KEY_RELEASE, | ||||
|     OC_KEY_REPEAT | ||||
| } oc_key_action; | ||||
| 
 | ||||
| typedef enum | ||||
| { | ||||
|     OC_KEY_UNKNOWN = 0, | ||||
|     OC_KEY_SPACE = 32, | ||||
|     OC_KEY_APOSTROPHE = 39, /* ' */ | ||||
|     OC_KEY_COMMA = 44,      /* , */ | ||||
|     OC_KEY_MINUS = 45,      // -
 | ||||
|     OC_KEY_PERIOD = 46,     // .
 | ||||
|     OC_KEY_SLASH = 47,      // /
 | ||||
|     OC_KEY_0 = 48, | ||||
|     OC_KEY_1 = 49, | ||||
|     OC_KEY_2 = 50, | ||||
|     OC_KEY_3 = 51, | ||||
|     OC_KEY_4 = 52, | ||||
|     OC_KEY_5 = 53, | ||||
|     OC_KEY_6 = 54, | ||||
|     OC_KEY_7 = 55, | ||||
|     OC_KEY_8 = 56, | ||||
|     OC_KEY_9 = 57, | ||||
|     OC_KEY_SEMICOLON = 59, // ;
 | ||||
|     OC_KEY_EQUAL = 61,     // =
 | ||||
|     OC_KEY_A = 65, | ||||
|     OC_KEY_B = 66, | ||||
|     OC_KEY_C = 67, | ||||
|     OC_KEY_D = 68, | ||||
|     OC_KEY_E = 69, | ||||
|     OC_KEY_F = 70, | ||||
|     OC_KEY_G = 71, | ||||
|     OC_KEY_H = 72, | ||||
|     OC_KEY_I = 73, | ||||
|     OC_KEY_J = 74, | ||||
|     OC_KEY_K = 75, | ||||
|     OC_KEY_L = 76, | ||||
|     OC_KEY_M = 77, | ||||
|     OC_KEY_N = 78, | ||||
|     OC_KEY_O = 79, | ||||
|     OC_KEY_P = 80, | ||||
|     OC_KEY_Q = 81, | ||||
|     OC_KEY_R = 82, | ||||
|     OC_KEY_S = 83, | ||||
|     OC_KEY_T = 84, | ||||
|     OC_KEY_U = 85, | ||||
|     OC_KEY_V = 86, | ||||
|     OC_KEY_W = 87, | ||||
|     OC_KEY_X = 88, | ||||
|     OC_KEY_Y = 89, | ||||
|     OC_KEY_Z = 90, | ||||
|     OC_KEY_LEFT_BRACKET = 91,  // [
 | ||||
|     OC_KEY_BACKSLASH = 92,     // \ */
 | ||||
|     OC_KEY_RIGHT_BRACKET = 93, // ]
 | ||||
|     OC_KEY_GRAVE_ACCENT = 96,  // `
 | ||||
|     OC_KEY_WORLD_1 = 161,      // non-US #1
 | ||||
|     OC_KEY_WORLD_2 = 162,      // non-US #2
 | ||||
|     OC_KEY_ESCAPE = 256, | ||||
|     OC_KEY_ENTER = 257, | ||||
|     OC_KEY_TAB = 258, | ||||
|     OC_KEY_BACKSPACE = 259, | ||||
|     OC_KEY_INSERT = 260, | ||||
|     OC_KEY_DELETE = 261, | ||||
|     OC_KEY_RIGHT = 262, | ||||
|     OC_KEY_LEFT = 263, | ||||
|     OC_KEY_DOWN = 264, | ||||
|     OC_KEY_UP = 265, | ||||
|     OC_KEY_PAGE_UP = 266, | ||||
|     OC_KEY_PAGE_DOWN = 267, | ||||
|     OC_KEY_HOME = 268, | ||||
|     OC_KEY_END = 269, | ||||
|     OC_KEY_CAPS_LOCK = 280, | ||||
|     OC_KEY_SCROLL_LOCK = 281, | ||||
|     OC_KEY_NUM_LOCK = 282, | ||||
|     OC_KEY_PRINT_SCREEN = 283, | ||||
|     OC_KEY_PAUSE = 284, | ||||
|     OC_KEY_F1 = 290, | ||||
|     OC_KEY_F2 = 291, | ||||
|     OC_KEY_F3 = 292, | ||||
|     OC_KEY_F4 = 293, | ||||
|     OC_KEY_F5 = 294, | ||||
|     OC_KEY_F6 = 295, | ||||
|     OC_KEY_F7 = 296, | ||||
|     OC_KEY_F8 = 297, | ||||
|     OC_KEY_F9 = 298, | ||||
|     OC_KEY_F10 = 299, | ||||
|     OC_KEY_F11 = 300, | ||||
|     OC_KEY_F12 = 301, | ||||
|     OC_KEY_F13 = 302, | ||||
|     OC_KEY_F14 = 303, | ||||
|     OC_KEY_F15 = 304, | ||||
|     OC_KEY_F16 = 305, | ||||
|     OC_KEY_F17 = 306, | ||||
|     OC_KEY_F18 = 307, | ||||
|     OC_KEY_F19 = 308, | ||||
|     OC_KEY_F20 = 309, | ||||
|     OC_KEY_F21 = 310, | ||||
|     OC_KEY_F22 = 311, | ||||
|     OC_KEY_F23 = 312, | ||||
|     OC_KEY_F24 = 313, | ||||
|     OC_KEY_F25 = 314, | ||||
|     OC_KEY_KP_0 = 320, | ||||
|     OC_KEY_KP_1 = 321, | ||||
|     OC_KEY_KP_2 = 322, | ||||
|     OC_KEY_KP_3 = 323, | ||||
|     OC_KEY_KP_4 = 324, | ||||
|     OC_KEY_KP_5 = 325, | ||||
|     OC_KEY_KP_6 = 326, | ||||
|     OC_KEY_KP_7 = 327, | ||||
|     OC_KEY_KP_8 = 328, | ||||
|     OC_KEY_KP_9 = 329, | ||||
|     OC_KEY_KP_DECIMAL = 330, | ||||
|     OC_KEY_KP_DIVIDE = 331, | ||||
|     OC_KEY_KP_MULTIPLY = 332, | ||||
|     OC_KEY_KP_SUBTRACT = 333, | ||||
|     OC_KEY_KP_ADD = 334, | ||||
|     OC_KEY_KP_ENTER = 335, | ||||
|     OC_KEY_KP_EQUAL = 336, | ||||
|     OC_KEY_LEFT_SHIFT = 340, | ||||
|     OC_KEY_LEFT_CONTROL = 341, | ||||
|     OC_KEY_LEFT_ALT = 342, | ||||
|     OC_KEY_LEFT_SUPER = 343, | ||||
|     OC_KEY_RIGHT_SHIFT = 344, | ||||
|     OC_KEY_RIGHT_CONTROL = 345, | ||||
|     OC_KEY_RIGHT_ALT = 346, | ||||
|     OC_KEY_RIGHT_SUPER = 347, | ||||
|     OC_KEY_MENU = 348, | ||||
|     OC_KEY_COUNT | ||||
| } oc_key_code; | ||||
| 
 | ||||
| typedef enum | ||||
| { | ||||
|     OC_KEYMOD_NONE = 0x00, | ||||
|     OC_KEYMOD_ALT = 0x01, | ||||
|     OC_KEYMOD_SHIFT = 0x02, | ||||
|     OC_KEYMOD_CTRL = 0x04, | ||||
|     OC_KEYMOD_CMD = 0x08, | ||||
|     OC_KEYMOD_MAIN_MODIFIER = 0x16 /* CMD on Mac, CTRL on Win32 */ | ||||
| } oc_keymod_flags; | ||||
| 
 | ||||
| typedef enum | ||||
| { | ||||
|     OC_MOUSE_LEFT = 0x00, | ||||
|     OC_MOUSE_RIGHT = 0x01, | ||||
|     OC_MOUSE_MIDDLE = 0x02, | ||||
|     OC_MOUSE_EXT1 = 0x03, | ||||
|     OC_MOUSE_EXT2 = 0x04, | ||||
|     OC_MOUSE_BUTTON_COUNT | ||||
| } oc_mouse_button; | ||||
| 
 | ||||
| typedef struct oc_key_event // keyboard and mouse buttons input
 | ||||
| { | ||||
|     oc_key_action action; | ||||
|     i32 code; | ||||
|     oc_keymod_flags mods; | ||||
|     char label[8]; | ||||
|     u8 labelLen; | ||||
|     int clickCount; | ||||
| } oc_key_event; | ||||
| 
 | ||||
| typedef struct oc_char_event // character input
 | ||||
| { | ||||
|     oc_utf32 codepoint; | ||||
|     char sequence[8]; | ||||
|     u8 seqLen; | ||||
| } oc_char_event; | ||||
| 
 | ||||
| typedef struct oc_mouse_event // mouse move/scroll
 | ||||
| { | ||||
|     f32 x; | ||||
|     f32 y; | ||||
|     f32 deltaX; | ||||
|     f32 deltaY; | ||||
|     oc_keymod_flags mods; | ||||
| } oc_mouse_event; | ||||
| 
 | ||||
| typedef struct oc_move_event // window resize / move
 | ||||
| { | ||||
|     oc_rect frame; | ||||
|     oc_rect content; | ||||
| } oc_move_event; | ||||
| 
 | ||||
| typedef struct oc_event | ||||
| { | ||||
|     //TODO clipboard and path drop
 | ||||
|     oc_window window; | ||||
|     oc_event_type type; | ||||
| 
 | ||||
|     union | ||||
|     { | ||||
|         u64 h; | ||||
|     } oc_window; | ||||
|         oc_key_event key; | ||||
|         oc_char_event character; | ||||
|         oc_mouse_event mouse; | ||||
|         oc_move_event move; | ||||
|         oc_str8_list paths; | ||||
|     }; | ||||
| 
 | ||||
|     typedef enum | ||||
|     { | ||||
|         OC_MOUSE_CURSOR_ARROW, | ||||
|         OC_MOUSE_CURSOR_RESIZE_0, | ||||
|         OC_MOUSE_CURSOR_RESIZE_90, | ||||
|         OC_MOUSE_CURSOR_RESIZE_45, | ||||
|         OC_MOUSE_CURSOR_RESIZE_135, | ||||
|         OC_MOUSE_CURSOR_TEXT | ||||
|     } oc_mouse_cursor; | ||||
| 
 | ||||
|     typedef i32 oc_window_style; | ||||
|     static const oc_window_style OC_WINDOW_STYLE_NO_TITLE = 0x01 << 0, | ||||
|                                  OC_WINDOW_STYLE_FIXED_SIZE = 0x01 << 1, | ||||
|                                  OC_WINDOW_STYLE_NO_CLOSE = 0x01 << 2, | ||||
|                                  OC_WINDOW_STYLE_NO_MINIFY = 0x01 << 3, | ||||
|                                  OC_WINDOW_STYLE_NO_FOCUS = 0x01 << 4, | ||||
|                                  OC_WINDOW_STYLE_FLOAT = 0x01 << 5, | ||||
|                                  OC_WINDOW_STYLE_POPUPMENU = 0x01 << 6, | ||||
|                                  OC_WINDOW_STYLE_NO_BUTTONS = 0x01 << 7; | ||||
| 
 | ||||
|     typedef enum | ||||
|     { | ||||
|         OC_EVENT_NONE, | ||||
|         OC_EVENT_KEYBOARD_MODS, //TODO: remove, keep only key?
 | ||||
|         OC_EVENT_KEYBOARD_KEY, | ||||
|         OC_EVENT_KEYBOARD_CHAR, | ||||
|         OC_EVENT_MOUSE_BUTTON, | ||||
|         OC_EVENT_MOUSE_MOVE, | ||||
|         OC_EVENT_MOUSE_WHEEL, | ||||
|         OC_EVENT_MOUSE_ENTER, | ||||
|         OC_EVENT_MOUSE_LEAVE, | ||||
|         OC_EVENT_WINDOW_RESIZE, | ||||
|         OC_EVENT_WINDOW_MOVE, | ||||
|         OC_EVENT_WINDOW_FOCUS, | ||||
|         OC_EVENT_WINDOW_UNFOCUS, | ||||
|         OC_EVENT_WINDOW_HIDE, // rename to minimize?
 | ||||
|         OC_EVENT_WINDOW_SHOW, // rename to restore?
 | ||||
|         OC_EVENT_WINDOW_CLOSE, | ||||
|         OC_EVENT_PATHDROP, | ||||
|         OC_EVENT_FRAME, | ||||
|         OC_EVENT_QUIT | ||||
|     } oc_event_type; | ||||
| 
 | ||||
|     typedef enum | ||||
|     { | ||||
|         OC_KEY_NO_ACTION, | ||||
|         OC_KEY_PRESS, | ||||
|         OC_KEY_RELEASE, | ||||
|         OC_KEY_REPEAT | ||||
|     } oc_key_action; | ||||
| 
 | ||||
|     typedef enum | ||||
|     { | ||||
|         OC_KEY_UNKNOWN = 0, | ||||
|         OC_KEY_SPACE = 32, | ||||
|         OC_KEY_APOSTROPHE = 39, /* ' */ | ||||
|         OC_KEY_COMMA = 44,      /* , */ | ||||
|         OC_KEY_MINUS = 45,      // -
 | ||||
|         OC_KEY_PERIOD = 46,     // .
 | ||||
|         OC_KEY_SLASH = 47,      // /
 | ||||
|         OC_KEY_0 = 48, | ||||
|         OC_KEY_1 = 49, | ||||
|         OC_KEY_2 = 50, | ||||
|         OC_KEY_3 = 51, | ||||
|         OC_KEY_4 = 52, | ||||
|         OC_KEY_5 = 53, | ||||
|         OC_KEY_6 = 54, | ||||
|         OC_KEY_7 = 55, | ||||
|         OC_KEY_8 = 56, | ||||
|         OC_KEY_9 = 57, | ||||
|         OC_KEY_SEMICOLON = 59, // ;
 | ||||
|         OC_KEY_EQUAL = 61,     // =
 | ||||
|         OC_KEY_A = 65, | ||||
|         OC_KEY_B = 66, | ||||
|         OC_KEY_C = 67, | ||||
|         OC_KEY_D = 68, | ||||
|         OC_KEY_E = 69, | ||||
|         OC_KEY_F = 70, | ||||
|         OC_KEY_G = 71, | ||||
|         OC_KEY_H = 72, | ||||
|         OC_KEY_I = 73, | ||||
|         OC_KEY_J = 74, | ||||
|         OC_KEY_K = 75, | ||||
|         OC_KEY_L = 76, | ||||
|         OC_KEY_M = 77, | ||||
|         OC_KEY_N = 78, | ||||
|         OC_KEY_O = 79, | ||||
|         OC_KEY_P = 80, | ||||
|         OC_KEY_Q = 81, | ||||
|         OC_KEY_R = 82, | ||||
|         OC_KEY_S = 83, | ||||
|         OC_KEY_T = 84, | ||||
|         OC_KEY_U = 85, | ||||
|         OC_KEY_V = 86, | ||||
|         OC_KEY_W = 87, | ||||
|         OC_KEY_X = 88, | ||||
|         OC_KEY_Y = 89, | ||||
|         OC_KEY_Z = 90, | ||||
|         OC_KEY_LEFT_BRACKET = 91,  // [
 | ||||
|         OC_KEY_BACKSLASH = 92,     // \ */
 | ||||
|         OC_KEY_RIGHT_BRACKET = 93, // ]
 | ||||
|         OC_KEY_GRAVE_ACCENT = 96,  // `
 | ||||
|         OC_KEY_WORLD_1 = 161,      // non-US #1
 | ||||
|         OC_KEY_WORLD_2 = 162,      // non-US #2
 | ||||
|         OC_KEY_ESCAPE = 256, | ||||
|         OC_KEY_ENTER = 257, | ||||
|         OC_KEY_TAB = 258, | ||||
|         OC_KEY_BACKSPACE = 259, | ||||
|         OC_KEY_INSERT = 260, | ||||
|         OC_KEY_DELETE = 261, | ||||
|         OC_KEY_RIGHT = 262, | ||||
|         OC_KEY_LEFT = 263, | ||||
|         OC_KEY_DOWN = 264, | ||||
|         OC_KEY_UP = 265, | ||||
|         OC_KEY_PAGE_UP = 266, | ||||
|         OC_KEY_PAGE_DOWN = 267, | ||||
|         OC_KEY_HOME = 268, | ||||
|         OC_KEY_END = 269, | ||||
|         OC_KEY_CAPS_LOCK = 280, | ||||
|         OC_KEY_SCROLL_LOCK = 281, | ||||
|         OC_KEY_NUM_LOCK = 282, | ||||
|         OC_KEY_PRINT_SCREEN = 283, | ||||
|         OC_KEY_PAUSE = 284, | ||||
|         OC_KEY_F1 = 290, | ||||
|         OC_KEY_F2 = 291, | ||||
|         OC_KEY_F3 = 292, | ||||
|         OC_KEY_F4 = 293, | ||||
|         OC_KEY_F5 = 294, | ||||
|         OC_KEY_F6 = 295, | ||||
|         OC_KEY_F7 = 296, | ||||
|         OC_KEY_F8 = 297, | ||||
|         OC_KEY_F9 = 298, | ||||
|         OC_KEY_F10 = 299, | ||||
|         OC_KEY_F11 = 300, | ||||
|         OC_KEY_F12 = 301, | ||||
|         OC_KEY_F13 = 302, | ||||
|         OC_KEY_F14 = 303, | ||||
|         OC_KEY_F15 = 304, | ||||
|         OC_KEY_F16 = 305, | ||||
|         OC_KEY_F17 = 306, | ||||
|         OC_KEY_F18 = 307, | ||||
|         OC_KEY_F19 = 308, | ||||
|         OC_KEY_F20 = 309, | ||||
|         OC_KEY_F21 = 310, | ||||
|         OC_KEY_F22 = 311, | ||||
|         OC_KEY_F23 = 312, | ||||
|         OC_KEY_F24 = 313, | ||||
|         OC_KEY_F25 = 314, | ||||
|         OC_KEY_KP_0 = 320, | ||||
|         OC_KEY_KP_1 = 321, | ||||
|         OC_KEY_KP_2 = 322, | ||||
|         OC_KEY_KP_3 = 323, | ||||
|         OC_KEY_KP_4 = 324, | ||||
|         OC_KEY_KP_5 = 325, | ||||
|         OC_KEY_KP_6 = 326, | ||||
|         OC_KEY_KP_7 = 327, | ||||
|         OC_KEY_KP_8 = 328, | ||||
|         OC_KEY_KP_9 = 329, | ||||
|         OC_KEY_KP_DECIMAL = 330, | ||||
|         OC_KEY_KP_DIVIDE = 331, | ||||
|         OC_KEY_KP_MULTIPLY = 332, | ||||
|         OC_KEY_KP_SUBTRACT = 333, | ||||
|         OC_KEY_KP_ADD = 334, | ||||
|         OC_KEY_KP_ENTER = 335, | ||||
|         OC_KEY_KP_EQUAL = 336, | ||||
|         OC_KEY_LEFT_SHIFT = 340, | ||||
|         OC_KEY_LEFT_CONTROL = 341, | ||||
|         OC_KEY_LEFT_ALT = 342, | ||||
|         OC_KEY_LEFT_SUPER = 343, | ||||
|         OC_KEY_RIGHT_SHIFT = 344, | ||||
|         OC_KEY_RIGHT_CONTROL = 345, | ||||
|         OC_KEY_RIGHT_ALT = 346, | ||||
|         OC_KEY_RIGHT_SUPER = 347, | ||||
|         OC_KEY_MENU = 348, | ||||
|         OC_KEY_COUNT | ||||
|     } oc_key_code; | ||||
| 
 | ||||
|     typedef enum | ||||
|     { | ||||
|         OC_KEYMOD_NONE = 0x00, | ||||
|         OC_KEYMOD_ALT = 0x01, | ||||
|         OC_KEYMOD_SHIFT = 0x02, | ||||
|         OC_KEYMOD_CTRL = 0x04, | ||||
|         OC_KEYMOD_CMD = 0x08, | ||||
|         OC_KEYMOD_MAIN_MODIFIER = 0x16 /* CMD on Mac, CTRL on Win32 */ | ||||
|     } oc_keymod_flags; | ||||
| 
 | ||||
|     typedef enum | ||||
|     { | ||||
|         OC_MOUSE_LEFT = 0x00, | ||||
|         OC_MOUSE_RIGHT = 0x01, | ||||
|         OC_MOUSE_MIDDLE = 0x02, | ||||
|         OC_MOUSE_EXT1 = 0x03, | ||||
|         OC_MOUSE_EXT2 = 0x04, | ||||
|         OC_MOUSE_BUTTON_COUNT | ||||
|     } oc_mouse_button; | ||||
| 
 | ||||
|     typedef struct oc_key_event // keyboard and mouse buttons input
 | ||||
|     { | ||||
|         oc_key_action action; | ||||
|         i32 code; | ||||
|         oc_keymod_flags mods; | ||||
|         char label[8]; | ||||
|         u8 labelLen; | ||||
|         int clickCount; | ||||
|     } oc_key_event; | ||||
| 
 | ||||
|     typedef struct oc_char_event // character input
 | ||||
|     { | ||||
|         oc_utf32 codepoint; | ||||
|         char sequence[8]; | ||||
|         u8 seqLen; | ||||
|     } oc_char_event; | ||||
| 
 | ||||
|     typedef struct oc_mouse_event // mouse move/scroll
 | ||||
|     { | ||||
|         f32 x; | ||||
|         f32 y; | ||||
|         f32 deltaX; | ||||
|         f32 deltaY; | ||||
|         oc_keymod_flags mods; | ||||
|     } oc_mouse_event; | ||||
| 
 | ||||
|     typedef struct oc_move_event // window resize / move
 | ||||
|     { | ||||
|         oc_rect frame; | ||||
|         oc_rect content; | ||||
|     } oc_move_event; | ||||
| 
 | ||||
|     typedef struct oc_event | ||||
|     { | ||||
|         //TODO clipboard and path drop
 | ||||
|         oc_window window; | ||||
|         oc_event_type type; | ||||
| 
 | ||||
|         union | ||||
|         { | ||||
|             oc_key_event key; | ||||
|             oc_char_event character; | ||||
|             oc_mouse_event mouse; | ||||
|             oc_move_event move; | ||||
|             oc_str8_list paths; | ||||
|         }; | ||||
| 
 | ||||
|     } oc_event; | ||||
| } oc_event; | ||||
| 
 | ||||
| //NOTE: these APIs are not directly available to Orca apps
 | ||||
| #if !defined(OC_PLATFORM_ORCA) || !(OC_PLATFORM_ORCA) | ||||
|     //--------------------------------------------------------------------
 | ||||
|     // app management
 | ||||
|     //--------------------------------------------------------------------
 | ||||
| //--------------------------------------------------------------------
 | ||||
| // app management
 | ||||
| //--------------------------------------------------------------------
 | ||||
| 
 | ||||
|     ORCA_API void oc_init(void); | ||||
|     ORCA_API void oc_terminate(void); | ||||
| ORCA_API void oc_init(void); | ||||
| ORCA_API void oc_terminate(void); | ||||
| 
 | ||||
|     ORCA_API bool oc_should_quit(void); | ||||
|     ORCA_API void oc_cancel_quit(void); | ||||
|     ORCA_API void oc_request_quit(void); | ||||
| ORCA_API bool oc_should_quit(void); | ||||
| ORCA_API void oc_cancel_quit(void); | ||||
| ORCA_API void oc_request_quit(void); | ||||
| 
 | ||||
|     ORCA_API void oc_set_cursor(oc_mouse_cursor cursor); | ||||
| ORCA_API void oc_set_cursor(oc_mouse_cursor cursor); | ||||
| 
 | ||||
|     //--------------------------------------------------------------------
 | ||||
|     // Main loop and events handling
 | ||||
|     //--------------------------------------------------------------------
 | ||||
|     /*NOTE:
 | ||||
| //--------------------------------------------------------------------
 | ||||
| // Main loop and events handling
 | ||||
| //--------------------------------------------------------------------
 | ||||
| /*NOTE:
 | ||||
| 	oc_pump_events() pumps system events into the event queue. A timeout of 0 polls for events, | ||||
| 	while a timeout of -1 blocks for events. A timeout > 0 blocks until new events are available | ||||
| 	or the timeout elapses. | ||||
| 
 | ||||
| 	oc_next_event() get the next event from the event queue, allocating from the passed arena | ||||
| */ | ||||
|     ORCA_API void oc_pump_events(f64 timeout); | ||||
|     ORCA_API oc_event* oc_next_event(oc_arena* arena); | ||||
| ORCA_API void oc_pump_events(f64 timeout); | ||||
| ORCA_API oc_event* oc_next_event(oc_arena* arena); | ||||
| 
 | ||||
|     typedef void (*oc_live_resize_callback)(oc_event event, void* data); | ||||
|     ORCA_API void oc_set_live_resize_callback(oc_live_resize_callback callback, void* data); | ||||
| typedef void (*oc_live_resize_callback)(oc_event event, void* data); | ||||
| ORCA_API void oc_set_live_resize_callback(oc_live_resize_callback callback, void* data); | ||||
| 
 | ||||
|     //--------------------------------------------------------------------
 | ||||
|     // window management
 | ||||
|     //--------------------------------------------------------------------
 | ||||
| //--------------------------------------------------------------------
 | ||||
| // window management
 | ||||
| //--------------------------------------------------------------------
 | ||||
| 
 | ||||
|     ORCA_API bool oc_window_handle_is_null(oc_window window); | ||||
|     ORCA_API oc_window oc_window_null_handle(void); | ||||
| ORCA_API bool oc_window_handle_is_null(oc_window window); | ||||
| ORCA_API oc_window oc_window_null_handle(void); | ||||
| 
 | ||||
|     ORCA_API oc_window oc_window_create(oc_rect contentRect, oc_str8 title, oc_window_style style); | ||||
|     ORCA_API void oc_window_destroy(oc_window window); | ||||
|     ORCA_API void* oc_window_native_pointer(oc_window window); | ||||
| ORCA_API oc_window oc_window_create(oc_rect contentRect, oc_str8 title, oc_window_style style); | ||||
| ORCA_API void oc_window_destroy(oc_window window); | ||||
| ORCA_API void* oc_window_native_pointer(oc_window window); | ||||
| 
 | ||||
|     ORCA_API bool oc_window_should_close(oc_window window); | ||||
|     ORCA_API void oc_window_request_close(oc_window window); | ||||
|     ORCA_API void oc_window_cancel_close(oc_window window); | ||||
| ORCA_API bool oc_window_should_close(oc_window window); | ||||
| ORCA_API void oc_window_request_close(oc_window window); | ||||
| ORCA_API void oc_window_cancel_close(oc_window window); | ||||
| 
 | ||||
|     ORCA_API bool oc_window_is_hidden(oc_window window); | ||||
|     ORCA_API void oc_window_hide(oc_window window); | ||||
|     ORCA_API void oc_window_show(oc_window window); | ||||
| ORCA_API bool oc_window_is_hidden(oc_window window); | ||||
| ORCA_API void oc_window_hide(oc_window window); | ||||
| ORCA_API void oc_window_show(oc_window window); | ||||
| 
 | ||||
|     ORCA_API bool oc_window_is_minimized(oc_window window); | ||||
|     ORCA_API void oc_window_minimize(oc_window window); | ||||
|     ORCA_API void oc_window_restore(oc_window window); | ||||
| ORCA_API void oc_window_set_title(oc_window window, oc_str8 title); | ||||
| 
 | ||||
|     ORCA_API bool oc_window_has_focus(oc_window window); | ||||
|     ORCA_API void oc_window_focus(oc_window window); | ||||
|     ORCA_API void oc_window_unfocus(oc_window window); | ||||
| ORCA_API bool oc_window_is_minimized(oc_window window); | ||||
| ORCA_API bool oc_window_is_maximized(oc_window window); | ||||
| ORCA_API void oc_window_minimize(oc_window window); | ||||
| ORCA_API void oc_window_maximize(oc_window window); | ||||
| ORCA_API void oc_window_restore(oc_window window); | ||||
| 
 | ||||
|     ORCA_API void oc_window_send_to_back(oc_window window); | ||||
|     ORCA_API void oc_window_bring_to_front(oc_window window); | ||||
| ORCA_API bool oc_window_has_focus(oc_window window); | ||||
| ORCA_API void oc_window_focus(oc_window window); | ||||
| ORCA_API void oc_window_unfocus(oc_window window); | ||||
| 
 | ||||
|     ORCA_API oc_rect oc_window_get_frame_rect(oc_window window); | ||||
|     ORCA_API void oc_window_set_frame_rect(oc_window window, oc_rect rect); | ||||
|     ORCA_API void oc_window_set_frame_position(oc_window window, oc_vec2 position); | ||||
|     ORCA_API void oc_window_set_frame_size(oc_window window, oc_vec2 size); | ||||
| ORCA_API void oc_window_send_to_back(oc_window window); | ||||
| ORCA_API void oc_window_bring_to_front(oc_window window); | ||||
| 
 | ||||
|     ORCA_API oc_rect oc_window_get_content_rect(oc_window window); | ||||
|     ORCA_API void oc_window_set_content_rect(oc_window window, oc_rect rect); | ||||
|     ORCA_API void oc_window_set_content_position(oc_window window, oc_vec2 position); | ||||
|     ORCA_API void oc_window_set_content_size(oc_window window, oc_vec2 size); | ||||
| ORCA_API oc_rect oc_window_get_frame_rect(oc_window window); | ||||
| ORCA_API void oc_window_set_frame_rect(oc_window window, oc_rect rect); | ||||
| ORCA_API void oc_window_set_frame_position(oc_window window, oc_vec2 position); | ||||
| ORCA_API void oc_window_set_frame_size(oc_window window, oc_vec2 size); | ||||
| 
 | ||||
|     ORCA_API void oc_window_center(oc_window window); | ||||
| ORCA_API oc_rect oc_window_get_content_rect(oc_window window); | ||||
| ORCA_API void oc_window_set_content_rect(oc_window window, oc_rect rect); | ||||
| ORCA_API void oc_window_set_content_position(oc_window window, oc_vec2 position); | ||||
| ORCA_API void oc_window_set_content_size(oc_window window, oc_vec2 size); | ||||
| 
 | ||||
|     ORCA_API oc_rect oc_window_content_rect_for_frame_rect(oc_rect frameRect, oc_window_style style); | ||||
|     ORCA_API oc_rect oc_window_frame_rect_for_content_rect(oc_rect contentRect, oc_window_style style); | ||||
| ORCA_API void oc_window_center(oc_window window); | ||||
| 
 | ||||
|     //---------------------------------------------------------------
 | ||||
|     // Dispatching stuff to the main thread
 | ||||
|     //---------------------------------------------------------------
 | ||||
| ORCA_API oc_rect oc_window_content_rect_for_frame_rect(oc_rect frameRect, oc_window_style style); | ||||
| ORCA_API oc_rect oc_window_frame_rect_for_content_rect(oc_rect contentRect, oc_window_style style); | ||||
| 
 | ||||
|     typedef i32 (*oc_dispatch_proc)(void* user); | ||||
| //---------------------------------------------------------------
 | ||||
| // Dispatching stuff to the main thread
 | ||||
| //---------------------------------------------------------------
 | ||||
| 
 | ||||
|     ORCA_API i32 oc_dispatch_on_main_thread_sync(oc_window main_window, oc_dispatch_proc proc, void* user); | ||||
| typedef i32 (*oc_dispatch_proc)(void* user); | ||||
| 
 | ||||
|     //--------------------------------------------------------------------
 | ||||
|     // Clipboard
 | ||||
|     //--------------------------------------------------------------------
 | ||||
|     ORCA_API void oc_clipboard_clear(void); | ||||
| ORCA_API i32 oc_dispatch_on_main_thread_sync(oc_window main_window, oc_dispatch_proc proc, void* user); | ||||
| 
 | ||||
|     ORCA_API void oc_clipboard_set_string(oc_str8 string); | ||||
|     ORCA_API oc_str8 oc_clipboard_get_string(oc_arena* arena); | ||||
|     ORCA_API oc_str8 oc_clipboard_copy_string(oc_str8 backing); | ||||
| //--------------------------------------------------------------------
 | ||||
| // Clipboard
 | ||||
| //--------------------------------------------------------------------
 | ||||
| ORCA_API void oc_clipboard_clear(void); | ||||
| 
 | ||||
|     ORCA_API bool oc_clipboard_has_tag(const char* tag); | ||||
|     ORCA_API void oc_clipboard_set_data_for_tag(const char* tag, oc_str8 data); | ||||
|     ORCA_API oc_str8 oc_clipboard_get_data_for_tag(oc_arena* arena, const char* tag); | ||||
| ORCA_API void oc_clipboard_set_string(oc_str8 string); | ||||
| ORCA_API oc_str8 oc_clipboard_get_string(oc_arena* arena); | ||||
| ORCA_API oc_str8 oc_clipboard_copy_string(oc_str8 backing); | ||||
| 
 | ||||
|     //--------------------------------------------------------------------
 | ||||
|     // native open/save/alert windows
 | ||||
|     //--------------------------------------------------------------------
 | ||||
| ORCA_API bool oc_clipboard_has_tag(const char* tag); | ||||
| ORCA_API void oc_clipboard_set_data_for_tag(const char* tag, oc_str8 data); | ||||
| ORCA_API oc_str8 oc_clipboard_get_data_for_tag(oc_arena* arena, const char* tag); | ||||
| 
 | ||||
|     ORCA_API oc_str8 oc_open_dialog(oc_arena* arena, | ||||
|                                     oc_str8 title, | ||||
|                                     oc_str8 defaultPath, | ||||
|                                     oc_str8_list filters, | ||||
|                                     bool directory); | ||||
| //--------------------------------------------------------------------
 | ||||
| // native open/save/alert windows
 | ||||
| //--------------------------------------------------------------------
 | ||||
| 
 | ||||
|     ORCA_API oc_str8 oc_save_dialog(oc_arena* arena, | ||||
|                                     oc_str8 title, | ||||
|                                     oc_str8 defaultPath, | ||||
|                                     oc_str8_list filters); | ||||
| ORCA_API oc_str8 oc_open_dialog(oc_arena* arena, | ||||
|                                 oc_str8 title, | ||||
|                                 oc_str8 defaultPath, | ||||
|                                 oc_str8_list filters, | ||||
|                                 bool directory); | ||||
| 
 | ||||
|     ORCA_API int oc_alert_popup(oc_str8 title, | ||||
|                                 oc_str8 message, | ||||
|                                 oc_str8_list options); | ||||
| ORCA_API oc_str8 oc_save_dialog(oc_arena* arena, | ||||
|                                 oc_str8 title, | ||||
|                                 oc_str8 defaultPath, | ||||
|                                 oc_str8_list filters); | ||||
| 
 | ||||
|     //--------------------------------------------------------------------
 | ||||
|     // file system stuff... //TODO: move elsewhere
 | ||||
|     //--------------------------------------------------------------------
 | ||||
|     ORCA_API int oc_file_move(oc_str8 from, oc_str8 to); | ||||
|     ORCA_API int oc_file_remove(oc_str8 path); | ||||
| ORCA_API int oc_alert_popup(oc_str8 title, | ||||
|                             oc_str8 message, | ||||
|                             oc_str8_list options); | ||||
| 
 | ||||
|     ORCA_API int oc_directory_create(oc_str8 path); | ||||
| //--------------------------------------------------------------------
 | ||||
| // file system stuff... //TODO: move elsewhere
 | ||||
| //--------------------------------------------------------------------
 | ||||
| ORCA_API int oc_file_move(oc_str8 from, oc_str8 to); | ||||
| ORCA_API int oc_file_remove(oc_str8 path); | ||||
| 
 | ||||
| ORCA_API int oc_directory_create(oc_str8 path); | ||||
| 
 | ||||
| #else | ||||
| 
 | ||||
|     void ORCA_IMPORT(oc_request_quit)(void); | ||||
| void ORCA_IMPORT(oc_request_quit)(void); | ||||
| 
 | ||||
| void ORCA_IMPORT(oc_runtime_window_set_title)(oc_str8 title); | ||||
| 
 | ||||
| void ORCA_IMPORT(oc_runtime_window_set_size)(oc_vec2 size); | ||||
| 
 | ||||
| #endif // !defined(OC_PLATFORM_ORCA) || !(OC_PLATFORM_ORCA)
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -1471,6 +1471,29 @@ bool oc_window_is_focused(oc_window window) | |||
|     } | ||||
| } | ||||
| 
 | ||||
| void oc_window_set_title(oc_window window, oc_str8 title) | ||||
| { | ||||
|     dispatch_block_t block = ^{ | ||||
|       @autoreleasepool | ||||
|       { | ||||
|           oc_window_data* windowData = oc_window_ptr_from_handle(window); | ||||
|           if(windowData) | ||||
|           { | ||||
|               windowData->osx.nsWindow.title = [[NSString alloc] initWithBytes:title.ptr length:title.len encoding:NSUTF8StringEncoding]; | ||||
|           } | ||||
|       } | ||||
|     }; | ||||
| 
 | ||||
|     if([NSThread isMainThread]) | ||||
|     { | ||||
|         block(); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         dispatch_sync(dispatch_get_main_queue(), block); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| bool oc_window_is_minimized(oc_window window) | ||||
| { | ||||
|     @autoreleasepool | ||||
|  | @ -1634,23 +1657,33 @@ oc_rect oc_window_get_content_rect(oc_window window) | |||
| 
 | ||||
| void oc_window_set_content_rect(oc_window window, oc_rect rect) | ||||
| { | ||||
|     @autoreleasepool | ||||
|     dispatch_block_t block = ^{ | ||||
|       @autoreleasepool | ||||
|       { | ||||
|           oc_window_data* windowData = oc_window_ptr_from_handle(window); | ||||
|           if(windowData) | ||||
|           { | ||||
|               NSScreen* screen = [windowData->osx.nsWindow screen]; | ||||
|               NSRect contentRect = { | ||||
|                   rect.x, | ||||
|                   screen.frame.size.height - rect.y - rect.h, | ||||
|                   rect.w, | ||||
|                   rect.h | ||||
|               }; | ||||
| 
 | ||||
|               NSRect frameRect = [windowData->osx.nsWindow frameRectForContentRect:contentRect]; | ||||
|               [windowData->osx.nsWindow setFrame:frameRect display:YES]; | ||||
|           } | ||||
|       } | ||||
|     }; | ||||
| 
 | ||||
|     if([NSThread isMainThread]) | ||||
|     { | ||||
| 
 | ||||
|         oc_window_data* windowData = oc_window_ptr_from_handle(window); | ||||
|         if(windowData) | ||||
|         { | ||||
|             NSScreen* screen = [windowData->osx.nsWindow screen]; | ||||
|             NSRect contentRect = { | ||||
|                 rect.x, | ||||
|                 screen.frame.size.height - rect.y - rect.h, | ||||
|                 rect.w, | ||||
|                 rect.h | ||||
|             }; | ||||
| 
 | ||||
|             NSRect frameRect = [windowData->osx.nsWindow frameRectForContentRect:contentRect]; | ||||
|             [windowData->osx.nsWindow setFrame:frameRect display:YES]; | ||||
|         } | ||||
|         block(); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         dispatch_sync(dispatch_get_main_queue(), block); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -791,6 +791,20 @@ void oc_window_show(oc_window window) | |||
|     } | ||||
| } | ||||
| 
 | ||||
| void oc_window_set_title(oc_window window, oc_str8 title) | ||||
| { | ||||
|     oc_window_data* windowData = oc_window_ptr_from_handle(window); | ||||
|     if(windowData) | ||||
|     { | ||||
|         oc_arena_scope scratch = oc_scratch_begin(); | ||||
|         const char* titleCString = oc_str8_to_cstring(scratch.arena, title); | ||||
| 
 | ||||
|         SetWindowText(windowData->win32.hWnd, titleCString); | ||||
| 
 | ||||
|         oc_scratch_end(scratch); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| bool oc_window_is_minimized(oc_window window) | ||||
| { | ||||
|     oc_window_data* windowData = oc_window_ptr_from_handle(window); | ||||
|  |  | |||
|  | @ -1448,6 +1448,7 @@ void oc_rectangle_stroke(f32 x, f32 y, f32 w, f32 h) | |||
| 
 | ||||
| void oc_rounded_rectangle_path(f32 x, f32 y, f32 w, f32 h, f32 r) | ||||
| { | ||||
|     r = oc_min(r, oc_min(w / 2, h / 2)); | ||||
|     f32 c = r * 4 * (sqrt(2) - 1) / 3; | ||||
| 
 | ||||
|     oc_move_to(x + r, y); | ||||
|  |  | |||
|  | @ -1,10 +1,10 @@ | |||
| /************************************************************/ /** | ||||
| * | ||||
| *	@file: mtl_canvas.m | ||||
| *	@author: Martin Fouilleul | ||||
| *	@date: 12/07/2020 | ||||
| *	@revision: 24/01/2023 | ||||
| * | ||||
| /************************************************************/ /** | ||||
| * | ||||
| *	@file: mtl_canvas.m | ||||
| *	@author: Martin Fouilleul | ||||
| *	@date: 12/07/2020 | ||||
| *	@revision: 24/01/2023 | ||||
| * | ||||
| *****************************************************************/ | ||||
| #import <Metal/Metal.h> | ||||
| #import <QuartzCore/CAMetalLayer.h> | ||||
|  | @ -266,10 +266,10 @@ void oc_mtl_encode_path(oc_mtl_canvas_backend* backend, oc_primitive* primitive, | |||
| 
 | ||||
| static bool oc_intersect_hull_legs(oc_vec2 p0, oc_vec2 p1, oc_vec2 p2, oc_vec2 p3, oc_vec2* intersection) | ||||
| { | ||||
|     /*NOTE: check intersection of lines (p0-p1) and (p2-p3) | ||||
| 
 | ||||
| 		P = p0 + u(p1-p0) | ||||
| 		P = p2 + w(p3-p2) | ||||
|     /*NOTE: check intersection of lines (p0-p1) and (p2-p3) | ||||
| 
 | ||||
| 		P = p0 + u(p1-p0) | ||||
| 		P = p2 + w(p3-p2) | ||||
| 	*/ | ||||
|     bool found = false; | ||||
| 
 | ||||
|  | @ -788,9 +788,9 @@ void oc_mtl_stroke_joint(oc_mtl_canvas_backend* backend, | |||
|     } | ||||
| 
 | ||||
|     //NOTE(martin): use the same code as hull offset to find mitter point... | ||||
|     /*NOTE(martin): let vector u = (n0+n1) and vector v = pIntersect - p1 | ||||
| 		then v = u * (2*offset / norm(u)^2) | ||||
| 		(this can be derived from writing the pythagoras theorems in the triangles of the joint) | ||||
|     /*NOTE(martin): let vector u = (n0+n1) and vector v = pIntersect - p1 | ||||
| 		then v = u * (2*offset / norm(u)^2) | ||||
| 		(this can be derived from writing the pythagoras theorems in the triangles of the joint) | ||||
| 	*/ | ||||
|     f32 halfW = 0.5 * attributes->width; | ||||
|     oc_vec2 u = { n0.x + n1.x, n0.y + n1.y }; | ||||
|  | @ -984,96 +984,108 @@ void oc_mtl_render_batch(oc_mtl_canvas_backend* backend, | |||
|         [blitEncoder endEncoding]; | ||||
| 
 | ||||
|         //NOTE: path setup pass | ||||
|         id<MTLComputeCommandEncoder> pathEncoder = [surface->commandBuffer computeCommandEncoder]; | ||||
|         pathEncoder.label = @"path pass"; | ||||
|         [pathEncoder setComputePipelineState:backend->pathPipeline]; | ||||
|         if(pathCount > 0) | ||||
|         { | ||||
|             id<MTLComputeCommandEncoder> pathEncoder = [surface->commandBuffer computeCommandEncoder]; | ||||
|             pathEncoder.label = @"path pass"; | ||||
|             [pathEncoder setComputePipelineState:backend->pathPipeline]; | ||||
| 
 | ||||
|         int tileQueueMax = [backend->tileQueueBuffer length] / sizeof(oc_mtl_tile_queue); | ||||
|             int tileQueueMax = [backend->tileQueueBuffer length] / sizeof(oc_mtl_tile_queue); | ||||
| 
 | ||||
|         [pathEncoder setBytes:&pathCount length:sizeof(int) atIndex:0]; | ||||
|         [pathEncoder setBuffer:backend->pathBuffer[backend->bufferIndex] offset:pathBufferOffset atIndex:1]; | ||||
|         [pathEncoder setBuffer:backend->pathQueueBuffer offset:0 atIndex:2]; | ||||
|         [pathEncoder setBuffer:backend->tileQueueBuffer offset:0 atIndex:3]; | ||||
|         [pathEncoder setBuffer:backend->tileQueueCountBuffer offset:0 atIndex:4]; | ||||
|         [pathEncoder setBytes:&tileQueueMax length:sizeof(int) atIndex:5]; | ||||
|         [pathEncoder setBytes:&tileSize length:sizeof(int) atIndex:6]; | ||||
|         [pathEncoder setBytes:&scale length:sizeof(int) atIndex:7]; | ||||
|             [pathEncoder setBytes:&pathCount length:sizeof(int) atIndex:0]; | ||||
|             [pathEncoder setBuffer:backend->pathBuffer[backend->bufferIndex] offset:pathBufferOffset atIndex:1]; | ||||
|             [pathEncoder setBuffer:backend->pathQueueBuffer offset:0 atIndex:2]; | ||||
|             [pathEncoder setBuffer:backend->tileQueueBuffer offset:0 atIndex:3]; | ||||
|             [pathEncoder setBuffer:backend->tileQueueCountBuffer offset:0 atIndex:4]; | ||||
|             [pathEncoder setBytes:&tileQueueMax length:sizeof(int) atIndex:5]; | ||||
|             [pathEncoder setBytes:&tileSize length:sizeof(int) atIndex:6]; | ||||
|             [pathEncoder setBytes:&scale length:sizeof(int) atIndex:7]; | ||||
| 
 | ||||
|         MTLSize pathGridSize = MTLSizeMake(pathCount, 1, 1); | ||||
|         MTLSize pathGroupSize = MTLSizeMake([backend->pathPipeline maxTotalThreadsPerThreadgroup], 1, 1); | ||||
|             MTLSize pathGridSize = MTLSizeMake(pathCount, 1, 1); | ||||
|             MTLSize pathGroupSize = MTLSizeMake([backend->pathPipeline maxTotalThreadsPerThreadgroup], 1, 1); | ||||
| 
 | ||||
|         [pathEncoder dispatchThreads:pathGridSize threadsPerThreadgroup:pathGroupSize]; | ||||
|         [pathEncoder endEncoding]; | ||||
| 
 | ||||
|         //NOTE: segment setup pass | ||||
|         id<MTLComputeCommandEncoder> segmentEncoder = [surface->commandBuffer computeCommandEncoder]; | ||||
|         segmentEncoder.label = @"segment pass"; | ||||
|         [segmentEncoder setComputePipelineState:backend->segmentPipeline]; | ||||
|             [pathEncoder dispatchThreads:pathGridSize threadsPerThreadgroup:pathGroupSize]; | ||||
|             [pathEncoder endEncoding]; | ||||
|         } | ||||
| 
 | ||||
|         int tileOpMax = [backend->tileOpBuffer length] / sizeof(oc_mtl_tile_op); | ||||
|         int segmentMax = [backend->segmentBuffer length] / sizeof(oc_mtl_segment); | ||||
| 
 | ||||
|         [segmentEncoder setBytes:&eltCount length:sizeof(int) atIndex:0]; | ||||
|         [segmentEncoder setBuffer:backend->elementBuffer[backend->bufferIndex] offset:elementBufferOffset atIndex:1]; | ||||
|         [segmentEncoder setBuffer:backend->segmentCountBuffer offset:0 atIndex:2]; | ||||
|         [segmentEncoder setBuffer:backend->segmentBuffer offset:0 atIndex:3]; | ||||
|         [segmentEncoder setBuffer:backend->pathQueueBuffer offset:0 atIndex:4]; | ||||
|         [segmentEncoder setBuffer:backend->tileQueueBuffer offset:0 atIndex:5]; | ||||
|         [segmentEncoder setBuffer:backend->tileOpBuffer offset:0 atIndex:6]; | ||||
|         [segmentEncoder setBuffer:backend->tileOpCountBuffer offset:0 atIndex:7]; | ||||
|         [segmentEncoder setBytes:&tileOpMax length:sizeof(int) atIndex:8]; | ||||
|         [segmentEncoder setBytes:&segmentMax length:sizeof(int) atIndex:9]; | ||||
|         [segmentEncoder setBytes:&tileSize length:sizeof(int) atIndex:10]; | ||||
|         [segmentEncoder setBytes:&scale length:sizeof(int) atIndex:11]; | ||||
|         [segmentEncoder setBuffer:backend->logBuffer[backend->bufferIndex] offset:0 atIndex:12]; | ||||
|         [segmentEncoder setBuffer:backend->logOffsetBuffer[backend->bufferIndex] offset:0 atIndex:13]; | ||||
|         //NOTE: segment setup pass | ||||
|         if(eltCount > 0) | ||||
|         { | ||||
|             id<MTLComputeCommandEncoder> segmentEncoder = [surface->commandBuffer computeCommandEncoder]; | ||||
|             segmentEncoder.label = @"segment pass"; | ||||
|             [segmentEncoder setComputePipelineState:backend->segmentPipeline]; | ||||
| 
 | ||||
|         MTLSize segmentGridSize = MTLSizeMake(eltCount, 1, 1); | ||||
|         MTLSize segmentGroupSize = MTLSizeMake([backend->segmentPipeline maxTotalThreadsPerThreadgroup], 1, 1); | ||||
|             [segmentEncoder setBytes:&eltCount length:sizeof(int) atIndex:0]; | ||||
|             [segmentEncoder setBuffer:backend->elementBuffer[backend->bufferIndex] offset:elementBufferOffset atIndex:1]; | ||||
|             [segmentEncoder setBuffer:backend->segmentCountBuffer offset:0 atIndex:2]; | ||||
|             [segmentEncoder setBuffer:backend->segmentBuffer offset:0 atIndex:3]; | ||||
|             [segmentEncoder setBuffer:backend->pathQueueBuffer offset:0 atIndex:4]; | ||||
|             [segmentEncoder setBuffer:backend->tileQueueBuffer offset:0 atIndex:5]; | ||||
|             [segmentEncoder setBuffer:backend->tileOpBuffer offset:0 atIndex:6]; | ||||
|             [segmentEncoder setBuffer:backend->tileOpCountBuffer offset:0 atIndex:7]; | ||||
|             [segmentEncoder setBytes:&tileOpMax length:sizeof(int) atIndex:8]; | ||||
|             [segmentEncoder setBytes:&segmentMax length:sizeof(int) atIndex:9]; | ||||
|             [segmentEncoder setBytes:&tileSize length:sizeof(int) atIndex:10]; | ||||
|             [segmentEncoder setBytes:&scale length:sizeof(int) atIndex:11]; | ||||
|             [segmentEncoder setBuffer:backend->logBuffer[backend->bufferIndex] offset:0 atIndex:12]; | ||||
|             [segmentEncoder setBuffer:backend->logOffsetBuffer[backend->bufferIndex] offset:0 atIndex:13]; | ||||
| 
 | ||||
|         [segmentEncoder dispatchThreads:segmentGridSize threadsPerThreadgroup:segmentGroupSize]; | ||||
|         [segmentEncoder endEncoding]; | ||||
|             MTLSize segmentGridSize = MTLSizeMake(eltCount, 1, 1); | ||||
|             MTLSize segmentGroupSize = MTLSizeMake([backend->segmentPipeline maxTotalThreadsPerThreadgroup], 1, 1); | ||||
| 
 | ||||
|             [segmentEncoder dispatchThreads:segmentGridSize threadsPerThreadgroup:segmentGroupSize]; | ||||
|             [segmentEncoder endEncoding]; | ||||
|         } | ||||
| 
 | ||||
|         //NOTE: backprop pass | ||||
|         id<MTLComputeCommandEncoder> backpropEncoder = [surface->commandBuffer computeCommandEncoder]; | ||||
|         backpropEncoder.label = @"backprop pass"; | ||||
|         [backpropEncoder setComputePipelineState:backend->backpropPipeline]; | ||||
|         if(pathCount > 0) | ||||
|         { | ||||
|             id<MTLComputeCommandEncoder> backpropEncoder = [surface->commandBuffer computeCommandEncoder]; | ||||
|             backpropEncoder.label = @"backprop pass"; | ||||
|             [backpropEncoder setComputePipelineState:backend->backpropPipeline]; | ||||
| 
 | ||||
|         [backpropEncoder setBuffer:backend->pathQueueBuffer offset:0 atIndex:0]; | ||||
|         [backpropEncoder setBuffer:backend->tileQueueBuffer offset:0 atIndex:1]; | ||||
|         [backpropEncoder setBuffer:backend->logBuffer[backend->bufferIndex] offset:0 atIndex:2]; | ||||
|         [backpropEncoder setBuffer:backend->logOffsetBuffer[backend->bufferIndex] offset:0 atIndex:3]; | ||||
|             [backpropEncoder setBuffer:backend->pathQueueBuffer offset:0 atIndex:0]; | ||||
|             [backpropEncoder setBuffer:backend->tileQueueBuffer offset:0 atIndex:1]; | ||||
|             [backpropEncoder setBuffer:backend->logBuffer[backend->bufferIndex] offset:0 atIndex:2]; | ||||
|             [backpropEncoder setBuffer:backend->logOffsetBuffer[backend->bufferIndex] offset:0 atIndex:3]; | ||||
| 
 | ||||
|         MTLSize backpropGroupSize = MTLSizeMake([backend->backpropPipeline maxTotalThreadsPerThreadgroup], 1, 1); | ||||
|         MTLSize backpropGridSize = MTLSizeMake(pathCount * backpropGroupSize.width, 1, 1); | ||||
|             MTLSize backpropGroupSize = MTLSizeMake([backend->backpropPipeline maxTotalThreadsPerThreadgroup], 1, 1); | ||||
|             MTLSize backpropGridSize = MTLSizeMake(pathCount * backpropGroupSize.width, 1, 1); | ||||
| 
 | ||||
|         [backpropEncoder dispatchThreads:backpropGridSize threadsPerThreadgroup:backpropGroupSize]; | ||||
|         [backpropEncoder endEncoding]; | ||||
|             [backpropEncoder dispatchThreads:backpropGridSize threadsPerThreadgroup:backpropGroupSize]; | ||||
|             [backpropEncoder endEncoding]; | ||||
|         } | ||||
| 
 | ||||
|         //NOTE: merge pass | ||||
|         id<MTLComputeCommandEncoder> mergeEncoder = [surface->commandBuffer computeCommandEncoder]; | ||||
|         mergeEncoder.label = @"merge pass"; | ||||
|         [mergeEncoder setComputePipelineState:backend->mergePipeline]; | ||||
|         if(pathCount > 0) | ||||
|         { | ||||
|             id<MTLComputeCommandEncoder> mergeEncoder = [surface->commandBuffer computeCommandEncoder]; | ||||
|             mergeEncoder.label = @"merge pass"; | ||||
|             [mergeEncoder setComputePipelineState:backend->mergePipeline]; | ||||
| 
 | ||||
|         [mergeEncoder setBytes:&pathCount length:sizeof(int) atIndex:0]; | ||||
|         [mergeEncoder setBuffer:backend->pathBuffer[backend->bufferIndex] offset:pathBufferOffset atIndex:1]; | ||||
|         [mergeEncoder setBuffer:backend->pathQueueBuffer offset:0 atIndex:2]; | ||||
|         [mergeEncoder setBuffer:backend->tileQueueBuffer offset:0 atIndex:3]; | ||||
|         [mergeEncoder setBuffer:backend->tileOpBuffer offset:0 atIndex:4]; | ||||
|         [mergeEncoder setBuffer:backend->tileOpCountBuffer offset:0 atIndex:5]; | ||||
|         [mergeEncoder setBuffer:backend->rasterDispatchBuffer offset:0 atIndex:6]; | ||||
|         [mergeEncoder setBuffer:backend->screenTilesBuffer offset:0 atIndex:7]; | ||||
|         [mergeEncoder setBytes:&tileOpMax length:sizeof(int) atIndex:8]; | ||||
|         [mergeEncoder setBytes:&tileSize length:sizeof(int) atIndex:9]; | ||||
|         [mergeEncoder setBytes:&scale length:sizeof(float) atIndex:10]; | ||||
|         [mergeEncoder setBuffer:backend->logBuffer[backend->bufferIndex] offset:0 atIndex:11]; | ||||
|         [mergeEncoder setBuffer:backend->logOffsetBuffer[backend->bufferIndex] offset:0 atIndex:12]; | ||||
|             [mergeEncoder setBytes:&pathCount length:sizeof(int) atIndex:0]; | ||||
|             [mergeEncoder setBuffer:backend->pathBuffer[backend->bufferIndex] offset:pathBufferOffset atIndex:1]; | ||||
|             [mergeEncoder setBuffer:backend->pathQueueBuffer offset:0 atIndex:2]; | ||||
|             [mergeEncoder setBuffer:backend->tileQueueBuffer offset:0 atIndex:3]; | ||||
|             [mergeEncoder setBuffer:backend->tileOpBuffer offset:0 atIndex:4]; | ||||
|             [mergeEncoder setBuffer:backend->tileOpCountBuffer offset:0 atIndex:5]; | ||||
|             [mergeEncoder setBuffer:backend->rasterDispatchBuffer offset:0 atIndex:6]; | ||||
|             [mergeEncoder setBuffer:backend->screenTilesBuffer offset:0 atIndex:7]; | ||||
|             [mergeEncoder setBytes:&tileOpMax length:sizeof(int) atIndex:8]; | ||||
|             [mergeEncoder setBytes:&tileSize length:sizeof(int) atIndex:9]; | ||||
|             [mergeEncoder setBytes:&scale length:sizeof(float) atIndex:10]; | ||||
|             [mergeEncoder setBuffer:backend->logBuffer[backend->bufferIndex] offset:0 atIndex:11]; | ||||
|             [mergeEncoder setBuffer:backend->logOffsetBuffer[backend->bufferIndex] offset:0 atIndex:12]; | ||||
| 
 | ||||
|         MTLSize mergeGridSize = MTLSizeMake(nTilesX, nTilesY, 1); | ||||
|         MTLSize mergeGroupSize = MTLSizeMake(OC_MTL_TILE_SIZE, OC_MTL_TILE_SIZE, 1); | ||||
|             MTLSize mergeGridSize = MTLSizeMake(nTilesX, nTilesY, 1); | ||||
|             MTLSize mergeGroupSize = MTLSizeMake(OC_MTL_TILE_SIZE, OC_MTL_TILE_SIZE, 1); | ||||
| 
 | ||||
|         [mergeEncoder dispatchThreads:mergeGridSize threadsPerThreadgroup:mergeGroupSize]; | ||||
|         [mergeEncoder endEncoding]; | ||||
|             [mergeEncoder dispatchThreads:mergeGridSize threadsPerThreadgroup:mergeGroupSize]; | ||||
|             [mergeEncoder endEncoding]; | ||||
|         } | ||||
| 
 | ||||
|         //NOTE: raster pass | ||||
|         id<MTLComputeCommandEncoder> rasterEncoder = [surface->commandBuffer computeCommandEncoder]; | ||||
|  |  | |||
|  | @ -96,6 +96,7 @@ | |||
| //NOTE: macos application layer and graphics backends are defined in orca.m
 | ||||
| #elif OC_PLATFORM_ORCA | ||||
|     #include "app/orca_app.c" | ||||
|     #include "wasmbind/core_api_stubs.c" | ||||
|     #include "graphics/graphics_common.c" | ||||
|     #include "graphics/orca_surface_stubs.c" | ||||
| #else | ||||
|  |  | |||
|  | @ -66,6 +66,37 @@ oc_runtime_env* oc_runtime_env_get() | |||
|     return (&__orcaApp.runtime); | ||||
| } | ||||
| 
 | ||||
| void* oc_runtime_ptr_to_native(oc_runtime* orca, void* wasmPtr, u32 length) | ||||
| { | ||||
|     // We can't use the runtime's memory pointer directly because wasm3 embeds a
 | ||||
|     // header at the beginning of the block we give it.
 | ||||
|     u64 bufferIndex = (u64)wasmPtr & 0xffffffff; | ||||
|     u32 memSize = 0; | ||||
|     char* memory = (char*)m3_GetMemory(orca->runtime.m3Runtime, &memSize, 0); | ||||
| 
 | ||||
|     if(bufferIndex + length < memSize) | ||||
|     { | ||||
|         char* nativePtr = memory + bufferIndex; | ||||
|         return nativePtr; | ||||
|     } | ||||
| 
 | ||||
|     return NULL; | ||||
| } | ||||
| 
 | ||||
| void oc_runtime_window_set_title(oc_str8 title) | ||||
| { | ||||
|     title.ptr = oc_runtime_ptr_to_native(oc_runtime_get(), title.ptr, title.len); | ||||
|     if(title.ptr) | ||||
|     { | ||||
|         oc_window_set_title(__orcaApp.window, title); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void oc_runtime_window_set_size(oc_vec2 size) | ||||
| { | ||||
|     oc_window_set_content_size(__orcaApp.window, size); | ||||
| } | ||||
| 
 | ||||
| void oc_runtime_log(oc_log_level level, | ||||
|                     int fileLen, | ||||
|                     char* file, | ||||
|  |  | |||
|  | @ -125,4 +125,6 @@ typedef struct oc_runtime | |||
| oc_runtime* oc_runtime_get(); | ||||
| oc_runtime_env* oc_runtime_env_get(); | ||||
| 
 | ||||
| void* oc_runtime_ptr_to_native(oc_runtime* runtime, void* wasmPtr, u32 length); | ||||
| 
 | ||||
| #endif //__RUNTIME_H_
 | ||||
|  |  | |||
|  | @ -14,19 +14,12 @@ oc_io_cmp oc_runtime_io_wait_single_req(oc_io_req* wasmReq) | |||
| 
 | ||||
|     oc_io_cmp cmp = { 0 }; | ||||
|     oc_io_req req = *wasmReq; | ||||
|     //NOTE: convert the req->buffer wasm pointer to a native pointer
 | ||||
|     //		for some reason, wasm3 memory doesn't start at the beginning of the block we give it.
 | ||||
|     u64 bufferIndex = (u64)req.buffer & 0xffffffff; | ||||
|     u32 memSize = 0; | ||||
|     char* memory = (char*)m3_GetMemory(orca->runtime.m3Runtime, &memSize, 0); | ||||
| 
 | ||||
|     if(bufferIndex + req.size > memSize) | ||||
|     void* buffer = oc_runtime_ptr_to_native(orca, req.buffer, req.size); | ||||
| 
 | ||||
|     if(buffer) | ||||
|     { | ||||
|         cmp.error = OC_IO_ERR_ARG; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         req.buffer = memory + bufferIndex; | ||||
|         req.buffer = buffer; | ||||
| 
 | ||||
|         if(req.op == OC_IO_OPEN_AT) | ||||
|         { | ||||
|  | @ -39,5 +32,10 @@ oc_io_cmp oc_runtime_io_wait_single_req(oc_io_req* wasmReq) | |||
|         } | ||||
|         cmp = oc_io_wait_single_req_with_table(&req, &orca->fileTable); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         cmp.error = OC_IO_ERR_ARG; | ||||
|     } | ||||
| 
 | ||||
|     return (cmp); | ||||
| } | ||||
|  |  | |||
|  | @ -69,5 +69,23 @@ | |||
| 	"cname": "oc_request_quit", | ||||
| 	"ret": {"name": "void", "tag": "v"}, | ||||
| 	"args": [] | ||||
| }, | ||||
| { | ||||
| 	"name": "oc_runtime_window_set_title", | ||||
| 	"cname": "oc_runtime_window_set_title", | ||||
| 	"ret": {"name": "void", "tag": "v"}, | ||||
| 	"args": [ | ||||
| 		{ "name": "title", | ||||
| 		  "type": {"name": "oc_str8", "tag": "S"}} | ||||
| 	] | ||||
| }, | ||||
| { | ||||
| 	"name": "oc_runtime_window_set_size", | ||||
| 	"cname": "oc_runtime_window_set_size", | ||||
| 	"ret": {"name": "void", "tag": "v"}, | ||||
| 	"args": [ | ||||
| 		{ "name": "size", | ||||
| 		  "type": {"name": "oc_vec2", "tag": "S"}} | ||||
| 	] | ||||
| } | ||||
| ] | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue