Ignore win32 Pong app #19
			
				
			
		
		
		
	|  | @ -45,6 +45,11 @@ if %target% == orca ( | ||||||
| 	        --guest-include graphics.h^ | 	        --guest-include graphics.h^ | ||||||
| 	        --wasm3-bindings src\canvas_api_bind_gen.c | 	        --wasm3-bindings src\canvas_api_bind_gen.c | ||||||
| 
 | 
 | ||||||
|  | 	python3 scripts\bindgen2.py clock src\clock_api.json^ | ||||||
|  | 	        --guest-stubs sdk\orca_clock.c^ | ||||||
|  | 	        --guest-include platform_clock.h^ | ||||||
|  | 	        --wasm3-bindings src\clock_api_bind_gen.c | ||||||
|  | 
 | ||||||
| 	python3 scripts\bindgen2.py io^ | 	python3 scripts\bindgen2.py io^ | ||||||
| 	        src\io_api.json^ | 	        src\io_api.json^ | ||||||
| 	        --guest-stubs sdk\io_stubs.c^ | 	        --guest-stubs sdk\io_stubs.c^ | ||||||
|  |  | ||||||
							
								
								
									
										6
									
								
								build.sh
								
								
								
								
							
							
						
						
									
										6
									
								
								build.sh
								
								
								
								
							|  | @ -67,6 +67,12 @@ elif [ $target = orca ] ; then | ||||||
| 		--guest-include graphics.h \ | 		--guest-include graphics.h \ | ||||||
| 		--wasm3-bindings ./src/canvas_api_bind_gen.c | 		--wasm3-bindings ./src/canvas_api_bind_gen.c | ||||||
| 
 | 
 | ||||||
|  | 	python3 ./scripts/bindgen2.py clock \ | ||||||
|  | 		src/clock_api.json \ | ||||||
|  | 		--guest-stubs sdk/orca_clock.c \ | ||||||
|  | 		--guest-include platform_clock.h \ | ||||||
|  | 		--wasm3-bindings ./src/clock_api_bind_gen.c | ||||||
|  | 
 | ||||||
| 	python3 ./scripts/bindgen2.py io \ | 	python3 ./scripts/bindgen2.py io \ | ||||||
| 		src/io_api.json \ | 		src/io_api.json \ | ||||||
| 		--guest-stubs sdk/io_stubs.c \ | 		--guest-stubs sdk/io_stubs.c \ | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								milepost
								
								
								
								
							
							
								
								
								
								
								
								
							
						
						
									
										2
									
								
								milepost
								
								
								
								
							|  | @ -1 +1 @@ | ||||||
| Subproject commit 59fdc27ac6dd84af4c9ed505213dea0fec641c32 | Subproject commit 2a4e90cf9aa88507640527a06b7ae08f25937155 | ||||||
|  | @ -26,7 +26,7 @@ wasmFlags="--target=wasm32 \ | ||||||
|   -D__ORCA__ \ |   -D__ORCA__ \ | ||||||
|   -I $STDLIB_DIR/include \ |   -I $STDLIB_DIR/include \ | ||||||
|   -I $ORCA_SDK_DIR \ |   -I $ORCA_SDK_DIR \ | ||||||
|   -I $MILEPOST_DIR/ext -I $MILEPOST_DIR -I $MILEPOST_DIR/src -I $MILEPOST_DIR/src/util -I $MILEPOST_DIR/src/platform" |   -I $MILEPOST_DIR/ext -I $MILEPOST_DIR -I $MILEPOST_DIR/src" | ||||||
| 
 | 
 | ||||||
| $CLANG $wasmFlags -o ./module.wasm ../../sdk/orca.c ../../cstdlib/src/*.c src/main.c | $CLANG $wasmFlags -o ./module.wasm ../../sdk/orca.c ../../cstdlib/src/*.c src/main.c | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | UI | ||||||
|  | @ -0,0 +1,17 @@ | ||||||
|  | @echo off | ||||||
|  | 
 | ||||||
|  | :: compile wasm module | ||||||
|  | set wasmFlags=--target=wasm32^ | ||||||
|  |        --no-standard-libraries ^ | ||||||
|  |        -fno-builtin ^ | ||||||
|  |        -Wl,--no-entry ^ | ||||||
|  |        -Wl,--export-dynamic ^ | ||||||
|  |        -g ^ | ||||||
|  |        -O2 ^ | ||||||
|  |        -mbulk-memory ^ | ||||||
|  |        -D__ORCA__ ^ | ||||||
|  |        -isystem ..\..\cstdlib\include -I ..\..\sdk -I..\..\milepost\ext -I ..\..\milepost -I ..\..\milepost\src | ||||||
|  | 
 | ||||||
|  | clang %wasmFlags% -o .\module.wasm ..\..\sdk\orca.c ..\..\cstdlib\src\*.c src\main.c | ||||||
|  | 
 | ||||||
|  | python3 ..\..\scripts\mkapp.py --orca-dir ..\.. --name UI --resource-dir data module.wasm | ||||||
|  | @ -0,0 +1,27 @@ | ||||||
|  | #!/bin/bash | ||||||
|  | 
 | ||||||
|  | set -euo pipefail | ||||||
|  | 
 | ||||||
|  | if [[ -x /usr/local/opt/llvm/bin/clang ]]; then | ||||||
|  |   CLANG=/usr/local/opt/llvm/bin/clang | ||||||
|  | elif [[ -x /opt/homebrew/opt/llvm/bin/clang ]]; then | ||||||
|  |   CLANG=/opt/homebrew/opt/llvm/bin/clang | ||||||
|  | else | ||||||
|  |   echo "Could not find Homebrew clang; this script will probably not work." | ||||||
|  |   CLANG=clang | ||||||
|  | fi | ||||||
|  | 
 | ||||||
|  | wasmFlags="--target=wasm32 \ | ||||||
|  |   --no-standard-libraries \ | ||||||
|  |   -fno-builtin \ | ||||||
|  |   -Wl,--no-entry \ | ||||||
|  |   -Wl,--export-dynamic \ | ||||||
|  |   -g \ | ||||||
|  |   -O2 \ | ||||||
|  |   -mbulk-memory \ | ||||||
|  |   -D__ORCA__ \ | ||||||
|  |   -isystem ../../cstdlib/include -I ../../sdk -I../../milepost/ext -I ../../milepost -I ../../milepost/src" | ||||||
|  | 
 | ||||||
|  | $CLANG $wasmFlags -o ./module.wasm ../../sdk/orca.c ../../cstdlib/src/*.c src/main.c | ||||||
|  | 
 | ||||||
|  | python3 ../../scripts/mkapp.py --orca-dir ../.. --name UI --resource-dir data module.wasm | ||||||
										
											Binary file not shown.
										
									
								
							|  | @ -0,0 +1,407 @@ | ||||||
|  | #include"keys.h" | ||||||
|  | #include"graphics.h" | ||||||
|  | #include"ui.h" | ||||||
|  | 
 | ||||||
|  | #include"orca.h" | ||||||
|  | 
 | ||||||
|  | vec2 frameSize = {100, 100}; | ||||||
|  | 
 | ||||||
|  | mg_surface surface; | ||||||
|  | mg_canvas canvas; | ||||||
|  | mg_font font; | ||||||
|  | ui_context ui; | ||||||
|  | mem_arena textArena = {0}; | ||||||
|  | 
 | ||||||
|  | mg_surface mg_surface_main(void); | ||||||
|  | 
 | ||||||
|  | ORCA_EXPORT void OnInit(void) | ||||||
|  | { | ||||||
|  | 	//TODO create surface for main window
 | ||||||
|  | 	surface = mg_surface_main(); | ||||||
|  | 	canvas = mg_canvas_create(); | ||||||
|  | 	ui_init(&ui); | ||||||
|  | 
 | ||||||
|  | 	//NOTE: load font
 | ||||||
|  | 	{ | ||||||
|  | 		file_handle file = file_open(STR8("/OpenSansLatinSubset.ttf"), FILE_ACCESS_READ, 0); | ||||||
|  | 		if(file_last_error(file) != IO_OK) | ||||||
|  | 		{ | ||||||
|  | 			log_error("Couldn't open file OpenSansLatinSubset.ttf\n"); | ||||||
|  | 		} | ||||||
|  | 		u64 size = file_size(file); | ||||||
|  | 		char* buffer = mem_arena_alloc(mem_scratch(), size); | ||||||
|  | 		file_read(file, size, buffer); | ||||||
|  | 		file_close(file); | ||||||
|  | 		unicode_range ranges[5] = {UNICODE_RANGE_BASIC_LATIN, | ||||||
|  | 		                       UNICODE_RANGE_C1_CONTROLS_AND_LATIN_1_SUPPLEMENT, | ||||||
|  | 		                       UNICODE_RANGE_LATIN_EXTENDED_A, | ||||||
|  | 		                       UNICODE_RANGE_LATIN_EXTENDED_B, | ||||||
|  | 		                       UNICODE_RANGE_SPECIALS}; | ||||||
|  | 		// TODO: Decide whether we're using strings or explicit pointer + length
 | ||||||
|  | 		font = mg_font_create_from_memory(size, (byte*)buffer, 5, ranges); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	mem_arena_clear(mem_scratch()); | ||||||
|  | 	mem_arena_init(&textArena); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | ORCA_EXPORT void OnFrameResize(u32 width, u32 height) | ||||||
|  | { | ||||||
|  | 	log_info("frame resize %u, %u", width, height); | ||||||
|  | 	frameSize.x = width; | ||||||
|  | 	frameSize.y = height; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | ORCA_EXPORT void OnRawEvent(mp_event *event) | ||||||
|  | { | ||||||
|  | 	ui_process_event(event); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void widget_begin_view(char* str) | ||||||
|  | { | ||||||
|  | 	ui_style_next(&(ui_style){.layout.axis = UI_AXIS_Y, | ||||||
|  | 	                          .layout.spacing = 10, | ||||||
|  | 	                          .layout.margin.x = 10, | ||||||
|  | 	                          .layout.margin.y = 10, | ||||||
|  | 	                          .layout.align.x = UI_ALIGN_CENTER, | ||||||
|  | 	                          .layout.align.y = UI_ALIGN_START}, | ||||||
|  | 	               UI_STYLE_LAYOUT); | ||||||
|  | 
 | ||||||
|  | 	ui_box_begin(str, UI_FLAG_DRAW_BORDER); | ||||||
|  | 	ui_label(str); | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void widget_end_view(void) | ||||||
|  | { | ||||||
|  | 	ui_box_end(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #define widget_view(s) defer_loop(widget_begin_view(s), widget_end_view()) | ||||||
|  | 
 | ||||||
|  | ORCA_EXPORT void OnFrameRefresh(void) | ||||||
|  | { | ||||||
|  | 	ui_style defaultStyle = {.bgColor = {0}, | ||||||
|  | 	                         .color = {1, 1, 1, 1}, | ||||||
|  | 	                         .font = font, | ||||||
|  | 	                         .fontSize = 16, | ||||||
|  | 	                         .borderColor = {0.278, 0.333, 0.412, 1}, | ||||||
|  | 		                     .borderSize = 2}; | ||||||
|  | 
 | ||||||
|  | 	ui_style_mask defaultMask = UI_STYLE_BG_COLOR | ||||||
|  | 	                          | UI_STYLE_COLOR | ||||||
|  | 	                          | UI_STYLE_BORDER_COLOR | ||||||
|  | 	                          | UI_STYLE_BORDER_SIZE | ||||||
|  | 	                          | UI_STYLE_FONT | ||||||
|  | 	                          | UI_STYLE_FONT_SIZE; | ||||||
|  | 
 | ||||||
|  | 	ui_frame(frameSize, &defaultStyle, defaultMask) | ||||||
|  | 	{ | ||||||
|  | 		ui_style_match_before(ui_pattern_all(), &defaultStyle, defaultMask); | ||||||
|  | 
 | ||||||
|  | 		ui_style_next(&(ui_style){.size.width = {UI_SIZE_PARENT, 1}, | ||||||
|  | 		                          .size.height = {UI_SIZE_PARENT, 1}, | ||||||
|  | 		                          .layout.axis = UI_AXIS_Y, | ||||||
|  | 		                          .layout.align.x = UI_ALIGN_CENTER, | ||||||
|  | 		                          .layout.align.y = UI_ALIGN_START, | ||||||
|  | 		                          .layout.spacing = 10, | ||||||
|  | 		                          .layout.margin.x = 10, | ||||||
|  | 		                          .layout.margin.y = 10, | ||||||
|  | 		                          .bgColor = {0.11, 0.11, 0.11, 1}}, | ||||||
|  | 		                UI_STYLE_SIZE | ||||||
|  | 		              | UI_STYLE_LAYOUT | ||||||
|  | 		              | UI_STYLE_BG_COLOR); | ||||||
|  | 
 | ||||||
|  | 		ui_container("background", UI_FLAG_DRAW_BACKGROUND) | ||||||
|  | 		{ | ||||||
|  | 			ui_style_next(&(ui_style){.size.width = {UI_SIZE_PARENT, 1}, | ||||||
|  | 			                          .size.height = {UI_SIZE_CHILDREN}, | ||||||
|  | 			                          .layout.align.x = UI_ALIGN_CENTER}, | ||||||
|  | 			               UI_STYLE_SIZE | ||||||
|  | 			              |UI_STYLE_LAYOUT_ALIGN_X); | ||||||
|  | 			ui_container("title", 0) | ||||||
|  | 			{ | ||||||
|  | 				ui_style_next(&(ui_style){.fontSize = 26}, UI_STYLE_FONT_SIZE); | ||||||
|  | 				ui_label("Orca UI Demo"); | ||||||
|  | 
 | ||||||
|  | 				if(ui_box_sig(ui_box_top()).hovering) | ||||||
|  | 				{ | ||||||
|  | 					ui_tooltip("tooltip") | ||||||
|  | 					{ | ||||||
|  | 						ui_style_next(&(ui_style){.bgColor = {1, 0.99, 0.82, 1}}, | ||||||
|  | 						               UI_STYLE_BG_COLOR); | ||||||
|  | 
 | ||||||
|  | 						ui_container("background", UI_FLAG_DRAW_BACKGROUND) | ||||||
|  | 						{ | ||||||
|  | 							ui_style_next(&(ui_style){.color = {0, 0, 0, 1}}, | ||||||
|  | 							               UI_STYLE_COLOR); | ||||||
|  | 
 | ||||||
|  | 							ui_label("That is a tooltip!"); | ||||||
|  | 						} | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			ui_menu_bar("Menu bar") | ||||||
|  | 			{ | ||||||
|  | 				ui_menu("Menu 1") | ||||||
|  | 				{ | ||||||
|  | 					if(ui_menu_button("Option 1.1").pressed) | ||||||
|  | 					{ | ||||||
|  | 						log_info("Pressed option 1.1\n"); | ||||||
|  | 					} | ||||||
|  | 					ui_menu_button("Option 1.2"); | ||||||
|  | 					ui_menu_button("Option 1.3"); | ||||||
|  | 					ui_menu_button("Option 1.4"); | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				ui_menu("Menu 2") | ||||||
|  | 				{ | ||||||
|  | 					ui_menu_button("Option 2.1"); | ||||||
|  | 					ui_menu_button("Option 2.2"); | ||||||
|  | 					ui_menu_button("Option 2.3"); | ||||||
|  | 					ui_menu_button("Option 2.4"); | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				ui_menu("Menu 3") | ||||||
|  | 				{ | ||||||
|  | 					ui_menu_button("Option 3.1"); | ||||||
|  | 					ui_menu_button("Option 3.2"); | ||||||
|  | 					ui_menu_button("Option 3.3"); | ||||||
|  | 					ui_menu_button("Option 3.4"); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			ui_style_next(&(ui_style){.size.width = {UI_SIZE_PARENT, 1}, | ||||||
|  | 			                          .size.height = {UI_SIZE_PARENT, 1, 1}}, | ||||||
|  | 			                          UI_STYLE_SIZE); | ||||||
|  | 
 | ||||||
|  | 			ui_style_next(&(ui_style){.layout.axis = UI_AXIS_X}, UI_STYLE_LAYOUT_AXIS); | ||||||
|  | 			ui_container("contents", 0) | ||||||
|  | 			{ | ||||||
|  | 				ui_style_next(&(ui_style){.size.width = {UI_SIZE_PARENT, 0.5}, | ||||||
|  | 				                          .size.height = {UI_SIZE_PARENT, 1}}, | ||||||
|  | 				              UI_STYLE_SIZE); | ||||||
|  | 
 | ||||||
|  | 				ui_container("left", 0) | ||||||
|  | 				{ | ||||||
|  | 					ui_style_next(&(ui_style){.layout.axis = UI_AXIS_X, | ||||||
|  | 					                          .layout.spacing = 10, | ||||||
|  | 					                          .layout.margin.x = 10, | ||||||
|  | 					                          .layout.margin.y = 10, | ||||||
|  | 					                          .size.width = {UI_SIZE_PARENT, 1}, | ||||||
|  | 					                          .size.height = {UI_SIZE_PARENT, 0.5}}, | ||||||
|  | 					               UI_STYLE_LAYOUT_AXIS | ||||||
|  | 					              |UI_STYLE_LAYOUT_SPACING | ||||||
|  | 					              |UI_STYLE_LAYOUT_MARGIN_X | ||||||
|  | 					              |UI_STYLE_LAYOUT_MARGIN_Y | ||||||
|  | 					              |UI_STYLE_SIZE); | ||||||
|  | 
 | ||||||
|  | 					ui_container("up", 0) | ||||||
|  | 					{ | ||||||
|  | 						ui_style_next(&(ui_style){.size.width = {UI_SIZE_PARENT, 0.5}, | ||||||
|  | 						                          .size.height = {UI_SIZE_PARENT, 1}}, | ||||||
|  | 						             UI_STYLE_SIZE); | ||||||
|  | 						widget_view("Buttons") | ||||||
|  | 						{ | ||||||
|  | 							if(ui_button("Button A").clicked) | ||||||
|  | 							{ | ||||||
|  | 								log_info("A clicked"); | ||||||
|  | 							} | ||||||
|  | 
 | ||||||
|  | 							if(ui_button("Button B").clicked) | ||||||
|  | 							{ | ||||||
|  | 								log_info("B clicked"); | ||||||
|  | 							} | ||||||
|  | 
 | ||||||
|  | 							if(ui_button("Button C").clicked) | ||||||
|  | 							{ | ||||||
|  | 								log_info("C clicked"); | ||||||
|  | 							} | ||||||
|  | 						} | ||||||
|  | 
 | ||||||
|  | 						ui_style_next(&(ui_style){.size.width = {UI_SIZE_PARENT, 0.5}, | ||||||
|  | 						                          .size.height = {UI_SIZE_PARENT, 1}}, | ||||||
|  | 						              UI_STYLE_SIZE); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 						ui_pattern pattern = {0}; | ||||||
|  | 						ui_pattern_push(mem_scratch(), &pattern, (ui_selector){.kind = UI_SEL_TAG, .tag = ui_tag_make("checkbox")}); | ||||||
|  | 						ui_style_match_after(pattern, | ||||||
|  | 						                     &(ui_style){.bgColor = {0, 1, 0, 1}, | ||||||
|  | 						                                 .color = {1, 1, 1, 1}}, | ||||||
|  | 						                     UI_STYLE_COLOR | UI_STYLE_BG_COLOR); | ||||||
|  | 
 | ||||||
|  | 						widget_view("checkboxes") | ||||||
|  | 						{ | ||||||
|  | 							static bool check1 = true; | ||||||
|  | 							static bool check2 = false; | ||||||
|  | 							static bool check3 = false; | ||||||
|  | 
 | ||||||
|  | 							ui_checkbox("check1", &check1); | ||||||
|  | 							ui_checkbox("check2", &check2); | ||||||
|  | 							ui_checkbox("check3", &check3); | ||||||
|  | 						} | ||||||
|  | 					} | ||||||
|  | 
 | ||||||
|  | 					ui_style_next(&(ui_style){.layout.axis = UI_AXIS_X, | ||||||
|  | 					                          .size.width = {UI_SIZE_PARENT, 1}, | ||||||
|  | 					                          .size.height = {UI_SIZE_PARENT, 0.5}}, | ||||||
|  | 					               UI_STYLE_LAYOUT_AXIS | ||||||
|  | 					              |UI_STYLE_SIZE); | ||||||
|  | 
 | ||||||
|  | 					ui_container("down", 0) | ||||||
|  | 					{ | ||||||
|  | 						widget_view("Vertical Sliders") | ||||||
|  | 						{ | ||||||
|  | 							ui_style_next(&(ui_style){.layout.axis = UI_AXIS_X, | ||||||
|  | 							                          .layout.spacing = 10}, | ||||||
|  | 							               UI_STYLE_LAYOUT_AXIS | ||||||
|  | 							              |UI_STYLE_LAYOUT_SPACING); | ||||||
|  | 							ui_container("contents", 0) | ||||||
|  | 							{ | ||||||
|  | 								ui_style_next(&(ui_style){.size.width = {UI_SIZE_PIXELS, 20}, | ||||||
|  | 								                          .size.height = {UI_SIZE_PIXELS, 200}}, | ||||||
|  | 								              UI_STYLE_SIZE); | ||||||
|  | 								static f32 slider1 = 0; | ||||||
|  | 								ui_slider("slider1", 0.2, &slider1); | ||||||
|  | 
 | ||||||
|  | 								ui_style_next(&(ui_style){.size.width = {UI_SIZE_PIXELS, 20}, | ||||||
|  | 								                          .size.height = {UI_SIZE_PIXELS, 200}}, | ||||||
|  | 								              UI_STYLE_SIZE); | ||||||
|  | 								static f32 slider2 = 0; | ||||||
|  | 								ui_slider("slider2", 0.2, &slider2); | ||||||
|  | 
 | ||||||
|  | 								ui_style_next(&(ui_style){.size.width = {UI_SIZE_PIXELS, 20}, | ||||||
|  | 								                          .size.height = {UI_SIZE_PIXELS, 200}}, | ||||||
|  | 								              UI_STYLE_SIZE); | ||||||
|  | 								static f32 slider3 = 0; | ||||||
|  | 								ui_slider("slider3", 0.2, &slider3); | ||||||
|  | 							} | ||||||
|  | 						} | ||||||
|  | 
 | ||||||
|  | 						widget_view("Horizontal Sliders") | ||||||
|  | 						{ | ||||||
|  | 							ui_style_next(&(ui_style){.size.width = {UI_SIZE_PIXELS, 200}, | ||||||
|  | 							                          .size.height = {UI_SIZE_PIXELS, 20}}, | ||||||
|  | 							              UI_STYLE_SIZE); | ||||||
|  | 							static f32 slider1 = 0; | ||||||
|  | 							ui_slider("slider1", 0.2, &slider1); | ||||||
|  | 
 | ||||||
|  | 							ui_style_next(&(ui_style){.size.width = {UI_SIZE_PIXELS, 200}, | ||||||
|  | 							                          .size.height = {UI_SIZE_PIXELS, 20}}, | ||||||
|  | 							              UI_STYLE_SIZE); | ||||||
|  | 							static f32 slider2 = 0; | ||||||
|  | 							ui_slider("slider2", 0.2, &slider2); | ||||||
|  | 
 | ||||||
|  | 							ui_style_next(&(ui_style){.size.width = {UI_SIZE_PIXELS, 200}, | ||||||
|  | 							                          .size.height = {UI_SIZE_PIXELS, 20}}, | ||||||
|  | 							              UI_STYLE_SIZE); | ||||||
|  | 							static f32 slider3 = 0; | ||||||
|  | 							ui_slider("slider3", 0.2, &slider3); | ||||||
|  | 						} | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				ui_style_next(&(ui_style){.size.width = {UI_SIZE_PARENT, 0.5}, | ||||||
|  | 				                          .size.height = {UI_SIZE_PARENT, 1}}, | ||||||
|  | 				              UI_STYLE_SIZE); | ||||||
|  | 
 | ||||||
|  | 				ui_container("right", 0) | ||||||
|  | 				{ | ||||||
|  | 
 | ||||||
|  | 					ui_style_next(&(ui_style){.size.width = {UI_SIZE_PARENT, 1}, | ||||||
|  | 					                          .size.height = {UI_SIZE_PARENT, 0.33}}, | ||||||
|  | 					             UI_STYLE_SIZE); | ||||||
|  | 					widget_view("Text box") | ||||||
|  | 					{ | ||||||
|  | 						ui_style_next(&(ui_style){.size.width = {UI_SIZE_PIXELS, 300}, | ||||||
|  | 						                          .size.height = {UI_SIZE_TEXT}}, | ||||||
|  | 						              UI_STYLE_SIZE); | ||||||
|  | 						static str8 text = {0}; | ||||||
|  | 						ui_text_box_result res = ui_text_box("textbox", mem_scratch(), text); | ||||||
|  | 						if(res.changed) | ||||||
|  | 						{ | ||||||
|  | 							mem_arena_clear(&textArena); | ||||||
|  | 							text = str8_push_copy(&textArena, res.text); | ||||||
|  | 						} | ||||||
|  | 					} | ||||||
|  | 
 | ||||||
|  | 					ui_style_next(&(ui_style){.size.width = {UI_SIZE_PARENT, 1}, | ||||||
|  | 					                          .size.height = {UI_SIZE_PARENT, 0.33}}, | ||||||
|  | 					             UI_STYLE_SIZE); | ||||||
|  | 					widget_view("Test") | ||||||
|  | 					{ | ||||||
|  | 						ui_pattern pattern = {0}; | ||||||
|  | 						ui_pattern_push(mem_scratch(), &pattern, (ui_selector){.kind = UI_SEL_TEXT, .text = STR8("panel")}); | ||||||
|  | 						ui_style_match_after(pattern, &(ui_style){.bgColor = {0.3, 0.3, 1, 1}}, UI_STYLE_BG_COLOR); | ||||||
|  | 
 | ||||||
|  | 						static int selected = 0; | ||||||
|  | 						str8 options[] = {STR8("option 1"), | ||||||
|  | 						                  STR8("option 2"), | ||||||
|  | 						                  STR8("long option 3"), | ||||||
|  | 						                  STR8("option 4"), | ||||||
|  | 						                  STR8("option 5")}; | ||||||
|  | 						ui_select_popup_info info = {.selectedIndex = selected, | ||||||
|  | 						                             .optionCount = 5, | ||||||
|  | 						                             .options = options}; | ||||||
|  | 
 | ||||||
|  | 						ui_select_popup_info result = ui_select_popup("popup", &info); | ||||||
|  | 						selected = result.selectedIndex; | ||||||
|  | 					} | ||||||
|  | 
 | ||||||
|  | 					ui_style_next(&(ui_style){.size.width = {UI_SIZE_PARENT, 1}, | ||||||
|  | 					                          .size.height = {UI_SIZE_PARENT, 0.33}}, | ||||||
|  | 					             UI_STYLE_SIZE); | ||||||
|  | 					widget_view("Color") | ||||||
|  | 					{ | ||||||
|  | 						ui_style_next(&(ui_style){.size.width = {UI_SIZE_PARENT, 1}, | ||||||
|  | 						                          .size.height = {UI_SIZE_PARENT, 0.7}, | ||||||
|  | 						                          .layout.axis = UI_AXIS_X}, | ||||||
|  | 						               UI_STYLE_SIZE | ||||||
|  | 						              |UI_STYLE_LAYOUT_AXIS); | ||||||
|  | 
 | ||||||
|  | 						ui_panel("Panel", UI_FLAG_DRAW_BORDER) | ||||||
|  | 						{ | ||||||
|  | 							ui_style_next(&(ui_style){.layout.axis = UI_AXIS_X}, | ||||||
|  | 							              UI_STYLE_LAYOUT_AXIS); | ||||||
|  | 							ui_container("contents", 0) | ||||||
|  | 							{ | ||||||
|  | 								ui_style_next(&(ui_style){.layout.spacing = 20}, | ||||||
|  | 								              UI_STYLE_LAYOUT_SPACING); | ||||||
|  | 								ui_container("buttons", 0) | ||||||
|  | 								{ | ||||||
|  | 									ui_button("Button A"); | ||||||
|  | 									ui_button("Button B"); | ||||||
|  | 									ui_button("Button C"); | ||||||
|  | 									ui_button("Button D"); | ||||||
|  | 								} | ||||||
|  | 
 | ||||||
|  | 								ui_style_next(&(ui_style){.layout.axis = UI_AXIS_X, | ||||||
|  | 								                          .layout.spacing = 20}, | ||||||
|  | 								              UI_STYLE_LAYOUT_SPACING | ||||||
|  | 								              |UI_STYLE_LAYOUT_AXIS); | ||||||
|  | 
 | ||||||
|  | 								ui_container("buttons2", 0) | ||||||
|  | 								{ | ||||||
|  | 									ui_button("Button A"); | ||||||
|  | 									ui_button("Button B"); | ||||||
|  | 									ui_button("Button C"); | ||||||
|  | 									ui_button("Button D"); | ||||||
|  | 								} | ||||||
|  | 							} | ||||||
|  | 						} | ||||||
|  | 					} | ||||||
|  | 
 | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 	mg_canvas_set_current(canvas); | ||||||
|  |     mg_surface_prepare(surface); | ||||||
|  | 	ui_draw(); | ||||||
|  |     mg_render(surface, canvas); | ||||||
|  |     mg_surface_present(surface); | ||||||
|  | } | ||||||
|  | @ -124,7 +124,7 @@ for decl in data: | ||||||
| 			s += '*((i64*)&_sp[0]) = ' | 			s += '*((i64*)&_sp[0]) = ' | ||||||
| 		elif retTag == 'f': | 		elif retTag == 'f': | ||||||
| 			s += '*((f32*)&_sp[0]) = ' | 			s += '*((f32*)&_sp[0]) = ' | ||||||
| 		elif retTag == 'd': | 		elif retTag == 'F': | ||||||
| 			s += '*((f64*)&_sp[0]) = ' | 			s += '*((f64*)&_sp[0]) = ' | ||||||
| 		elif retTag == 'S': | 		elif retTag == 'S': | ||||||
| 			retTypeName = decl['ret']['name'] | 			retTypeName = decl['ret']['name'] | ||||||
|  | @ -147,7 +147,7 @@ for decl in data: | ||||||
| 				s += '*(i64*)&_sp[' + str(firstArgIndex + i) + ']' | 				s += '*(i64*)&_sp[' + str(firstArgIndex + i) + ']' | ||||||
| 			elif argTag == 'f': | 			elif argTag == 'f': | ||||||
| 				s += '*(f32*)&_sp[' + str(firstArgIndex + i) + ']' | 				s += '*(f32*)&_sp[' + str(firstArgIndex + i) + ']' | ||||||
| 			elif argTag == 'd': | 			elif argTag == 'F': | ||||||
| 				s += '*(f64*)&_sp[' + str(firstArgIndex + i) + ']' | 				s += '*(f64*)&_sp[' + str(firstArgIndex + i) + ']' | ||||||
| 			elif argTag == 'p': | 			elif argTag == 'p': | ||||||
| 				s += '(void*)((char*)_mem + *(i32*)&_sp[' + str(firstArgIndex + i) + '])' | 				s += '(void*)((char*)_mem + *(i32*)&_sp[' + str(firstArgIndex + i) + '])' | ||||||
|  |  | ||||||
|  | @ -6,17 +6,22 @@ | ||||||
| * | * | ||||||
| *****************************************************************/ | *****************************************************************/ | ||||||
| 
 | 
 | ||||||
|  | #include"platform/orca_clock.c" | ||||||
| #include"platform/orca_memory.c" | #include"platform/orca_memory.c" | ||||||
| #include"platform/orca_malloc.c" | #include"platform/orca_malloc.c" | ||||||
| #include"platform/orca_strings.c" | #include"platform/orca_strings.c" | ||||||
| #include"platform/orca_log.c" | #include"platform/orca_log.c" | ||||||
| #include"platform/platform_io_common.c" | #include"platform/platform_io_common.c" | ||||||
| 
 | 
 | ||||||
|  | #include"util/hash.c" | ||||||
| #include"util/memory.c" | #include"util/memory.c" | ||||||
| #include"util/strings.c" | #include"util/strings.c" | ||||||
| #include"util/utf8.c" | #include"util/utf8.c" | ||||||
| 
 | 
 | ||||||
| #include"graphics_common.c" | #include"graphics_common.c" | ||||||
|  | #include"input_state.c" | ||||||
|  | #include"orca_exports.c" | ||||||
| #include"orca_surface.c" | #include"orca_surface.c" | ||||||
|  | #include"ui.c" | ||||||
| 
 | 
 | ||||||
| #include"io_stubs.c" | #include"io_stubs.c" | ||||||
|  |  | ||||||
|  | @ -16,6 +16,7 @@ | ||||||
| #include"platform/platform.h" | #include"platform/platform.h" | ||||||
| #include"platform/platform_log.h" | #include"platform/platform_log.h" | ||||||
| #include"platform/platform_assert.h" | #include"platform/platform_assert.h" | ||||||
|  | #include"platform/platform_clock.h" | ||||||
| #include"platform/platform_io.h" | #include"platform/platform_io.h" | ||||||
| 
 | 
 | ||||||
| #if COMPILER_CLANG | #if COMPILER_CLANG | ||||||
|  |  | ||||||
|  | @ -0,0 +1,3 @@ | ||||||
|  | #include"orca.h" | ||||||
|  | 
 | ||||||
|  | ORCA_EXPORT mp_event _OrcaRawEvent; | ||||||
|  | @ -0,0 +1,9 @@ | ||||||
|  | [ | ||||||
|  | { | ||||||
|  | 	"name": "mp_get_time", | ||||||
|  | 	"cname": "mp_get_time", | ||||||
|  | 	"ret": {"name": "time", "tag": "F"}, | ||||||
|  | 	"args": [ {"name": "clock", | ||||||
|  | 	           "type": {"name": "mp_clock_kind", "tag": "i"}}] | ||||||
|  | } | ||||||
|  | ] | ||||||
							
								
								
									
										63
									
								
								src/main.c
								
								
								
								
							
							
						
						
									
										63
									
								
								src/main.c
								
								
								
								
							|  | @ -300,6 +300,7 @@ void orca_runtime_init(orca_runtime* runtime) | ||||||
| 
 | 
 | ||||||
| #include"bindgen_core_api.c" | #include"bindgen_core_api.c" | ||||||
| #include"canvas_api_bind.c" | #include"canvas_api_bind.c" | ||||||
|  | #include"clock_api_bind_gen.c" | ||||||
| #include"io_api_bind_gen.c" | #include"io_api_bind_gen.c" | ||||||
| 
 | 
 | ||||||
| #include"bindgen_gles_api.c" | #include"bindgen_gles_api.c" | ||||||
|  | @ -356,6 +357,7 @@ void* orca_runloop(void* user) | ||||||
| 	//NOTE: bind orca APIs
 | 	//NOTE: bind orca APIs
 | ||||||
| 	bindgen_link_core_api(app->runtime.m3Module); | 	bindgen_link_core_api(app->runtime.m3Module); | ||||||
| 	bindgen_link_canvas_api(app->runtime.m3Module); | 	bindgen_link_canvas_api(app->runtime.m3Module); | ||||||
|  | 	bindgen_link_clock_api(app->runtime.m3Module); | ||||||
| 	bindgen_link_io_api(app->runtime.m3Module); | 	bindgen_link_io_api(app->runtime.m3Module); | ||||||
| 	bindgen_link_gles_api(app->runtime.m3Module); | 	bindgen_link_gles_api(app->runtime.m3Module); | ||||||
| 	manual_link_gles_api(app->runtime.m3Module); | 	manual_link_gles_api(app->runtime.m3Module); | ||||||
|  | @ -380,9 +382,9 @@ void* orca_runloop(void* user) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	//NOTE: Find and type check event handlers.
 | 	//NOTE: Find and type check event handlers.
 | ||||||
| 	for(int i=0; i<G_EVENT_COUNT; i++) | 	for(int i=0; i<G_EXPORT_COUNT; i++) | ||||||
| 	{ | 	{ | ||||||
| 		const g_event_handler_desc* desc = &G_EVENT_HANDLER_DESC[i]; | 		const g_export_desc* desc = &G_EXPORT_DESC[i]; | ||||||
| 		IM3Function handler = 0; | 		IM3Function handler = 0; | ||||||
| 		m3_FindFunction(&handler, app->runtime.m3Runtime, desc->name.ptr); | 		m3_FindFunction(&handler, app->runtime.m3Runtime, desc->name.ptr); | ||||||
| 
 | 
 | ||||||
|  | @ -425,7 +427,7 @@ void* orca_runloop(void* user) | ||||||
| 
 | 
 | ||||||
| 			if(checked) | 			if(checked) | ||||||
| 			{ | 			{ | ||||||
| 				app->runtime.eventHandlers[i] = handler; | 				app->runtime.exports[i] = handler; | ||||||
| 			} | 			} | ||||||
| 			else | 			else | ||||||
| 			{ | 			{ | ||||||
|  | @ -434,6 +436,10 @@ void* orca_runloop(void* user) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	//NOTE: get location of the raw event slot
 | ||||||
|  | 	IM3Global rawEventGlobal = m3_FindGlobal(app->runtime.m3Module, "_OrcaRawEvent"); | ||||||
|  | 	app->runtime.rawEventOffset = (u32)rawEventGlobal->intValue; | ||||||
|  | 
 | ||||||
| 	//NOTE: preopen the app local root dir
 | 	//NOTE: preopen the app local root dir
 | ||||||
| 	{ | 	{ | ||||||
| 		str8 localRootPath = path_executable_relative(mem_scratch(), STR8("../app/data")); | 		str8 localRootPath = path_executable_relative(mem_scratch(), STR8("../app/data")); | ||||||
|  | @ -449,12 +455,12 @@ void* orca_runloop(void* user) | ||||||
| 	//NOTE: prepare GL surface
 | 	//NOTE: prepare GL surface
 | ||||||
| 	mg_surface_prepare(app->surface); | 	mg_surface_prepare(app->surface); | ||||||
| 
 | 
 | ||||||
| 	IM3Function* eventHandlers = app->runtime.eventHandlers; | 	IM3Function* exports = app->runtime.exports; | ||||||
| 
 | 
 | ||||||
| 	//NOTE: call init handler
 | 	//NOTE: call init handler
 | ||||||
| 	if(eventHandlers[G_EVENT_START]) | 	if(exports[G_EXPORT_ON_INIT]) | ||||||
| 	{ | 	{ | ||||||
| 		M3Result err = m3_Call(eventHandlers[G_EVENT_START], 0, 0); | 		M3Result err = m3_Call(exports[G_EXPORT_ON_INIT], 0, 0); | ||||||
| 		if(err != NULL) | 		if(err != NULL) | ||||||
| 		{ | 		{ | ||||||
| 			log_error("runtime error: %s\n", err); | 			log_error("runtime error: %s\n", err); | ||||||
|  | @ -471,13 +477,13 @@ void* orca_runloop(void* user) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if(eventHandlers[G_EVENT_FRAME_RESIZE]) | 	if(exports[G_EXPORT_FRAME_RESIZE]) | ||||||
| 	{ | 	{ | ||||||
| 		mp_rect frame = mg_surface_get_frame(app->surface); | 		mp_rect frame = mg_surface_get_frame(app->surface); | ||||||
| 		u32 width = (u32)frame.w; | 		u32 width = (u32)frame.w; | ||||||
| 		u32 height = (u32)frame.h; | 		u32 height = (u32)frame.h; | ||||||
| 		const void* args[2] = {&width, &height}; | 		const void* args[2] = {&width, &height}; | ||||||
| 		m3_Call(eventHandlers[G_EVENT_FRAME_RESIZE], 2, args); | 		m3_Call(exports[G_EXPORT_FRAME_RESIZE], 2, args); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	ui_set_context(&app->debugOverlay.ui); | 	ui_set_context(&app->debugOverlay.ui); | ||||||
|  | @ -493,6 +499,19 @@ void* orca_runloop(void* user) | ||||||
| 				ui_process_event(event); | 				ui_process_event(event); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
|  | 			if(exports[G_EXPORT_RAW_EVENT]) | ||||||
|  | 			{ | ||||||
|  | 				#ifndef M3_BIG_ENDIAN | ||||||
|  | 				mp_event* eventPtr = (mp_event*)wasm_memory_offset_to_ptr(&app->runtime.wasmMemory, app->runtime.rawEventOffset); | ||||||
|  | 				memcpy(eventPtr, event, sizeof(*event)); | ||||||
|  | 
 | ||||||
|  | 				const void* args[1] = {&app->runtime.rawEventOffset}; | ||||||
|  | 				m3_Call(exports[G_EXPORT_RAW_EVENT], 1, args); | ||||||
|  | 				#else | ||||||
|  | 				log_error("OnRawEvent() is not supported on big endian platforms"); | ||||||
|  | 				#endif | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
| 			switch(event->type) | 			switch(event->type) | ||||||
| 			{ | 			{ | ||||||
| 				case MP_EVENT_WINDOW_CLOSE: | 				case MP_EVENT_WINDOW_CLOSE: | ||||||
|  | @ -507,12 +526,12 @@ void* orca_runloop(void* user) | ||||||
| 
 | 
 | ||||||
| //					mg_surface_set_frame(app->debugOverlay.surface, frame);
 | //					mg_surface_set_frame(app->debugOverlay.surface, frame);
 | ||||||
| 
 | 
 | ||||||
| 					if(eventHandlers[G_EVENT_FRAME_RESIZE]) | 					if(exports[G_EXPORT_FRAME_RESIZE]) | ||||||
| 					{ | 					{ | ||||||
| 						u32 width = (u32)event->frame.rect.w; | 						u32 width = (u32)event->frame.rect.w; | ||||||
| 						u32 height = (u32)event->frame.rect.h; | 						u32 height = (u32)event->frame.rect.h; | ||||||
| 						const void* args[2] = {&width, &height}; | 						const void* args[2] = {&width, &height}; | ||||||
| 						m3_Call(eventHandlers[G_EVENT_FRAME_RESIZE], 2, args); | 						m3_Call(exports[G_EXPORT_FRAME_RESIZE], 2, args); | ||||||
| 					} | 					} | ||||||
| 				} break; | 				} break; | ||||||
| 
 | 
 | ||||||
|  | @ -520,30 +539,30 @@ void* orca_runloop(void* user) | ||||||
| 				{ | 				{ | ||||||
| 					if(event->key.action == MP_KEY_PRESS) | 					if(event->key.action == MP_KEY_PRESS) | ||||||
| 					{ | 					{ | ||||||
| 						if(eventHandlers[G_EVENT_MOUSE_DOWN]) | 						if(exports[G_EXPORT_MOUSE_DOWN]) | ||||||
| 						{ | 						{ | ||||||
| 							int key = event->key.code; | 							int key = event->key.code; | ||||||
| 							const void* args[1] = {&key}; | 							const void* args[1] = {&key}; | ||||||
| 							m3_Call(eventHandlers[G_EVENT_MOUSE_DOWN], 1, args); | 							m3_Call(exports[G_EXPORT_MOUSE_DOWN], 1, args); | ||||||
| 						} | 						} | ||||||
| 					} | 					} | ||||||
| 					else | 					else | ||||||
| 					{ | 					{ | ||||||
| 						if(eventHandlers[G_EVENT_MOUSE_UP]) | 						if(exports[G_EXPORT_MOUSE_UP]) | ||||||
| 						{ | 						{ | ||||||
| 							int key = event->key.code; | 							int key = event->key.code; | ||||||
| 							const void* args[1] = {&key}; | 							const void* args[1] = {&key}; | ||||||
| 							m3_Call(eventHandlers[G_EVENT_MOUSE_UP], 1, args); | 							m3_Call(exports[G_EXPORT_MOUSE_UP], 1, args); | ||||||
| 						} | 						} | ||||||
| 					} | 					} | ||||||
| 				} break; | 				} break; | ||||||
| 
 | 
 | ||||||
| 				case MP_EVENT_MOUSE_MOVE: | 				case MP_EVENT_MOUSE_MOVE: | ||||||
| 				{ | 				{ | ||||||
| 					if(eventHandlers[G_EVENT_MOUSE_MOVE]) | 					if(exports[G_EXPORT_MOUSE_MOVE]) | ||||||
| 					{ | 					{ | ||||||
| 						const void* args[4] = {&event->move.x, &event->move.y, &event->move.deltaX, &event->move.deltaY}; | 						const void* args[4] = {&event->move.x, &event->move.y, &event->move.deltaX, &event->move.deltaY}; | ||||||
| 						m3_Call(eventHandlers[G_EVENT_MOUSE_MOVE], 4, args); | 						m3_Call(exports[G_EXPORT_MOUSE_MOVE], 4, args); | ||||||
| 					} | 					} | ||||||
| 				} break; | 				} break; | ||||||
| 
 | 
 | ||||||
|  | @ -558,18 +577,18 @@ void* orca_runloop(void* user) | ||||||
| 						#endif | 						#endif | ||||||
| 						} | 						} | ||||||
| 
 | 
 | ||||||
| 						if(eventHandlers[G_EVENT_KEY_DOWN]) | 						if(exports[G_EXPORT_KEY_DOWN]) | ||||||
| 						{ | 						{ | ||||||
| 							const void* args[1] = {&event->key.code}; | 							const void* args[1] = {&event->key.code}; | ||||||
| 							m3_Call(eventHandlers[G_EVENT_KEY_DOWN], 1, args); | 							m3_Call(exports[G_EXPORT_KEY_DOWN], 1, args); | ||||||
| 						} | 						} | ||||||
| 					} | 					} | ||||||
| 					else if(event->key.action == MP_KEY_RELEASE) | 					else if(event->key.action == MP_KEY_RELEASE) | ||||||
| 					{ | 					{ | ||||||
| 						if(eventHandlers[G_EVENT_KEY_UP]) | 						if(exports[G_EXPORT_KEY_UP]) | ||||||
| 						{ | 						{ | ||||||
| 							const void* args[1] = {&event->key.code}; | 							const void* args[1] = {&event->key.code}; | ||||||
| 							m3_Call(eventHandlers[G_EVENT_KEY_UP], 1, args); | 							m3_Call(exports[G_EXPORT_KEY_UP], 1, args); | ||||||
| 						} | 						} | ||||||
| 					} | 					} | ||||||
| 				} break; | 				} break; | ||||||
|  | @ -716,10 +735,10 @@ void* orca_runloop(void* user) | ||||||
| 			mg_render(app->debugOverlay.surface, app->debugOverlay.canvas); | 			mg_render(app->debugOverlay.surface, app->debugOverlay.canvas); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if(eventHandlers[G_EVENT_FRAME_REFRESH]) | 		if(exports[G_EXPORT_FRAME_REFRESH]) | ||||||
| 		{ | 		{ | ||||||
| 			mg_surface_prepare(app->surface); | 			mg_surface_prepare(app->surface); | ||||||
| 			m3_Call(eventHandlers[G_EVENT_FRAME_REFRESH], 0, 0); | 			m3_Call(exports[G_EXPORT_FRAME_REFRESH], 0, 0); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if(app->debugOverlay.show) | 		if(app->debugOverlay.show) | ||||||
|  |  | ||||||
|  | @ -57,3 +57,10 @@ extern u32 orca_mem_grow(u64 size) | ||||||
| 
 | 
 | ||||||
| 	return(addr); | 	return(addr); | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | void* wasm_memory_offset_to_ptr(wasm_memory* memory, u32 offset) | ||||||
|  | { | ||||||
|  | 	M3MemoryHeader* header = (M3MemoryHeader*)(memory->ptr); | ||||||
|  | 	DEBUG_ASSERT(offset < header->length, "Wasm offset exceeds memory length") | ||||||
|  | 	return memory->ptr + sizeof(M3MemoryHeader) + offset; | ||||||
|  | } | ||||||
|  | @ -14,40 +14,41 @@ | ||||||
| #include"m3_env.h" | #include"m3_env.h" | ||||||
| #include"m3_compile.h" | #include"m3_compile.h" | ||||||
| 
 | 
 | ||||||
| #define G_EVENTS(X) \ | #define G_EXPORTS(X) \ | ||||||
| 	X(G_EVENT_START, "OnInit", "", "") \ | 	X(G_EXPORT_ON_INIT, "OnInit", "", "") \ | ||||||
| 	X(G_EVENT_MOUSE_DOWN, "OnMouseDown", "", "i") \ | 	X(G_EXPORT_MOUSE_DOWN, "OnMouseDown", "", "i") \ | ||||||
| 	X(G_EVENT_MOUSE_UP, "OnMouseUp", "", "i") \ | 	X(G_EXPORT_MOUSE_UP, "OnMouseUp", "", "i") \ | ||||||
| 	X(G_EVENT_MOUSE_ENTER, "OnMouseEnter", "", "") \ | 	X(G_EXPORT_MOUSE_ENTER, "OnMouseEnter", "", "") \ | ||||||
| 	X(G_EVENT_MOUSE_LEAVE, "OnMouseLeave", "", "") \ | 	X(G_EXPORT_MOUSE_LEAVE, "OnMouseLeave", "", "") \ | ||||||
| 	X(G_EVENT_MOUSE_MOVE, "OnMouseMove", "", "ffff") \ | 	X(G_EXPORT_MOUSE_MOVE, "OnMouseMove", "", "ffff") \ | ||||||
| 	X(G_EVENT_MOUSE_WHEEL, "OnMouseWheel", "", "ff") \ | 	X(G_EXPORT_MOUSE_WHEEL, "OnMouseWheel", "", "ff") \ | ||||||
| 	X(G_EVENT_KEY_DOWN, "OnKeyDown", "", "i") \ | 	X(G_EXPORT_KEY_DOWN, "OnKeyDown", "", "i") \ | ||||||
| 	X(G_EVENT_KEY_UP, "OnKeyUp", "", "i") \ | 	X(G_EXPORT_KEY_UP, "OnKeyUp", "", "i") \ | ||||||
| 	X(G_EVENT_FRAME_REFRESH, "OnFrameRefresh", "", "") \ | 	X(G_EXPORT_FRAME_REFRESH, "OnFrameRefresh", "", "") \ | ||||||
| 	X(G_EVENT_FRAME_RESIZE, "OnFrameResize", "", "ii") | 	X(G_EXPORT_FRAME_RESIZE, "OnFrameResize", "", "ii") \ | ||||||
|  | 	X(G_EXPORT_RAW_EVENT, "OnRawEvent", "", "i") \ | ||||||
| 
 | 
 | ||||||
| typedef enum { | typedef enum { | ||||||
| 	#define G_EVENT_KIND(kind, ...) kind, | 	#define G_EXPORT_KIND(kind, ...) kind, | ||||||
| 	G_EVENTS(G_EVENT_KIND) | 	G_EXPORTS(G_EXPORT_KIND) | ||||||
| 	G_EVENT_COUNT | 	G_EXPORT_COUNT | ||||||
| } guest_event_kind; | } guest_export_kind; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| typedef struct g_event_handler_desc | typedef struct g_export_desc | ||||||
| { | { | ||||||
| 	str8 name; | 	str8 name; | ||||||
| 	str8 retTags; | 	str8 retTags; | ||||||
| 	str8 argTags; | 	str8 argTags; | ||||||
| } g_event_handler_desc; | } g_export_desc; | ||||||
| 
 | 
 | ||||||
| const g_event_handler_desc G_EVENT_HANDLER_DESC[] = { | const g_export_desc G_EXPORT_DESC[] = { | ||||||
| 	#define STR8LIT(s) {sizeof(s)-1, s} //NOTE: msvc doesn't accept STR8(s) as compile-time constant...
 | 	#define STR8LIT(s) {sizeof(s)-1, s} //NOTE: msvc doesn't accept STR8(s) as compile-time constant...
 | ||||||
| 	#define G_EVENT_HANDLER_DESC_ENTRY(kind, name, rets, args) {STR8LIT(name), STR8LIT(rets), STR8LIT(args)}, | 	#define G_EXPORT_DESC_ENTRY(kind, name, rets, args) {STR8LIT(name), STR8LIT(rets), STR8LIT(args)}, | ||||||
| 
 | 
 | ||||||
| 	G_EVENTS(G_EVENT_HANDLER_DESC_ENTRY) | 	G_EXPORTS(G_EXPORT_DESC_ENTRY) | ||||||
| 
 | 
 | ||||||
| 	#undef G_EVENT_HANDLER_DESC_ENTRY | 	#undef G_EXPORT_DESC_ENTRY | ||||||
| 	#undef STR8LIT | 	#undef STR8LIT | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | @ -68,7 +69,8 @@ typedef struct orca_runtime | ||||||
| 	IM3Environment m3Env; | 	IM3Environment m3Env; | ||||||
| 	IM3Runtime m3Runtime; | 	IM3Runtime m3Runtime; | ||||||
| 	IM3Module m3Module; | 	IM3Module m3Module; | ||||||
| 	IM3Function eventHandlers[G_EVENT_COUNT]; | 	IM3Function exports[G_EXPORT_COUNT]; | ||||||
|  | 	u32 rawEventOffset; | ||||||
| 
 | 
 | ||||||
| } orca_runtime; | } orca_runtime; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue