Compare commits
3 Commits
7632329c92
...
099c3c0607
| Author | SHA1 | Date | |
|---|---|---|---|
| 099c3c0607 | |||
| e4000646ad | |||
| 4764f153e6 |
BIN
assets/icon.png
Normal file
BIN
assets/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 454 B |
317
build.zig
317
build.zig
@ -6,9 +6,57 @@ pub fn build(b: *std.Build) !void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
|
||||
const dep_stb = b.dependency("stb", .{});
|
||||
const ctx = Context.init(b, dep_stb.module("stb_image"));
|
||||
|
||||
var run_cmd_step: *std.Build.Step = undefined;
|
||||
switch (try buildProject(ctx, target, optimize)) {
|
||||
.native => |exe| {
|
||||
b.installArtifact(exe);
|
||||
|
||||
const run_cmd = b.addRunArtifact(exe);
|
||||
run_cmd.addPassthruArgs();
|
||||
run_cmd_step = &run_cmd.step;
|
||||
|
||||
{
|
||||
const exe_tests = b.addTest(.{ .root_module = exe.root_module, });
|
||||
const run_exe_tests = b.addRunArtifact(exe_tests);
|
||||
|
||||
const test_step = b.step("test", "Run tests");
|
||||
test_step.dependOn(&run_exe_tests.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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const run_step = b.step("run", "Run game");
|
||||
run_step.dependOn(run_cmd_step);
|
||||
}
|
||||
|
||||
const ProjectResult = union(enum) {
|
||||
native: *std.Build.Step.Compile,
|
||||
wasm: *std.Build.Step,
|
||||
};
|
||||
|
||||
fn buildProject(ctx: Context, target: Build.ResolvedTarget, optimize: std.builtin.OptimizeMode) !ProjectResult {
|
||||
const b = ctx.b;
|
||||
|
||||
const name = "sokol_template_v2";
|
||||
|
||||
const assets_dir = "assets";
|
||||
const assets_dir = b.path("assets");
|
||||
const asset_files = [_][]const u8{
|
||||
"sokoban/sokoban_tilesheet.png",
|
||||
"sokoban/sokoban_tilesheet@2.png",
|
||||
@ -18,19 +66,23 @@ pub fn build(b: *std.Build) !void {
|
||||
"impact-sounds/footstep_concrete_000.ogg"
|
||||
};
|
||||
|
||||
const asset_dir_realpath = try b.build_root.join(b.graph.arena, &.{ assets_dir });
|
||||
|
||||
const is_wasm = target.result.cpu.arch.isWasm();
|
||||
const is_debug = (optimize == .Debug);
|
||||
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) {
|
||||
has_tracy = b.option(bool, "tracy", "Tracy integration") orelse is_debug;
|
||||
}
|
||||
|
||||
const win32_has_console = null;
|
||||
const win32_icon_png: ?Build.LazyPath = b.path("assets/icon.png");
|
||||
|
||||
const exe_mod = b.createModule(.{
|
||||
.root_source_file = b.path("src/main.zig"),
|
||||
.target = target,
|
||||
@ -52,10 +104,12 @@ pub fn build(b: *std.Build) !void {
|
||||
{
|
||||
const build_options = b.addOptions();
|
||||
build_options.addOption(bool, "has_imgui", has_imgui);
|
||||
build_options.addOption(?[]const u8, "assets_dir", if (assets_from_filesystem) asset_dir_realpath else null);
|
||||
if (assets_from_filesystem) {
|
||||
build_options.addOptionPathDirectory("assets_dir", assets_dir);
|
||||
}
|
||||
platform_mod.addOptions("build_options", build_options);
|
||||
|
||||
platform_mod.addImport("embedded_assets", try createEmbeddedAssets(b, assets_dir, &asset_files));
|
||||
platform_mod.addImport("embedded_assets", try createAssetsModule(b, assets_dir, &asset_files));
|
||||
|
||||
const math_mod = b.createModule(.{
|
||||
.root_source_file = b.path("src/platform/math.zig")
|
||||
@ -76,6 +130,7 @@ pub fn build(b: *std.Build) !void {
|
||||
var slang = sokol.shdc.Slang{};
|
||||
if (is_wasm) {
|
||||
slang.wgsl = true;
|
||||
slang.glsl300es = true;
|
||||
} else {
|
||||
slang.glsl410 = true;
|
||||
slang.hlsl4 = true;
|
||||
@ -118,205 +173,120 @@ pub fn build(b: *std.Build) !void {
|
||||
platform_mod.addImport("tracy", dep_tracy.module("tracy"));
|
||||
}
|
||||
|
||||
var run_cmd_step: *std.Build.Step = undefined;
|
||||
if (is_wasm) {
|
||||
@panic("TODO: Test wasm support on 0.17");
|
||||
|
||||
// const build_step = buildWasm(b, .{
|
||||
// .name = "index",
|
||||
// .root_module = exe_mod,
|
||||
// .dep_sokol = dep_sokol,
|
||||
// });
|
||||
// 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;
|
||||
|
||||
// TODO: Create a zip archive of all of the files. Would be useful for easier itch.io upload
|
||||
return ProjectResult{
|
||||
.wasm = buildWasm(b, .{
|
||||
.name = "index",
|
||||
.root_module = exe_mod,
|
||||
.dep_sokol = dep_sokol,
|
||||
})
|
||||
};
|
||||
} else {
|
||||
const exe = buildNative(b, .{
|
||||
const exe = b.addExecutable(.{
|
||||
.name = name,
|
||||
.root_module = exe_mod
|
||||
.root_module = exe_mod,
|
||||
});
|
||||
b.installArtifact(exe);
|
||||
|
||||
{
|
||||
const run_cmd = b.addRunArtifact(exe);
|
||||
if (b.args) |args| {
|
||||
run_cmd.addArgs(args);
|
||||
}
|
||||
run_cmd_step = &run_cmd.step;
|
||||
}
|
||||
if (target.result.os.tag == .windows) {
|
||||
const has_console = win32_has_console orelse is_debug;
|
||||
exe.subsystem = if (has_console) .console else .windows;
|
||||
|
||||
{
|
||||
const exe_tests = b.addTest(.{ .root_module = exe_mod, });
|
||||
const run_exe_tests = b.addRunArtifact(exe_tests);
|
||||
|
||||
const test_step = b.step("test", "Run tests");
|
||||
test_step.dependOn(&run_exe_tests.step);
|
||||
if (win32_icon_png) |icon_png| {
|
||||
buildWin32ResourceFile(ctx, exe.root_module, .{
|
||||
.icon_png = icon_png
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const run_step = b.step("run", "Run game");
|
||||
run_step.dependOn(run_cmd_step);
|
||||
return ProjectResult{
|
||||
.native = exe
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
fn createEmbeddedAssets(
|
||||
fn createAssetsModule(
|
||||
b: *std.Build,
|
||||
assets_dir: []const u8,
|
||||
assets_dir: Build.LazyPath,
|
||||
asset_files: []const []const u8
|
||||
) !*std.Build.Module {
|
||||
const write_files = b.addWriteFiles();
|
||||
|
||||
var embedded_assets: std.ArrayList(u8) = .empty;
|
||||
defer embedded_assets.deinit(b.allocator);
|
||||
var mod_contents: std.ArrayList(u8) = .empty;
|
||||
defer mod_contents.deinit(b.allocator);
|
||||
|
||||
try embedded_assets.appendSlice(b.allocator, "pub const files = .{\n");
|
||||
const mod_embedded_assets = b.createModule(.{});
|
||||
try mod_contents.appendSlice(b.allocator, "pub const files = .{\n");
|
||||
const mod = b.createModule(.{});
|
||||
for (asset_files) |asset_file| {
|
||||
mod_embedded_assets.addAnonymousImport(asset_file, .{
|
||||
.root_source_file = b.path(b.pathJoin(&.{ assets_dir, asset_file }))
|
||||
mod.addAnonymousImport(asset_file, .{
|
||||
.root_source_file = assets_dir.path(b, asset_file)
|
||||
});
|
||||
|
||||
try embedded_assets.appendSlice(b.allocator, " .{ ");
|
||||
try mod_contents.appendSlice(b.allocator, " .{ ");
|
||||
|
||||
try embedded_assets.appendSlice(b.allocator, ".name = \"");
|
||||
try embedded_assets.appendSlice(b.allocator, asset_file);
|
||||
try embedded_assets.appendSlice(b.allocator, "\"");
|
||||
try mod_contents.appendSlice(b.allocator, ".name = \"");
|
||||
try mod_contents.appendSlice(b.allocator, asset_file);
|
||||
try mod_contents.appendSlice(b.allocator, "\"");
|
||||
|
||||
try embedded_assets.appendSlice(b.allocator, ", ");
|
||||
try mod_contents.appendSlice(b.allocator, ", ");
|
||||
|
||||
try embedded_assets.appendSlice(b.allocator, ".contents = @embedFile(\"");
|
||||
try embedded_assets.appendSlice(b.allocator, asset_file);
|
||||
try embedded_assets.appendSlice(b.allocator, "\")");
|
||||
try mod_contents.appendSlice(b.allocator, ".contents = @embedFile(\"");
|
||||
try mod_contents.appendSlice(b.allocator, asset_file);
|
||||
try mod_contents.appendSlice(b.allocator, "\")");
|
||||
|
||||
try embedded_assets.appendSlice(b.allocator, " },\n");
|
||||
try mod_contents.appendSlice(b.allocator, " },\n");
|
||||
}
|
||||
try embedded_assets.appendSlice(b.allocator, "};\n");
|
||||
mod_embedded_assets.root_source_file = write_files.add("embedded_assets.zig", embedded_assets.items);
|
||||
try mod_contents.appendSlice(b.allocator, "};\n");
|
||||
mod.root_source_file = write_files.add("assets.zig", mod_contents.items);
|
||||
|
||||
return mod_embedded_assets;
|
||||
return mod;
|
||||
}
|
||||
|
||||
const BuildNativeOptions = struct {
|
||||
name: []const u8,
|
||||
root_module: *std.Build.Module,
|
||||
win32_has_console: ?bool = null,
|
||||
win32_png_icon: ?std.Build.LazyPath = null
|
||||
const Context = struct {
|
||||
b: *std.Build,
|
||||
png_to_icon: *Build.Step.Compile,
|
||||
create_win32_resource: *Build.Step.Compile,
|
||||
|
||||
pub fn init(b: *std.Build, stb_image: *Build.Module) Context {
|
||||
return Context{
|
||||
.b = b,
|
||||
.png_to_icon = b.addExecutable(.{
|
||||
.name = "png-to-icon",
|
||||
.root_module = b.createModule(.{
|
||||
.target = b.graph.host,
|
||||
.root_source_file = b.path("scripts/png-to-icon.zig"),
|
||||
.imports = &.{
|
||||
.{ .name = "stb_image", .module = stb_image }
|
||||
}
|
||||
})
|
||||
}),
|
||||
.create_win32_resource = b.addExecutable(.{
|
||||
.name = "create-win32-resource",
|
||||
.root_module = b.createModule(.{
|
||||
.target = b.graph.host,
|
||||
.root_source_file = b.path("scripts/create-win32-resource.zig"),
|
||||
})
|
||||
})
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
fn buildNative(
|
||||
b: *std.Build,
|
||||
opts: BuildNativeOptions,
|
||||
) *std.Build.Step.Compile {
|
||||
const exe = b.addExecutable(.{
|
||||
.name = opts.name,
|
||||
.root_module = opts.root_module,
|
||||
});
|
||||
const Win32ResourceFileOptions = struct {
|
||||
icon_png: Build.LazyPath
|
||||
};
|
||||
|
||||
const target = opts.root_module.resolved_target.?;
|
||||
if (target.result.os.tag == .windows) {
|
||||
const optimize = opts.root_module.optimize.?;
|
||||
const has_console = opts.win32_has_console orelse (optimize == .Debug);
|
||||
exe.subsystem = if (has_console) .Console else .Windows;
|
||||
fn buildWin32ResourceFile(ctx: Context, mod: *Build.Module, opts: Win32ResourceFileOptions) void {
|
||||
const b = ctx.b;
|
||||
|
||||
if (opts.win32_png_icon) |win32_png_icon| {
|
||||
const png_to_icon_tool = buildPngToIconTool(b, b.graph.host, .ReleaseSafe);
|
||||
|
||||
const png_to_icon_step = b.addRunArtifact(png_to_icon_tool);
|
||||
png_to_icon_step.addFileArg(win32_png_icon);
|
||||
const png_to_icon_step = b.addRunArtifact(ctx.png_to_icon);
|
||||
png_to_icon_step.addFileArg(opts.icon_png);
|
||||
const icon_file = png_to_icon_step.addOutputFileArg("icon.ico");
|
||||
|
||||
const add_icon_step = AddExecutableIcon.init(exe, icon_file);
|
||||
exe.step.dependOn(&add_icon_step.step);
|
||||
const resource_file_step = b.addRunArtifact(ctx.create_win32_resource);
|
||||
resource_file_step.addFileArg(icon_file);
|
||||
const resource_file = resource_file_step.addOutputFileArg("resource-file.rc");
|
||||
|
||||
mod.addWin32ResourceFile(.{ .file = resource_file });
|
||||
}
|
||||
}
|
||||
|
||||
return exe;
|
||||
}
|
||||
|
||||
fn buildPngToIconTool(
|
||||
b: *std.Build,
|
||||
target: std.Build.ResolvedTarget,
|
||||
optimize: std.builtin.OptimizeMode,
|
||||
) *std.Build.Step.Compile {
|
||||
const mod = b.createModule(.{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.root_source_file = b.path("tools/png-to-icon.zig"),
|
||||
});
|
||||
|
||||
const dep_stb = b.dependency("stb", .{});
|
||||
mod.addImport("stb_image", dep_stb.module("stb_image"));
|
||||
|
||||
return b.addExecutable(.{
|
||||
.name = "png-to-icon",
|
||||
.root_module = mod,
|
||||
});
|
||||
}
|
||||
|
||||
const AddExecutableIcon = struct {
|
||||
obj: *std.Build.Step.Compile,
|
||||
step: std.Build.Step,
|
||||
icon_file: std.Build.LazyPath,
|
||||
resource_file: std.Build.LazyPath,
|
||||
|
||||
fn init(obj: *std.Build.Step.Compile, icon_file: std.Build.LazyPath) *AddExecutableIcon {
|
||||
const b = obj.step.owner;
|
||||
const self = b.allocator.create(AddExecutableIcon) catch @panic("OOM");
|
||||
|
||||
self.obj = obj;
|
||||
self.step = std.Build.Step.init(.{
|
||||
.id = .custom,
|
||||
.name = "add executable icon",
|
||||
.owner = b,
|
||||
.makeFn = make
|
||||
});
|
||||
|
||||
self.icon_file = icon_file;
|
||||
icon_file.addStepDependencies(&self.step);
|
||||
|
||||
const write_files = b.addWriteFiles();
|
||||
self.resource_file = write_files.add("resource-file.rc", "");
|
||||
self.step.dependOn(&write_files.step);
|
||||
|
||||
self.obj.root_module.addWin32ResourceFile(.{
|
||||
.file = self.resource_file,
|
||||
});
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
fn make(step: *std.Build.Step, _: std.Build.Step.MakeOptions) !void {
|
||||
const b = step.owner;
|
||||
const self: *AddExecutableIcon = @fieldParentPtr("step", step);
|
||||
|
||||
const relative_icon_path = try std.fs.path.relative(
|
||||
b.allocator,
|
||||
"",
|
||||
null,
|
||||
self.resource_file.dirname().getPath(b),
|
||||
self.icon_file.getPath(b)
|
||||
);
|
||||
std.mem.replaceScalar(u8, relative_icon_path, '\\', '/');
|
||||
|
||||
{
|
||||
const cwd = std.Io.Dir.cwd();
|
||||
const resource_file = try cwd.createFile(b.graph.io, self.resource_file.getPath(b), .{ });
|
||||
defer resource_file.close(b.graph.io);
|
||||
|
||||
var buff: [4*4096]u8 = undefined;
|
||||
var file_writer = resource_file.writer(b.graph.io, &buff);
|
||||
const w = &file_writer.interface;
|
||||
|
||||
try w.writeAll("IDI_ICON ICON \"");
|
||||
try w.writeAll(relative_icon_path);
|
||||
try w.writeAll("\"");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const BuildWasmOptions = struct {
|
||||
name: []const u8,
|
||||
@ -354,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,12 +4,12 @@
|
||||
.fingerprint = 0xf440b4e6e51f5206, // Changing this has security and trust implications.
|
||||
.dependencies = .{
|
||||
.sokol = .{
|
||||
.url = "git+https://github.com/floooh/sokol-zig.git#ff40f04d4f51c73b2bf460d87fd2d7aa0dedc22f",
|
||||
.hash = "sokol-0.1.0-pb1HKygbQQCINV-qSe4SFm92QWaT_95VpWTJkwYqzOrX",
|
||||
.url = "git+https://github.com/floooh/sokol-zig.git#e371234960812882406a296c4f3154321a16ee4d",
|
||||
.hash = "sokol-0.1.0-pb1HK0kUQABqwuelY7BmmQmAm-jLBZKJ7uyoxkdS49Ib",
|
||||
},
|
||||
.cimgui = .{
|
||||
.url = "git+https://github.com/floooh/dcimgui.git#e2f0e0d93adec02743c55940be23ffe286e857f7",
|
||||
.hash = "cimgui-0.1.0-44ClkR8dmgDqqnfloyLE1bUAtl4zSKTT1wxaHSEC0ikV",
|
||||
.url = "git+https://github.com/floooh/dcimgui.git#ef68bcf1ea0a8218f4a2f24fb9414515ecbf5af4",
|
||||
.hash = "cimgui-0.1.0-44ClkVBEnABUEg0-NuUgCcvqhRLr9BCUWHFbuVYt9Nuv",
|
||||
.lazy = true
|
||||
},
|
||||
.stb = .{
|
||||
|
||||
@ -2,36 +2,97 @@ const std = @import("std");
|
||||
const Build = std.Build;
|
||||
const LazyPath = Build.LazyPath;
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
pub fn build(b: *std.Build) !void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
|
||||
buildSTBModule(b, target, optimize, "stb_image", b.path("src/stb_image.zig"), b.path("src/stb_image_impl.c"));
|
||||
buildSTBModule(b, target, optimize, "stb_vorbis", b.path("src/stb_vorbis.zig"), b.path("src/stb_vorbis_impl.c"));
|
||||
buildSTBModule(b, target, optimize, "stb_rect_pack", b.path("src/stb_rect_pack.zig"), b.path("src/stb_rect_pack_impl.c"));
|
||||
buildSTBModule(b, target, optimize, "stb_truetype", b.path("src/stb_truetype.zig"), b.path("src/stb_truetype_impl.c"));
|
||||
try buildSTBModule(b, target, optimize, .{
|
||||
.name = "stb_image",
|
||||
.zig_file = b.path("src/stb_image.zig"),
|
||||
.header_name = "stb_image.h",
|
||||
.defines = &.{ "STBI_NO_STDIO" },
|
||||
.impl_define = "STB_IMAGE_IMPLEMENTATION"
|
||||
});
|
||||
try buildSTBModule(b, target, optimize, .{
|
||||
.name = "stb_vorbis",
|
||||
.zig_file = b.path("src/stb_vorbis.zig"),
|
||||
.header_name = "stb_vorbis.c",
|
||||
.defines = &.{ "STB_VORBIS_NO_INTEGER_CONVERSION", "STB_VORBIS_NO_STDIO" },
|
||||
.header_only_define = "STB_VORBIS_HEADER_ONLY"
|
||||
});
|
||||
try buildSTBModule(b, target, optimize, .{
|
||||
.name = "stb_rect_pack",
|
||||
.zig_file = b.path("src/stb_rect_pack.zig"),
|
||||
.header_name = "stb_rect_pack.h",
|
||||
.impl_define = "STB_RECT_PACK_IMPLEMENTATION"
|
||||
});
|
||||
try buildSTBModule(b, target, optimize, .{
|
||||
.name = "stb_truetype",
|
||||
.zig_file = b.path("src/stb_truetype.zig"),
|
||||
.header_name = "stb_truetype.h",
|
||||
// TODO: .defines = &.{ "STBTT_STATIC" },
|
||||
.impl_define = "STB_TRUETYPE_IMPLEMENTATION"
|
||||
});
|
||||
}
|
||||
|
||||
const STBModuleOptions = struct {
|
||||
name: []const u8,
|
||||
zig_file: LazyPath,
|
||||
header_name: []const u8,
|
||||
defines: []const []const u8 = &.{},
|
||||
impl_define: ?[]const u8 = null,
|
||||
header_only_define: ?[]const u8 = null,
|
||||
};
|
||||
|
||||
fn buildSTBModule(
|
||||
b: *std.Build,
|
||||
target: Build.ResolvedTarget,
|
||||
optimize: std.builtin.OptimizeMode,
|
||||
name: []const u8,
|
||||
zig_file: LazyPath,
|
||||
impl_file: LazyPath
|
||||
) void {
|
||||
opts: STBModuleOptions
|
||||
) !void {
|
||||
const stb_dependency = b.dependency("stb", .{});
|
||||
|
||||
const mod = b.addModule(name, .{
|
||||
const mod = b.addModule(opts.name, .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.root_source_file = zig_file,
|
||||
.root_source_file = opts.zig_file,
|
||||
.link_libc = true,
|
||||
});
|
||||
|
||||
mod.addIncludePath(stb_dependency.path("."));
|
||||
const write_file_step = b.addWriteFiles();
|
||||
|
||||
{
|
||||
var translate_c_contents: std.ArrayList(u8) = .empty;
|
||||
try translate_c_contents.appendSlice(b.graph.arena, "#include \"");
|
||||
try translate_c_contents.appendSlice(b.graph.arena, opts.header_name);
|
||||
try translate_c_contents.appendSlice(b.graph.arena, "\"");
|
||||
|
||||
const translate_c = b.addTranslateC(.{
|
||||
.root_source_file = write_file_step.add("c.h", translate_c_contents.items),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
translate_c.addIncludePath(stb_dependency.path("."));
|
||||
for (opts.defines) |define| {
|
||||
translate_c.defineCMacro(define, null);
|
||||
}
|
||||
if (opts.header_only_define) |header_only_define| {
|
||||
translate_c.defineCMacro(header_only_define, null);
|
||||
}
|
||||
mod.addImport("c", translate_c.createModule());
|
||||
}
|
||||
|
||||
{
|
||||
mod.addCSourceFile(.{
|
||||
.file = impl_file,
|
||||
.file = write_file_step.add("impl.c", b.fmt("#include \"{s}\"", .{opts.header_name})),
|
||||
.flags = &.{}
|
||||
});
|
||||
mod.addIncludePath(stb_dependency.path("."));
|
||||
for (opts.defines) |define| {
|
||||
mod.addCMacro(define, "");
|
||||
}
|
||||
if (opts.impl_define) |impl_define| {
|
||||
mod.addCMacro(impl_define, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,9 +1,6 @@
|
||||
const std = @import("std");
|
||||
|
||||
const c = @cImport({
|
||||
@cDefine("STBI_NO_STDIO", {});
|
||||
@cInclude("stb_image.h");
|
||||
});
|
||||
const c = @import("c");
|
||||
|
||||
const STBImage = @This();
|
||||
|
||||
|
||||
@ -1,3 +0,0 @@
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#define STBI_NO_STDIO
|
||||
#include "stb_image.h"
|
||||
@ -1,12 +1,10 @@
|
||||
const std = @import("std");
|
||||
|
||||
const c = @cImport({
|
||||
@cInclude("stb_rect_pack.h");
|
||||
});
|
||||
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));
|
||||
|
||||
@ -1,2 +0,0 @@
|
||||
#define STB_RECT_PACK_IMPLEMENTATION
|
||||
#include "stb_rect_pack.h"
|
||||
@ -1,8 +1,6 @@
|
||||
const std = @import("std");
|
||||
|
||||
const c = @cImport({
|
||||
@cInclude("stb_truetype.h");
|
||||
});
|
||||
const c = @import("c");
|
||||
|
||||
pub const Box = struct {
|
||||
x0: i32,
|
||||
|
||||
@ -1,4 +0,0 @@
|
||||
#define STB_TRUETYPE_IMPLEMENTATION
|
||||
// TODO: #define STBTT_STATIC
|
||||
#include "stb_truetype.h"
|
||||
|
||||
@ -2,12 +2,7 @@ const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
const log = std.log.scoped(.stb_vorbis);
|
||||
|
||||
const c = @cImport({
|
||||
@cDefine("STB_VORBIS_NO_INTEGER_CONVERSION", {});
|
||||
@cDefine("STB_VORBIS_NO_STDIO", {});
|
||||
@cDefine("STB_VORBIS_HEADER_ONLY", {});
|
||||
@cInclude("stb_vorbis.c");
|
||||
});
|
||||
const c = @import("c");
|
||||
|
||||
const STBVorbis = @This();
|
||||
|
||||
|
||||
@ -1,3 +0,0 @@
|
||||
#define STB_VORBIS_NO_INTEGER_CONVERSION
|
||||
#define STB_VORBIS_NO_STDIO
|
||||
#include "stb_vorbis.c"
|
||||
@ -1,7 +1,7 @@
|
||||
const std = @import("std");
|
||||
const digits2 = std.fmt.digits2;
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
pub fn build(b: *std.Build) !void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
|
||||
@ -29,110 +29,113 @@ pub fn build(b: *std.Build) void {
|
||||
const tracy_timer_fallback = b.option(bool, "tracy_timer_fallback", "Use lower resolution timers") orelse false;
|
||||
const shared = b.option(bool, "shared", "Build the tracy client as a shared libary") orelse false;
|
||||
|
||||
const options = b.addOptions();
|
||||
options.addOption(bool, "tracy_enable", tracy_enable);
|
||||
options.addOption(bool, "tracy_on_demand", tracy_on_demand);
|
||||
options.addOption(?u8, "tracy_callstack", tracy_callstack);
|
||||
options.addOption(bool, "tracy_no_callstack", tracy_no_callstack);
|
||||
options.addOption(bool, "tracy_no_callstack_inlines", tracy_no_callstack_inlines);
|
||||
options.addOption(bool, "tracy_only_localhost", tracy_only_localhost);
|
||||
options.addOption(bool, "tracy_no_broadcast", tracy_no_broadcast);
|
||||
options.addOption(bool, "tracy_only_ipv4", tracy_only_ipv4);
|
||||
options.addOption(bool, "tracy_no_code_transfer", tracy_no_code_transfer);
|
||||
options.addOption(bool, "tracy_no_context_switch", tracy_no_context_switch);
|
||||
options.addOption(bool, "tracy_no_exit", tracy_no_exit);
|
||||
options.addOption(bool, "tracy_no_sampling", tracy_no_sampling);
|
||||
options.addOption(bool, "tracy_no_verify", tracy_no_verify);
|
||||
options.addOption(bool, "tracy_no_vsync_capture", tracy_no_vsync_capture);
|
||||
options.addOption(bool, "tracy_no_frame_image", tracy_no_frame_image);
|
||||
options.addOption(bool, "tracy_no_system_tracing", tracy_no_system_tracing);
|
||||
options.addOption(bool, "tracy_delayed_init", tracy_delayed_init);
|
||||
options.addOption(bool, "tracy_manual_lifetime", tracy_manual_lifetime);
|
||||
options.addOption(bool, "tracy_fibers", tracy_fibers);
|
||||
options.addOption(bool, "tracy_no_crash_handler", tracy_no_crash_handler);
|
||||
options.addOption(bool, "tracy_timer_fallback", tracy_timer_fallback);
|
||||
options.addOption(bool, "shared", shared);
|
||||
|
||||
const dep_src = b.dependency("src", .{});
|
||||
const is_windows = target.result.os.tag == .windows;
|
||||
|
||||
const arena = b.graph.arena;
|
||||
var defines: std.ArrayList(CDefine) = .empty;
|
||||
inline for (.{
|
||||
.{ tracy_enable , "TRACY_ENABLE" , "1" },
|
||||
.{ tracy_on_demand , "TRACY_ON_DEMAND" , "1" },
|
||||
.{ tracy_no_callstack , "TRACY_NO_CALLSTACK" , "1" },
|
||||
.{ tracy_no_callstack_inlines, "TRACY_NO_CALLSTACK_INLINES", "1" },
|
||||
.{ tracy_only_localhost , "TRACY_ONLY_LOCALHOST" , "1" },
|
||||
.{ tracy_no_broadcast , "TRACY_NO_BROADCAST" , "1" },
|
||||
.{ tracy_only_ipv4 , "TRACY_ONLY_IPV4" , "1" },
|
||||
.{ tracy_no_code_transfer , "TRACY_NO_CODE_TRANSFER" , "1" },
|
||||
.{ tracy_no_context_switch , "TRACY_NO_CONTEXT_SWITCH" , "1" },
|
||||
.{ tracy_no_exit , "TRACY_NO_EXIT" , "1" },
|
||||
.{ tracy_no_sampling , "TRACY_NO_SAMPLING" , "1" },
|
||||
.{ tracy_no_verify , "TRACY_NO_VERIFY" , "1" },
|
||||
.{ tracy_no_vsync_capture , "TRACY_NO_VSYNC_CAPTURE" , "1" },
|
||||
.{ tracy_no_frame_image , "TRACY_NO_FRAME_IMAGE" , "1" },
|
||||
.{ tracy_no_system_tracing , "TRACY_NO_SYSTEM_TRACING" , "1" },
|
||||
.{ tracy_delayed_init , "TRACY_DELAYED_INIT" , "1" },
|
||||
.{ tracy_manual_lifetime , "TRACY_MANUAL_LIFETIME" , "1" },
|
||||
.{ tracy_fibers , "TRACY_FIBERS" , "1" },
|
||||
.{ tracy_no_crash_handler , "TRACY_NO_CRASH_HANDLER" , "1" },
|
||||
.{ tracy_timer_fallback , "TRACY_TIMER_FALLBACK" , "1" },
|
||||
}) |entry| {
|
||||
const condition = entry[0];
|
||||
const name = entry[1];
|
||||
const value = entry[2];
|
||||
if (condition) {
|
||||
try defines.append(arena, .{ .name = name, .value = value });
|
||||
}
|
||||
}
|
||||
if (tracy_callstack) |depth| {
|
||||
try defines.append(arena, .{ .name = "TRACY_CALLSTACK", .value = "\"" ++ digits2(depth) ++ "\"" });
|
||||
}
|
||||
|
||||
{
|
||||
const tracy_module = b.addModule("tracy", .{
|
||||
.root_source_file = b.path("src/root.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
|
||||
tracy_module.addImport("tracy-options", options.createModule());
|
||||
tracy_module.addIncludePath(dep_src.path("./public"));
|
||||
const options = b.addOptions();
|
||||
options.addOption(bool, "tracy_enable", tracy_enable);
|
||||
options.addOption(?u8, "tracy_callstack", tracy_callstack);
|
||||
options.addOption(bool, "tracy_no_callstack", tracy_no_callstack);
|
||||
options.addOption(bool, "tracy_fibers", tracy_fibers);
|
||||
tracy_module.addImport("options", options.createModule());
|
||||
|
||||
const write_file_step = b.addWriteFiles();
|
||||
const translate_c = b.addTranslateC(.{
|
||||
.root_source_file = write_file_step.add("c.h", "#include <tracy/TracyC.h>"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
translate_c.addIncludePath(dep_src.path("./public"));
|
||||
if (shared and is_windows) {
|
||||
translate_c.defineCMacro("TRACY_IMPORTS", "1");
|
||||
}
|
||||
for (defines.items) |define| {
|
||||
translate_c.defineCMacro(define.name, define.value);
|
||||
}
|
||||
tracy_module.addImport("c", translate_c.createModule());
|
||||
}
|
||||
|
||||
{
|
||||
const mod = b.createModule(.{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
|
||||
if (is_windows) {
|
||||
mod.linkSystemLibrary("dbghelp", .{});
|
||||
mod.linkSystemLibrary("ws2_32", .{});
|
||||
}
|
||||
if (target.result.abi != .msvc) {
|
||||
mod.link_libcpp = true;
|
||||
} else {
|
||||
mod.link_libc = true;
|
||||
}
|
||||
mod.addCSourceFile(.{
|
||||
.file = dep_src.path("./public/TracyClient.cpp"),
|
||||
.flags = if (is_windows) &.{"-fms-extensions"} else &.{},
|
||||
});
|
||||
if (shared and is_windows) {
|
||||
mod.addCMacro("TRACY_EXPORTS", "1");
|
||||
}
|
||||
for (defines.items) |define| {
|
||||
mod.addCMacro(define.name, define.value);
|
||||
}
|
||||
|
||||
const tracy_client = b.addLibrary(.{
|
||||
.linkage = if (shared) .dynamic else .static,
|
||||
.name = "tracy",
|
||||
.root_module = b.createModule(.{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
}),
|
||||
});
|
||||
|
||||
if (target.result.os.tag == .windows) {
|
||||
tracy_client.root_module.linkSystemLibrary("dbghelp", .{});
|
||||
tracy_client.root_module.linkSystemLibrary("ws2_32", .{});
|
||||
}
|
||||
if (target.result.abi != .msvc) {
|
||||
tracy_client.root_module.link_libcpp = true;
|
||||
} else {
|
||||
tracy_client.root_module.link_libc = true;
|
||||
}
|
||||
tracy_client.root_module.addCSourceFile(.{
|
||||
.file = dep_src.path("./public/TracyClient.cpp"),
|
||||
.flags = if (target.result.os.tag == .windows) &.{"-fms-extensions"} else &.{},
|
||||
.root_module = mod
|
||||
});
|
||||
tracy_client.installHeadersDirectory(dep_src.path("public"), "", .{
|
||||
.include_extensions = &.{".h", ".hpp"},
|
||||
});
|
||||
if (tracy_enable)
|
||||
tracy_client.root_module.addCMacro("TRACY_ENABLE", "1");
|
||||
if (tracy_on_demand)
|
||||
tracy_client.root_module.addCMacro("TRACY_ON_DEMAND", "1");
|
||||
if (tracy_callstack) |depth| {
|
||||
tracy_client.root_module.addCMacro("TRACY_CALLSTACK", "\"" ++ digits2(depth) ++ "\"");
|
||||
}
|
||||
if (tracy_no_callstack)
|
||||
tracy_client.root_module.addCMacro("TRACY_NO_CALLSTACK", "1");
|
||||
if (tracy_no_callstack_inlines)
|
||||
tracy_client.root_module.addCMacro("TRACY_NO_CALLSTACK_INLINES", "1");
|
||||
if (tracy_only_localhost)
|
||||
tracy_client.root_module.addCMacro("TRACY_ONLY_LOCALHOST", "1");
|
||||
if (tracy_no_broadcast)
|
||||
tracy_client.root_module.addCMacro("TRACY_NO_BROADCAST", "1");
|
||||
if (tracy_only_ipv4)
|
||||
tracy_client.root_module.addCMacro("TRACY_ONLY_IPV4", "1");
|
||||
if (tracy_no_code_transfer)
|
||||
tracy_client.root_module.addCMacro("TRACY_NO_CODE_TRANSFER", "1");
|
||||
if (tracy_no_context_switch)
|
||||
tracy_client.root_module.addCMacro("TRACY_NO_CONTEXT_SWITCH", "1");
|
||||
if (tracy_no_exit)
|
||||
tracy_client.root_module.addCMacro("TRACY_NO_EXIT", "1");
|
||||
if (tracy_no_sampling)
|
||||
tracy_client.root_module.addCMacro("TRACY_NO_SAMPLING", "1");
|
||||
if (tracy_no_verify)
|
||||
tracy_client.root_module.addCMacro("TRACY_NO_VERIFY", "1");
|
||||
if (tracy_no_vsync_capture)
|
||||
tracy_client.root_module.addCMacro("TRACY_NO_VSYNC_CAPTURE", "1");
|
||||
if (tracy_no_frame_image)
|
||||
tracy_client.root_module.addCMacro("TRACY_NO_FRAME_IMAGE", "1");
|
||||
if (tracy_no_system_tracing)
|
||||
tracy_client.root_module.addCMacro("TRACY_NO_SYSTEM_TRACING", "1");
|
||||
if (tracy_delayed_init)
|
||||
tracy_client.root_module.addCMacro("TRACY_DELAYED_INIT", "1");
|
||||
if (tracy_manual_lifetime)
|
||||
tracy_client.root_module.addCMacro("TRACY_MANUAL_LIFETIME", "1");
|
||||
if (tracy_fibers)
|
||||
tracy_client.root_module.addCMacro("TRACY_FIBERS", "1");
|
||||
if (tracy_no_crash_handler)
|
||||
tracy_client.root_module.addCMacro("TRACY_NO_CRASH_HANDLER", "1");
|
||||
if (tracy_timer_fallback)
|
||||
tracy_client.root_module.addCMacro("TRACY_TIMER_FALLBACK", "1");
|
||||
if (shared and target.result.os.tag == .windows)
|
||||
tracy_client.root_module.addCMacro("TRACY_EXPORTS", "1");
|
||||
b.installArtifact(tracy_client);
|
||||
}
|
||||
}
|
||||
|
||||
const CDefine = struct {
|
||||
name: []const u8,
|
||||
value: []const u8,
|
||||
};
|
||||
|
||||
@ -2,34 +2,9 @@ const std = @import("std");
|
||||
const digits2 = std.fmt.digits2;
|
||||
const builtin = @import("builtin");
|
||||
|
||||
const options = @import("tracy-options");
|
||||
const options = @import("options");
|
||||
|
||||
const c = @cImport({
|
||||
if (options.tracy_enable) @cDefine("TRACY_ENABLE", {});
|
||||
if (options.tracy_on_demand) @cDefine("TRACY_ON_DEMAND", {});
|
||||
if (options.tracy_callstack) |depth| @cDefine("TRACY_CALLSTACK", "\"" ++ digits2(depth) ++ "\"");
|
||||
if (options.tracy_no_callstack) @cDefine("TRACY_NO_CALLSTACK", {});
|
||||
if (options.tracy_no_callstack_inlines) @cDefine("TRACY_NO_CALLSTACK_INLINES", {});
|
||||
if (options.tracy_only_localhost) @cDefine("TRACY_ONLY_LOCALHOST", {});
|
||||
if (options.tracy_no_broadcast) @cDefine("TRACY_NO_BROADCAST", {});
|
||||
if (options.tracy_only_ipv4) @cDefine("TRACY_ONLY_IPV4", {});
|
||||
if (options.tracy_no_code_transfer) @cDefine("TRACY_NO_CODE_TRANSFER", {});
|
||||
if (options.tracy_no_context_switch) @cDefine("TRACY_NO_CONTEXT_SWITCH", {});
|
||||
if (options.tracy_no_exit) @cDefine("TRACY_NO_EXIT", {});
|
||||
if (options.tracy_no_sampling) @cDefine("TRACY_NO_SAMPLING", {});
|
||||
if (options.tracy_no_verify) @cDefine("TRACY_NO_VERIFY", {});
|
||||
if (options.tracy_no_vsync_capture) @cDefine("TRACY_NO_VSYNC_CAPTURE", {});
|
||||
if (options.tracy_no_frame_image) @cDefine("TRACY_NO_FRAME_IMAGE", {});
|
||||
if (options.tracy_no_system_tracing) @cDefine("TRACY_NO_SYSTEM_TRACING", {});
|
||||
if (options.tracy_delayed_init) @cDefine("TRACY_DELAYED_INIT", {});
|
||||
if (options.tracy_manual_lifetime) @cDefine("TRACY_MANUAL_LIFETIME", {});
|
||||
if (options.tracy_fibers) @cDefine("TRACY_FIBERS", {});
|
||||
if (options.tracy_no_crash_handler) @cDefine("TRACY_NO_CRASH_HANDLER", {});
|
||||
if (options.tracy_timer_fallback) @cDefine("TRACY_TIMER_FALLBACK", {});
|
||||
if (options.shared and builtin.os.tag == .windows) @cDefine("TRACY_IMPORTS", {});
|
||||
|
||||
@cInclude("tracy/TracyC.h");
|
||||
});
|
||||
const c = @import("c");
|
||||
|
||||
pub inline fn setThreadName(comptime name: [:0]const u8) void {
|
||||
if (!options.tracy_enable) return;
|
||||
|
||||
31
scripts/create-win32-resource.zig
Normal file
31
scripts/create-win32-resource.zig
Normal file
@ -0,0 +1,31 @@
|
||||
const std = @import("std");
|
||||
const Io = std.Io;
|
||||
|
||||
pub fn main(init: std.process.Init) !void {
|
||||
const io = init.io;
|
||||
const arena = init.arena.allocator();
|
||||
const args = try init.minimal.args.toSlice(arena);
|
||||
|
||||
if (args.len != 3) {
|
||||
std.debug.print("Usage: ./create-win32-resource-file <icon> <output>", .{});
|
||||
std.process.exit(1);
|
||||
}
|
||||
|
||||
const icon_file_path = args[1];
|
||||
const output_file_path = args[2];
|
||||
|
||||
const cwd = Io.Dir.cwd();
|
||||
|
||||
const output_file = try cwd.createFile(io, output_file_path, .{});
|
||||
defer output_file.close(io);
|
||||
|
||||
var buff: [4*4096]u8 = undefined;
|
||||
var file_writer = output_file.writer(io, &buff);
|
||||
const writer = &file_writer.interface;
|
||||
|
||||
try writer.writeAll("IDI_ICON ICON \"");
|
||||
try writer.writeAll(icon_file_path);
|
||||
try writer.writeAll("\"");
|
||||
|
||||
try writer.flush();
|
||||
}
|
||||
@ -1,27 +1,26 @@
|
||||
const std = @import("std");
|
||||
const Io = std.Io;
|
||||
const STBImage = @import("stb_image");
|
||||
|
||||
// https://en.wikipedia.org/wiki/ICO_(file_format)#Icon_file_structure
|
||||
|
||||
pub fn main() !void {
|
||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||
const allocator = gpa.allocator();
|
||||
defer _ = gpa.deinit();
|
||||
|
||||
const args = try std.process.argsAlloc(allocator);
|
||||
defer std.process.argsFree(allocator, args);
|
||||
pub fn main(init: std.process.Init) !void {
|
||||
const io = init.io;
|
||||
const gpa = init.gpa;
|
||||
const arena = init.arena.allocator();
|
||||
const args = try init.minimal.args.toSlice(arena);
|
||||
|
||||
if (args.len != 3) {
|
||||
std.debug.print("Usage: ./png-to-icon <png-file> <output-ico>", .{});
|
||||
std.process.exit(1);
|
||||
}
|
||||
|
||||
const cwd = std.fs.cwd();
|
||||
const cwd = Io.Dir.cwd();
|
||||
const input_png_path = args[1];
|
||||
const output_ico_path = args[2];
|
||||
|
||||
const input_png_data = try cwd.readFileAlloc(allocator, input_png_path, 1024 * 1024 * 5);
|
||||
defer allocator.free(input_png_data);
|
||||
const input_png_data = try cwd.readFileAlloc(io, input_png_path, gpa, .unlimited);
|
||||
defer gpa.free(input_png_data);
|
||||
|
||||
const png_image = try STBImage.load(input_png_data);
|
||||
defer png_image.deinit();
|
||||
@ -29,29 +28,30 @@ pub fn main() !void {
|
||||
std.debug.assert(png_image.width > 0 and png_image.width <= 256);
|
||||
std.debug.assert(png_image.height > 0 and png_image.height <= 256);
|
||||
|
||||
const output_ico_file = try std.fs.cwd().createFile(output_ico_path, .{ });
|
||||
defer output_ico_file.close();
|
||||
const output_ico_file = try cwd.createFile(io, output_ico_path, .{});
|
||||
defer output_ico_file.close(io);
|
||||
|
||||
var buffer: [4096 * 4]u8 = undefined;
|
||||
var writer = output_ico_file.writer(&buffer);
|
||||
var file_writer = output_ico_file.writer(io, &buffer);
|
||||
const writer = &file_writer.interface;
|
||||
|
||||
// ICONDIR structure
|
||||
try writer.interface.writeInt(u16, 0, .little); // Must always be zero
|
||||
try writer.interface.writeInt(u16, 1, .little); // Image type. 1 for .ICO
|
||||
try writer.interface.writeInt(u16, 1, .little); // Number of images
|
||||
try writer.writeInt(u16, 0, .little); // Must always be zero
|
||||
try writer.writeInt(u16, 1, .little); // Image type. 1 for .ICO
|
||||
try writer.writeInt(u16, 1, .little); // Number of images
|
||||
|
||||
// ICONDIRENTRY structure
|
||||
try writer.interface.writeInt(u8, @truncate(png_image.width), .little); // Image width
|
||||
try writer.interface.writeInt(u8, @truncate(png_image.height), .little); // Image height
|
||||
try writer.interface.writeInt(u8, 0, .little); // Number of colors in color pallete. 0 means that color pallete is not used
|
||||
try writer.interface.writeInt(u8, 0, .little); // Must always be zero
|
||||
try writer.interface.writeInt(u16, 0, .little); // Color plane
|
||||
try writer.interface.writeInt(u16, 32, .little); // Bits per pixel
|
||||
try writer.interface.writeInt(u32, @intCast(input_png_data.len), .little); // Image size in bytes
|
||||
try writer.interface.writeInt(u32, 22, .little); // Offset to image data from the start
|
||||
try writer.writeInt(u8, @truncate(png_image.width), .little); // Image width
|
||||
try writer.writeInt(u8, @truncate(png_image.height), .little); // Image height
|
||||
try writer.writeInt(u8, 0, .little); // Number of colors in color pallete. 0 means that color pallete is not used
|
||||
try writer.writeInt(u8, 0, .little); // Must always be zero
|
||||
try writer.writeInt(u16, 0, .little); // Color plane
|
||||
try writer.writeInt(u16, 32, .little); // Bits per pixel
|
||||
try writer.writeInt(u32, @intCast(input_png_data.len), .little); // Image size in bytes
|
||||
try writer.writeInt(u32, 22, .little); // Offset to image data from the start
|
||||
|
||||
// PNG image data
|
||||
try writer.interface.writeAll(input_png_data);
|
||||
try writer.interface.flush();
|
||||
try writer.writeAll(input_png_data);
|
||||
try writer.flush();
|
||||
}
|
||||
|
||||
|
||||
@ -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));
|
||||
|
||||
@ -91,7 +91,7 @@ pub fn init(gpa: std.mem.Allocator, logger: sg.Logger) !void {
|
||||
.primitive_type = .TRIANGLES,
|
||||
.index_type = .UINT16,
|
||||
.colors = init: {
|
||||
var s: [8]sg.ColorTargetState = [_]sg.ColorTargetState{.{}} ** 8;
|
||||
var s: [8]sg.ColorTargetState = @splat(.{});
|
||||
s[0] = .{
|
||||
.blend = .{
|
||||
.enabled = true,
|
||||
@ -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| {
|
||||
@ -1270,8 +1271,8 @@ pub const Image = struct {
|
||||
|
||||
pub fn maxPixelSize() usize {
|
||||
var result: usize = 0;
|
||||
for (@typeInfo(Image.Format).@"enum".fields) |field| {
|
||||
const pixel_size = Image.Format.pixelSize(@enumFromInt(field.value));
|
||||
for (@typeInfo(Image.Format).@"enum".field_values) |field_value| {
|
||||
const pixel_size = Image.Format.pixelSize(@enumFromInt(field_value));
|
||||
result = @max(result, pixel_size);
|
||||
}
|
||||
return result;
|
||||
|
||||
@ -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,26 +618,27 @@ 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;
|
||||
|
||||
var assets_dir: ?Io.Dir = null;
|
||||
if (build_options.assets_dir) |assets_dir_path| {
|
||||
if (@hasDecl(build_options, "assets_dir")) {
|
||||
const cwd = Io.Dir.cwd();
|
||||
assets_dir = cwd.openDir(io, assets_dir_path, .{}) catch |e| blk: {
|
||||
assets_dir = cwd.openDir(io, build_options.assets_dir, .{}) catch |e| blk: {
|
||||
log.err("Failed to open assets directory: {}", .{e});
|
||||
break :blk null;
|
||||
};
|
||||
}
|
||||
|
||||
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