Skip to content

Commit d39fc66

Browse files
committed
Initial commit
1 parent b282c8f commit d39fc66

File tree

4 files changed

+172
-5
lines changed

4 files changed

+172
-5
lines changed

build.zig

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@ const std = @import("std");
33

44
pub const emsdk_ver_major = "3";
55
pub const emsdk_ver_minor = "1";
6-
pub const emsdk_ver_tiny = "52";
6+
pub const emsdk_ver_tiny = "70";
77
pub const emsdk_version = emsdk_ver_major ++ "." ++ emsdk_ver_minor ++ "." ++ emsdk_ver_tiny;
88

99
pub fn build(b: *std.Build) void {
1010
_ = b.addModule("root", .{ .root_source_file = b.path("src/zemscripten.zig") });
11+
_ = b.addModule("dummy", .{ .root_source_file = b.path("src/dummy.zig") });
1112
}
1213

1314
pub fn emccPath(b: *std.Build) []const u8 {

content/shell_minimal.html

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<!doctype html>
2+
<html lang="en-us">
3+
<head>
4+
<meta charset="utf-8">
5+
<meta name="viewport"
6+
content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=0" />
7+
<meta name="apple-mobile-web-app-capable" content="yes" />
8+
<title>Resource Simulation</title>
9+
<link rel="icon" type="image/x-icon" href="img/favicon.ico">
10+
<style>
11+
html, body {
12+
height: 100%;
13+
margin: 0;
14+
}
15+
canvas {
16+
width: 100%;
17+
height: 100%;
18+
display: block;
19+
}
20+
#canvas-container {
21+
position: absolute;
22+
top: 0;
23+
left: 0;
24+
padding: 0;
25+
border: 0 none;
26+
margin: 0;
27+
width: 100%;
28+
height: 100%;
29+
}
30+
</style>
31+
</head>
32+
<body>
33+
<canvas id="canvas" oncontextmenu="event.preventDefault()" tabindex=-1></canvas>
34+
<script type='text/javascript'>
35+
var Module = {
36+
canvas: (() => {
37+
var canvas = document.getElementById('canvas');
38+
39+
// As a default initial behavior, pop up an alert when webgl context is lost. To make your
40+
// application robust, you may want to override this behavior before shipping!
41+
// See http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15.2
42+
canvas.addEventListener("webglcontextlost", (e) => { alert('WebGL context lost. You will need to reload the page.'); e.preventDefault(); }, false);
43+
44+
return canvas;
45+
})(),
46+
totalDependencies: 0,
47+
};
48+
</script>
49+
{{{ SCRIPT }}}
50+
</body>
51+
</html>

src/dummy.zig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub const is_emscripten = false;

src/zemscripten.zig

Lines changed: 118 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,7 @@ comptime {
66
_ = std.testing.refAllDeclsRecursive(@This());
77
}
88

9-
extern fn emscripten_err([*c]const u8) void;
10-
extern fn emscripten_console_error([*c]const u8) void;
11-
extern fn emscripten_console_warn([*c]const u8) void;
12-
extern fn emscripten_console_log([*c]const u8) void;
9+
pub extern fn emscripten_sleep(ms: u32) void;
1310

1411
pub const MainLoopCallback = *const fn () callconv(.C) void;
1512
extern fn emscripten_set_main_loop(MainLoopCallback, c_int, c_int) void;
@@ -21,6 +18,123 @@ pub const AnimationFrameCallback = *const fn (f64, ?*anyopaque) callconv(.C) c_i
2118
extern fn emscripten_request_animation_frame_loop(AnimationFrameCallback, ?*anyopaque) void;
2219
pub const requestAnimationFrameLoop = emscripten_request_animation_frame_loop;
2320

