diff options
author | Mitya Selivanov <automainint@guattari.tech> | 2024-11-17 05:22:41 +0100 |
---|---|---|
committer | Mitya Selivanov <automainint@guattari.tech> | 2024-11-17 05:22:41 +0100 |
commit | 94598aa337e0fd02a4bfd38929acfdb8296ee23b (patch) | |
tree | 40369c49a5075c1b21dcceed08c8e31119414b2b | |
parent | 674f8aa8f7a4e5a7197eae49c116727f4d681831 (diff) | |
download | reduced_system_layer-94598aa337e0fd02a4bfd38929acfdb8296ee23b.zip |
wasm input
-rwxr-xr-x | examples/landscape.c | 269 | ||||
-rw-r--r-- | index.htm | 125 | ||||
-rwxr-xr-x | reduced_system_layer.c | 113 |
3 files changed, 205 insertions, 302 deletions
diff --git a/examples/landscape.c b/examples/landscape.c deleted file mode 100755 index 9ee2e98..0000000 --- a/examples/landscape.c +++ /dev/null @@ -1,269 +0,0 @@ -#if 0 /* -#/ ================================================================ -#/ -#/ landscape.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 \ - -o $BIN $SRC && \ - ./$BIN $@ && rm $BIN -exit $? # */ -#endif - -#include "../graphics.c" - -#define EPS 1e-8 - -enum { - MAX_NUM_TILES = 10 * 1024 * 1024, -}; - -typedef struct { - i32 index; - i32 version; -} Handle; - -typedef union { - struct { f64 x, y; }; - struct { f64 v[2]; }; -} Vec2; - -typedef union { - struct { f64 x, y, z; }; - struct { f64 r, g, b; }; - struct { f64 v[3]; }; -} Vec3; - -typedef union { - struct { f64 x, y, z, w; }; - struct { f64 r, g, b, a; }; - struct { f64 v[4]; }; -} Vec4; - -typedef struct { - b8 visible; - f64 x; - f64 y; - f64 size; -} Screen_Area; - -typedef struct { - u32 background; - i64 system_time; - i64 time; - i32 map_num_x; - i32 map_num_y; - f64 map[MAX_NUM_TILES]; - f64 screen_distance; - f64 zoom; - f64 tilt; - Vec3 eye_position; - Vec3 right; - Vec3 up; - Vec3 forward; - Vec3 screen_x_axis; - Vec3 screen_y_axis; - Vec3 screen_z_axis; -} World; - -#define CHECK(fail_return, condition) \ - assert(condition); \ - if (!(condition)) \ - return fail_return; - -World world = {0}; - -f64 dot(Vec3 a, Vec3 b) { - return a.x * b.x + a.y * b.y + a.z * b.z; -} - -Vec3 cross(Vec3 a, Vec3 b) { - return (Vec3) { - .x = a.y * b.z - a.z * b.y, - .y = a.z * b.x - a.x * b.z, - .z = a.x * b.y - a.y * b.x, - }; -} - -Vec3 neg(Vec3 a) { - return (Vec3) { - .x = -a.x, - .y = -a.y, - .z = -a.z, - }; -} - -Vec3 add(Vec3 a, Vec3 b) { - return (Vec3) { - .x = a.x + b.x, - .y = a.y + b.y, - .z = a.z + b.z, - }; -} - -Vec3 sub(Vec3 a, Vec3 b) { - return (Vec3) { - .x = a.x - b.x, - .y = a.y - b.y, - .z = a.z - b.z, - }; -} - -Vec3 mul(Vec3 a, f64 b) { - return (Vec3) { - .x = a.x * b, - .y = a.y * b, - .z = a.z * b, - }; -} - -Vec3 v_div(Vec3 a, f64 b) { - if (b > -EPS && b < EPS) { - assert(0); - return (Vec3) { - .x = 0., - .y = 0., - .z = 1., - }; - } - return (Vec3) { - .x = a.x / b, - .y = a.y / b, - .z = a.z / b, - }; -} - -Vec3 normal(Vec3 a) { - return v_div(a, sqrt(dot(a, a))); -} - -void resolve_axes(void) { - world.right = (Vec3) { .x = 1., .y = 0., .z = 0., }; - world.forward = (Vec3) { .x = 0., .y = 1., .z = 0., }; - world.up = (Vec3) { .x = 0., .y = 0., .z = 1., }; - - if (world.tilt < 0.0) - world.tilt += M_PI * 2.0 * floor(-world.tilt / (M_PI * 2.0) + 1.0); - if (world.tilt >= M_PI * 2.0) - world.tilt -= M_PI * 2.0 * floor(world.tilt / (M_PI * 2.0)); - - world.screen_z_axis = (Vec3) { - .x = 0., - .y = sin(world.tilt), - .z = -cos(world.tilt), - }; - - world.screen_y_axis = normal(cross(world.screen_z_axis, world.right)); - world.screen_x_axis = normal(cross(world.screen_y_axis, world.screen_z_axis)); -} - -Screen_Area world_to_screen(Vec3 p, f64 size) { - Vec3 r = sub(p, world.eye_position); - f64 l = dot(r, world.screen_z_axis); - - if (l < EPS) - return (Screen_Area) { .visible = 0, }; - - f64 k = (world.screen_distance / l) * world.zoom; - - f64 x = k * dot(r, world.screen_x_axis); - f64 y = k * dot(r, world.screen_y_axis); - - f64 hw = platform.frame_width * .5; - f64 hh = platform.frame_height * .5; - - return (Screen_Area) { - .visible = 1, - .x = hw + x, - .y = hh + y, - .size = k * size, - }; -} - -Vec3 screen_to_world(i32 x, i32 y) { - f64 fx = ((f64) x - platform.frame_width * .5) / world.zoom; - f64 fy = ((f64) y - platform.frame_height * .5) / world.zoom; - - Vec3 r = add(add( - mul(world.screen_x_axis, fx), - mul(world.screen_y_axis, fy)), - mul(world.screen_z_axis, world.screen_distance) - ); - - if (r.z < -EPS || r.z > EPS) - r = mul(r, -world.eye_position.z / r.z); - - return add(world.eye_position, r); -} - -void update_and_render_frame(void) { - p_handle_events(); - - i64 time_elapsed = p_time() - world.system_time; - world.system_time += time_elapsed; - - resolve_axes(); - - if (time_elapsed > 0) { - if (platform.key_down['w']) - world.tilt += .001 * time_elapsed; - if (platform.key_down['s']) - world.tilt -= .001 * time_elapsed; - - f64 k = world.eye_position.z; - if (world.zoom > EPS) - k /= world.zoom; - - if (platform.wheel_dy != 0) - world.eye_position.z -= (f64) platform.wheel_dy; - - if (platform.key_down[BUTTON_RIGHT]) { - world.eye_position.x -= platform.cursor_dx * k; - world.eye_position.y += platform.cursor_dy * k; - } - - 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] = world.background; - - p_render_frame(); -} - -i32 main(i32 argc, c8 **argv) { - (void) argc; - (void) argv; - - platform = (Platform) { - .title = "Landscape", - .frame_width = 960, - .frame_height = 720, - }; - - world.background = u32_from_rgb(.03f, .08f, .01f); - world.system_time = p_time(); - world.screen_distance = 1.; - world.zoom = 1e+3; - world.eye_position = (Vec3) { .z = 10., }; - - p_event_loop(); - - return 0; -} @@ -72,15 +72,25 @@ p_wait_events_impl : () => { wait_for_events = true; }, p_sleep_for : (time) => { sleep_duration += time; }, p_time : Date.now, - sqrt : Math.sqrt, - floor : Math.floor, - ceil : Math.ceil, - memset : (dst, val, num) => { - program.instance.exports.js_memset(dst, val, num); - }, - memcpy : (dst, src, num) => { - program.instance.exports.js_memcpy(dst, src, num); - }, + + floor : Math.floor, + ceil : Math.ceil, + sqrt : Math.sqrt, + pow : Math.pow, + log : Math.log, + log2 : Math.log2, + log10 : Math.log10, + exp : Math.exp, + sin : Math.sin, + cos : Math.cos, + tan : Math.tan, + asin : Math.asin, + acos : Math.acos, + atan : Math.atan, + atan2 : Math.atan2, + + memset : (dst, val, num) => { program.instance.exports.js_memset(dst, val, num); }, + memcpy : (dst, src, num) => { program.instance.exports.js_memcpy(dst, src, num); }, }, } ); @@ -129,7 +139,102 @@ let key_from_code = (code) => { switch (code) { - case "KeyA": return 97; + case "Backspace": return 8; + case "Tab": return 9; + case "Enter": return 10; + case "ControlLeft": return 11; + case "ControlRight": return 12; + case "ShiftLeft": return 13; + case "ShiftRight": return 14; + case "AltLeft": return 15; + case "AltRight": return 16; + case "ArrowLeft": return 17; + case "ArrowRight": return 18; + case "ArrowUp": return 19; + case "ArrowDown": return 20; + case "Pause": return 21; + case "Insert": return 22; + case "Home": return 23; + case "End": return 24; + case "PageUp": return 25; + case "PageDown": return 26; + case "Escape": return 27; + case "PrintScreen": return 28; + case "Space": return 32; + case "MetaLeft": return 33; + case "MetaRight": return 34; + case "Quote": return 39; + case "Comma": return 44; + case "Minus": return 45; + case "Period": return 46; + case "Slash": return 47; + case "Digit0": return 48; + case "Digit1": return 49; + case "Digit2": return 50; + case "Digit3": return 51; + case "Digit4": return 52; + case "Digit5": return 53; + case "Digit6": return 54; + case "Digit7": return 55; + case "Digit8": return 56; + case "Digit9": return 57; + case "Semicolon": return 59; + case "Equal": return 61; + case "BracketLeft": return 91; + case "Backslash": return 92; + case "BracketRight": return 93; + case "Backquote": return 96; + case "KeyA": return 97; + case "KeyB": return 98; + case "KeyC": return 99; + case "KeyD": return 100; + case "KeyE": return 101; + case "KeyF": return 102; + case "KeyG": return 103; + case "KeyH": return 104; + case "KeyI": return 105; + case "KeyJ": return 106; + case "KeyK": return 107; + case "KeyL": return 108; + case "KeyM": return 109; + case "KeyN": return 110; + case "KeyO": return 111; + case "KeyP": return 112; + case "KeyQ": return 113; + case "KeyR": return 114; + case "KeyS": return 115; + case "KeyT": return 116; + case "KeyU": return 117; + case "KeyV": return 118; + case "KeyW": return 119; + case "KeyX": return 120; + case "KeyY": return 121; + case "KeyZ": return 122; + case "Delete": return 127; + case "F1": return 145; + case "F2": return 146; + case "F3": return 147; + case "F4": return 148; + case "F5": return 149; + case "F6": return 150; + case "F7": return 151; + case "F8": return 152; + case "F9": return 153; + case "F10": return 154; + case "F11": return 155; + case "F12": return 156; + case "F13": return 157; + case "F14": return 158; + case "F15": return 159; + case "F16": return 160; + case "F17": return 161; + case "F18": return 162; + case "F19": return 163; + case "F20": return 164; + case "F21": return 165; + case "F22": return 166; + case "F23": return 167; + case "F24": return 168; } return 0; }; diff --git a/reduced_system_layer.c b/reduced_system_layer.c index 9c1e67e..7b18780 100755 --- a/reduced_system_layer.c +++ b/reduced_system_layer.c @@ -33,17 +33,37 @@ #/ - Conway's Game of Life #/ - Julia Set #/ - Labyrinth -#/ - Landscape -#/ - Features -#/ - Sound -#/ - Clipboard daemon +#/ - Chat +#/ - Graphics +#/ - Vector math +#/ - UI +#/ - Wayland +#/ - Windows graphics +#/ - Sound +#/ - ALSA -- https://www.alsa-project.org/alsa-doc/alsa-lib/_2test_2pcm_min_8c-example.html +#/ - Windows audio +#/ - WebAssembly audio +#/ - Networking +#/ - Windows sockets +#/ - Web Sockets #/ -#/ ALSA -#/ https://www.alsa-project.org/alsa-doc/alsa-lib/_2test_2pcm_min_8c-example.html +#/ Done +#/ +#/ - Examples +#/ - Echo +#/ - UI +#/ - Particles +#/ - Graph +#/ - Graphics +#/ - Font +#/ - X11 +#/ - WebAssembly +#/ - Networking +#/ - Unix UDP sockets #/ #/ ---------------------------------------------------------------- #/ -#/ (C) 2024 Mitya Selivanov <guattari.tech>, MIT License +#/ (C) 2024 Mitya Selivanov <guattari.tech> #/ #/ ================================================================ #/ @@ -344,9 +364,21 @@ extern Platform platform; #ifdef __wasm__ i32 main(i32 argc, c8 **argv); -f64 sqrt(f64 x); f64 floor(f64 x); f64 ceil(f64 x); +f64 sqrt(f64 x); +f64 pow(f64 x, f64 y); +f64 log(f64 x); +f64 log2(f64 x); +f64 log10(f64 x); +f64 exp(f64 x); +f64 sin(f64 x); +f64 cos(f64 x); +f64 tan(f64 x); +f64 asin(f64 x); +f64 acos(f64 x); +f64 atan(f64 x); +f64 atan2(f64 y, f64 x); #ifndef NULL #define NULL ((void *) 0) @@ -546,7 +578,6 @@ void p_sleep_for(i64 duration) { #include <stdio.h> #include <string.h> -#include <assert.h> #include <errno.h> #include <signal.h> #include <netinet/in.h> @@ -655,8 +686,15 @@ b8 sockets_open(u16 slot, IP_Address address, u16 *local_port) { } i64 p_recv(u16 slot, IP_Address address, i64 size, u8 *data, u16 *local_port, IP_Address *remote_address) { - assert(slot < MAX_NUM_SOCKETS); - assert(address.protocol == IPv4_UDP || address.protocol == IPv6_UDP); + if (slot >= MAX_NUM_SOCKETS) { + fprintf(stderr, "%s:%d, %s: Invalid slot %d.\n", __FILE__, __LINE__, __FUNCTION__, (i32) (u32) slot); + return 0; + } + + if (address.protocol != IPv4_UDP && address.protocol != IPv6_UDP) { + fprintf(stderr, "%s:%d, %s: Invalid address protocol %d.\n", __FILE__, __LINE__, __FUNCTION__, (i32) (u32) address.protocol); + return 0; + } if (!sockets_open(slot, address, local_port)) return 0; @@ -690,7 +728,7 @@ i64 p_recv(u16 slot, IP_Address address, i64 size, u8 *data, u16 *local_port, IP if (errno == EAGAIN || errno == EWOULDBLOCK) return 0; - fprintf(stderr, "ERROR: recvfrom failed (errno %d)\n", errno); + fprintf(stderr, "%s:%d, %s: recvfrom failed (errno %d).\n", __FILE__, __LINE__, __FUNCTION__, errno); return 0; } @@ -711,8 +749,15 @@ i64 p_recv(u16 slot, IP_Address address, i64 size, u8 *data, u16 *local_port, IP } i64 p_send(u16 slot, IP_Address address, i64 size, u8 *data, u16 *local_port) { - assert(slot < MAX_NUM_SOCKETS); - assert(address.protocol == IPv4_UDP || address.protocol == IPv6_UDP); + if (slot >= MAX_NUM_SOCKETS) { + fprintf(stderr, "%s:%d, %s: Invalid slot %d.\n", __FILE__, __LINE__, __FUNCTION__, (i32) (u32) slot); + return 0; + } + + if (address.protocol != IPv4_UDP && address.protocol != IPv6_UDP) { + fprintf(stderr, "%s:%d, %s: Invalid address protocol %d.\n", __FILE__, __LINE__, __FUNCTION__, (i32) (u32) address.protocol); + return 0; + } IP_Address local_address = address; local_address.port = 0; @@ -757,7 +802,7 @@ i64 p_send(u16 slot, IP_Address address, i64 size, u8 *data, u16 *local_port) { if (errno == EAGAIN || errno == EWOULDBLOCK) return 0; - fprintf(stderr, "ERROR: sendto failed (errno %d)\n", errno); + fprintf(stderr, "%s:%d, %s: sendto failed (errno %d).\n", __FILE__, __LINE__, __FUNCTION__, errno); return 0; } @@ -797,7 +842,11 @@ static Atom _target = None; void p_init(void) { _display = XOpenDisplay(NULL); - assert(_display != NULL); + + if (_display == NULL) { + fprintf(stderr, "%s:%d, %s: XOpenDisplay failed.\n", __FILE__, __LINE__, __FUNCTION__); + return; + } _key_table[XKeysymToKeycode(_display, XK_Left)] = KEY_LEFT; _key_table[XKeysymToKeycode(_display, XK_Right)] = KEY_RIGHT; @@ -906,7 +955,11 @@ void p_init(void) { Visual *visual = DefaultVisual(_display, screen); _gc = DefaultGC(_display, screen); - assert(_gc != NULL); + + if (_gc == NULL) { + fprintf(stderr, "%s:%d, %s: DefaultGC failed.\n", __FILE__, __LINE__, __FUNCTION__); + return; + } XSetGraphicsExposures(_display, _gc, False); @@ -924,10 +977,18 @@ void p_init(void) { _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, }); _im = XOpenIM(_display, NULL, NULL, NULL); - assert(_im != NULL); + + if (_im == NULL) { + fprintf(stderr, "%s:%d, %s: XOpenIM failed.\n", __FILE__, __LINE__, __FUNCTION__); + return; + } _ic = XCreateIC(_im, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, XNClientWindow, _window, NULL); - assert(_ic != NULL); + + if (_ic == NULL) { + fprintf(stderr, "%s:%d, %s: XCreateIC failed.\n", __FILE__, __LINE__, __FUNCTION__); + return; + } platform.pixels = _buffer; platform.input = _input; @@ -986,6 +1047,9 @@ void p_cleanup(void) { } i32 p_handle_events(void) { + if (_display == NULL) + return 0; + i32 num_events = 0; memset(platform.key_pressed, 0, sizeof platform.key_pressed); @@ -1264,7 +1328,7 @@ i32 p_wait_events(void) { do { num_events = p_handle_events(); - sched_yield(); + usleep(0); } while (num_events == 0); return num_events; @@ -1279,7 +1343,10 @@ void p_render_frame(void) { } void p_clipboard_write(i64 size, c8 *data) { - assert(size <= MAX_CLIPBOARD_SIZE); + if (size > MAX_CLIPBOARD_SIZE) { + fprintf(stderr, "%s:%d, %s: Size is too big %lld.\n", __FILE__, __LINE__, __FUNCTION__, size); + return; + } XSetSelectionOwner(_display, _clipboard, _window, CurrentTime); @@ -1300,14 +1367,14 @@ void p_clipboard_write(i64 size, c8 *data) { void p_handle_audio(i64 time_elapsed) { (void) time_elapsed; - assert(0); + // TODO } void p_queue_sound(i64 delay, i64 num_samples, f32 *samples) { (void) delay; (void) num_samples; (void) samples; - assert(0); + // TODO } #endif // defined(__linux__) |