summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitya Selivanov <automainint@guattari.tech>2025-01-18 01:54:57 +0100
committerMitya Selivanov <automainint@guattari.tech>2025-01-18 01:54:57 +0100
commit43585fc93cd5e682777829f088d825ee13404d60 (patch)
tree000ea20582f8b376d17753b08add227468ea42f2
parentbd77df921a9591802adfd7f17a2f9c878efda7ac (diff)
downloadreduced_system_layer-43585fc93cd5e682777829f088d825ee13404d60.zip
Impl drag and drop in WebHEADdev
-rw-r--r--index.htm159
-rw-r--r--reduced_system_layer.c363
2 files changed, 345 insertions, 177 deletions
diff --git a/index.htm b/index.htm
index 18c110f..1207f79 100644
--- a/index.htm
+++ b/index.htm
@@ -76,7 +76,14 @@
this.sound_buffer_address = program.exports.js_sound_buffer();
this.pixels_address = program.exports.js_pixels();
- this.frames = new Float32Array(this.memory_buffer, this.sound_buffer_address, program.exports.js_max_num_sound_frames());
+ this.max_drop_size = program.exports.js_max_drop_size();
+ this.drop_address = program.exports.js_drop_buffer();
+
+ this.frames = new Float32Array(
+ this.memory_buffer,
+ this.sound_buffer_address,
+ program.exports.js_max_num_sound_frames()
+ );
let title_address = program.exports.js_title();
@@ -160,6 +167,50 @@
this.program.exports.js_keydown(ev.key, ev.mod, ev.ch);
},
+
+ dragenter : (ev) => {
+ if (this.program === undefined)
+ return;
+
+ this.program.exports.js_dragenter();
+ },
+
+ dragleave : (ev) => {
+ if (this.program === undefined)
+ return;
+
+ this.program.exports.js_dragenter();
+ },
+
+ drop : (ev) => {
+ if (this.program === undefined)
+ return;
+
+ for (let f of ev.files) {
+ if (f.name.byteLength + f.data.byteLength > this.max_drop_size) {
+ console.error("File too big");
+ continue;
+ }
+
+ new Uint8Array(
+ this.memory_buffer,
+ this.drop_address,
+ f.name.byteLength
+ ).set(
+ new Uint8Array(f.name)
+ );
+
+ new Uint8Array(
+ this.memory_buffer,
+ this.drop_address + f.name.byteLength,
+ f.data.byteLength
+ ).set(
+ new Uint8Array(f.data)
+ );
+
+ this.program.exports.js_drop(f.name.byteLength, f.data.byteLength);
+ }
+ },
};
this.port.onmessage = (ev) => {
@@ -223,35 +274,26 @@
let program = await WebAssembly.instantiate(
wasm,
{
- wasi_snapshot_preview1 : {
- clock_time_get : () => {},
- args_sizes_get : () => {},
- args_get : () => {},
- proc_exit : () => {},
- fd_close : () => {},
- fd_write : () => {},
- fd_seek : () => {},
- },
env : {
p_clipboard_write_impl : () => {},
p_time_impl : () => {},
-
- floor : () => {},
- ceil : () => {},
- sqrt : () => {},
- cbrt : () => {},
- pow : () => {},
- log : () => {},
- log2 : () => {},
- log10 : () => {},
- exp : () => {},
- sin : () => {},
- cos : () => {},
- tan : () => {},
- asin : () => {},
- acos : () => {},
- atan : () => {},
- atan2 : () => {},
+ floor : () => {},
+ ceil : () => {},
+ trunc : () => {},
+ sqrt : () => {},
+ cbrt : () => {},
+ pow : () => {},
+ log : () => {},
+ log2 : () => {},
+ log10 : () => {},
+ exp : () => {},
+ sin : () => {},
+ cos : () => {},
+ tan : () => {},
+ asin : () => {},
+ acos : () => {},
+ atan : () => {},
+ atan2 : () => {},
},
}
);
@@ -568,7 +610,6 @@
});
window.addEventListener("wheel", (ev) => {
- ev.preventDefault();
if (!sound_ready)
return;
@@ -592,6 +633,68 @@
ch : paste_ch,
});
});
+
+ canvas.addEventListener("dragover", (ev) => {
+ ev.preventDefault();
+ if (!sound_ready) {
+ ev.dataTransfer.dropEffect = "none";
+ return;
+ }
+
+ if (ev.clientX != undefined && ev.clientY != undefined)
+ sound_node.port.postMessage({
+ id : "mousemove",
+ x : ev.clientX,
+ y : ev.clientY,
+ });
+ });
+
+ canvas.addEventListener("dragenter", (ev) => {
+ ev.preventDefault();
+ if (!sound_ready)
+ return;
+
+ sound_node.port.postMessage({
+ id : "dragenter",
+ });
+ });
+
+ canvas.addEventListener("dragleave", (ev) => {
+ ev.preventDefault();
+ if (!sound_ready)
+ return;
+
+ sound_node.port.postMessage({
+ id : "dragleave",
+ });
+ });
+
+ canvas.addEventListener("drop", (ev) => {
+ ev.preventDefault();
+ if (!sound_ready)
+ return;
+
+ (async () => {
+ let files = [];
+
+ for (let f of ev.dataTransfer.files) {
+ // Copy the buffer in case the underlaying buffer's size is larger.
+ let bytes = await f.bytes();
+ let buffer = new ArrayBuffer(bytes.length);
+ new Uint8Array(buffer).set(bytes);
+
+ files.push({
+ name : new TextEncoder("utf8").encode(f.name),
+ data : buffer,
+ });
+ }
+
+ sound_node.port.postMessage({
+ id : "drop",
+ files : files,
+ });
+ })();
+ });
}
run({
diff --git a/reduced_system_layer.c b/reduced_system_layer.c
index 6032ee3..a1bac25 100644
--- a/reduced_system_layer.c
+++ b/reduced_system_layer.c
@@ -176,6 +176,7 @@ i32 main(i32 argc, c8 **argv);
#endif
#ifndef MAX_INPUT_SIZE
+// How many input events can be buffered during one frame.
#define MAX_INPUT_SIZE 256
#endif
@@ -203,22 +204,29 @@ i32 main(i32 argc, c8 **argv);
#define MAX_PIXEL_SIZE (16.0)
#endif
-#ifndef PIXEL_SIZE_DELTA
-#define PIXEL_SIZE_DELTA (0.1)
+#ifndef DEFAULT_PIXEL_SIZE
+#define DEFAULT_PIXEL_SIZE (8.0)
#endif
-#ifndef DEFAULT_PIXEL_SIZE
-#define DEFAULT_PIXEL_SIZE (3.0)
+#ifndef PIXEL_SIZE_DELTA
+#define PIXEL_SIZE_DELTA (0.05)
#endif
#ifndef MIN_FRAME_DURATION
+// The pixel size will decrease when the frame duration is lower.
#define MIN_FRAME_DURATION 17
#endif
#ifndef MAX_FRAME_DURATION
+// The pixel size will increaseo when the frame duration is higher.
#define MAX_FRAME_DURATION 34
#endif
+#ifndef FRAME_DURATION_HARD_LIMIT
+// The pixel size value will reset if the frame duration is higher.
+#define FRAME_DURATION_HARD_LIMIT 500
+#endif
+
#ifndef NUM_FRAMES_AVERAGED
#define NUM_FRAMES_AVERAGED 400
#endif
@@ -924,7 +932,7 @@ static void drop_files_set_data_(i64 index, i64 data_size) {
g_platform.drop_files[index].data = _drop_files_buffer + offset;
}
-i8 pixel_size_update_(i32 real_width, i32 real_height) {
+static i8 pixel_size_update_(i32 real_width, i32 real_height) {
i8 size_changed = 0;
i32 width = real_width;
@@ -954,13 +962,15 @@ i8 pixel_size_update_(i32 real_width, i32 real_height) {
return size_changed;
}
-void pixel_size_calubrate_(i64 current_frame_duration) {
+static void pixel_size_calubrate_(i64 current_frame_duration) {
if (g_platform.exact_resolution)
return;
i64 frame_duration = average_frame_duration_(current_frame_duration);
- if (g_platform.pixel_size < MAX_PIXEL_SIZE && frame_duration > MAX_FRAME_DURATION)
+ if (current_frame_duration > FRAME_DURATION_HARD_LIMIT)
+ g_platform.pixel_size = MAX_PIXEL_SIZE;
+ else if (g_platform.pixel_size < MAX_PIXEL_SIZE && frame_duration > MAX_FRAME_DURATION)
g_platform.pixel_size += PIXEL_SIZE_DELTA * (frame_duration - MAX_FRAME_DURATION);
else if (g_platform.pixel_size > MIN_PIXEL_SIZE && frame_duration < MIN_FRAME_DURATION)
g_platform.pixel_size -= PIXEL_SIZE_DELTA * (MIN_FRAME_DURATION - frame_duration);
@@ -2223,7 +2233,134 @@ void p_clipboard_write(i64 size, c8 *data) {
// ================================================================
//
-// WebAssembly
+// Web startup options
+//
+// ================================================================
+
+#if defined(__wasm__)
+
+static u16 _key_map[MAX_NUM_KEYS] = {0};
+
+__attribute__((export_name("js_max_num_keys"))) i32 js_max_num_keys(void) {
+ return MAX_NUM_KEYS;
+}
+
+__attribute__((export_name("js_key_map"))) void *js_key_map(void) {
+ i32 n = 0;
+
+ _key_map[n++] = KEY_BACKSPACE;
+ _key_map[n++] = KEY_TAB;
+ _key_map[n++] = KEY_ENTER;
+ _key_map[n++] = KEY_LCTRL;
+ _key_map[n++] = KEY_RCTRL;
+ _key_map[n++] = KEY_LSHIFT;
+ _key_map[n++] = KEY_RSHIFT;
+ _key_map[n++] = KEY_LALT;
+ _key_map[n++] = KEY_RALT;
+ _key_map[n++] = KEY_LEFT;
+ _key_map[n++] = KEY_RIGHT;
+ _key_map[n++] = KEY_UP;
+ _key_map[n++] = KEY_DOWN;
+ _key_map[n++] = KEY_PAUSE;
+ _key_map[n++] = KEY_INSERT;
+ _key_map[n++] = KEY_HOME;
+ _key_map[n++] = KEY_END;
+ _key_map[n++] = KEY_PAGEUP;
+ _key_map[n++] = KEY_PAGEDOWN;
+ _key_map[n++] = KEY_ESCAPE;
+ _key_map[n++] = KEY_PRINTSCREEN;
+ _key_map[n++] = KEY_SPACE;
+ _key_map[n++] = KEY_LMETA;
+ _key_map[n++] = KEY_RMETA;
+ _key_map[n++] = KEY_QUOTE;
+ _key_map[n++] = KEY_COMMA;
+ _key_map[n++] = KEY_MINUS;
+ _key_map[n++] = KEY_PERIOD;
+ _key_map[n++] = KEY_SLASH;
+ _key_map[n++] = KEY_0;
+ _key_map[n++] = KEY_1;
+ _key_map[n++] = KEY_2;
+ _key_map[n++] = KEY_3;
+ _key_map[n++] = KEY_4;
+ _key_map[n++] = KEY_5;
+ _key_map[n++] = KEY_6;
+ _key_map[n++] = KEY_7;
+ _key_map[n++] = KEY_8;
+ _key_map[n++] = KEY_9;
+ _key_map[n++] = KEY_COLON;
+ _key_map[n++] = KEY_EQUAL;
+ _key_map[n++] = KEY_LBRACE;
+ _key_map[n++] = KEY_BACKSLASH;
+ _key_map[n++] = KEY_RBRACE;
+ _key_map[n++] = KEY_TILDE;
+ _key_map[n++] = KEY_A;
+ _key_map[n++] = KEY_B;
+ _key_map[n++] = KEY_C;
+ _key_map[n++] = KEY_D;
+ _key_map[n++] = KEY_E;
+ _key_map[n++] = KEY_F;
+ _key_map[n++] = KEY_G;
+ _key_map[n++] = KEY_H;
+ _key_map[n++] = KEY_I;
+ _key_map[n++] = KEY_J;
+ _key_map[n++] = KEY_K;
+ _key_map[n++] = KEY_L;
+ _key_map[n++] = KEY_M;
+ _key_map[n++] = KEY_N;
+ _key_map[n++] = KEY_O;
+ _key_map[n++] = KEY_P;
+ _key_map[n++] = KEY_Q;
+ _key_map[n++] = KEY_R;
+ _key_map[n++] = KEY_S;
+ _key_map[n++] = KEY_T;
+ _key_map[n++] = KEY_U;
+ _key_map[n++] = KEY_V;
+ _key_map[n++] = KEY_W;
+ _key_map[n++] = KEY_X;
+ _key_map[n++] = KEY_Y;
+ _key_map[n++] = KEY_Z;
+ _key_map[n++] = KEY_DELETE;
+ _key_map[n++] = KEY_F1;
+ _key_map[n++] = KEY_F2;
+ _key_map[n++] = KEY_F3;
+ _key_map[n++] = KEY_F4;
+ _key_map[n++] = KEY_F5;
+ _key_map[n++] = KEY_F6;
+ _key_map[n++] = KEY_F7;
+ _key_map[n++] = KEY_F8;
+ _key_map[n++] = KEY_F9;
+ _key_map[n++] = KEY_F10;
+ _key_map[n++] = KEY_F11;
+ _key_map[n++] = KEY_F12;
+ _key_map[n++] = KEY_F13;
+ _key_map[n++] = KEY_F14;
+ _key_map[n++] = KEY_F15;
+ _key_map[n++] = KEY_F16;
+ _key_map[n++] = KEY_F17;
+ _key_map[n++] = KEY_F18;
+ _key_map[n++] = KEY_F19;
+ _key_map[n++] = KEY_F20;
+ _key_map[n++] = KEY_F21;
+ _key_map[n++] = KEY_F22;
+ _key_map[n++] = KEY_F23;
+ _key_map[n++] = KEY_F24;
+
+ return _key_map;
+}
+
+__attribute__((export_name("js_sound_sample_rate"))) f64 js_sound_sample_rate(void) {
+ return (f64) SOUND_SAMPLE_RATE;
+}
+
+__attribute__((export_name("js_num_sound_channels"))) i32 js_num_sound_channels(void) {
+ return NUM_SOUND_CHANNELS;
+}
+
+#endif // defined(__wasm__)
+
+// ================================================================
+//
+// Web
//
// ================================================================
@@ -2240,21 +2377,23 @@ static f64 _wheel_dy = 0;
static b8 _wait_events = 0;
static i64 _timeout = 0;
static i64 _sound_read = 0;
+static b8 _files_dragged = 0;
+static b8 _files_dropped = 0;
-static u16 _key_map [MAX_NUM_KEYS] = {0};
-static c8 _href [4096] = {0};
-static u32 _pixels_scaled [MAX_NUM_PIXELS] = {0};
-static u32 _pixels_internal [MAX_NUM_PIXELS] = {0};
-static b8 _key_pressed [MAX_NUM_KEYS] = {0};
-static f32 _sound_buffer [MAX_NUM_SOUND_FRAMES] = {0};
+static c8 _href [4096] = {0};
+static u32 _pixels_scaled [MAX_NUM_PIXELS] = {0};
+static u32 _pixels_internal [MAX_NUM_PIXELS] = {0};
+static b8 _key_pressed [MAX_NUM_KEYS] = {0};
+static f32 _sound_buffer [MAX_NUM_SOUND_FRAMES] = {0};
+static u8 _drop_buffer [DROP_FILES_BUFFER_SIZE] = {0};
i64 p_recv(u16 slot, IP_Address address, i64 size, u8 *data, u16 *local_port, IP_Address *remote_address) {
- // Not implemented
+ LOG_ERROR("Web sockets are not implemented.");
return 0;
}
i64 p_send(u16 slot, IP_Address address, i64 size, u8 *data, u16 *local_port) {
- // Not implemented
+ LOG_ERROR("Web sockets are not implemented.");
return 0;
}
@@ -2288,17 +2427,27 @@ void p_init(void) {
}
i32 p_handle_events(void) {
- g_platform.input_size = _input_size;
- g_platform.cursor_dx = _cursor_dx;
- g_platform.cursor_dy = _cursor_dy;
- g_platform.wheel_dx = _wheel_dx;
- g_platform.wheel_dy = _wheel_dy;
-
- _input_size = 0;
- _cursor_dx = 0;
- _cursor_dy = 0;
- _wheel_dx = 0;
- _wheel_dy = 0;
+ if (g_platform.files_dropped)
+ drop_files_clean_();
+
+ g_platform.input_size = _input_size;
+ g_platform.cursor_dx = _cursor_dx;
+ g_platform.cursor_dy = _cursor_dy;
+ g_platform.wheel_dx = _wheel_dx;
+ g_platform.wheel_dy = _wheel_dy;
+ g_platform.files_dragged = _files_dragged;
+ g_platform.files_dropped = _files_dropped;
+
+ _input_size = 0;
+ _cursor_dx = 0;
+ _cursor_dy = 0;
+ _wheel_dx = 0;
+ _wheel_dy = 0;
+
+ if (_files_dropped) {
+ _files_dragged = 0;
+ _files_dropped = 0;
+ }
for (i64 i = 0; i < MAX_NUM_KEYS; ++i)
g_platform.key_pressed[i] = _key_pressed[i];
@@ -2370,8 +2519,10 @@ void p_queue_sound(i64 delay_in_samples, i64 num_samples, f32 *frames) {
return;
i64 num_frames = num_samples * NUM_SOUND_CHANNELS;
- if (num_frames > MAX_NUM_SOUND_FRAMES)
+ if (num_frames > MAX_NUM_SOUND_FRAMES) {
+ LOG_ERROR("Sound buffer overflow.");
return;
+ }
i64 begin = (_sound_position + delay_in_samples * NUM_SOUND_CHANNELS) % MAX_NUM_SOUND_FRAMES;
@@ -2389,121 +2540,6 @@ void p_queue_sound(i64 delay_in_samples, i64 num_samples, f32 *frames) {
}
}
-__attribute__((export_name("js_max_num_keys"))) i32 js_max_num_keys(void) {
- return MAX_NUM_KEYS;
-}
-
-__attribute__((export_name("js_key_map"))) void *js_key_map(void) {
- i32 n = 0;
-
- _key_map[n++] = KEY_BACKSPACE;
- _key_map[n++] = KEY_TAB;
- _key_map[n++] = KEY_ENTER;
- _key_map[n++] = KEY_LCTRL;
- _key_map[n++] = KEY_RCTRL;
- _key_map[n++] = KEY_LSHIFT;
- _key_map[n++] = KEY_RSHIFT;
- _key_map[n++] = KEY_LALT;
- _key_map[n++] = KEY_RALT;
- _key_map[n++] = KEY_LEFT;
- _key_map[n++] = KEY_RIGHT;
- _key_map[n++] = KEY_UP;
- _key_map[n++] = KEY_DOWN;
- _key_map[n++] = KEY_PAUSE;
- _key_map[n++] = KEY_INSERT;
- _key_map[n++] = KEY_HOME;
- _key_map[n++] = KEY_END;
- _key_map[n++] = KEY_PAGEUP;
- _key_map[n++] = KEY_PAGEDOWN;
- _key_map[n++] = KEY_ESCAPE;
- _key_map[n++] = KEY_PRINTSCREEN;
- _key_map[n++] = KEY_SPACE;
- _key_map[n++] = KEY_LMETA;
- _key_map[n++] = KEY_RMETA;
- _key_map[n++] = KEY_QUOTE;
- _key_map[n++] = KEY_COMMA;
- _key_map[n++] = KEY_MINUS;
- _key_map[n++] = KEY_PERIOD;
- _key_map[n++] = KEY_SLASH;
- _key_map[n++] = KEY_0;
- _key_map[n++] = KEY_1;
- _key_map[n++] = KEY_2;
- _key_map[n++] = KEY_3;
- _key_map[n++] = KEY_4;
- _key_map[n++] = KEY_5;
- _key_map[n++] = KEY_6;
- _key_map[n++] = KEY_7;
- _key_map[n++] = KEY_8;
- _key_map[n++] = KEY_9;
- _key_map[n++] = KEY_COLON;
- _key_map[n++] = KEY_EQUAL;
- _key_map[n++] = KEY_LBRACE;
- _key_map[n++] = KEY_BACKSLASH;
- _key_map[n++] = KEY_RBRACE;
- _key_map[n++] = KEY_TILDE;
- _key_map[n++] = KEY_A;
- _key_map[n++] = KEY_B;
- _key_map[n++] = KEY_C;
- _key_map[n++] = KEY_D;
- _key_map[n++] = KEY_E;
- _key_map[n++] = KEY_F;
- _key_map[n++] = KEY_G;
- _key_map[n++] = KEY_H;
- _key_map[n++] = KEY_I;
- _key_map[n++] = KEY_J;
- _key_map[n++] = KEY_K;
- _key_map[n++] = KEY_L;
- _key_map[n++] = KEY_M;
- _key_map[n++] = KEY_N;
- _key_map[n++] = KEY_O;
- _key_map[n++] = KEY_P;
- _key_map[n++] = KEY_Q;
- _key_map[n++] = KEY_R;
- _key_map[n++] = KEY_S;
- _key_map[n++] = KEY_T;
- _key_map[n++] = KEY_U;
- _key_map[n++] = KEY_V;
- _key_map[n++] = KEY_W;
- _key_map[n++] = KEY_X;
- _key_map[n++] = KEY_Y;
- _key_map[n++] = KEY_Z;
- _key_map[n++] = KEY_DELETE;
- _key_map[n++] = KEY_F1;
- _key_map[n++] = KEY_F2;
- _key_map[n++] = KEY_F3;
- _key_map[n++] = KEY_F4;
- _key_map[n++] = KEY_F5;
- _key_map[n++] = KEY_F6;
- _key_map[n++] = KEY_F7;
- _key_map[n++] = KEY_F8;
- _key_map[n++] = KEY_F9;
- _key_map[n++] = KEY_F10;
- _key_map[n++] = KEY_F11;
- _key_map[n++] = KEY_F12;
- _key_map[n++] = KEY_F13;
- _key_map[n++] = KEY_F14;
- _key_map[n++] = KEY_F15;
- _key_map[n++] = KEY_F16;
- _key_map[n++] = KEY_F17;
- _key_map[n++] = KEY_F18;
- _key_map[n++] = KEY_F19;
- _key_map[n++] = KEY_F20;
- _key_map[n++] = KEY_F21;
- _key_map[n++] = KEY_F22;
- _key_map[n++] = KEY_F23;
- _key_map[n++] = KEY_F24;
-
- return _key_map;
-}
-
-__attribute__((export_name("js_sound_sample_rate"))) f64 js_sound_sample_rate(void) {
- return (f64) SOUND_SAMPLE_RATE;
-}
-
-__attribute__((export_name("js_num_sound_channels"))) i32 js_num_sound_channels(void) {
- return NUM_SOUND_CHANNELS;
-}
-
__attribute__((export_name("js_max_num_sound_frames"))) i32 js_max_num_sound_frames(void) {
return MAX_NUM_SOUND_FRAMES;
}
@@ -2521,11 +2557,6 @@ __attribute__((export_name("js_href_size"))) i32 js_href_size(void) {
}
__attribute__((export_name("js_main"))) void js_main(void) {
- (void) drop_files_clean_;
- (void) drop_files_set_num_;
- (void) drop_files_set_name_;
- (void) drop_files_set_data_;
-
main(1, (c8 *[1]) { _href });
}
@@ -2545,7 +2576,7 @@ __attribute__((export_name("js_frame"))) void js_frame(i32 frame_width, i32 fram
_frame_height = frame_height;
}
- _num_size += pixel_size_update_(_frame_width, _frame_height);
+ _num_events += pixel_size_update_(_frame_width, _frame_height);
g_platform.done = 0;
@@ -2642,6 +2673,40 @@ __attribute__((export_name("js_clipboard_buffer"))) void *js_clipboard_buffer(i3
return g_platform.clipboard;
}
+__attribute__((export_name("js_dragenter"))) void js_dragenter(void) {
+ _files_dragged = 1;
+}
+
+__attribute__((export_name("js_dragleave"))) void js_dragleave(void) {
+ _files_dragged = 0;
+}
+
+__attribute__((export_name("js_max_drop_size"))) i32 js_max_drop_size(void) {
+ return sizeof _drop_buffer;
+}
+
+__attribute__((export_name("js_drop_buffer"))) void *js_drop_buffer(void) {
+ return _drop_buffer;
+}
+
+__attribute__((export_name("js_drop"))) void js_drop(i32 name_len, i32 data_size) {
+ if (name_len + data_size > sizeof _drop_buffer) {
+ LOG_ERROR("File too big.");
+ return;
+ }
+
+ i64 n = g_platform.num_drop_files;
+
+ drop_files_set_num_(n + 1);
+ drop_files_set_name_(n, name_len, (c8 *) _drop_buffer);
+ drop_files_set_data_(n, data_size);
+
+ for (i64 i = 0; i < data_size; ++i)
+ g_platform.drop_files[n].data[i] = _drop_buffer[name_len + i];
+
+ _files_dropped = 1;
+}
+
#endif // defined(__wasm__)
// ================================================================