From b9e843f4bb7f3778276d9bc442c71d080d5ef73a Mon Sep 17 00:00:00 2001 From: Reuben Dunnington Date: Thu, 24 Aug 2023 11:33:21 -0700 Subject: [PATCH 1/8] fix some crashes in metal implementation when pathCount and etlCount are 0 --- src/graphics/mtl_renderer.m | 180 +++++++++++++++++++----------------- 1 file changed, 96 insertions(+), 84 deletions(-) diff --git a/src/graphics/mtl_renderer.m b/src/graphics/mtl_renderer.m index d7b626b..c98c05b 100644 --- a/src/graphics/mtl_renderer.m +++ b/src/graphics/mtl_renderer.m @@ -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 #import @@ -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 pathEncoder = [surface->commandBuffer computeCommandEncoder]; - pathEncoder.label = @"path pass"; - [pathEncoder setComputePipelineState:backend->pathPipeline]; + if(pathCount > 0) + { + id 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 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 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 backpropEncoder = [surface->commandBuffer computeCommandEncoder]; - backpropEncoder.label = @"backprop pass"; - [backpropEncoder setComputePipelineState:backend->backpropPipeline]; + if(pathCount > 0) + { + id 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 mergeEncoder = [surface->commandBuffer computeCommandEncoder]; - mergeEncoder.label = @"merge pass"; - [mergeEncoder setComputePipelineState:backend->mergePipeline]; + if(pathCount > 0) + { + id 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 rasterEncoder = [surface->commandBuffer computeCommandEncoder]; -- 2.25.1 From 72209200b5f7875b905a7a7fb7f308d2713a3c13 Mon Sep 17 00:00:00 2001 From: Reuben Dunnington Date: Wed, 23 Aug 2023 12:59:53 -0700 Subject: [PATCH 2/8] format app.h --- src/app/app.h | 681 +++++++++++++++++++++++++------------------------- 1 file changed, 341 insertions(+), 340 deletions(-) diff --git a/src/app/app.h b/src/app/app.h index 6266f52..5f5b4e2 100644 --- a/src/app/app.h +++ b/src/app/app.h @@ -15,392 +15,393 @@ #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 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 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_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 void oc_window_send_to_back(oc_window window); - ORCA_API void oc_window_bring_to_front(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 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 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 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_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 void oc_window_center(oc_window window); +ORCA_API void oc_window_center(oc_window window); - 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 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); - //--------------------------------------------------------------- - // Dispatching stuff to the main thread - //--------------------------------------------------------------- +//--------------------------------------------------------------- +// Dispatching stuff to the main thread +//--------------------------------------------------------------- - typedef i32 (*oc_dispatch_proc)(void* user); +typedef i32 (*oc_dispatch_proc)(void* user); - ORCA_API i32 oc_dispatch_on_main_thread_sync(oc_window main_window, oc_dispatch_proc proc, void* user); +ORCA_API i32 oc_dispatch_on_main_thread_sync(oc_window main_window, oc_dispatch_proc proc, void* user); - //-------------------------------------------------------------------- - // Clipboard - //-------------------------------------------------------------------- - ORCA_API void oc_clipboard_clear(void); +//-------------------------------------------------------------------- +// Clipboard +//-------------------------------------------------------------------- +ORCA_API void oc_clipboard_clear(void); - 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); +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); - 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 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); - //-------------------------------------------------------------------- - // native open/save/alert windows - //-------------------------------------------------------------------- +//-------------------------------------------------------------------- +// native open/save/alert windows +//-------------------------------------------------------------------- - ORCA_API oc_str8 oc_open_dialog(oc_arena* arena, - oc_str8 title, - oc_str8 defaultPath, - oc_str8_list filters, - bool directory); +ORCA_API oc_str8 oc_open_dialog(oc_arena* arena, + oc_str8 title, + oc_str8 defaultPath, + oc_str8_list filters, + bool directory); - 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_save_dialog(oc_arena* arena, + oc_str8 title, + oc_str8 defaultPath, + oc_str8_list filters); - ORCA_API int oc_alert_popup(oc_str8 title, - oc_str8 message, - oc_str8_list options); +ORCA_API int oc_alert_popup(oc_str8 title, + oc_str8 message, + oc_str8_list options); - //-------------------------------------------------------------------- - // 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); +//-------------------------------------------------------------------- +// 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); +ORCA_API int oc_directory_create(oc_str8 path); #else - void ORCA_IMPORT(oc_request_quit)(void); +void ORCA_IMPORT(oc_request_quit)(void); #endif // !defined(OC_PLATFORM_ORCA) || !(OC_PLATFORM_ORCA) -- 2.25.1 From e4ac21240894c58a4fcc7e22cf2fb695abd5d6f6 Mon Sep 17 00:00:00 2001 From: Reuben Dunnington Date: Tue, 22 Aug 2023 21:28:37 -0700 Subject: [PATCH 3/8] wip window title and size API --- src/app/app.h | 6 ++++++ src/app/win32_app.c | 16 +++++++++++++++- src/runtime.c | 10 ++++++++++ src/wasmbind/core_api.json | 20 ++++++++++++++++++++ 4 files changed, 51 insertions(+), 1 deletion(-) diff --git a/src/app/app.h b/src/app/app.h index 5f5b4e2..34c8699 100644 --- a/src/app/app.h +++ b/src/app/app.h @@ -323,6 +323,8 @@ 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 void oc_window_set_title(oc_window window, oc_str8 title); + 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); @@ -403,6 +405,10 @@ ORCA_API int oc_directory_create(oc_str8 path); void ORCA_IMPORT(oc_request_quit)(void); +void ORCA_IMPORT(oc_runtime_window_set_title)(const char* title); + +void ORCA_IMPORT(oc_runtime_window_set_size)(f32 width, f32 height); + #endif // !defined(OC_PLATFORM_ORCA) || !(OC_PLATFORM_ORCA) #ifdef __cplusplus diff --git a/src/app/win32_app.c b/src/app/win32_app.c index 9492784..a2bb729 100644 --- a/src/app/win32_app.c +++ b/src/app/win32_app.c @@ -789,6 +789,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); @@ -1252,7 +1266,7 @@ void oc_surface_init_for_window(oc_surface_data* surface, oc_window_data* window oc_log_error("couldn't enable blur behind\n"); } - //NOTE(reuben): Creating the child window takes focus away from the main window, but we want to keep + //NOTE(reuben): Creating the child window takes focus away from the main window, but we want to keep //the focus on the main window SetFocus(window->win32.hWnd); diff --git a/src/runtime.c b/src/runtime.c index 5ee8118..f47ea3f 100644 --- a/src/runtime.c +++ b/src/runtime.c @@ -66,6 +66,16 @@ oc_runtime_env* oc_runtime_env_get() return (&__orcaApp.runtime); } +void oc_runtime_window_set_title(const char* title) +{ + oc_window_set_title(__orcaApp.window, OC_STR8(title)); +} + +void oc_runtime_window_set_size(f32 width, f32 height) +{ + oc_window_set_content_size(__orcaApp.window, (oc_vec2){ .x = width, .y = height }); +} + void oc_runtime_log(oc_log_level level, int fileLen, char* file, diff --git a/src/wasmbind/core_api.json b/src/wasmbind/core_api.json index 9ffc568..15297b9 100644 --- a/src/wasmbind/core_api.json +++ b/src/wasmbind/core_api.json @@ -69,5 +69,25 @@ "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": "const char*", "tag": "p"}} + ] +}, +{ + "name": "oc_runtime_window_set_size", + "cname": "oc_runtime_window_set_size", + "ret": {"name": "void", "tag": "v"}, + "args": [ + { "name": "width", + "type": {"name": "f32", "tag": "f"}}, + { "name": "height", + "type": {"name": "f32", "tag": "f"}} + ] } ] -- 2.25.1 From d4cb93c61a431afd71b9096728d758f79e5d5fe2 Mon Sep 17 00:00:00 2001 From: Reuben Dunnington Date: Wed, 23 Aug 2023 13:00:38 -0700 Subject: [PATCH 4/8] oc_runtime_window_set_title and oc_runtime_window_set_size --- scripts/dev.py | 1 + src/app/app.h | 2 +- src/orca.c | 1 + src/runtime.c | 25 +++++++++++++++++++++++-- src/runtime.h | 2 ++ src/runtime_io.c | 20 +++++++++----------- src/wasmbind/core_api.json | 2 +- 7 files changed, 38 insertions(+), 15 deletions(-) diff --git a/scripts/dev.py b/scripts/dev.py index e465ea9..6a6ad8a 100644 --- a/scripts/dev.py +++ b/scripts/dev.py @@ -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", ) diff --git a/src/app/app.h b/src/app/app.h index 34c8699..b8f8639 100644 --- a/src/app/app.h +++ b/src/app/app.h @@ -405,7 +405,7 @@ ORCA_API int oc_directory_create(oc_str8 path); void ORCA_IMPORT(oc_request_quit)(void); -void ORCA_IMPORT(oc_runtime_window_set_title)(const char* title); +void ORCA_IMPORT(oc_runtime_window_set_title)(oc_str8 title); void ORCA_IMPORT(oc_runtime_window_set_size)(f32 width, f32 height); diff --git a/src/orca.c b/src/orca.c index a74ebe0..078a89e 100644 --- a/src/orca.c +++ b/src/orca.c @@ -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 diff --git a/src/runtime.c b/src/runtime.c index f47ea3f..8a820ec 100644 --- a/src/runtime.c +++ b/src/runtime.c @@ -66,9 +66,30 @@ oc_runtime_env* oc_runtime_env_get() return (&__orcaApp.runtime); } -void oc_runtime_window_set_title(const char* title) +void* oc_runtime_ptr_to_native(oc_runtime* orca, void* wasmPtr, u32 length) { - oc_window_set_title(__orcaApp.window, OC_STR8(title)); + // 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(f32 width, f32 height) diff --git a/src/runtime.h b/src/runtime.h index 92302e4..7d6b4d2 100644 --- a/src/runtime.h +++ b/src/runtime.h @@ -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_ diff --git a/src/runtime_io.c b/src/runtime_io.c index 0aad530..aa80007 100644 --- a/src/runtime_io.c +++ b/src/runtime_io.c @@ -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); } diff --git a/src/wasmbind/core_api.json b/src/wasmbind/core_api.json index 15297b9..c237570 100644 --- a/src/wasmbind/core_api.json +++ b/src/wasmbind/core_api.json @@ -76,7 +76,7 @@ "ret": {"name": "void", "tag": "v"}, "args": [ { "name": "title", - "type": {"name": "const char*", "tag": "p"}} + "type": {"name": "oc_str8", "tag": "S"}} ] }, { -- 2.25.1 From 81712c14c104ca62ac65cd8cd59b6852043f02f6 Mon Sep 17 00:00:00 2001 From: Reuben Dunnington Date: Wed, 23 Aug 2023 13:08:09 -0700 Subject: [PATCH 5/8] update samples with title/window size --- samples/clock/src/main.c | 3 +++ samples/fluid/src/main.c | 2 ++ samples/glesTriangle/src/main.c | 3 +++ samples/pong/src/main.c | 2 ++ samples/ui/src/main.c | 2 ++ 5 files changed, 12 insertions(+) diff --git a/samples/clock/src/main.c b/samples/clock/src/main.c index c82764b..2d83126 100644 --- a/samples/clock/src/main.c +++ b/samples/clock/src/main.c @@ -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(400, 400); + surface = oc_surface_canvas(); canvas = oc_canvas_create(); diff --git a/samples/fluid/src/main.c b/samples/fluid/src/main.c index c473e65..82a9d4a 100644 --- a/samples/fluid/src/main.c +++ b/samples/fluid/src/main.c @@ -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); diff --git a/samples/glesTriangle/src/main.c b/samples/glesTriangle/src/main.c index 2f4501c..0165026 100644 --- a/samples/glesTriangle/src/main.c +++ b/samples/glesTriangle/src/main.c @@ -37,6 +37,9 @@ void compile_shader(GLuint shader, const char* source) ORCA_EXPORT void oc_on_init(void) { + oc_runtime_window_set_title(OC_STR8("triangle")); + oc_runtime_window_set_size(640, 480); + surface = oc_surface_gles(); oc_surface_select(surface); diff --git a/samples/pong/src/main.c b/samples/pong/src/main.c index 98af1e5..04fa461 100644 --- a/samples/pong/src/main.c +++ b/samples/pong/src/main.c @@ -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(); diff --git a/samples/ui/src/main.c b/samples/ui/src/main.c index 7da4677..15e0d17 100644 --- a/samples/ui/src/main.c +++ b/samples/ui/src/main.c @@ -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); -- 2.25.1 From bfd4c2a450cda8dcfa91a6dc9528381f9a7f4fab Mon Sep 17 00:00:00 2001 From: Reuben Dunnington Date: Wed, 23 Aug 2023 13:13:38 -0700 Subject: [PATCH 6/8] update oc_window_set_content_size to use oc_vec2 for consistency --- src/app/app.h | 2 +- src/runtime.c | 4 ++-- src/wasmbind/core_api.json | 6 ++---- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/app/app.h b/src/app/app.h index b8f8639..b789a81 100644 --- a/src/app/app.h +++ b/src/app/app.h @@ -407,7 +407,7 @@ 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)(f32 width, f32 height); +void ORCA_IMPORT(oc_runtime_window_set_size)(oc_vec2 size); #endif // !defined(OC_PLATFORM_ORCA) || !(OC_PLATFORM_ORCA) diff --git a/src/runtime.c b/src/runtime.c index 8a820ec..47e6b2b 100644 --- a/src/runtime.c +++ b/src/runtime.c @@ -92,9 +92,9 @@ void oc_runtime_window_set_title(oc_str8 title) } } -void oc_runtime_window_set_size(f32 width, f32 height) +void oc_runtime_window_set_size(oc_vec2 size) { - oc_window_set_content_size(__orcaApp.window, (oc_vec2){ .x = width, .y = height }); + oc_window_set_content_size(__orcaApp.window, size); } void oc_runtime_log(oc_log_level level, diff --git a/src/wasmbind/core_api.json b/src/wasmbind/core_api.json index c237570..7cc1a5f 100644 --- a/src/wasmbind/core_api.json +++ b/src/wasmbind/core_api.json @@ -84,10 +84,8 @@ "cname": "oc_runtime_window_set_size", "ret": {"name": "void", "tag": "v"}, "args": [ - { "name": "width", - "type": {"name": "f32", "tag": "f"}}, - { "name": "height", - "type": {"name": "f32", "tag": "f"}} + { "name": "size", + "type": {"name": "oc_vec2", "tag": "S"}} ] } ] -- 2.25.1 From 9ed636e01877074b07a6a3c3c62cd9afa3ee399e Mon Sep 17 00:00:00 2001 From: Reuben Dunnington Date: Wed, 23 Aug 2023 13:15:46 -0700 Subject: [PATCH 7/8] update samples for oc_window_set_content_size oc_vec2 change --- samples/clock/src/main.c | 2 +- samples/glesTriangle/src/main.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/samples/clock/src/main.c b/samples/clock/src/main.c index 2d83126..e5b21ac 100644 --- a/samples/clock/src/main.c +++ b/samples/clock/src/main.c @@ -20,7 +20,7 @@ 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(400, 400); + oc_runtime_window_set_size((oc_vec2){ .x = 400, .y = 400 }); surface = oc_surface_canvas(); canvas = oc_canvas_create(); diff --git a/samples/glesTriangle/src/main.c b/samples/glesTriangle/src/main.c index 0165026..4517302 100644 --- a/samples/glesTriangle/src/main.c +++ b/samples/glesTriangle/src/main.c @@ -38,7 +38,6 @@ void compile_shader(GLuint shader, const char* source) ORCA_EXPORT void oc_on_init(void) { oc_runtime_window_set_title(OC_STR8("triangle")); - oc_runtime_window_set_size(640, 480); surface = oc_surface_gles(); oc_surface_select(surface); -- 2.25.1 From fad375c403250f26c020fc552069657c85758c2a Mon Sep 17 00:00:00 2001 From: Reuben Dunnington Date: Thu, 24 Aug 2023 11:57:41 -0700 Subject: [PATCH 8/8] macos window title/size * add macOS implmentation for oc_window_set_title() * move implementation of oc_window_set_content_size() to a block that is guaranteed to run on the main thread --- src/app/osx_app.m | 65 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 49 insertions(+), 16 deletions(-) diff --git a/src/app/osx_app.m b/src/app/osx_app.m index bf01d83..57f570c 100644 --- a/src/app/osx_app.m +++ b/src/app/osx_app.m @@ -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); } } -- 2.25.1