21+
pub const EmscriptenResult = enum(i16) {
22+
success = 0,
23+
deferred = 1,
24+
not_supported = -1,
25+
failed_not_deferred = -2,
26+
invalid_target = -3,
27+
unknown_target = -4,
28+
invalid_param = -5,
29+
failed = -6,
30+
no_data = -7,
31+
timed_out = -8,
32+
};
33+
pub const CanvasSizeChangedCallback = *const fn (
34+
i16,
35+
*anyopaque,
36+
?*anyopaque,
37+
) callconv(.C) c_int;
38+
pub fn setResizeCallback(
39+
cb: CanvasSizeChangedCallback,
40+
use_capture: bool,
41+
user_data: ?*anyopaque,
42+
) EmscriptenResult {
43+
const result = emscripten_set_resize_callback_on_thread(
44+
"2",
45+
user_data,
46+
@intFromBool(use_capture),
47+
cb,
48+
2,
49+
);
50+
return @enumFromInt(result);
51+
}
52+
extern fn emscripten_set_resize_callback_on_thread(
53+
[*:0]const u8,
54+
?*anyopaque,
55+
c_int,
56+
CanvasSizeChangedCallback,
57+
c_int,
58+
) c_int;
59+
60+
pub fn getElementCssSize(
61+
target_id: [:0]const u8,
62+
width: *f64,
63+
height: *f64,
64+
) EmscriptenResult {
65+
return @enumFromInt(emscripten_get_element_css_size(
66+
target_id,
67+
width,
68+
height,
69+
));
70+
}
71+
extern fn emscripten_get_element_css_size([*:0]const u8, *f64, *f64) c_int;
72+
73+
/// EmmalocAllocator allocator
74+
/// use with linker flag -sMALLOC=emmalloc
75+
/// for details see docs: https://github.com/emscripten-core/emscripten/blob/main/system/lib/emmalloc.c
76+
extern fn emmalloc_memalign(u32, u32) ?*anyopaque;
77+
extern fn emmalloc_realloc_try(?*anyopaque, u32) ?*anyopaque;
78+
extern fn emmalloc_free(?*anyopaque) void;
79+
pub const EmmalocAllocator = struct {
80+
const Self = @This();
81+
dummy: u32 = undefined,
82+
83+
pub fn allocator(self: *Self) std.mem.Allocator {
84+
return .{
85+
.ptr = self,
86+
.vtable = &.{
87+
.alloc = &alloc,
88+
.resize = &resize,
89+
.free = &free,
90+
},
91+
};
92+
}
93+
94+
fn alloc(
95+
ctx: *anyopaque,
96+
len: usize,
97+
ptr_align_log2: u8,
98+
return_address: usize,
99+
) ?[*]u8 {
100+
_ = ctx;
101+
_ = return_address;
102+
const ptr_align: u32 = @as(u32, 1) << @as(u5, @intCast(ptr_align_log2));
103+
if (!std.math.isPowerOfTwo(ptr_align)) unreachable;
104+
const ptr = emmalloc_memalign(ptr_align, len) orelse return null;
105+
return @ptrCast(ptr);
106+
}
107+
108+
fn resize(
109+
ctx: *anyopaque,
110+
buf: []u8,
111+
buf_align_log2: u8,
112+
new_len: usize,
113+
return_address: usize,
114+
) bool {
115+
_ = ctx;
116+
_ = return_address;
117+
_ = buf_align_log2;
118+
return emmalloc_realloc_try(buf.ptr, new_len) != null;
119+
}
120+
121+
fn free(
122+
ctx: *anyopaque,
123+
buf: []u8,
124+
buf_align_log2: u8,
125+
return_address: usize,
126+
) void {
127+
_ = ctx;
128+
_ = buf_align_log2;
129+
_ = return_address;
130+
return emmalloc_free(buf.ptr);
131+
}
132+
};
133+
134+
extern fn emscripten_err([*c]const u8) void;
135+
extern fn emscripten_console_error([*c]const u8) void;
136+
extern fn emscripten_console_warn([*c]const u8) void;
137+
extern fn emscripten_console_log([*c]const u8) void;
24138
/// std.panic impl
25139
pub fn panic(msg: []const u8, error_return_trace: ?*std.builtin.StackTrace, ret_addr: ?usize) noreturn {
26140
_ = error_return_trace;

0 commit comments

Comments
 (0)