Running dvui + sdl3 on WEB

I successfully run SDL with embedded dvui on WEB. Project link https://codeberg.org/knightpp/game-of-life-zig and you can play here https://knightpp.codeberg.page/game-of-life-zig/@pages/.

SDL3 supports callbacks style, so you don’t have to change a lot of code to port your app to a new platform. And it works! After I setup build.zig and added some tweaks to fix dvui’s compilation, my app run on WEB relatively easy!

Though it took a lot of time to get there. Turns out LTO breaks generated wasm really badly, it still loaded and displayed something but was half functional.

Miscompilations? I had something like this

const new_game = try Game.init(...);
state.game.deinit()
state.game = new_game;

But for some reason it worked fine on x86_64-linux but not on wasm-emscripten target. By pure luck I could track down the issue really quickly.

5 Likes

That is very cool! I did not know that you could run sdl3 on top of emscripten, way to go!

1 Like

Ported this over to using Vulkan! GitHub - mm318/vulkan-sdl3: Sample GPU-accelerated application built using Zig + Vulkan + SDL3 + DVUI

Also tried to port the shaders to Zig, but Zig as a shader compiler doesn’t seem to be there yet.

1 Like

Will check this out soon, excited!

1 Like

Nice!

I had to apply a patch to get it working. On NixOS I have to link to system(patched) sdl3 to run graphical apps.

diff --git a/build.zig b/build.zig
index dd1bed7..776f148 100644
--- a/build.zig
+++ b/build.zig
@@ -13,19 +13,22 @@ pub fn build(b: *std.Build) void {
         .backend = .custom,
     });

-    const sdl3_dep = b.dependency("sdl3", .{
-        .target = target,
-        .optimize = optimize,
-    });
-
     const vulkan_mod = b.createModule(.{
         .root_source_file = b.path("src/vulkan/vulkan_init.zig"),
         .target = target,
         .optimize = optimize,
     });
-    vulkan_mod.linkLibrary(sdl3_dep.artifact("SDL3"));
     vulkan_mod.addIncludePath(b.path("src/vulkan/"));
     vulkan_mod.addCSourceFile(.{ .file = b.path("src/vulkan/vk_mem_alloc.cpp") });
+    if (b.systemIntegrationOption("sdl3", .{})) {
+        vulkan_mod.linkSystemLibrary("SDL3", .{});
+    } else {
+        const sdl3_dep = b.dependency("sdl3", .{
+            .target = target,
+            .optimize = optimize,
+        });
+        vulkan_mod.linkLibrary(sdl3_dep.artifact("SDL3"));
+    }

     const dvui_backend_mod = b.createModule(.{
         .root_source_file = b.path("src/dvui_backend/sdl3_vk.zig"),