add wasm support
This commit is contained in:
parent
e4000646ad
commit
099c3c0607
31
build.zig
31
build.zig
@ -26,14 +26,18 @@ pub fn build(b: *std.Build) !void {
|
||||
test_step.dependOn(&run_exe_tests.step);
|
||||
}
|
||||
},
|
||||
.wasm => {
|
||||
// TODO:
|
||||
// b.getInstallStep().dependOn(build_step);
|
||||
//
|
||||
// const dep_emsdk = dep_sokol.builder.dependency("emsdk", .{});
|
||||
// const emrun_step = sokol.emRunStep(b, .{ .name = "index", .emsdk = dep_emsdk });
|
||||
// emrun_step.step.dependOn(build_step);
|
||||
// run_cmd_step = &emrun_step.step;
|
||||
.wasm => |build_step| {
|
||||
b.getInstallStep().dependOn(build_step);
|
||||
|
||||
const dep_sokol = b.dependency("sokol", .{});
|
||||
const dep_emsdk = dep_sokol.builder.dependency("emsdk", .{});
|
||||
const emrun_step = sokol.emRunStep(b, .{ .name = "index", .emsdk = dep_emsdk });
|
||||
emrun_step.step.dependOn(build_step);
|
||||
run_cmd_step = &emrun_step.step;
|
||||
|
||||
// add an emsdk install step
|
||||
const emsdk_install_step = sokol.emSdkInstallStep(b, dep_sokol.builder.dependency("emsdk", .{}), .{});
|
||||
b.step("install-emsdk", "Install Emscripten SDK in zig-pkg").dependOn(emsdk_install_step);
|
||||
}
|
||||
}
|
||||
|
||||
@ -66,7 +70,10 @@ fn buildProject(ctx: Context, target: Build.ResolvedTarget, optimize: std.builti
|
||||
const is_debug = optimize == .debug;
|
||||
|
||||
const has_imgui = b.option(bool, "imgui", "ImGui integration") orelse is_debug;
|
||||
const assets_from_filesystem = b.option(bool, "assets-filesystem", "Allow reading assets from filesystem") orelse is_debug;
|
||||
var assets_from_filesystem = false;
|
||||
if (!is_wasm) {
|
||||
assets_from_filesystem = b.option(bool, "assets-filesystem", "Allow reading assets from filesystem") orelse is_debug;
|
||||
}
|
||||
|
||||
var has_tracy = false;
|
||||
if (!is_wasm) {
|
||||
@ -123,6 +130,7 @@ fn buildProject(ctx: Context, target: Build.ResolvedTarget, optimize: std.builti
|
||||
var slang = sokol.shdc.Slang{};
|
||||
if (is_wasm) {
|
||||
slang.wgsl = true;
|
||||
slang.glsl300es = true;
|
||||
} else {
|
||||
slang.glsl410 = true;
|
||||
slang.hlsl4 = true;
|
||||
@ -316,8 +324,9 @@ fn buildWasm(b: *std.Build, opts: BuildWasmOptions) *std.Build.Step {
|
||||
.emsdk = dep_emsdk,
|
||||
.use_webgl2 = true,
|
||||
.use_emmalloc = true,
|
||||
.use_filesystem = false,
|
||||
.shell_file_path = b.path("src/engine/shell.html"),
|
||||
.use_filesystem = true,
|
||||
.shell_file_path = b.path("src/platform/shell.html"),
|
||||
.extra_args = &.{ "-sALLOW_MEMORY_GROWTH", "-sENVIRONMENT=web" }
|
||||
}) catch unreachable;
|
||||
|
||||
return &link_step.step;
|
||||
|
||||
@ -4,7 +4,7 @@ const c = @import("c");
|
||||
|
||||
const STBRectPack = @This();
|
||||
|
||||
ctx: c.stbrp_context,
|
||||
ctx: c.stbrp_context = .{},
|
||||
|
||||
pub fn init(self: *STBRectPack, width: u32, height: u32, nodes: []Node) void {
|
||||
c.stbrp_init_target(&self.ctx, @intCast(width), @intCast(height), nodes.ptr, @intCast(nodes.len));
|
||||
|
||||
@ -164,6 +164,7 @@ pub fn init(io: Io, gpa: std.mem.Allocator, opts: InitOptions) !void {
|
||||
.buffer_frames = @intCast(opts.buffer_frames),
|
||||
.sample_rate = g_sample_rate
|
||||
});
|
||||
assert(saudio.isvalid());
|
||||
|
||||
if (opts.track_elapsed_time) {
|
||||
const measurements_per_second: usize = @intCast(@divFloor(std.time.ns_per_s, getMaxAudioThreadDuration().nanoseconds));
|
||||
|
||||
@ -130,7 +130,8 @@ pub fn init(gpa: std.mem.Allocator, logger: sg.Logger) !void {
|
||||
});
|
||||
|
||||
const index_count = max_quads * 6;
|
||||
var indices: [index_count]u16 = undefined;
|
||||
var indices: []u16 = try gpa.alloc(u16, index_count);
|
||||
defer gpa.free(indices);
|
||||
for (0..max_quads) |i| {
|
||||
indices[6*i + 0] = @intCast(4*i + 0);
|
||||
indices[6*i + 1] = @intCast(4*i + 1);
|
||||
@ -142,7 +143,7 @@ pub fn init(gpa: std.mem.Allocator, logger: sg.Logger) !void {
|
||||
}
|
||||
|
||||
bindings.index_buffer = sg.makeBuffer(.{
|
||||
.data = sg.asRange(&indices),
|
||||
.data = sg.asRange(indices),
|
||||
.usage = .{ .index_buffer = true, },
|
||||
.label = "indices"
|
||||
});
|
||||
@ -997,7 +998,7 @@ fn repackSpritesheet(id: Spritesheet.Id) void {
|
||||
};
|
||||
}
|
||||
|
||||
spritesheet.packer = undefined;
|
||||
spritesheet.packer = .{};
|
||||
const packer = &spritesheet.packer.?;
|
||||
|
||||
for (&texture_sizes) |texture_size| {
|
||||
|
||||
@ -36,7 +36,7 @@ fn PlatformType(App: type) type {
|
||||
const Self = @This();
|
||||
|
||||
gpa: Allocator,
|
||||
arena: *std.heap.ArenaAllocator,
|
||||
arena: std.heap.ArenaAllocator,
|
||||
io: Io,
|
||||
cli_args: []const [:0]const u8,
|
||||
|
||||
@ -406,6 +406,13 @@ fn PlatformType(App: type) type {
|
||||
});
|
||||
},
|
||||
.KEY_DOWN => {
|
||||
if (builtin.cpu.arch.isWasm()) {
|
||||
// Pass through developer tools keybind
|
||||
if (e.key_code == .I and e.modifiers & sapp.modifier_shift != 0 and e.modifiers & sapp.modifier_ctrl != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
self.last_key_press_is_repeat = e.key_repeat;
|
||||
if (!e.key_repeat) {
|
||||
self.pushEvent(.{
|
||||
@ -478,6 +485,8 @@ fn PlatformType(App: type) type {
|
||||
ImGUI.deinit();
|
||||
Gfx.deinit();
|
||||
Audio.deinit(self.gpa);
|
||||
|
||||
self.arena.deinit();
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -609,7 +618,6 @@ pub const Frame = struct {
|
||||
};
|
||||
|
||||
pub fn run(App: type, opts: RunOptions) void {
|
||||
const arena = opts.init.arena.allocator();
|
||||
const gpa = opts.init.gpa;
|
||||
const io = opts.init.io;
|
||||
|
||||
@ -623,12 +631,14 @@ pub fn run(App: type, opts: RunOptions) void {
|
||||
}
|
||||
|
||||
const PlatformApp = PlatformType(App);
|
||||
const plt = arena.create(PlatformApp) catch @panic("OOM");
|
||||
|
||||
var arena = std.heap.ArenaAllocator.init(gpa);
|
||||
const plt = arena.allocator().create(PlatformApp) catch @panic("OOM");
|
||||
plt.* = PlatformApp{
|
||||
.gpa = gpa,
|
||||
.arena = opts.init.arena,
|
||||
.arena = undefined,
|
||||
.io = io,
|
||||
.cli_args = opts.init.minimal.args.toSlice(arena) catch @panic("OOM"),
|
||||
.cli_args = opts.init.minimal.args.toSlice(arena.allocator()) catch @panic("OOM"),
|
||||
.app = undefined,
|
||||
.input = undefined,
|
||||
.events_buffer = undefined,
|
||||
@ -643,6 +653,7 @@ pub fn run(App: type, opts: RunOptions) void {
|
||||
.assets = .init(gpa, io, assets_dir),
|
||||
.last_mouse_position = null
|
||||
};
|
||||
plt.arena = arena;
|
||||
|
||||
inline for (EmbeddedAssets.files) |file| {
|
||||
plt.assets.insertStaticFile(file.name, file.contents) catch @panic("OOM");
|
||||
|
||||
53
src/platform/shell.html
Normal file
53
src/platform/shell.html
Normal file
@ -0,0 +1,53 @@
|
||||
<!doctype html>
|
||||
<html lang="en-us">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"/>
|
||||
<title>Sokol</title>
|
||||
<style>
|
||||
body { margin: 0; background-color: black }
|
||||
.game {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
margin: 0px;
|
||||
border: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
display: block;
|
||||
image-rendering: optimizeSpeed;
|
||||
image-rendering: -moz-crisp-edges;
|
||||
image-rendering: -o-crisp-edges;
|
||||
image-rendering: -webkit-optimize-contrast;
|
||||
image-rendering: optimize-contrast;
|
||||
image-rendering: crisp-edges;
|
||||
image-rendering: pixelated;
|
||||
-ms-interpolation-mode: nearest-neighbor;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<canvas class="game" id="canvas" oncontextmenu="event.preventDefault()"></canvas>
|
||||
<script type='text/javascript'>
|
||||
var Module = {
|
||||
preRun: [],
|
||||
print: (function() {
|
||||
return function(text) {
|
||||
text = Array.prototype.slice.call(arguments).join(' ');
|
||||
console.log(text);
|
||||
};
|
||||
})(),
|
||||
printErr: function(text) {
|
||||
text = Array.prototype.slice.call(arguments).join(' ');
|
||||
console.error(text);
|
||||
},
|
||||
};
|
||||
window.onerror = function() {
|
||||
console.log("onerror: " + event.message);
|
||||
};
|
||||
window.addEventListener("click", () => window.focus())
|
||||
</script>
|
||||
{{{ SCRIPT }}}
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Reference in New Issue
Block a user