lerp :: (t: f32, a: $T, b: T) -> T {
return ~~(~~a * (1 - t) + ~~b * t);
-}
\ No newline at end of file
+}
+
+choose :: (n: $T, k: T) -> T {
+ assert(T == i32 || T == i64 || T == u32 || T == u64, "bad type for choose function");
+
+ ret := 1;
+ for i: (n - k + 1) .. (n + 1) {
+ ret *= i;
+ }
+
+ for i: 1 .. (k + 1) {
+ ret /= i;
+ }
+
+ return ret;
+}
};
}
+free_slice :: (sl: ^[] $T, allocator := context.allocator) {
+ if sl.data == null do return;
+
+ raw_free(allocator, sl.data);
+ sl.data = null;
+ sl.count = 0;
+}
+
align :: #match {
(size: ^u64, align: u64) {
if *size % align != 0 {
apply_transform :: (use ir: ^Immediate_Renderer, transform: Transform) {
transform_apply(array.get_ptr(^world_transform_stack, -1), transform);
+ world_transform_dirty = true;
}
to_screen_coordinates :: (use ir: ^Immediate_Renderer, use v: Vector2) -> Vector2 {
push_event_to_buffer(esp, event_size, 0x06, [ window.innerWidth, window.innerHeight ]);
+ document.getElementsByTagName("canvas")[0].addEventListener("drop", function (ev) {
+ ev.preventDefault();
+
+ // ROBUSTNESS: Currently, this only gives the first file, which for a lot of purposes, will be enough.
+ // But if multiple files are dropped, the application will only know about the first one.
+ ev.dataTransfer.items[0].getAsFile().arrayBuffer()
+ .then(response => {
+ // 0 is assumed to be reserved in request_file.onyx.
+ requested_file_data[0] = response;
+ push_event_to_buffer(esp, event_size, 0x08, [0x01, 0, response.byteLength]);
+ })
+ .catch(error => {
+ push_event_to_buffer(esp, event_size, 0x08, [0x02, 0, 0]);
+ });
+
+ return false;
+ });
+
+ document.getElementsByTagName("canvas")[0].addEventListener("dragover", function(ev) {
+ ev.preventDefault();
+ return false;
+ });
+
document.oncontextmenu = (e) => {
e.preventDefault = true;
return false;
package js_events
-#private_file next_request_id := 0;
+// 0 is reserved for dropped files
+#private_file next_request_id := 1;
request_file :: (filepath: str) -> u32 {
js_request_file :: (event_storage: ^EventStorage, event_size: u32, filepath: str, fileid: u32) -> void #foreign "js_events" "request_file" ---;
- next_request_id += 1;
fileid := next_request_id;
+ next_request_id += 1;
js_request_file(^event_storage, sizeof Event, filepath, fileid);
return fileid;
hash := get_site_hash(site, increment);
animation_state := map.get(^animation_states, hash);
+ mx, my := get_mouse_position();
+
if is_active_item(hash) {
if mouse_state.left_button_just_up {
- if is_hot_item(hash) && Rectangle.contains(r, mouse_state.x, mouse_state.y) {
+ if is_hot_item(hash) && Rectangle.contains(r, mx, my) {
result = true;
*selected = value;
animation_state.click_time = 1.0f;
}
}
- if Rectangle.contains(r, mouse_state.x, mouse_state.y) {
+ if Rectangle.contains(r, mx, my) {
set_hot_item(hash);
}
hash := get_site_hash(site, increment);
animation_state := map.get(^animation_states, hash);
width, height := Rectangle.dimensions(r);
+ mx, my := get_mouse_position();
if is_hot_item(hash) {
if mouse_state.left_button_down {
result = true;
// Animate this?
- x := mouse_state.x - x0;
+ x := mx - x0;
if T == i32 || T == i64 || T == u32 || T == u64 {
step_width := width / ~~math.abs(max_value - min_value);
}
}
- if Rectangle.contains(r, mouse_state.x, mouse_state.y) {
+ if Rectangle.contains(r, mx, my) {
set_hot_item(hash);
}
return ws;
}
+free :: (use bin: ^WasmBinary) {
+ map.free(^sections);
+ map.free(^custom_section_locations);
+}
+
+
free_sections :: (use sections: ^WasmSections) {
if type_section.data != null do raw_free(allocator, type_section.data);
if import_section.data != null do raw_free(allocator, import_section.data);