diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rwxr-xr-x | build_all.sh | 25 | ||||
-rw-r--r--[-rwxr-xr-x] | examples/echo.c | 27 | ||||
-rw-r--r--[-rwxr-xr-x] | examples/game_of_life.c | 29 | ||||
-rw-r--r--[-rwxr-xr-x] | examples/graph.c | 81 | ||||
-rw-r--r--[-rwxr-xr-x] | examples/julia_set.c | 61 | ||||
-rw-r--r--[-rwxr-xr-x] | examples/labyrinth.c | 29 | ||||
-rw-r--r--[-rwxr-xr-x] | examples/particles.c | 66 | ||||
-rw-r--r-- | examples/proto.c | 5 | ||||
-rw-r--r--[-rwxr-xr-x] | examples/sinewave.c | 45 | ||||
-rw-r--r--[-rwxr-xr-x] | examples/ui.c | 99 | ||||
-rw-r--r-- | graphics.c | 64 | ||||
-rw-r--r-- | index.htm | 6 | ||||
-rwxr-xr-x | reduced_system_layer.c | 339 | ||||
-rw-r--r-- | test.c | 2 |
15 files changed, 362 insertions, 517 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5e56e04 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/bin diff --git a/build_all.sh b/build_all.sh new file mode 100755 index 0000000..619cbcb --- /dev/null +++ b/build_all.sh @@ -0,0 +1,25 @@ +FLAGS=" \ + -Wall -Wextra -Werror -pedantic \ + -Wno-old-style-declaration \ + -Wno-missing-braces \ + -Wno-unused-variable \ + -Wno-unused-but-set-variable \ + -Wno-unused-parameter \ + -Wno-overlength-strings \ + -O3 \ + -fsanitize=undefined,address,leak \ + -lX11 -lm -lasound" + +if [ ! -d ./bin ]; then + mkdir ./bin +fi + +gcc $FLAGS -o ./bin/graph ./examples/graph.c +gcc $FLAGS -o ./bin/particles ./examples/particles.c +gcc $FLAGS -o ./bin/julia_set ./examples/julia_set.c +gcc $FLAGS -o ./bin/game_of_life ./examples/game_of_life.c +gcc $FLAGS -o ./bin/labyrinth ./examples/labyrinth.c +gcc $FLAGS -o ./bin/sinewave ./examples/sinewave.c +gcc $FLAGS -o ./bin/ui ./examples/ui.c +gcc $FLAGS -o ./bin/echo ./examples/echo.c +gcc $FLAGS -o ./bin/proto ./examples/proto.c diff --git a/examples/echo.c b/examples/echo.c index 2444747..10f3cd5 100755..100644 --- a/examples/echo.c +++ b/examples/echo.c @@ -1,30 +1,3 @@ -#if 0 /* -#/ ================================================================ -#/ -#/ echo.c -#/ -#/ ================================================================ -#/ -#/ Self-compilation shell script -#/ -SRC=${0##*./} -BIN=${SRC%.*} -gcc \ - -Wall -Wextra -Werror -pedantic \ - -Wno-old-style-declaration \ - -Wno-missing-braces \ - -Wno-unused-variable \ - -Wno-unused-but-set-variable \ - -Wno-unused-parameter \ - -Wno-overlength-strings \ - -O3 \ - -fsanitize=undefined,address,leak \ - -lX11 -lm -lasound \ - -o $BIN $SRC && \ - ./$BIN $@ && rm $BIN -exit $? # */ -#endif - #ifdef __wasm__ #error Not implemented! #endif diff --git a/examples/game_of_life.c b/examples/game_of_life.c index 540251d..fdd3d54 100755..100644 --- a/examples/game_of_life.c +++ b/examples/game_of_life.c @@ -1,30 +1,3 @@ -#if 0 /* -#/ ================================================================ -#/ -#/ game_of_life.c -#/ -#/ ================================================================ -#/ -#/ Self-compilation shell script -#/ -SRC=${0##*./} -BIN=${SRC%.*} -gcc \ - -Wall -Wextra -Werror -pedantic \ - -Wno-old-style-declaration \ - -Wno-missing-braces \ - -Wno-unused-variable \ - -Wno-unused-but-set-variable \ - -Wno-unused-parameter \ - -Wno-overlength-strings \ - -O3 \ - -fsanitize=undefined,address,leak \ - -lX11 -lm -lasound \ - -o $BIN $SRC && \ - ./$BIN $@ && rm $BIN -exit $? # */ -#endif - #include "../reduced_system_layer.c" void update_and_render_frame(void) { @@ -37,7 +10,7 @@ i32 main(i32 argc, c8 **argv) { (void) argc; (void) argv; - platform = (Platform) { + g_platform = (Platform) { .title = "Conway's Game of Life", .frame_width = 960, .frame_height = 720, diff --git a/examples/graph.c b/examples/graph.c index 6ad5fdc..f03cc93 100755..100644 --- a/examples/graph.c +++ b/examples/graph.c @@ -1,30 +1,3 @@ -#if 0 /* -#/ ================================================================ -#/ -#/ graph.c -#/ -#/ ================================================================ -#/ -#/ Self-compilation shell script -#/ -SRC=${0##*./} -BIN=${SRC%.*} -gcc \ - -Wall -Wextra -Werror -pedantic \ - -Wno-old-style-declaration \ - -Wno-missing-braces \ - -Wno-unused-variable \ - -Wno-unused-but-set-variable \ - -Wno-unused-parameter \ - -Wno-overlength-strings \ - -O3 \ - -fsanitize=undefined,address,leak \ - -lX11 -lm -lasound \ - -o $BIN $SRC && \ - ./$BIN $@ && rm $BIN -exit $? # */ -#endif - #include "../graphics.c" enum { @@ -80,12 +53,12 @@ void draw_node(i64 node_index) { Node n = world.nodes[node_index]; - u32 color = 0; // black color + vec3_f32 color = {0}; // black color if (n.highlight) - color = 0xff00ff; // pink color + color = (vec3_f32) { 1.f, .0f, 1.f }; // pink color if (n.hover) - color = 0x007f00; // green color + color = (vec3_f32) { 0.f, .5f, 0.f }; // green color fill_ellipse( OP_SET, // set pixels @@ -105,12 +78,12 @@ void draw_edge(i64 edge_index) { Node n0 = world.nodes[e.src]; Node n1 = world.nodes[e.dst]; - u32 color = 0x7f7f7f; // grey color + vec3_f32 color = { .5f, .5f, .5f }; // grey color if (e.highlight) - color = 0xff00ff; // pink color + color = (vec3_f32) { 1.f, .0f, 1.f }; // pink color if (e.hover) - color = 0x007f00; // green color + color = (vec3_f32) { 0.f, .5f, 0.f }; // green color fill_line( OP_SET, // set pixels @@ -146,8 +119,8 @@ void update_node(i64 node_index) { n.y - n.radius, n.radius * 2, n.radius * 2, - platform.cursor_x, - platform.cursor_y + g_platform.cursor_x, + g_platform.cursor_y ); } @@ -165,8 +138,8 @@ void update_edge(i64 edge_index) { n1.x, n1.y, e.width, - platform.cursor_x, - platform.cursor_y + g_platform.cursor_x, + g_platform.cursor_y ); } @@ -421,7 +394,7 @@ void update_and_render_frame(void) { update_edge(i); } - if (platform.key_pressed[KEY_DELETE]) { + if (g_platform.key_pressed[KEY_DELETE]) { for (i64 i = 0; i < MAX_NUM_EDGES; ++i) if (world.edges[i].enabled && world.edges[i].hover) remove_edge(i); @@ -433,7 +406,7 @@ void update_and_render_frame(void) { path_changed = 1; } - if (platform.key_pressed['1']) { + if (g_platform.key_pressed['1']) { for (i64 i = 0; i < MAX_NUM_NODES; ++i) if (world.nodes[i].enabled && world.nodes[i].hover) { path_src = i; @@ -442,7 +415,7 @@ void update_and_render_frame(void) { } } - if (platform.key_pressed['2']) + if (g_platform.key_pressed['2']) for (i64 i = 0; i < MAX_NUM_NODES; ++i) if (world.nodes[i].enabled && world.nodes[i].hover) { path_dst = i; @@ -455,13 +428,13 @@ void update_and_render_frame(void) { path_changed = 0; } - if (platform.key_pressed[BUTTON_LEFT]) { + if (g_platform.key_pressed[BUTTON_LEFT]) { for (i64 i = 0; i < MAX_NUM_NODES; ++i) if (world.nodes[i].enabled && world.nodes[i].hover) { drag_on = 1; drag_node = i; - drag_x0 = platform.cursor_x; - drag_y0 = platform.cursor_y; + drag_x0 = g_platform.cursor_x; + drag_y0 = g_platform.cursor_y; for (i64 j = 0; j < MAX_NUM_NODES; ++j) { world.nodes[j].drag_x = world.nodes[j].x; world.nodes[j].drag_y = world.nodes[j].y; @@ -470,10 +443,10 @@ void update_and_render_frame(void) { } if (!drag_on) - add_node(platform.cursor_x, platform.cursor_y); + add_node(g_platform.cursor_x, g_platform.cursor_y); } - if (platform.key_pressed[BUTTON_RIGHT]) + if (g_platform.key_pressed[BUTTON_RIGHT]) for (i64 i = 0; i < MAX_NUM_NODES; ++i) if (world.nodes[i].enabled && world.nodes[i].hover) { adding_edge = 1; @@ -489,7 +462,7 @@ void update_and_render_frame(void) { break; } - if (adding_edge && !platform.key_down[BUTTON_RIGHT]) { + if (adding_edge && !g_platform.key_down[BUTTON_RIGHT]) { adding_edge = 0; add_edge(adding_src, adding_dst); path_changed = 1; @@ -497,8 +470,8 @@ void update_and_render_frame(void) { if (drag_on) { if (check_node_index(drag_node)) { - f64 dx = platform.cursor_x - drag_x0; - f64 dy = platform.cursor_y - drag_y0; + f64 dx = g_platform.cursor_x - drag_x0; + f64 dy = g_platform.cursor_y - drag_y0; world.nodes[drag_node].x = world.nodes[drag_node].drag_x + dx; world.nodes[drag_node].y = world.nodes[drag_node].drag_y + dy; @@ -525,26 +498,26 @@ void update_and_render_frame(void) { path_changed = 1; } - if (!platform.key_down[BUTTON_LEFT]) + if (!g_platform.key_down[BUTTON_LEFT]) drag_on = 0; } // Render - fill_rectangle(OP_SET, 0xa0b0c0, 0, 0, platform.frame_width, platform.frame_height); + fill_rectangle(OP_SET, (vec3_f32) { .7f, .8f, .9f }, 0, 0, g_platform.frame_width, g_platform.frame_height); if (adding_edge) { f64 x0 = world.nodes[adding_src].x; f64 y0 = world.nodes[adding_src].y; - f64 x1 = platform.cursor_x; - f64 y1 = platform.cursor_y; + f64 x1 = g_platform.cursor_x; + f64 y1 = g_platform.cursor_y; if (adding_src != adding_dst) { x1 = world.nodes[adding_dst].x; y1 = world.nodes[adding_dst].y; } - fill_line(OP_SET, 0x7f007f, x0, y0, x1, y1, 30); + fill_line(OP_SET, (vec3_f32) { .5f, 0.f, .5f }, x0, y0, x1, y1, 30); } draw_graph(); @@ -556,7 +529,7 @@ i32 main(i32 argc, c8 **argv) { (void) argc; (void) argv; - platform = (Platform) { + g_platform = (Platform) { .title = "Graph", .frame_width = 960, .frame_height = 720, diff --git a/examples/julia_set.c b/examples/julia_set.c index c25b028..26e7a7a 100755..100644 --- a/examples/julia_set.c +++ b/examples/julia_set.c @@ -1,30 +1,3 @@ -#if 0 /* -#/ ================================================================ -#/ -#/ julia_set.c -#/ -#/ ================================================================ -#/ -#/ Self-compilation shell script -#/ -SRC=${0##*./} -BIN=${SRC%.*} -gcc \ - -Wall -Wextra -Werror -pedantic \ - -Wno-old-style-declaration \ - -Wno-missing-braces \ - -Wno-unused-variable \ - -Wno-unused-but-set-variable \ - -Wno-unused-parameter \ - -Wno-overlength-strings \ - -g -O3 \ - -fsanitize=undefined,address,leak \ - -lX11 -lm -lasound \ - -o $BIN $SRC && \ - ./$BIN $@ && rm $BIN -exit $? # */ -#endif - #include "../reduced_system_layer.c" i64 p = 4; @@ -43,43 +16,43 @@ void update_and_render_frame(void) { i64 time_elapsed = p_time() - time_0; time_0 += time_elapsed; - b8 left = platform.key_down[KEY_LEFT]; - b8 right = platform.key_down[KEY_RIGHT]; - b8 up = platform.key_down[KEY_UP]; - b8 down = platform.key_down[KEY_DOWN]; + b8 left = g_platform.key_down[KEY_LEFT]; + b8 right = g_platform.key_down[KEY_RIGHT]; + b8 up = g_platform.key_down[KEY_UP]; + b8 down = g_platform.key_down[KEY_DOWN]; if (!left && !right && !up && !down && num_events == 0) { p_sleep_for(1); return; } - if (platform.key_pressed['\n']) + if (g_platform.key_pressed['\n']) p = (p == 1 ? 4 : 1); - if (platform.key_pressed[KEY_ESCAPE]) { + if (g_platform.key_pressed[KEY_ESCAPE]) { view_x = 0.; view_y = 0.; view_s = 1.; } - f64 d = (platform.key_down[MOD_CTRL] ? .00005 : .001) * view_s * time_elapsed; + f64 d = (g_platform.key_down[MOD_CTRL] ? .00005 : .001) * view_s * time_elapsed; if (left) { cx -= d; cy -= d; } if (right) { cx += d; cy += d; } if (up) { cx += d; cy -= d; } if (down) { cx -= d; cy += d; } - if (platform.key_down[BUTTON_LEFT]) { - view_x += platform.cursor_dx * view_s; - view_y += platform.cursor_dy * view_s; + if (g_platform.key_down[BUTTON_LEFT]) { + view_x += g_platform.cursor_dx * view_s; + view_y += g_platform.cursor_dy * view_s; } - view_s += .1 * platform.wheel_dy * view_s; + view_s += .1 * g_platform.wheel_dy * view_s; - for (i32 j = 0; j + p <= platform.frame_height; j += p) - for (i32 i = 0; i + p <= platform.frame_width; i += p) { - f64 x = .003 * ((i - platform.frame_width * .5) * view_s - view_x); - f64 y = .003 * ((j - platform.frame_height * .5) * view_s - view_y); + for (i32 j = 0; j + p <= g_platform.frame_height; j += p) + for (i32 i = 0; i + p <= g_platform.frame_width; i += p) { + f64 x = .003 * ((i - g_platform.frame_width * .5) * view_s - view_x); + f64 y = .003 * ((j - g_platform.frame_height * .5) * view_s - view_y); i64 n = 0; @@ -98,7 +71,7 @@ void update_and_render_frame(void) { for (i32 jj = 0; jj < p; ++jj) for (i32 ii = 0; ii < p; ++ii) - platform.pixels[(j + jj) * platform.frame_width + (i + ii)] = c; + g_platform.pixels[(j + jj) * g_platform.frame_width + (i + ii)] = rgb_f32_from_u32(c); } p_render_frame(); @@ -108,7 +81,7 @@ i32 main(i32 argc, c8 **argv) { (void) argc; (void) argv; - platform = (Platform) { + g_platform = (Platform) { .title = "Julia Set", .frame_width = 960, .frame_height = 720, diff --git a/examples/labyrinth.c b/examples/labyrinth.c index 28ca0da..54bed19 100755..100644 --- a/examples/labyrinth.c +++ b/examples/labyrinth.c @@ -1,30 +1,3 @@ -#if 0 /* -#/ ================================================================ -#/ -#/ labyrinth.c -#/ -#/ ================================================================ -#/ -#/ Self-compilation shell script -#/ -SRC=${0##*./} -BIN=${SRC%.*} -gcc \ - -Wall -Wextra -Werror -pedantic \ - -Wno-old-style-declaration \ - -Wno-missing-braces \ - -Wno-unused-variable \ - -Wno-unused-but-set-variable \ - -Wno-unused-parameter \ - -Wno-overlength-strings \ - -O3 \ - -fsanitize=undefined,address,leak \ - -lX11 -lm -lasound \ - -o $BIN $SRC && \ - ./$BIN $@ && rm $BIN -exit $? # */ -#endif - #include "../reduced_system_layer.c" void update_and_render_frame(void) { @@ -37,7 +10,7 @@ i32 main(i32 argc, c8 **argv) { (void) argc; (void) argv; - platform = (Platform) { + g_platform = (Platform) { .title = "Labyrinth", .frame_width = 960, .frame_height = 720, diff --git a/examples/particles.c b/examples/particles.c index bf90123..37a77a5 100755..100644 --- a/examples/particles.c +++ b/examples/particles.c @@ -1,30 +1,3 @@ -#if 0 /* -#/ ================================================================ -#/ -#/ particles.c -#/ -#/ ================================================================ -#/ -#/ Self-compilation shell script -#/ -SRC=${0##*./} -BIN=${SRC%.*} -gcc \ - -Wall -Wextra -Werror -pedantic \ - -Wno-old-style-declaration \ - -Wno-missing-braces \ - -Wno-unused-variable \ - -Wno-unused-but-set-variable \ - -Wno-unused-parameter \ - -Wno-overlength-strings \ - -O3 \ - -fsanitize=undefined,address,leak \ - -lX11 -lm -lasound \ - -o $BIN $SRC && \ - ./$BIN $@ && rm $BIN -exit $? # */ -#endif - #include "../graphics.c" typedef struct { @@ -40,9 +13,9 @@ typedef struct { Entity entities[10 * 1024 * 1024]; } World; -World world = {0}; -u32 background; -i64 time_0; +World world = {0}; +vec3_f32 background = { .0f, .0f, .08f }; +i64 time_0; void update_and_render_frame(void) { p_handle_events(); @@ -50,21 +23,21 @@ void update_and_render_frame(void) { i64 time_elapsed = p_time() - time_0; time_0 += time_elapsed; - if (platform.key_pressed[BUTTON_LEFT]) { + if (g_platform.key_pressed[BUTTON_LEFT]) { i64 n = world.num_entities++; world.entities[n] = (Entity) { - .x = (f64) platform.cursor_x - (f64) platform.frame_width / 2, - .y = -((f64) platform.cursor_y - (f64) platform.frame_height / 2), + .x = (f64) g_platform.cursor_x - (f64) g_platform.frame_width / 2, + .y = -((f64) g_platform.cursor_y - (f64) g_platform.frame_height / 2), }; } if (time_elapsed > 0) { - if (platform.key_down[BUTTON_RIGHT]) { + if (g_platform.key_down[BUTTON_RIGHT]) { for (i64 n = 0; n < time_elapsed; ++n) world.entities[world.num_entities + n] = (Entity) { - .x = (f64) platform.cursor_x - (f64) platform.frame_width / 2, - .y = -((f64) platform.cursor_y - (f64) platform.frame_height / 2), + .x = (f64) g_platform.cursor_x - (f64) g_platform.frame_width / 2, + .y = -((f64) g_platform.cursor_y - (f64) g_platform.frame_height / 2), }; world.num_entities += time_elapsed; @@ -111,23 +84,23 @@ void update_and_render_frame(void) { world.time += time_elapsed; } - for (i32 j = 0; j < platform.frame_height; ++j) - for (i32 i = 0; i < platform.frame_width; ++i) - platform.pixels[j * platform.frame_width + i] = background; + for (i32 j = 0; j < g_platform.frame_height; ++j) + for (i32 i = 0; i < g_platform.frame_width; ++i) + g_platform.pixels[j * g_platform.frame_width + i] = background; for (i64 n = 0; n < world.num_entities; ++n) { Entity *e = &world.entities[n]; - i32 x = platform.frame_width / 2 + (i32) floor(e->x + .5); - i32 y = platform.frame_height / 2 - (i32) floor(e->y + .5); + i32 x = g_platform.frame_width / 2 + (i32) floor(e->x + .5); + i32 y = g_platform.frame_height / 2 - (i32) floor(e->y + .5); for (i32 j = y - 10; j <= y + 10; ++j) { - if (j < 0 || j >= platform.frame_height) continue; + if (j < 0 || j >= g_platform.frame_height) continue; for (i32 i = x - 10; i <= x + 10; ++i) { - if (i < 0 || i >= platform.frame_width) continue; + if (i < 0 || i >= g_platform.frame_width) continue; if ((i - x) * (i - x) + (j - y) * (j - y) > 100) continue; f64 v = (e->vx * e->vx + e->vy * e->vy) * 8.; - platform.pixels[j * platform.frame_width + i] = u32_from_rgb(-.2 + v * 2., .1 + v * .7, 1. - v); + g_platform.pixels[j * g_platform.frame_width + i] = (vec3_f32) { -.2 + v * 2., .1 + v * .7, 1. - v }; } } } @@ -139,14 +112,13 @@ i32 main(i32 argc, c8 **argv) { (void) argc; (void) argv; - platform = (Platform) { + g_platform = (Platform) { .title = "Gravity", .frame_width = 960, .frame_height = 720, }; - background = u32_from_rgb(.0f, .0f, .08f); - time_0 = p_time(); + time_0 = p_time(); srand(p_time()); diff --git a/examples/proto.c b/examples/proto.c new file mode 100644 index 0000000..dbb64a8 --- /dev/null +++ b/examples/proto.c @@ -0,0 +1,5 @@ +int main(int argc, char **argv) { + (void) argc; + (void) argv; + return 0; +} diff --git a/examples/sinewave.c b/examples/sinewave.c index a1f19f8..3a127ae 100755..100644 --- a/examples/sinewave.c +++ b/examples/sinewave.c @@ -1,30 +1,3 @@ -#if 0 /* -#/ ================================================================ -#/ -#/ sinewave.c -#/ -#/ ================================================================ -#/ -#/ Self-compilation shell script -#/ -SRC=${0##*./} -BIN=${SRC%.*} -gcc \ - -Wall -Wextra -Werror -pedantic \ - -Wno-old-style-declaration \ - -Wno-missing-braces \ - -Wno-unused-variable \ - -Wno-unused-but-set-variable \ - -Wno-unused-parameter \ - -Wno-overlength-strings \ - -O3 \ - -fsanitize=undefined,address,leak \ - -lX11 -lm -lasound \ - -o $BIN $SRC && \ - ./$BIN $@ && rm $BIN -exit $? # */ -#endif - #include "../graphics.c" i64 time_0 = 0; @@ -33,26 +6,26 @@ i64 audio_samples = 0; f32 frames[AUDIO_SAMPLE_RATE * AUDIO_NUM_CHANNELS] = {0}; b8 ui_button(f64 x, f64 y, f64 width, f64 height) { - b8 has_cursor = platform.cursor_x >= x && platform.cursor_x < x + width && - platform.cursor_y >= y && platform.cursor_y < y + height; + b8 has_cursor = g_platform.cursor_x >= x && g_platform.cursor_x < x + width && + g_platform.cursor_y >= y && g_platform.cursor_y < y + height; - b8 is_pressed = has_cursor && platform.key_down[BUTTON_LEFT]; + b8 is_pressed = has_cursor && g_platform.key_down[BUTTON_LEFT]; if (is_pressed) - fill_rectangle(OP_SET, 0xffffff, x, y, width, height); + fill_rectangle(OP_SET, (vec3_f32) { 1.f, 1.f, 1.f }, x, y, width, height); else if (has_cursor) - fill_rectangle(OP_SET, 0xa0a000, x, y, width, height); + fill_rectangle(OP_SET, (vec3_f32) { .8f, .8f, 0.f }, x, y, width, height); else - fill_rectangle(OP_SET, 0x808030, x, y, width, height); + fill_rectangle(OP_SET, (vec3_f32) { .8f, .8f, .2f }, x, y, width, height); - return has_cursor && platform.key_pressed[BUTTON_LEFT]; + return has_cursor && g_platform.key_pressed[BUTTON_LEFT]; } void update_and_render_frame(void) { i32 num_events = p_handle_events(); if (num_events > 0) { - fill_rectangle(OP_SET, 0x202020, 0, 0, platform.frame_width, platform.frame_height); + fill_rectangle(OP_SET, (vec3_f32) { .1f, .1f, .1f }, 0, 0, g_platform.frame_width, g_platform.frame_height); if (ui_button(100, 100, 200, 200)) p_queue_sound(0, AUDIO_SAMPLE_RATE, frames); @@ -70,7 +43,7 @@ i32 main(i32 argc, c8 **argv) { (void) argc; (void) argv; - platform = (Platform) { + g_platform = (Platform) { .title = "Sine Wave", .graceful_exit = 1, }; diff --git a/examples/ui.c b/examples/ui.c index 79bdd70..684b428 100755..100644 --- a/examples/ui.c +++ b/examples/ui.c @@ -1,30 +1,3 @@ -#if 0 /* -#/ ================================================================ -#/ -#/ ui.c -#/ -#/ ================================================================ -#/ -#/ Self-compilation shell script -#/ -SRC=${0##*./} -BIN=${SRC%.*} -gcc \ - -Wall -Wextra -Werror -pedantic \ - -Wno-old-style-declaration \ - -Wno-missing-braces \ - -Wno-unused-variable \ - -Wno-unused-but-set-variable \ - -Wno-unused-parameter \ - -Wno-overlength-strings \ - -O3 \ - -fsanitize=undefined,address,leak \ - -lX11 -lm -lasound \ - -o $BIN $SRC && \ - ./$BIN $@ && rm $BIN -exit $? # */ -#endif - #include "../graphics.c" b8 button_0_down = 0; @@ -40,53 +13,53 @@ i64 selection = 0; void update_and_render_frame(void) { p_wait_events(); - for (i32 j = 0; j < platform.frame_height; ++j) - for (i32 i = 0; i < platform.frame_width; ++i) - platform.pixels[j * platform.frame_width + i] = 0x302000; + for (i32 j = 0; j < g_platform.frame_height; ++j) + for (i32 i = 0; i < g_platform.frame_width; ++i) + g_platform.pixels[j * g_platform.frame_width + i] = (vec3_f32) { .2f, .1f, 0.f }; - if (platform.cursor_x >= 40 && platform.cursor_x < 100 && platform.cursor_y >= 40 && platform.cursor_y < 100) { - button_0_down = platform.key_down[BUTTON_LEFT]; + if (g_platform.cursor_x >= 40 && g_platform.cursor_x < 100 && g_platform.cursor_y >= 40 && g_platform.cursor_y < 100) { + button_0_down = g_platform.key_down[BUTTON_LEFT]; if (button_0_down) - fill_rectangle(OP_SET, 0xffffff, 40, 40, 60, 60); + fill_rectangle(OP_SET, (vec3_f32) { 1.f, 1.f, 1.f }, 40, 40, 60, 60); else - fill_rectangle(OP_SET, 0x00ff00, 40, 40, 60, 60); + fill_rectangle(OP_SET, (vec3_f32) { 0.f, 1.f, 0.f }, 40, 40, 60, 60); } else { button_0_down = 0; - fill_rectangle(OP_SET, 0x208020, 40, 40, 60, 60); + fill_rectangle(OP_SET, (vec3_f32) { .1f, .5f, .1f }, 40, 40, 60, 60); } - if (platform.cursor_x >= 40 && platform.cursor_x < 100 && platform.cursor_y >= 120 && platform.cursor_y < 180) { - button_1_down = platform.key_down[BUTTON_LEFT]; - if (platform.key_pressed[BUTTON_LEFT]) + if (g_platform.cursor_x >= 40 && g_platform.cursor_x < 100 && g_platform.cursor_y >= 120 && g_platform.cursor_y < 180) { + button_1_down = g_platform.key_down[BUTTON_LEFT]; + if (g_platform.key_pressed[BUTTON_LEFT]) button_1_checked = !button_1_checked; if (button_1_down) - fill_rectangle(OP_SET, 0xffffff, 40, 120, 60, 60); + fill_rectangle(OP_SET, (vec3_f32) { 1.f, 1.f, 1.f }, 40, 120, 60, 60); else if (button_1_checked) - fill_rectangle(OP_SET, 0xff8080, 40, 120, 60, 60); + fill_rectangle(OP_SET, (vec3_f32) { 1.f, .5f, .5f }, 40, 120, 60, 60); else - fill_rectangle(OP_SET, 0x80ff80, 40, 120, 60, 60); + fill_rectangle(OP_SET, (vec3_f32) { .5f, 1.f, .5f }, 40, 120, 60, 60); } else { button_1_down = 0; if (button_1_checked) - fill_rectangle(OP_SET, 0xff0000, 40, 120, 60, 60); + fill_rectangle(OP_SET, (vec3_f32) { 1.f, 0.f, 0.f }, 40, 120, 60, 60); else - fill_rectangle(OP_SET, 0x00ff00, 40, 120, 60, 60); + fill_rectangle(OP_SET, (vec3_f32) { 0.f, 1.f, 0.f }, 40, 120, 60, 60); } - i64 w = platform.frame_width / 2; - i64 h = platform.frame_height / 2; + i64 w = g_platform.frame_width / 2; + i64 h = g_platform.frame_height / 2; i64 x0 = w / 2; i64 y0 = h / 2; - i64 color = 0xff7f7f; + vec3_f32 color = { 1.f, .5f, .5f }; - if (platform.cursor_x >= x0 && platform.cursor_x < x0 + w && - platform.cursor_y >= y0 && platform.cursor_y < y0 + h) - color = 0xffffff; + if (g_platform.cursor_x >= x0 && g_platform.cursor_x < x0 + w && + g_platform.cursor_y >= y0 && g_platform.cursor_y < y0 + h) + color = (vec3_f32) { 1.f, 1.f, 1.f }; - for (i64 i = 0; i < platform.input_size; ++i) - if (platform.input[i].ctrl) - switch (platform.input[i].key) { + for (i64 i = 0; i < g_platform.input_size; ++i) + if (g_platform.input[i].ctrl) + switch (g_platform.input[i].key) { case KEY_V: { if (selection != 0) { i64 i0 = selection < 0 ? cursor + selection : cursor; @@ -98,8 +71,8 @@ void update_and_render_frame(void) { text_len -= i1 - i0; } - for (i64 n = 0; n < platform.clipboard_size;) { - c32 c = utf8_read(platform.clipboard_size - n, platform.clipboard + n); + for (i64 n = 0; n < g_platform.clipboard_size;) { + c32 c = utf8_read(g_platform.clipboard_size - n, g_platform.clipboard + n); if (text_len < (i64) (sizeof text / sizeof *text)) { for (i64 j = text_len; j > cursor; --j) @@ -147,9 +120,9 @@ void update_and_render_frame(void) { default:; } else - switch (platform.input[i].key) { + switch (g_platform.input[i].key) { case KEY_LEFT: - if (platform.key_down[MOD_SHIFT]) { + if (g_platform.key_down[MOD_SHIFT]) { if (cursor > 0) ++selection; } else if (selection != 0) { @@ -161,7 +134,7 @@ void update_and_render_frame(void) { break; case KEY_RIGHT: - if (platform.key_down[MOD_SHIFT]) { + if (g_platform.key_down[MOD_SHIFT]) { if (cursor < text_len) --selection; } else if (selection != 0) { @@ -207,11 +180,11 @@ void update_and_render_frame(void) { case KEY_ENTER: case KEY_TAB: - platform.input[i].c = platform.input[i].key; + g_platform.input[i].c = g_platform.input[i].key; // fallthrough default: - if (platform.input[i].c) { + if (g_platform.input[i].c) { if (selection != 0) { i64 i0 = selection < 0 ? cursor + selection : cursor; i64 i1 = selection < 0 ? cursor : cursor + selection; @@ -225,15 +198,15 @@ void update_and_render_frame(void) { if (text_len < (i64) (sizeof text / sizeof *text)) { for (i64 i = text_len; i > cursor; --i) text[i] = text[i - 1]; - text[cursor++] = platform.input[i].c; + text[cursor++] = g_platform.input[i].c; ++text_len; } } } - draw_text_area(0, x0 + 8, y0 - 8, w, h, 10., 10., text_len, text); + draw_text_area((vec3_f32) {0}, x0 + 8, y0 - 8, w, h, 10., 10., text_len, text); draw_text_area(color, x0, y0, w, h, 10., 10., text_len, text); - draw_selection_cursor(0xffffff, x0, y0, w, h, 10., 10., cursor, selection, text_len, text); + draw_selection_cursor((vec3_f32) { 1.f, 1.f, 1.f }, x0, y0, w, h, 10., 10., cursor, selection, text_len, text); p_render_frame(); } @@ -242,7 +215,7 @@ i32 main(i32 argc, c8 **argv) { (void) argc; (void) argv; - platform = (Platform) { + g_platform = (Platform) { .title = "UI", .frame_width = 960, .frame_height = 720, @@ -29,13 +29,12 @@ b8 triangle_contains (f64 x0, f64 y0, f64 x1, f64 y1, f64 x2, f64 y2, f64 px, f6 b8 ellipse_contains (f64 x0, f64 y0, f64 width, f64 height, f64 px, f64 py); b8 line_contains (f64 x0, f64 y0, f64 x1, f64 y1, f64 width, f64 px, f64 py); -u32 u32_from_rgb (f32 red, f32 green, f32 blue); -void fill_rectangle (u32 op, u32 color, f64 x0, f64 y0, f64 width, f64 height); -void fill_triangle (u32 op, u32 color, f64 x0, f64 y0, f64 x1, f64 y1, f64 x2, f64 y2); -void fill_ellipse (u32 op, u32 color, f64 x0, f64 y0, f64 width, f64 height); -void fill_line (u32 op, u32 color, f64 x0, f64 y0, f64 x1, f64 y1, f64 width); -void draw_text_area (u32 color, f64 x0, f64 y0, f64 width, f64 height, f64 max_scale_x, f64 max_scale_y, i64 num_chars, c32 *text); -void draw_selection_cursor(u32 color, f64 x0, f64 y0, f64 width, f64 height, f64 max_scale_x, f64 max_scale_y, i64 cursor, i64 selection, i64 num_chars, c32 *text); +void fill_rectangle (u32 op, vec3_f32 color, f64 x0, f64 y0, f64 width, f64 height); +void fill_triangle (u32 op, vec3_f32 color, f64 x0, f64 y0, f64 x1, f64 y1, f64 x2, f64 y2); +void fill_ellipse (u32 op, vec3_f32 color, f64 x0, f64 y0, f64 width, f64 height); +void fill_line (u32 op, vec3_f32 color, f64 x0, f64 y0, f64 x1, f64 y1, f64 width); +void draw_text_area (vec3_f32 color, f64 x0, f64 y0, f64 width, f64 height, f64 max_scale_x, f64 max_scale_y, i64 num_chars, c32 *text); +void draw_selection_cursor(vec3_f32 color, f64 x0, f64 y0, f64 width, f64 height, f64 max_scale_x, f64 max_scale_y, i64 cursor, i64 selection, i64 num_chars, c32 *text); #endif // GRAPHICS_HEADER_GUARD_ @@ -67,21 +66,6 @@ b8 same_sign(f64 a, f64 b) { return 1; } -u32 u32_from_rgb(f32 red, f32 green, f32 blue) { - i32 r = (i32) floor(red * 255.f); - i32 g = (i32) floor(green * 255.f); - i32 b = (i32) floor(blue * 255.f); - - if (r < 0) r = 0; - if (r > 255) r = 255; - if (g < 0) g = 0; - if (g > 255) g = 255; - if (b < 0) b = 0; - if (b > 255) b = 255; - - return (r << 16) | (g << 8) | b; -} - static u64 _bitfont[] = { 0xbc0000000000, 0xc00300000, 0x5fd5040093f24fc9, 0xa00a2c2a1a280105, 0xc000415e6f, 0x400000020be0000, 0x1c38a8400000007d, 0x40002043e1020215, 0x408102000000010, 0x9800000000020002, 0xf913e00000033, 0x53200000207c8800, 0x3654880000099, 0x54b800000f840e00, 0xe953c000001a, 0x953e000000674080, 0x1e54b800000f, 0x490000000000240, 0x88a08000000, 0x20a220050a142850, 0x6520800000, 0x912f801eab260be, 0x800034952bf0001f, 0xc850bf0000921427, 0xf00010a54afc0003, 0xd29427800002142b, 0x840007e1023f0000, 0x7d09100000217e, 0x3f000188a08fc000, 0xc30c0cfc00000810, 0x27803f101013f00f, 0xc244bf0000f214, 0x4bf0002f21427800, 0xc254a480006c24, 0x407c00102fc08100, 0xf208080f0000fa0, 0x531007d81c607c0, 0xc208288c031141, 0x83fc00046954b10, 0x180e03000000, 0x41040000000ff04, 0x8102040810000404, 0x2a54600000000101, 0x309123e0000e, 0xc912180000a22447, 0x8000062a54700007, 0xe52a4300000029f0, 0xa0000602043e0001, 0x1d48000002074, 0x1f000003610f8000, 0x13e04f800000010, 0x470000780813e00f, 0x184893e0000e224, 0x23e0001f12243000, 0x82a54100000008, 0x40780000009f0200, 0xe208080e0001f20, 0xa22007981860780, 0x82082888022282, 0x16c200004ca95320, 0x7f000004, 0x408200000086d04, 0x8204, }; @@ -240,7 +224,7 @@ i64 enum_text_rows(i64 num_chars, c32 *text) { return rows; } -void draw_text(u32 color, f64 x0, f64 y0, f64 scale_x, f64 scale_y, i64 num_chars, c32 *text) { +void draw_text(vec3_f32 color, f64 x0, f64 y0, f64 scale_x, f64 scale_y, i64 num_chars, c32 *text) { if (text == NULL) return; @@ -275,19 +259,19 @@ void draw_text(u32 color, f64 x0, f64 y0, f64 scale_x, f64 scale_y, i64 num_char for (i64 i = i0; i < i1; ++i) { if (i < 0) continue; - if (i >= platform.frame_width) break; + if (i >= g_platform.frame_width) break; i64 column = ((i - i0) * num_cols) / (i1 - i0); i64 offset = char_column_offset(text[n], column); for (i64 j = j0; j < j1; ++j) { if (j < 0) continue; - if (j >= platform.frame_height) break; + if (j >= g_platform.frame_height) break; i64 row = ((j - j0) * CHAR_NUM_BITS_Y) / (j1 - j0); if (char_bit(offset, row)) - platform.pixels[j * platform.frame_width + i] = color; + g_platform.pixels[j * g_platform.frame_width + i] = color; } } @@ -295,13 +279,13 @@ void draw_text(u32 color, f64 x0, f64 y0, f64 scale_x, f64 scale_y, i64 num_char } } -void put_pixel(i64 i, i64 j, u32 op, u32 color) { - if (i < 0 || i >= platform.frame_width || j < 0 || j >= platform.frame_height) +void put_pixel(i64 i, i64 j, u32 op, vec3_f32 color) { + if (i < 0 || i >= g_platform.frame_width || j < 0 || j >= g_platform.frame_height) return; if (op == OP_XOR) - platform.pixels[j * platform.frame_width + i] ^= color; + g_platform.pixels[j * g_platform.frame_width + i] = rgb_f32_from_u32(rgb_u32_from_f32(color) ^ rgb_u32_from_f32(g_platform.pixels[j * g_platform.frame_width + i])); else - platform.pixels[j * platform.frame_width + i] = color; + g_platform.pixels[j * g_platform.frame_width + i] = color; } b8 rectangle_contains(f64 x0, f64 y0, f64 width, f64 height, f64 px, f64 py) { @@ -365,7 +349,7 @@ b8 line_contains(f64 x0, f64 y0, f64 x1, f64 y1, f64 width, f64 px, f64 py) { || triangle_contains(x0 - tx, y0 - ty, x1 + tx, y1 + ty, x1 - tx, y1 - ty, px, py); } -void fill_rectangle(u32 op, u32 color, f64 x0, f64 y0, f64 width, f64 height) { +void fill_rectangle(u32 op, vec3_f32 color, f64 x0, f64 y0, f64 width, f64 height) { i64 i0 = (i64) floor(x0 + .5); i64 j0 = (i64) floor(y0 + .5); i64 i1 = (i64) floor(x0 + width + .5); @@ -373,15 +357,15 @@ void fill_rectangle(u32 op, u32 color, f64 x0, f64 y0, f64 width, f64 height) { if (i0 < 0) i0 = 0; if (j0 < 0) j0 = 0; - if (i1 >= platform.frame_width) i1 = platform.frame_width - 1; - if (j1 >= platform.frame_height) j1 = platform.frame_height - 1; + if (i1 >= g_platform.frame_width) i1 = g_platform.frame_width - 1; + if (j1 >= g_platform.frame_height) j1 = g_platform.frame_height - 1; for (i64 j = j0; j < j1; ++j) for (i64 i = i0; i < i1; ++i) put_pixel(i, j, op, color); } -void fill_triangle(u32 op, u32 color, f64 x0, f64 y0, f64 x1, f64 y1, f64 x2, f64 y2) { +void fill_triangle(u32 op, vec3_f32 color, f64 x0, f64 y0, f64 x1, f64 y1, f64 x2, f64 y2) { // FIXME PERF: // Implement better algorithm. @@ -396,7 +380,7 @@ void fill_triangle(u32 op, u32 color, f64 x0, f64 y0, f64 x1, f64 y1, f64 x2, f6 put_pixel(i, j, op, color); } -void fill_ellipse(u32 op, u32 color, f64 x0, f64 y0, f64 width, f64 height) { +void fill_ellipse(u32 op, vec3_f32 color, f64 x0, f64 y0, f64 width, f64 height) { // FIXME PERF: // Implement better algorithm. @@ -406,10 +390,10 @@ void fill_ellipse(u32 op, u32 color, f64 x0, f64 y0, f64 width, f64 height) { i64 j1 = (i64) floor(y0 + height + .5); for (i64 j = j0; j < j1; ++j) { - if (j < 0 || j >= platform.frame_height) + if (j < 0 || j >= g_platform.frame_height) continue; for (i64 i = i0; i < i1; ++i) { - if (i < 0 || i >= platform.frame_width) + if (i < 0 || i >= g_platform.frame_width) continue; if (ellipse_contains(x0, y0, width, height, (f64) i, (f64) j)) put_pixel(i, j, op, color); @@ -417,7 +401,7 @@ void fill_ellipse(u32 op, u32 color, f64 x0, f64 y0, f64 width, f64 height) { } } -void fill_line(u32 op, u32 color, f64 x0, f64 y0, f64 x1, f64 y1, f64 width) { +void fill_line(u32 op, vec3_f32 color, f64 x0, f64 y0, f64 x1, f64 y1, f64 width) { f64 dx = x1 - x0; f64 dy = y1 - y0; @@ -437,7 +421,7 @@ void fill_line(u32 op, u32 color, f64 x0, f64 y0, f64 x1, f64 y1, f64 width) { fill_triangle(op, color, x0 - tx, y0 - ty, x1 + tx, y1 + ty, x1 - tx, y1 - ty); } -void draw_text_area(u32 color, f64 x0, f64 y0, f64 width, f64 height, f64 max_scale_x, f64 max_scale_y, i64 num_chars, c32 *text) { +void draw_text_area(vec3_f32 color, f64 x0, f64 y0, f64 width, f64 height, f64 max_scale_x, f64 max_scale_y, i64 num_chars, c32 *text) { if (max_scale_x < 1e-6 || max_scale_y < 1e-6) return; @@ -458,7 +442,7 @@ void draw_text_area(u32 color, f64 x0, f64 y0, f64 width, f64 height, f64 max_sc draw_text(color, x0, y0, kx, ky, num_chars, text); } -void draw_selection_cursor(u32 color, f64 x0, f64 y0, f64 width, f64 height, f64 max_scale_x, f64 max_scale_y, i64 cursor, i64 selection, i64 num_chars, c32 *text) { +void draw_selection_cursor(vec3_f32 color, f64 x0, f64 y0, f64 width, f64 height, f64 max_scale_x, f64 max_scale_y, i64 cursor, i64 selection, i64 num_chars, c32 *text) { if (max_scale_x < 1e-6 || max_scale_y < 1e-6) return; @@ -62,7 +62,9 @@ }, } ).then((program) => { - program.exports.js_main(options.processorOptions.href); + program.exports.js_main( + options.processorOptions.href // FIXME + ); this.memory_buffer = program.exports.memory.buffer; this.sound_buffer_address = program.exports.js_sound_buffer(); @@ -497,7 +499,7 @@ sound_node.port.postMessage({ id : "paste", - bytes : new TextEncoder("utf-8").encode(ev.clipboardData.getData("text")), + bytes : new TextEncoder("utf8").encode(ev.clipboardData.getData("text")), mod : paste_mod, key : KEY_PASTE, ch : paste_ch, diff --git a/reduced_system_layer.c b/reduced_system_layer.c index c27be56..af49453 100755 --- a/reduced_system_layer.c +++ b/reduced_system_layer.c @@ -37,13 +37,12 @@ #/ - Window #/ - Wayland #/ - Windows graphics +#/ - Drop files #/ - Sound #/ - Windows audio #/ - Recording #/ - Networking -#/ - TCP #/ - Windows sockets -#/ - Web Sockets #/ - Graphics #/ - Self-contained impl #/ - UI @@ -83,6 +82,8 @@ #/ #/ Self-compilation shell script #/ +#/ ================================================================ + SRC=${0##*./} BIN=${SRC%.*} gcc \ @@ -125,6 +126,19 @@ typedef signed char b8; typedef float f32; typedef double f64; +typedef struct { f64 x, y; } vec2; +typedef struct { f64 x, y, z; } vec3; +typedef struct { f64 x, y, z, w; } vec4; +typedef struct { f32 x, y; } vec2_f32; +typedef struct { f32 x, y, z; } vec3_f32; +typedef struct { f32 x, y, z, w; } vec4_f32; +typedef struct { i64 x, y; } vec2_i64; +typedef struct { i64 x, y, z; } vec3_i64; +typedef struct { i64 x, y, z, w; } vec4_i64; +typedef struct { f64 v[ 4]; } mat2; +typedef struct { f64 v[ 9]; } mat3; +typedef struct { f64 v[16]; } mat4; + #endif // TYPES_HEADER_GUARD_ // ================================================================ @@ -311,7 +325,7 @@ typedef struct { c8 * title; i32 frame_width; i32 frame_height; - u32 * pixels; + vec3_f32 * pixels; i64 input_size; Input_Key *input; i64 clipboard_size; @@ -345,6 +359,10 @@ i32 utf8_size(c32 c); c32 utf8_read(i64 len, c8 *s); i32 utf8_write(c32 c, c8 *buffer); +// Color +u32 rgb_u32_from_f32(vec3_f32 c); +vec3_f32 rgb_f32_from_u32(u32 color); + // Time and sleep i64 p_time(void); void p_yield(void); @@ -375,7 +393,7 @@ void p_queue_sound(i64 delay_in_samples, i64 num_samples, f32 *frames); i64 p_recv(u16 slot, IP_Address address, i64 size, u8 *data, u16 *local_port, IP_Address *remote_address); i64 p_send(u16 slot, IP_Address address, i64 size, u8 *data, u16 *local_port); -extern Platform platform; +extern Platform g_platform; #ifdef __wasm__ i32 main(i32 argc, c8 **argv); @@ -424,17 +442,17 @@ f64 atan2(f64 y, f64 x); void update_and_render_frame(void) { p_handle_events(); - i64 w = platform.frame_width / 2; - i64 h = platform.frame_height / 2; + i64 w = g_platform.frame_width / 2; + i64 h = g_platform.frame_height / 2; i64 x = w / 2; i64 y = h / 2; - for (i64 j = 0; j < platform.frame_height; ++j) - for (i64 i = 0; i < platform.frame_width; ++i) + for (i64 j = 0; j < g_platform.frame_height; ++j) + for (i64 i = 0; i < g_platform.frame_width; ++i) if (i < x || i >= x + w || j < y || j >= y + h) - platform.pixels[j * platform.frame_width + i] = 0xa0a0a0; + g_platform.pixels[j * g_platform.frame_width + i] = (vec3_f32) { .8f, .8f, .8f }; else - platform.pixels[j * platform.frame_width + i] = 0x131112; + g_platform.pixels[j * g_platform.frame_width + i] = (vec3_f32) { .27f, .21f, .24f }; p_render_frame(); p_sleep_for(0); @@ -444,7 +462,7 @@ i32 main(i32 argc, c8 **argv) { (void) argc; (void) argv; - platform = (Platform) { + g_platform = (Platform) { .title = "Example", .frame_width = 1280, .frame_height = 720, @@ -467,12 +485,14 @@ i32 main(i32 argc, c8 **argv) { #ifndef REDUCED_SYSTEM_LAYER_IMPL_GUARD_ #define REDUCED_SYSTEM_LAYER_IMPL_GUARD_ -Platform platform = {0}; +Platform g_platform = {0}; void p_event_loop(void) { + (void) sqrt; // For the compiler. + p_init(); #if !defined(__wasm__) - while (!platform.done) update_and_render_frame(); + while (!g_platform.done) update_and_render_frame(); p_cleanup(); #endif } @@ -549,6 +569,26 @@ i32 utf8_write(c32 c, c8 *buffer) { return 0; } +u32 rgb_u32_from_f32(vec3_f32 c) { + i32 ir = (i32) floor(c.x * 255. + .5); + i32 ig = (i32) floor(c.y * 255. + .5); + i32 ib = (i32) floor(c.z * 255. + .5); + + u32 r = ir < 0 ? 0u : ir > 255 ? 255u : (u32) ir; + u32 g = ig < 0 ? 0u : ig > 255 ? 255u : (u32) ig; + u32 b = ib < 0 ? 0u : ib > 255 ? 255u : (u32) ib; + + return (r << 16) | (g << 8) | b; +} + +vec3_f32 rgb_f32_from_u32(u32 color) { + return (vec3_f32) { + .x = (f32) ((color >> 16) & 0xff) / 255., + .y = (f32) ((color >> 8) & 0xff) / 255., + .z = (f32) ( color & 0xff) / 255., + }; +} + // ================================================================ // // Unix @@ -1024,7 +1064,8 @@ void p_queue_sound(i64 delay_in_samples, i64 num_samples, f32 *frames) { static i16 _key_table[MAX_NUM_KEYS] = {0}; static b8 _key_repeat[MAX_NUM_KEYS] = {0}; -static u32 _buffer[MAX_NUM_PIXELS] = {0}; +static vec3_f32 _pixels[MAX_NUM_PIXELS] = {0}; +static u32 _pixels_internal[MAX_NUM_PIXELS] = {0}; static Input_Key _input[MAX_INPUT_SIZE] = {0}; static c8 _clipboard_buffer[MAX_CLIPBOARD_SIZE] = {0}; static XImage _image = {0}; @@ -1165,15 +1206,15 @@ void p_init(void) { i32 display_width = DisplayWidth (_display, screen); i32 display_height = DisplayHeight(_display, screen); - if (platform.frame_width <= 0) - platform.frame_width = 400; - if (platform.frame_height <= 0) - platform.frame_height = 300; + if (g_platform.frame_width <= 0) + g_platform.frame_width = 400; + if (g_platform.frame_height <= 0) + g_platform.frame_height = 300; - i32 x = (display_width - platform.frame_width) / 2; - i32 y = (display_height - platform.frame_height) / 2; + i32 x = (display_width - g_platform.frame_width) / 2; + i32 y = (display_height - g_platform.frame_height) / 2; - _window = XCreateWindow(_display, XDefaultRootWindow(_display), x, y, platform.frame_width, platform.frame_height, 0, depth, InputOutput, visual, CWEventMask, &(XSetWindowAttributes) { .event_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask | VisibilityChangeMask | FocusChangeMask | StructureNotifyMask | SubstructureNotifyMask, }); + _window = XCreateWindow(_display, XDefaultRootWindow(_display), x, y, g_platform.frame_width, g_platform.frame_height, 0, depth, InputOutput, visual, CWEventMask, &(XSetWindowAttributes) { .event_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask | VisibilityChangeMask | FocusChangeMask | StructureNotifyMask | SubstructureNotifyMask, }); _im = XOpenIM(_display, NULL, NULL, NULL); @@ -1189,23 +1230,23 @@ void p_init(void) { return; } - platform.pixels = _buffer; - platform.input = _input; - platform.clipboard = _clipboard_buffer; + g_platform.pixels = _pixels; + g_platform.input = _input; + g_platform.clipboard = _clipboard_buffer; _image = (XImage) { - .width = platform.frame_width, - .height = platform.frame_height, + .width = g_platform.frame_width, + .height = g_platform.frame_height, .depth = depth, .xoffset = 0, .format = ZPixmap, - .data = (c8 *) _buffer, + .data = (c8 *) _pixels_internal, .byte_order = LSBFirst, .bitmap_unit = 32, .bitmap_bit_order = LSBFirst, .bitmap_pad = 32, .bits_per_pixel = 32, - .bytes_per_line = 4 * platform.frame_width, + .bytes_per_line = 4 * g_platform.frame_width, .red_mask = 0xff0000, .green_mask = 0x00ff00, .blue_mask = 0x0000ff, @@ -1221,17 +1262,17 @@ void p_init(void) { XSetICFocus(_ic); XSetWMProtocols(_display, _window, &_wm_delete_window, 1); - if (platform.title != NULL) - XStoreName(_display, _window, platform.title); + if (g_platform.title != NULL) + XStoreName(_display, _window, g_platform.title); XMapWindow(_display, _window); - XPutImage(_display, _window, _gc, &_image, 0, 0, 0, 0, platform.frame_width, platform.frame_height); + XPutImage(_display, _window, _gc, &_image, 0, 0, 0, 0, g_platform.frame_width, g_platform.frame_height); XFlush(_display); } void p_cleanup(void) { - if (!platform.graceful_exit) + if (!g_platform.graceful_exit) return; if (_window != 0) @@ -1252,13 +1293,13 @@ i32 p_handle_events(void) { i32 num_events = 0; - memset(platform.key_pressed, 0, sizeof platform.key_pressed); + memset(g_platform.key_pressed, 0, sizeof g_platform.key_pressed); memset(_key_repeat, 0, sizeof _key_repeat); - platform.input_size = 0; - platform.cursor_dx = 0; - platform.cursor_dy = 0; - platform.wheel_dy = 0; + g_platform.input_size = 0; + g_platform.cursor_dx = 0; + g_platform.cursor_dy = 0; + g_platform.wheel_dy = 0; XEvent ev; @@ -1272,34 +1313,34 @@ i32 p_handle_events(void) { switch (ev.type) { case DestroyNotify: - platform.done = 1; + g_platform.done = 1; break; case MotionNotify: - platform.cursor_dx += ev.xmotion.x - platform.cursor_x; - platform.cursor_dy += ev.xmotion.y - platform.cursor_y; - platform.cursor_x = ev.xmotion.x; - platform.cursor_y = ev.xmotion.y; + g_platform.cursor_dx += ev.xmotion.x - g_platform.cursor_x; + g_platform.cursor_dy += ev.xmotion.y - g_platform.cursor_y; + g_platform.cursor_x = ev.xmotion.x; + g_platform.cursor_y = ev.xmotion.y; break; case ButtonPress: - platform.cursor_x = ev.xbutton.x; - platform.cursor_y = ev.xbutton.y; + g_platform.cursor_x = ev.xbutton.x; + g_platform.cursor_y = ev.xbutton.y; switch (ev.xbutton.button) { case Button1: - platform.key_down[BUTTON_LEFT] = 1; - platform.key_pressed[BUTTON_LEFT] = 1; + g_platform.key_down[BUTTON_LEFT] = 1; + g_platform.key_pressed[BUTTON_LEFT] = 1; break; case Button2: - platform.key_down[BUTTON_MIDDLE] = 1; - platform.key_pressed[BUTTON_MIDDLE] = 1; + g_platform.key_down[BUTTON_MIDDLE] = 1; + g_platform.key_pressed[BUTTON_MIDDLE] = 1; break; case Button3: - platform.key_down[BUTTON_RIGHT] = 1; - platform.key_pressed[BUTTON_RIGHT] = 1; + g_platform.key_down[BUTTON_RIGHT] = 1; + g_platform.key_pressed[BUTTON_RIGHT] = 1; break; - case Button4: ++platform.wheel_dy; break; - case Button5: --platform.wheel_dy; break; + case Button4: ++g_platform.wheel_dy; break; + case Button5: --g_platform.wheel_dy; break; default:; } if (!requested_clipboard) { @@ -1309,36 +1350,36 @@ i32 p_handle_events(void) { break; case ButtonRelease: - platform.cursor_x = ev.xbutton.x; - platform.cursor_y = ev.xbutton.y; + g_platform.cursor_x = ev.xbutton.x; + g_platform.cursor_y = ev.xbutton.y; switch (ev.xbutton.button) { - case Button1: platform.key_down[BUTTON_LEFT] = 0; break; - case Button2: platform.key_down[BUTTON_MIDDLE] = 0; break; - case Button3: platform.key_down[BUTTON_RIGHT] = 0; break; + case Button1: g_platform.key_down[BUTTON_LEFT] = 0; break; + case Button2: g_platform.key_down[BUTTON_MIDDLE] = 0; break; + case Button3: g_platform.key_down[BUTTON_RIGHT] = 0; break; default:; } break; case KeyPress: { i16 k = _key_table[ev.xkey.keycode]; - platform.cursor_x = ev.xkey.x; - platform.cursor_y = ev.xkey.y; + g_platform.cursor_x = ev.xkey.x; + g_platform.cursor_y = ev.xkey.y; - platform.key_down[k] = 1; + g_platform.key_down[k] = 1; if (!_key_repeat[k]) - platform.key_pressed[k] = 1; + g_platform.key_pressed[k] = 1; - platform.key_down[MOD_CTRL] = !!(ev.xkey.state & ControlMask); - platform.key_down[MOD_SHIFT] = !!(ev.xkey.state & ShiftMask); - platform.key_down[MOD_ALT] = !!(ev.xkey.state & Mod1Mask); - platform.key_down[MOD_CAPS] = !!(ev.xkey.state & LockMask); - platform.key_down[MOD_NUM] = !!(ev.xkey.state & Mod2Mask); - platform.key_down[MOD_SCROLL] = !!(ev.xkey.state & Mod3Mask); - platform.key_down[MOD_META] = !!(ev.xkey.state & Mod4Mask); + g_platform.key_down[MOD_CTRL] = !!(ev.xkey.state & ControlMask); + g_platform.key_down[MOD_SHIFT] = !!(ev.xkey.state & ShiftMask); + g_platform.key_down[MOD_ALT] = !!(ev.xkey.state & Mod1Mask); + g_platform.key_down[MOD_CAPS] = !!(ev.xkey.state & LockMask); + g_platform.key_down[MOD_NUM] = !!(ev.xkey.state & Mod2Mask); + g_platform.key_down[MOD_SCROLL] = !!(ev.xkey.state & Mod3Mask); + g_platform.key_down[MOD_META] = !!(ev.xkey.state & Mod4Mask); - if (platform.input_size < MAX_INPUT_SIZE) { + if (g_platform.input_size < MAX_INPUT_SIZE) { if (k < 32 || k >= 128) - platform.input[platform.input_size++] = (Input_Key) { + g_platform.input[g_platform.input_size++] = (Input_Key) { .ctrl = !!(ev.xkey.state & ControlMask), .shift = !!(ev.xkey.state & ShiftMask), .alt = !!(ev.xkey.state & Mod1Mask), @@ -1353,7 +1394,7 @@ i32 p_handle_events(void) { c8 buf[16]; i32 len = Xutf8LookupString(_ic, &ev.xkey, buf, sizeof buf - 1, NULL, NULL); if (len > 0) - platform.input[platform.input_size++] = (Input_Key) { + g_platform.input[g_platform.input_size++] = (Input_Key) { .ctrl = !!(ev.xkey.state & ControlMask), .shift = !!(ev.xkey.state & ShiftMask), .alt = !!(ev.xkey.state & Mod1Mask), @@ -1376,19 +1417,19 @@ i32 p_handle_events(void) { case KeyRelease: { i16 k = _key_table[ev.xkey.keycode]; - platform.cursor_x = ev.xkey.x; - platform.cursor_y = ev.xkey.y; + g_platform.cursor_x = ev.xkey.x; + g_platform.cursor_y = ev.xkey.y; - platform.key_down[k] = 0; + g_platform.key_down[k] = 0; _key_repeat[k] = 1; - platform.key_down[MOD_CTRL] = !!(ev.xkey.state & ControlMask); - platform.key_down[MOD_SHIFT] = !!(ev.xkey.state & ShiftMask); - platform.key_down[MOD_ALT] = !!(ev.xkey.state & Mod1Mask); - platform.key_down[MOD_CAPS] = !!(ev.xkey.state & LockMask); - platform.key_down[MOD_NUM] = !!(ev.xkey.state & Mod2Mask); - platform.key_down[MOD_SCROLL] = !!(ev.xkey.state & Mod3Mask); - platform.key_down[MOD_META] = !!(ev.xkey.state & Mod4Mask); + g_platform.key_down[MOD_CTRL] = !!(ev.xkey.state & ControlMask); + g_platform.key_down[MOD_SHIFT] = !!(ev.xkey.state & ShiftMask); + g_platform.key_down[MOD_ALT] = !!(ev.xkey.state & Mod1Mask); + g_platform.key_down[MOD_CAPS] = !!(ev.xkey.state & LockMask); + g_platform.key_down[MOD_NUM] = !!(ev.xkey.state & Mod2Mask); + g_platform.key_down[MOD_SCROLL] = !!(ev.xkey.state & Mod3Mask); + g_platform.key_down[MOD_META] = !!(ev.xkey.state & Mod4Mask); } break; case SelectionRequest: @@ -1415,8 +1456,8 @@ i32 p_handle_events(void) { ev.xselectionrequest.target, 8, PropModeReplace, - (u8 *) platform.clipboard, - platform.clipboard_size + (u8 *) g_platform.clipboard, + g_platform.clipboard_size ); } @@ -1471,9 +1512,9 @@ i32 p_handle_events(void) { } else if (ev.xselection.target == _target) { if (len > MAX_CLIPBOARD_SIZE) len = MAX_CLIPBOARD_SIZE; - platform.clipboard_size = len; + g_platform.clipboard_size = len; if (len > 0) - memcpy(platform.clipboard, data, len); + memcpy(g_platform.clipboard, data, len); } if (data) @@ -1481,12 +1522,12 @@ i32 p_handle_events(void) { } break; - case EnterNotify: platform.has_cursor = 1; break; - case LeaveNotify: platform.has_cursor = 0; break; - case FocusOut: platform.has_focus = 0; break; + case EnterNotify: g_platform.has_cursor = 1; break; + case LeaveNotify: g_platform.has_cursor = 0; break; + case FocusOut: g_platform.has_focus = 0; break; case FocusIn: - platform.has_focus = 1; + g_platform.has_focus = 1; if (!requested_clipboard) { XConvertSelection(_display, _clipboard, _targets, _clipboard, _window, CurrentTime); requested_clipboard = 1; @@ -1499,7 +1540,7 @@ i32 p_handle_events(void) { case ClientMessage: if ((Atom) ev.xclient.data.l[0] == _wm_delete_window) - platform.done = 1; + g_platform.done = 1; break; default:; @@ -1509,15 +1550,15 @@ i32 p_handle_events(void) { XWindowAttributes attrs; XGetWindowAttributes(_display, _window, &attrs); - if ((platform.frame_width != attrs.width || platform.frame_height != attrs.height) && attrs.width * attrs.height * 4 <= (i32) sizeof _buffer) { + if ((g_platform.frame_width != attrs.width || g_platform.frame_height != attrs.height) && attrs.width * attrs.height * 4 <= (i32) sizeof _pixels_internal) { if (attrs.width > 0 && attrs.height > 0) { _image.width = attrs.width; _image.height = attrs.height; _image.bytes_per_line = 4 * attrs.width; } - platform.frame_width = attrs.width; - platform.frame_height = attrs.height; + g_platform.frame_width = attrs.width; + g_platform.frame_height = attrs.height; } return num_events; @@ -1535,10 +1576,14 @@ i32 p_wait_events(void) { } void p_render_frame(void) { - if (platform.done) + if (g_platform.done) return; - XPutImage(_display, _window, _gc, &_image, 0, 0, 0, 0, platform.frame_width, platform.frame_height); + i64 size = g_platform.frame_width * g_platform.frame_height; + for (i64 i = 0; i < size; ++i) + _pixels_internal[i] = rgb_u32_from_f32(_pixels[i]); + + XPutImage(_display, _window, _gc, &_image, 0, 0, 0, 0, g_platform.frame_width, g_platform.frame_height); XFlush(_display); } @@ -1550,9 +1595,9 @@ void p_clipboard_write(i64 size, c8 *data) { XSetSelectionOwner(_display, _clipboard, _window, CurrentTime); - platform.clipboard_size = size < MAX_CLIPBOARD_SIZE ? size : MAX_CLIPBOARD_SIZE; - if (platform.clipboard_size > 0) - memcpy(platform.clipboard, data, platform.clipboard_size); + g_platform.clipboard_size = size < MAX_CLIPBOARD_SIZE ? size : MAX_CLIPBOARD_SIZE; + if (g_platform.clipboard_size > 0) + memcpy(g_platform.clipboard, data, g_platform.clipboard_size); } #endif // defined(__linux__) @@ -1565,7 +1610,8 @@ void p_clipboard_write(i64 size, c8 *data) { #ifdef __wasm__ -static u32 _buffer[MAX_NUM_PIXELS] = {0}; +static vec3_f32 _pixels[MAX_NUM_PIXELS] = {0}; +static u32 _pixels_internal[MAX_NUM_PIXELS] = {0}; static Input_Key _input[MAX_INPUT_SIZE] = {0}; static c8 _clipboard_buffer[MAX_CLIPBOARD_SIZE] = {0}; static i32 _num_events = 0; @@ -1589,19 +1635,19 @@ void p_sleep_for(i64 duration) { void p_init(void) { ++_num_events; - platform.pixels = _buffer; - platform.input = _input; - platform.clipboard = _clipboard_buffer; - platform.done = 1; + g_platform.pixels = _pixels; + g_platform.input = _input; + g_platform.clipboard = _clipboard_buffer; + g_platform.done = 1; _sound_position = AUDIO_AVAIL_MIN % MAX_NUM_AUDIO_FRAMES; _sound_read = 0; } i32 p_handle_events(void) { - platform.input_size = _input_size; + g_platform.input_size = _input_size; _input_size = 0; for (i64 i = 0; i < MAX_NUM_KEYS; ++i) - platform.key_pressed[i] = _key_pressed[i]; + g_platform.key_pressed[i] = _key_pressed[i]; for (i64 i = 0; i < MAX_NUM_KEYS; ++i) _key_pressed[i] = 0; i32 n = _num_events; @@ -1615,7 +1661,11 @@ i32 p_wait_events(void) { return p_handle_events(); } -void p_render_frame(void) { } +void p_render_frame(void) { + i64 size = g_platform.frame_width * g_platform.frame_height; + for (i64 i = 0; i < size; ++i) + _pixels_internal[i] = 0xff000000u | rgb_u32_from_f32(_pixels[i]); +} void p_clipboard_write_impl(i32 size, c8 *data); @@ -1625,9 +1675,9 @@ void p_clipboard_write(i64 size, c8 *data) { if (size > MAX_CLIPBOARD_SIZE) size = MAX_CLIPBOARD_SIZE; - platform.clipboard_size = size; + g_platform.clipboard_size = size; for (i64 i = 0; i < size; ++i) - platform.clipboard[i] = data[i]; + g_platform.clipboard[i] = data[i]; p_clipboard_write_impl((i32) size, data); } @@ -1677,30 +1727,25 @@ __attribute__((export_name("js_main"))) void js_main(c8 *href) { } __attribute__((export_name("js_title"))) void *js_title(void) { - return platform.title; + return g_platform.title; } __attribute__((export_name("js_pixels"))) void *js_pixels(void) { - return platform.pixels; + return _pixels_internal; } __attribute__((export_name("js_frame"))) void js_frame(i32 frame_width, i32 frame_height, i32 num_samples) { - if (platform.frame_width != frame_width || platform.frame_height != frame_height) { + if (g_platform.frame_width != frame_width || g_platform.frame_height != frame_height) { ++_num_events; - platform.frame_width = frame_width; - platform.frame_height = frame_height; + g_platform.frame_width = frame_width; + g_platform.frame_height = frame_height; } - platform.done = 0; + g_platform.done = 0; if (_num_events > 0 || !_wait_events) { _wait_events = 0; update_and_render_frame(); - - // Make canvas pixels opaque. - i64 size = platform.frame_width * platform.frame_height; - for (i64 i = 0; i < size; ++i) - platform.pixels[i] |= 0xff000000; } // Convert interleaved frames to non-interleaved. @@ -1716,39 +1761,39 @@ __attribute__((export_name("js_frame"))) void js_frame(i32 frame_width, i32 fram __attribute__((export_name("js_mousemove"))) void js_mousemove(i32 x, i32 y) { ++_num_events; - platform.cursor_dx = x - platform.cursor_x; - platform.cursor_dy = y - platform.cursor_y; - platform.cursor_x = x; - platform.cursor_y = y; + g_platform.cursor_dx = x - g_platform.cursor_x; + g_platform.cursor_dy = y - g_platform.cursor_y; + g_platform.cursor_x = x; + g_platform.cursor_y = y; } __attribute__((export_name("js_mousedown"))) void js_mousedown(u32 buttons) { ++_num_events; - if ((buttons & 1) && !platform.key_down[BUTTON_LEFT]) _key_pressed[BUTTON_LEFT] = 1; - if ((buttons & 2) && !platform.key_down[BUTTON_RIGHT]) _key_pressed[BUTTON_RIGHT] = 1; - if ((buttons & 4) && !platform.key_down[BUTTON_MIDDLE]) _key_pressed[BUTTON_MIDDLE] = 1; - if (buttons & 1) platform.key_down[BUTTON_LEFT] = 1; - if (buttons & 2) platform.key_down[BUTTON_RIGHT] = 1; - if (buttons & 4) platform.key_down[BUTTON_MIDDLE] = 1; + if ((buttons & 1) && !g_platform.key_down[BUTTON_LEFT]) _key_pressed[BUTTON_LEFT] = 1; + if ((buttons & 2) && !g_platform.key_down[BUTTON_RIGHT]) _key_pressed[BUTTON_RIGHT] = 1; + if ((buttons & 4) && !g_platform.key_down[BUTTON_MIDDLE]) _key_pressed[BUTTON_MIDDLE] = 1; + if (buttons & 1) g_platform.key_down[BUTTON_LEFT] = 1; + if (buttons & 2) g_platform.key_down[BUTTON_RIGHT] = 1; + if (buttons & 4) g_platform.key_down[BUTTON_MIDDLE] = 1; } __attribute__((export_name("js_mouseup"))) void js_mouseup(u32 buttons) { ++_num_events; - if (!(buttons & 1)) platform.key_down[BUTTON_LEFT] = 0; - if (!(buttons & 2)) platform.key_down[BUTTON_RIGHT] = 0; - if (!(buttons & 4)) platform.key_down[BUTTON_MIDDLE] = 0; + if (!(buttons & 1)) g_platform.key_down[BUTTON_LEFT] = 0; + if (!(buttons & 2)) g_platform.key_down[BUTTON_RIGHT] = 0; + if (!(buttons & 4)) g_platform.key_down[BUTTON_MIDDLE] = 0; } __attribute__((export_name("js_keydown"))) void js_keydown(u32 key, u32 mod, u32 ch) { ++_num_events; _key_pressed[key] = 1; - platform.key_down[key] = 1; - platform.key_down[MOD_CTRL] = (mod & 1) ? 1 : 0; - platform.key_down[MOD_SHIFT] = (mod & 2) ? 1 : 0; - platform.key_down[MOD_ALT] = (mod & 4) ? 1 : 0; - platform.key_down[MOD_META] = (mod & 8) ? 1 : 0; - if (platform.input_size < MAX_INPUT_SIZE) - platform.input[_input_size++] = (Input_Key) { + g_platform.key_down[key] = 1; + g_platform.key_down[MOD_CTRL] = (mod & 1) ? 1 : 0; + g_platform.key_down[MOD_SHIFT] = (mod & 2) ? 1 : 0; + g_platform.key_down[MOD_ALT] = (mod & 4) ? 1 : 0; + g_platform.key_down[MOD_META] = (mod & 8) ? 1 : 0; + if (g_platform.input_size < MAX_INPUT_SIZE) + g_platform.input[_input_size++] = (Input_Key) { .ctrl = (mod & 1) ? 1 : 0, .shift = (mod & 2) ? 1 : 0, .alt = (mod & 4) ? 1 : 0, @@ -1760,11 +1805,11 @@ __attribute__((export_name("js_keydown"))) void js_keydown(u32 key, u32 mod, u32 __attribute__((export_name("js_keyup"))) void js_keyup(u32 key, u32 mod) { ++_num_events; - platform.key_down[key] = 0; - platform.key_down[MOD_CTRL] = (mod & 1) ? 1 : 0; - platform.key_down[MOD_SHIFT] = (mod & 2) ? 1 : 0; - platform.key_down[MOD_ALT] = (mod & 4) ? 1 : 0; - platform.key_down[MOD_META] = (mod & 8) ? 1 : 0; + g_platform.key_down[key] = 0; + g_platform.key_down[MOD_CTRL] = (mod & 1) ? 1 : 0; + g_platform.key_down[MOD_SHIFT] = (mod & 2) ? 1 : 0; + g_platform.key_down[MOD_ALT] = (mod & 4) ? 1 : 0; + g_platform.key_down[MOD_META] = (mod & 8) ? 1 : 0; } __attribute__((export_name("js_sample_rate"))) f64 js_sample_rate(void) { @@ -1784,7 +1829,7 @@ __attribute__((export_name("js_sound_buffer"))) void *js_sound_buffer(void) { } __attribute__((export_name("js_clipboard_size"))) i32 js_clipboard_size(void) { - return platform.clipboard_size; + return g_platform.clipboard_size; } __attribute__((export_name("js_clipboard_buffer"))) void *js_clipboard_buffer(i32 len) { @@ -1792,8 +1837,8 @@ __attribute__((export_name("js_clipboard_buffer"))) void *js_clipboard_buffer(i3 len = 0; if (len > MAX_CLIPBOARD_SIZE) len = MAX_CLIPBOARD_SIZE; - platform.clipboard_size = len; - return platform.clipboard; + g_platform.clipboard_size = len; + return g_platform.clipboard; } #endif // __wasm__ @@ -2,7 +2,7 @@ // // test.c // -// Unit-testing and microbenchmarks modular library for C +// Unit-testing and microbenchmarks modular library for C. // // ---------------------------------------------------------------- // |