Compare commits
23
Commits
06599a564f
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
077ceb810e | ||
|
|
35bbc5cbfd | ||
|
|
5a79ae71c0 | ||
|
|
29c136d34c | ||
|
|
9a5c15e47e | ||
|
|
5864401129 | ||
|
|
5eba80a6c6 | ||
|
|
395320a794 | ||
|
|
bab331083e | ||
|
|
fb238a1966 | ||
|
|
c6fdd68afe | ||
|
|
ee790cf700 | ||
|
|
510c19fbd5 | ||
|
|
b91bce8840 | ||
|
|
e6d8607d3f | ||
|
|
719973ad19 | ||
|
|
49ce31ee2e | ||
|
|
6d69fa8898 | ||
|
|
c41f8866d9 | ||
|
|
a06333f66f | ||
|
|
2d778ef20e | ||
|
|
c36b868f46 | ||
|
|
1384a4ba57 |
No files matched your search
Vendored
+13
-2
@@ -5,7 +5,7 @@
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "(lldb) Launch",
|
||||
"name": "Client",
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/zig-out/bin/client",
|
||||
@@ -13,7 +13,18 @@
|
||||
"cwd": "${workspaceFolder}",
|
||||
"internalConsoleOptions": "openOnSessionStart",
|
||||
"preLaunchTask": "build",
|
||||
"sourceLanguages": ["zig"]
|
||||
"sourceLanguages": ["zig"],
|
||||
},
|
||||
{
|
||||
"name": "Server",
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/zig-out/bin/server",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"internalConsoleOptions": "openOnSessionStart",
|
||||
"preLaunchTask": "build",
|
||||
"sourceLanguages": ["zig"],
|
||||
}
|
||||
]
|
||||
}
|
||||
Vendored
+13
-1
@@ -6,7 +6,19 @@
|
||||
{
|
||||
"label": "build",
|
||||
"type": "shell",
|
||||
"command": "zig build",
|
||||
"command": "zig",
|
||||
"args": ["build"],
|
||||
"options": {
|
||||
"cwd": "${workspaceRoot}"
|
||||
},
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "always",
|
||||
"focus": false,
|
||||
"panel": "shared",
|
||||
"showReuseMessage": true,
|
||||
"clear": true,
|
||||
},
|
||||
"problemMatcher": [],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const raylib_src = @import("raylib");
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
const target = b.standardTargetOptions(.{ .default_target = .{ .cpu_model = .native } });
|
||||
const optimize = b.standardOptimizeOption(.{ .preferred_optimize_mode = .ReleaseFast });
|
||||
const target = b.standardTargetOptions(.{
|
||||
.default_target = if (builtin.target.os.tag == .windows)
|
||||
.{ .os_tag = .windows, .abi = .msvc }
|
||||
else
|
||||
.{},
|
||||
});
|
||||
|
||||
const optimize = b.standardOptimizeOption(.{ .preferred_optimize_mode = .Debug });
|
||||
|
||||
const assets = b.addInstallDirectory(.{
|
||||
.source_dir = b.path("assets"),
|
||||
@@ -24,13 +32,12 @@ pub fn build(b: *std.Build) void {
|
||||
.imports = &.{
|
||||
.{
|
||||
.name = "shared",
|
||||
.module = shared
|
||||
.module = shared,
|
||||
},
|
||||
},
|
||||
}),
|
||||
.use_llvm = true,
|
||||
});
|
||||
client.root_module.strip = true;
|
||||
|
||||
const server = b.addExecutable(.{
|
||||
.name = "server",
|
||||
@@ -39,130 +46,162 @@ pub fn build(b: *std.Build) void {
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.imports = &.{
|
||||
.{ .name = "shared", .module = shared },
|
||||
.{
|
||||
.name = "shared",
|
||||
.module = shared,
|
||||
},
|
||||
},
|
||||
}),
|
||||
.use_llvm = true,
|
||||
});
|
||||
server.root_module.strip = true;
|
||||
|
||||
const ztracy = b.dependency(
|
||||
"ztracy",
|
||||
.{
|
||||
.enable_ztracy = true,
|
||||
.enable_fibers = false,
|
||||
.on_demand = false,
|
||||
}
|
||||
);
|
||||
client.root_module.addImport("ztracy", ztracy.module("root"));
|
||||
client.linkLibrary(ztracy.artifact("tracy"));
|
||||
// tracy
|
||||
{
|
||||
const tracy = b.dependency(
|
||||
"tracy",
|
||||
.{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.enable_tracy = true,
|
||||
.enable_fibers = false,
|
||||
.on_demand = false,
|
||||
},
|
||||
);
|
||||
client.root_module.addImport("tracy", tracy.module("tracy"));
|
||||
}
|
||||
|
||||
const mach_freetype = b.dependency("mach_freetype", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
client.root_module.addImport("mach-freetype", mach_freetype.module("mach-freetype"));
|
||||
client.root_module.addImport("mach-harfbuzz", mach_freetype.module("mach-harfbuzz"));
|
||||
// freetype
|
||||
{
|
||||
const freetype = b.dependency(
|
||||
"freetype",
|
||||
.{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
}
|
||||
);
|
||||
client.root_module.addImport("freetype", freetype.module("freetype"));
|
||||
}
|
||||
|
||||
client.root_module.addCSourceFile(.{
|
||||
.file = b.path("vendor/kb_text_shape/kb_text_shape.h"),
|
||||
.language = .c,
|
||||
.flags = &.{
|
||||
"-DKB_TEXT_SHAPE_IMPLEMENTATION",
|
||||
"-O3", // Maximum optimization
|
||||
// "-ffast-math", // Allows algebraic reorganizations (risky for precision, great for speed)
|
||||
// "-fno-plt", // Reduces overhead for library calls
|
||||
// "-march=native", // Use every instruction your CPU has
|
||||
// "-flto", // Enable LTO for the C side specifically
|
||||
},
|
||||
});
|
||||
const kb_text_shape = b.addTranslateC(.{
|
||||
.root_source_file = b.path("vendor/kb_text_shape/kb_text_shape.h"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
client.root_module.addImport("kb", kb_text_shape.createModule());
|
||||
|
||||
client.root_module.addCSourceFile(.{ .file = b.path("vendor/stb/stb_rect_pack.h"), .language = .c, .flags = &.{} });
|
||||
const stb_rect_pack = b.addTranslateC(.{
|
||||
.root_source_file = b.path("vendor/stb/stb_rect_pack.h"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
client.root_module.addImport("stb_rect_pack", stb_rect_pack.createModule());
|
||||
|
||||
const zmath = b.dependency(
|
||||
"zmath",
|
||||
.{
|
||||
// kb_text_shape
|
||||
{
|
||||
client.root_module.addCSourceFile(.{
|
||||
.file = b.path("vendor/kb_text_shape/kb_text_shape.h"),
|
||||
.language = .c,
|
||||
.flags = &.{
|
||||
"-DKB_TEXT_SHAPE_IMPLEMENTATION",
|
||||
"-O3", // Maximum optimization
|
||||
// "-ffast-math", // Allows algebraic reorganizations (risky for precision, great for speed)
|
||||
// "-fno-plt", // Reduces overhead for library calls
|
||||
// "-march=native", // Use every instruction your CPU has
|
||||
// "-flto", // Enable LTO for the C side specifically
|
||||
},
|
||||
});
|
||||
const kb_text_shape = b.addTranslateC(.{
|
||||
.root_source_file = b.path("vendor/kb_text_shape/kb_text_shape.h"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
}
|
||||
);
|
||||
client.root_module.addImport("zmath", zmath.module("root"));
|
||||
server.root_module.addImport("zmath", zmath.module("root"));
|
||||
shared.addImport("zmath", zmath.module("root"));
|
||||
});
|
||||
client.root_module.addImport("kb", kb_text_shape.createModule());
|
||||
}
|
||||
|
||||
const znet = b.dependency(
|
||||
"znet",
|
||||
.{
|
||||
// stb_rect_pack
|
||||
{
|
||||
client.root_module.addCSourceFile(.{ .file = b.path("vendor/stb/stb_rect_pack.h"), .language = .c, .flags = &.{} });
|
||||
const stb_rect_pack = b.addTranslateC(.{
|
||||
.root_source_file = b.path("vendor/stb/stb_rect_pack.h"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
}
|
||||
);
|
||||
client.root_module.addImport("znet", znet.module("znet"));
|
||||
server.root_module.addImport("znet", znet.module("znet"));
|
||||
});
|
||||
client.root_module.addImport("stb_rect_pack", stb_rect_pack.createModule());
|
||||
}
|
||||
|
||||
const bufzilla = b.dependency(
|
||||
"bufzilla",
|
||||
.{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
client.root_module.addImport("bufzilla", bufzilla.module("bufzilla"));
|
||||
server.root_module.addImport("bufzilla", bufzilla.module("bufzilla"));
|
||||
// zmath
|
||||
{
|
||||
const zmath = b.dependency(
|
||||
"zmath",
|
||||
.{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
}
|
||||
);
|
||||
client.root_module.addImport("zmath", zmath.module("root"));
|
||||
server.root_module.addImport("zmath", zmath.module("root"));
|
||||
shared.addImport("zmath", zmath.module("root"));
|
||||
}
|
||||
|
||||
const raylib_dep = b.dependency("raylib_zig", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
|
||||
const raylib = raylib_dep.module("raylib"); // main raylib module
|
||||
const raygui = raylib_dep.module("raygui"); // raygui module
|
||||
const raylib_artifact = raylib_dep.artifact("raylib"); // raylib C library
|
||||
raylib_artifact.root_module.addCMacro("SUPPORT_CUSTOM_FRAME_CONTROL", "");
|
||||
// ENet
|
||||
{
|
||||
const enet = b.dependency("enet", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
|
||||
client.linkLibrary(raylib_artifact);
|
||||
client.root_module.addImport("raylib", raylib);
|
||||
client.root_module.addImport("raygui", raygui);
|
||||
// shared.linkLibrary(enet.artifact("enet"));
|
||||
client.root_module.linkLibrary(enet.artifact("enet"));
|
||||
server.root_module.linkLibrary(enet.artifact("enet"));
|
||||
}
|
||||
|
||||
// // Bufzilla
|
||||
// {
|
||||
// const bufzilla = b.dependency(
|
||||
// "bufzilla",
|
||||
// .{
|
||||
// .target = target,
|
||||
// .optimize = optimize,
|
||||
// });
|
||||
// shared.addImport("bufzilla", bufzilla.module("bufzilla"));
|
||||
// client.root_module.addImport("bufzilla", bufzilla.module("bufzilla"));
|
||||
// server.root_module.addImport("bufzilla", bufzilla.module("bufzilla"));
|
||||
// }
|
||||
|
||||
// Raylib
|
||||
{
|
||||
const raylib_dep = b.dependency("raylib", .{ .target = target, .optimize = optimize });
|
||||
|
||||
const raylib_lib = raylib_dep.artifact("raylib");
|
||||
raylib_lib.root_module.addCMacro("SUPPORT_CUSTOM_FRAME_CONTROL", "");
|
||||
|
||||
client.root_module.linkLibrary(raylib_lib);
|
||||
|
||||
if (target.result.os.tag == .windows)
|
||||
client.root_module.linkSystemLibrary("shell32", .{ .needed = true });
|
||||
}
|
||||
|
||||
client.root_module.link_libc = true;
|
||||
server.root_module.link_libc = true;
|
||||
|
||||
b.installArtifact(client);
|
||||
b.installArtifact(server);
|
||||
|
||||
b.getInstallStep().dependOn(&assets.step);
|
||||
|
||||
const run_step = b.step("run", "Run the app");
|
||||
const run_client_step = b.step("run-client", "Run the client");
|
||||
const run_server_step = b.step("run-server", "Run the server");
|
||||
|
||||
const run_cmd_client = b.addRunArtifact(client);
|
||||
const run_cmd_server = b.addRunArtifact(server);
|
||||
run_step.dependOn(&run_cmd_client.step);
|
||||
run_step.dependOn(&run_cmd_server.step);
|
||||
run_client_step.dependOn(&run_cmd_client.step);
|
||||
run_server_step.dependOn(&run_cmd_server.step);
|
||||
|
||||
run_cmd_client.step.dependOn(b.getInstallStep());
|
||||
run_cmd_server.step.dependOn(b.getInstallStep());
|
||||
|
||||
if (b.args) |args| {
|
||||
run_cmd_client.addArgs(args);
|
||||
run_cmd_server.addArgs(args);
|
||||
}
|
||||
|
||||
// Creates an executable that will run `test` blocks from the provided module.
|
||||
// Here `mod` needs to define a target, which is why earlier we made sure to
|
||||
// set the releative field.
|
||||
// const mod_tests = b.addTest(.{
|
||||
// .root_module = mod,
|
||||
// });
|
||||
const shared_tests = b.addTest(.{
|
||||
.root_module = shared,
|
||||
.use_llvm = true,
|
||||
});
|
||||
|
||||
// A run step that will run the test executable.
|
||||
// const run_mod_tests = b.addRunArtifact(mod_tests);
|
||||
const run_shared_tests = b.addRunArtifact(shared_tests);
|
||||
|
||||
// Creates an executable that will run `test` blocks from the executable's
|
||||
// root module. Note that test executables only test one module at a time,
|
||||
@@ -177,8 +216,8 @@ pub fn build(b: *std.Build) void {
|
||||
// A top level step for running all tests. dependOn can be called multiple
|
||||
// times and since the two run steps do not depend on one another, this will
|
||||
// make the two of them run in parallel.
|
||||
// const test_step = b.step("test", "Run tests");
|
||||
// test_step.dependOn(&run_mod_tests.step);
|
||||
const test_step = b.step("test", "Run tests");
|
||||
test_step.dependOn(&run_shared_tests.step);
|
||||
// test_step.dependOn(&run_exe_tests.step);
|
||||
|
||||
// Just like flags, top level steps are also listed in the `--help` menu.
|
||||
@@ -193,3 +232,37 @@ pub fn build(b: *std.Build) void {
|
||||
// Lastly, the Zig build system is relatively simple and self-contained,
|
||||
// and reading its source code will allow you to master it.
|
||||
}
|
||||
|
||||
fn getRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, options: raylib_src.Options) *std.Build.Step.Compile {
|
||||
const raylib_dep = b.dependency("raylib", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.raudio = options.raudio,
|
||||
.rmodels = options.rmodels,
|
||||
.rshapes = options.rshapes,
|
||||
.rtext = options.rtext,
|
||||
.rtextures = options.rtextures,
|
||||
.platform = options.platform,
|
||||
.linkage = options.linkage,
|
||||
.linux_display_backend = options.linux_display_backend,
|
||||
.opengl_version = options.opengl_version,
|
||||
.android_api_version = options.android_api_version,
|
||||
.android_ndk = options.android_ndk,
|
||||
});
|
||||
|
||||
const raylib = raylib_dep.artifact("raylib");
|
||||
|
||||
b.installArtifact(raylib);
|
||||
return raylib;
|
||||
}
|
||||
|
||||
fn getModule(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode) *std.Build.Module {
|
||||
if (b.modules.contains("raylib")) {
|
||||
return b.modules.get("raylib").?;
|
||||
}
|
||||
return b.addModule("raylib", .{
|
||||
.root_source_file = b.path("lib/raylib.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
}
|
||||
+12
-15
@@ -40,25 +40,22 @@
|
||||
.url = "git+https://github.com/Gota7/zig-sdl3?ref=master#79b0d1f1ef10a424037025f6af44fe06bf7e062c",
|
||||
.hash = "sdl3-0.1.5-NmT1Q3ARJgDmFWtbbK3KBb7vufbQD0EjD4Me4Fbdq0p3",
|
||||
},
|
||||
.raylib_zig = .{
|
||||
.url = "git+https://github.com/raylib-zig/raylib-zig#7d4761b878f43671024ce197f721827b5355a67e",
|
||||
.hash = "raylib_zig-5.6.0-dev-KE8REGlNBQDR7NML06VBtT7gP3VZNY70E5WohAxzqrNn",
|
||||
},
|
||||
.znet = .{
|
||||
.url = "git+https://github.com/connellr023/znet#cb11fb0c4a2b668128c436fbbccd111223c74898",
|
||||
.hash = "znet-0.0.0-PGDNtD9RAAChe8Ky4dhWhS2XH77-xyf1X8HcDBwpM3kA",
|
||||
.enet = .{
|
||||
.path = "vendor/enet",
|
||||
},
|
||||
.bufzilla = .{
|
||||
.url = "https://github.com/theseyan/bufzilla/archive/refs/tags/v0.3.2.tar.gz",
|
||||
.hash = "bufzilla-0.3.0-gU6dXi67AQAg3WIFrNQ0iafrvexj3iBwVcczrVzrN3Ir",
|
||||
.url = "https://github.com/theseyan/bufzilla/archive/refs/tags/v0.3.3.tar.gz",
|
||||
.hash = "bufzilla-0.3.0-gU6dXie7AQDTXB7ptRjLa1plj3txaUVKFvT39e3v-pop",
|
||||
},
|
||||
.ztracy = .{
|
||||
.url = "git+https://github.com/zig-gamedev/ztracy#d95d2a193b9f97944a17026c9a42b5d0f9a88c94",
|
||||
.hash = "ztracy-0.14.0-dev-zHJSqzUHGQAmhJybhlwtl1QKevUBw4M5YKZqPfWx2y99",
|
||||
.tracy = .{
|
||||
.path = "vendor/tracy",
|
||||
},
|
||||
.mach_freetype = .{
|
||||
.url = "git+https://github.com/hexops/mach-freetype#44f481e3435592810a7c55fc2f37e470dcba2a9c",
|
||||
.hash = "mach_freetype-0.0.0-AAAAAG4nCAANuVIO0Lmyh-H-eN2d60k-xlxIW_Xv90jq",
|
||||
.freetype = .{
|
||||
.path = "vendor/freetype",
|
||||
},
|
||||
.raylib = .{
|
||||
.url = "git+https://github.com/raysan5/raylib/#403c2cbccff44cac0c0bbae034c00191eeee7b4c",
|
||||
.hash = "raylib-5.6.0-dev-whq8uKAqDQWosMsUzhDBAbuDSmbxaqJeydmpgv5e8wzU",
|
||||
},
|
||||
},
|
||||
.paths = .{
|
||||
|
||||
@@ -3,3 +3,13 @@ pub const c = @cImport({
|
||||
@cInclude("raymath.h");
|
||||
@cInclude("rlgl.h");
|
||||
});
|
||||
|
||||
pub const enet = @cImport({
|
||||
@cInclude("enet/enet.h");
|
||||
});
|
||||
|
||||
pub const rl = @cImport({
|
||||
@cInclude("raylib.h");
|
||||
@cInclude("rlgl.h");
|
||||
@cInclude("raymath.h");
|
||||
});
|
||||
@@ -0,0 +1,73 @@
|
||||
const std = @import("std");
|
||||
|
||||
const shared = @import("shared");
|
||||
const enet = @import("c.zig").enet;
|
||||
|
||||
pub fn spawn(self: *shared.chunk.Chunk, allocator: std.mem.Allocator, comptime T: type, value: T) !shared.entity.id {
|
||||
std.debug.assert(value.id != shared.entity.INVALID_ID);
|
||||
|
||||
const ptr = try allocator.create(T);
|
||||
errdefer allocator.destroy(ptr);
|
||||
|
||||
ptr.* = value;
|
||||
|
||||
const ref = shared.entity.makeRef(T, ptr);
|
||||
|
||||
try self.entities.append(allocator, ref);
|
||||
|
||||
return ptr.id;
|
||||
}
|
||||
|
||||
pub fn find(self: *shared.chunk.Chunk, id: shared.entity.id) ?shared.entity.Ref {
|
||||
for (self.entities.items) |ref| {
|
||||
switch (ref) {
|
||||
inline else => |ptr| {
|
||||
if (ptr.id == id) {
|
||||
return ref;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
pub fn findT(self: *shared.chunk.Chunk, comptime T: type, id: shared.entity.id) ?*T {
|
||||
for (self.entities.items) |ref| {
|
||||
switch (ref) {
|
||||
inline else => |ptr| {
|
||||
if (ptr.id == id and @TypeOf(ptr) == *T) {
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
pub fn despawn(self: *shared.chunk.Chunk, allocator: std.mem.Allocator, id: shared.entity.id) bool {
|
||||
var i: usize = 0;
|
||||
while (i < self.entities.items.len) {
|
||||
const ref = self.entities.items[i];
|
||||
|
||||
var found = false;
|
||||
|
||||
switch (ref) {
|
||||
inline else => |ptr| {
|
||||
if (ptr.id == id) {
|
||||
allocator.destroy(ptr);
|
||||
found = true;
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
if (found) {
|
||||
_ = self.entities.swapRemove(i);
|
||||
return true;
|
||||
}
|
||||
|
||||
i += 1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
const std = @import("std");
|
||||
const std = @import("std");
|
||||
const shared = @import("shared");
|
||||
|
||||
const ConnectState = union(enum) {
|
||||
disconnected,
|
||||
|
||||
+23
-15
@@ -2,21 +2,29 @@ const rl = @import("raylib");
|
||||
const shared = @import("shared");
|
||||
const zm = @import("zmath");
|
||||
|
||||
pub const Elf = struct {
|
||||
elf: shared.entity.Elf,
|
||||
// pub const Elf = struct {
|
||||
// elf: shared.entity.Elf,
|
||||
|
||||
boy: rl.Texture,
|
||||
// boy: rl.Texture,
|
||||
|
||||
pub fn init() Elf {
|
||||
return .{
|
||||
.elf = .{ .hp = 10, .pos = zm.f32x4(0, 0, 0, 0) },
|
||||
.boy = rl.loadTexture("assets/tile_0000.png") catch unreachable,
|
||||
};
|
||||
}
|
||||
// pub fn init() Elf {
|
||||
// return .{
|
||||
// .elf = .{ .hp = 10, .pos = zm.f32x4(0, 0, 0, 0) },
|
||||
// .boy = rl.loadTexture("assets/tile_0000.png") catch unreachable,
|
||||
// };
|
||||
// }
|
||||
|
||||
pub fn draw(self: *Elf) void {
|
||||
const src = rl.Rectangle.init(0, 0, @floatFromInt(self.boy.width), @floatFromInt(self.boy.height));
|
||||
const dst = rl.Rectangle.init(100 + 100 * zm.cos(@as(f32, @floatCast(rl.getTime()))), 100 + 100 * zm.sin(@as(f32, @floatCast(rl.getTime()))), 2.0 * @as(f32, @floatFromInt(self.boy.width)), 2.0 * @as(f32, @floatFromInt(self.boy.height)));
|
||||
self.boy.drawPro(src, dst, .{ .x = 0, .y = 0 }, 0, .white);
|
||||
}
|
||||
};
|
||||
// pub fn draw(self: *Elf) void {
|
||||
// const src = rl.Rectangle.init(0, 0, @floatFromInt(self.boy.width), @floatFromInt(self.boy.height));
|
||||
// const dst = rl.Rectangle.init(100 + 100 * zm.cos(@as(f32, @floatCast(rl.getTime()))), 100 + 100 * zm.sin(@as(f32, @floatCast(rl.getTime()))), 2.0 * @as(f32, @floatFromInt(self.boy.width)), 2.0 * @as(f32, @floatFromInt(self.boy.height)));
|
||||
// self.boy.drawPro(src, dst, .{ .x = 0, .y = 0 }, 0, .white);
|
||||
// }
|
||||
// };
|
||||
|
||||
pub fn draw_soldier(self: *shared.entity.Soldier) void {
|
||||
|
||||
}
|
||||
|
||||
pub fn draw_alien(self: *shared.entity.Alien) void {
|
||||
|
||||
}
|
||||
+40
-45
@@ -1,10 +1,9 @@
|
||||
const std = @import("std");
|
||||
const rl = @import("raylib");
|
||||
const rl = @import("c.zig").rl;
|
||||
const kb = @import("kb");
|
||||
const ft = @import("mach-freetype");
|
||||
const hb = @import("mach-harfbuzz");
|
||||
const ft = @import("freetype");
|
||||
const rp = @import("stb_rect_pack");
|
||||
const ztracy = @import("ztracy");
|
||||
const tracy = @import("tracy");
|
||||
|
||||
pub var ft_lib : ft.Library = undefined;
|
||||
pub var shader : rl.Shader = undefined;
|
||||
@@ -39,7 +38,6 @@ pub const Font = struct {
|
||||
face : ft.Face,
|
||||
glyphs : std.AutoHashMap(u32, Glyph),
|
||||
kbts_font : kb.kbts_font,
|
||||
// texture : c.Texture2D,
|
||||
texture : rl.Texture2D,
|
||||
kb_file_data : []u8,
|
||||
|
||||
@@ -57,7 +55,7 @@ pub const Font = struct {
|
||||
|
||||
var face = try ft_lib.createFaceMemory(file_data, 0);
|
||||
var glyphs = std.AutoHashMap(u32, Glyph).init(allocator);
|
||||
try face.setCharSize(0, size * 64, 0, 96 * @as(u16, @intFromFloat(rl.getWindowScaleDPI().y)));
|
||||
try face.setCharSize(0, size * 64, 0, 96 * @as(u16, @intFromFloat(rl.GetWindowScaleDPI().y)));
|
||||
try face.selectCharmap(.unicode);
|
||||
|
||||
var rects = try std.ArrayList(rp.stbrp_rect).initCapacity(allocator, 1024);
|
||||
@@ -77,7 +75,7 @@ pub const Font = struct {
|
||||
.width = ATLAS_SIZE,
|
||||
.height = ATLAS_SIZE,
|
||||
.mipmaps = 1,
|
||||
.format = rl.PixelFormat.uncompressed_grayscale,
|
||||
.format = rl.PIXELFORMAT_UNCOMPRESSED_GRAYSCALE,
|
||||
};
|
||||
|
||||
for (0..face.numGlyphs()) |index| {
|
||||
@@ -85,7 +83,7 @@ pub const Font = struct {
|
||||
const bmp = face.glyph().bitmap();
|
||||
|
||||
try rects.append(allocator, .{
|
||||
.id = @intCast(index),//@intCast(face.glyph().glyphIndex()),
|
||||
.id = @intCast(index),
|
||||
.w = @max(1, @as(c_int, @intCast(bmp.width()))),
|
||||
.h = @max(1, @as(c_int, @intCast(bmp.rows()))),
|
||||
.x = 0,
|
||||
@@ -123,12 +121,12 @@ pub const Font = struct {
|
||||
|
||||
const width : i32 = @intCast(bmp.width());
|
||||
const height : i32 = @intCast(bmp.rows());
|
||||
const dpi_width : f32 = @as(f32, @floatFromInt(width)) / rl.getWindowScaleDPI().x;
|
||||
const dpi_height : f32 = @as(f32, @floatFromInt(height)) / rl.getWindowScaleDPI().y;
|
||||
const dpi_width : f32 = @as(f32, @floatFromInt(width)) / rl.GetWindowScaleDPI().x;
|
||||
const dpi_height : f32 = @as(f32, @floatFromInt(height)) / rl.GetWindowScaleDPI().y;
|
||||
const bearing_x : i32 = face.glyph().bitmapLeft();
|
||||
const bearing_y : i32 = face.glyph().bitmapTop();
|
||||
const dpi_bearing_x : f32 = @as(f32, @floatFromInt(bearing_x)) / rl.getWindowScaleDPI().x;
|
||||
const dpi_bearing_y : f32 = @as(f32, @floatFromInt(bearing_y)) / rl.getWindowScaleDPI().y;
|
||||
const dpi_bearing_x : f32 = @as(f32, @floatFromInt(bearing_x)) / rl.GetWindowScaleDPI().x;
|
||||
const dpi_bearing_y : f32 = @as(f32, @floatFromInt(bearing_y)) / rl.GetWindowScaleDPI().y;
|
||||
const descent : i32 = height - bearing_y;
|
||||
const ascent : i32 = height - descent;
|
||||
const dpi_descent : f32 = dpi_height - dpi_bearing_y;
|
||||
@@ -166,7 +164,7 @@ pub const Font = struct {
|
||||
try glyphs.put(glyph.index, glyph);
|
||||
}
|
||||
|
||||
const texture = try rl.loadTextureFromImage(atlas);
|
||||
const texture = rl.LoadTextureFromImage(atlas);
|
||||
|
||||
var kbts_font = kb.kbts_FontFromMemory(kb_file_data.ptr, @intCast(kb_file_data.len), 0, null, null);
|
||||
|
||||
@@ -174,9 +172,6 @@ pub const Font = struct {
|
||||
std.log.info("[Error] [kb_text_shape] Failed to load the font.", .{});
|
||||
}
|
||||
|
||||
const hb_blob = hb.Blob.initFromFile(filename);
|
||||
_ = hb_blob;
|
||||
|
||||
return .{
|
||||
.face = face,
|
||||
.glyphs = glyphs,
|
||||
@@ -190,7 +185,7 @@ pub const Font = struct {
|
||||
self.glyphs.deinit();
|
||||
self.face.deinit();
|
||||
kb.kbts_FreeFont(&self.kbts_font);
|
||||
self.texture.unload();
|
||||
rl.UnloadTexture(self.texture);
|
||||
allocator.free(self.kb_file_data);
|
||||
}
|
||||
|
||||
@@ -207,17 +202,17 @@ pub const Font = struct {
|
||||
if (text.len == 0)
|
||||
return;
|
||||
|
||||
const zone = ztracy.ZoneNC(@src(), "render_text", 0x00_ff_00_00);
|
||||
const zone = tracy.ZoneNC(@src(), "render_text", 0x00_ff_00_00);
|
||||
defer zone.End();
|
||||
|
||||
rl.beginShaderMode(shader);
|
||||
rl.gl.rlSetTexture(self.texture.id);
|
||||
rl.gl.rlBegin(rl.gl.rl_quads);
|
||||
rl.BeginShaderMode(shader);
|
||||
rl.rlSetTexture(self.texture.id);
|
||||
rl.rlBegin(rl.RL_QUADS);
|
||||
|
||||
if (nice_background) {
|
||||
self.render_text(
|
||||
text,
|
||||
pos.add(.{.x = 3.0, .y = -3.0}),
|
||||
rl.Vector2Add(pos, .{.x = 3.0, .y = -3.0}),
|
||||
window_space,
|
||||
rl.Color{ .r = 0, .g = 0, .b = 0, .a = 255 },
|
||||
rl.Color{ .r = 0, .g = 0, .b = 0, .a = 0 },
|
||||
@@ -231,7 +226,7 @@ pub const Font = struct {
|
||||
_ = background;
|
||||
|
||||
const font_ascent : f32 = @floatFromInt(self.face.size().metrics().ascender >> 6);
|
||||
const dpi_font_ascent = font_ascent / rl.getWindowScaleDPI().y;
|
||||
const dpi_font_ascent = font_ascent / rl.GetWindowScaleDPI().y;
|
||||
|
||||
render_pos.y += dpi_font_ascent;
|
||||
|
||||
@@ -243,7 +238,7 @@ pub const Font = struct {
|
||||
return;
|
||||
}
|
||||
|
||||
const zone2 = ztracy.ZoneNC(@src(), "ShapeUtf8", 0x00_ff_00_00);
|
||||
const zone2 = tracy.ZoneNC(@src(), "ShapeUtf8", 0x00_ff_00_00);
|
||||
kb.kbts_ShapeBegin(Context, kb.KBTS_DIRECTION_DONT_KNOW, kb.KBTS_LANGUAGE_DONT_KNOW);
|
||||
kb.kbts_ShapeUtf8(Context, text.ptr, @intCast(text.len), kb.KBTS_USER_ID_GENERATION_MODE_CODEPOINT_INDEX);
|
||||
kb.kbts_ShapeEnd(Context);
|
||||
@@ -254,11 +249,11 @@ pub const Font = struct {
|
||||
|
||||
var Run = kb.kbts_run{};
|
||||
while (my_kbts_ShapeRun(Context, &Run) != 0) {
|
||||
const zone3 = ztracy.ZoneNC(@src(), "shape run", 0x00_ff_00_00);
|
||||
const zone3 = tracy.ZoneNC(@src(), "shape run", 0x00_ff_00_00);
|
||||
defer zone3.End();
|
||||
if ((Run.Flags & kb.KBTS_BREAK_FLAG_LINE_HARD) != 0) {
|
||||
const font_linegap : f32 = @floatFromInt(self.face.size().metrics().height >> 6);
|
||||
const dpi_font_linegap = font_linegap / rl.getWindowScaleDPI().y;
|
||||
const dpi_font_linegap = font_linegap / rl.GetWindowScaleDPI().y;
|
||||
|
||||
cursor_y += dpi_font_linegap;
|
||||
cursor_x = 0;
|
||||
@@ -266,7 +261,7 @@ pub const Font = struct {
|
||||
|
||||
var g : [*c]kb.kbts_glyph = null;
|
||||
while (kb.kbts_GlyphIteratorNext(&Run.Glyphs, &g) != 0) {
|
||||
const zone4 = ztracy.ZoneNC(@src(), "glyph iterator", 0x00_ff_00_00);
|
||||
const zone4 = tracy.ZoneNC(@src(), "glyph iterator", 0x00_ff_00_00);
|
||||
defer zone4.End();
|
||||
const RunGlyph : *kb.kbts_glyph = g.?;
|
||||
const CodepointIndex : i32 = RunGlyph.UserIdOrCodepointIndex;
|
||||
@@ -277,23 +272,23 @@ pub const Font = struct {
|
||||
|
||||
const advance_x : f32 = @floatFromInt(ft.mulFix(RunGlyph.AdvanceX, @intCast(self.face.size().metrics().x_scale)) >> 6);
|
||||
const advance_y : f32 = @floatFromInt(ft.mulFix(RunGlyph.AdvanceY, @intCast(self.face.size().metrics().y_scale)) >> 6);
|
||||
const dpi_advance_x = advance_x / rl.getWindowScaleDPI().x;
|
||||
const dpi_advance_y = advance_y / rl.getWindowScaleDPI().y;
|
||||
const dpi_advance_x = advance_x / rl.GetWindowScaleDPI().x;
|
||||
const dpi_advance_y = advance_y / rl.GetWindowScaleDPI().y;
|
||||
|
||||
const offset_x : f32 = @floatFromInt(ft.mulFix(RunGlyph.OffsetX, @intCast(self.face.size().metrics().x_scale)) >> 6);
|
||||
const offset_y : f32 = @floatFromInt(ft.mulFix(RunGlyph.OffsetY, @intCast(self.face.size().metrics().y_scale)) >> 6);
|
||||
const dpi_offset_x = offset_x / rl.getWindowScaleDPI().x;
|
||||
const dpi_offset_y = offset_y / rl.getWindowScaleDPI().y;
|
||||
const dpi_offset_x = offset_x / rl.GetWindowScaleDPI().x;
|
||||
const dpi_offset_y = offset_y / rl.GetWindowScaleDPI().y;
|
||||
|
||||
if (self.glyphs.getPtr(RunGlyph.Id)) |glyph| {
|
||||
|
||||
var v0 = rl.Vector2.zero();
|
||||
var v1 = rl.Vector2.zero();
|
||||
var v0 = rl.Vector2{};
|
||||
var v1 = rl.Vector2{};
|
||||
|
||||
v0 = render_pos.add(.{ .x = cursor_x + glyph.dpi_bearing_x + dpi_offset_x,
|
||||
v0 = rl.Vector2Add(render_pos, .{ .x = cursor_x + glyph.dpi_bearing_x + dpi_offset_x,
|
||||
.y = cursor_y - glyph.dpi_bearing_y - dpi_offset_y });
|
||||
|
||||
v1 = v0.add(rl.Vector2{ .x = glyph.dpi_width, .y = glyph.dpi_height });
|
||||
v1 = rl.Vector2Add(v0, rl.Vector2{ .x = glyph.dpi_width, .y = glyph.dpi_height });
|
||||
const p0 : rl.Vector4 = .{ .x = v0.x, .y = v0.y, .z = 0.0, .w = 1.0 };
|
||||
const p1 : rl.Vector4 = .{ .x = v1.x, .y = v1.y, .z = 0.0, .w = 1.0 };
|
||||
|
||||
@@ -303,13 +298,13 @@ pub const Font = struct {
|
||||
const st0 = glyph.st0;
|
||||
const st1 = glyph.st1;
|
||||
|
||||
rl.gl.rlColor4ub(colour.r, colour.g, colour.b, colour.a);
|
||||
rl.gl.rlNormal3f(0.0, 0.0, 1.0);
|
||||
rl.rlColor4ub(colour.r, colour.g, colour.b, colour.a);
|
||||
rl.rlNormal3f(0.0, 0.0, 1.0);
|
||||
|
||||
rl.gl.rlTexCoord2f(st0.x, st0.y); rl.gl.rlVertex2f(p0.x, p0.y);
|
||||
rl.gl.rlTexCoord2f(st0.x, st1.y); rl.gl.rlVertex2f(p0.x, p1.y);
|
||||
rl.gl.rlTexCoord2f(st1.x, st1.y); rl.gl.rlVertex2f(p1.x, p1.y);
|
||||
rl.gl.rlTexCoord2f(st1.x, st0.y); rl.gl.rlVertex2f(p1.x, p0.y);
|
||||
rl.rlTexCoord2f(st0.x, st0.y); rl.rlVertex2f(p0.x, p0.y);
|
||||
rl.rlTexCoord2f(st0.x, st1.y); rl.rlVertex2f(p0.x, p1.y);
|
||||
rl.rlTexCoord2f(st1.x, st1.y); rl.rlVertex2f(p1.x, p1.y);
|
||||
rl.rlTexCoord2f(st1.x, st0.y); rl.rlVertex2f(p1.x, p0.y);
|
||||
|
||||
} else {
|
||||
std.log.warn("kb_text_shape found the glyph, but we didn't load it from the font. index {}", .{RunGlyph.Id});
|
||||
@@ -320,9 +315,9 @@ pub const Font = struct {
|
||||
}
|
||||
}
|
||||
|
||||
rl.gl.rlEnd();
|
||||
rl.gl.rlSetTexture(0);
|
||||
rl.endShaderMode();
|
||||
rl.rlEnd();
|
||||
rl.rlSetTexture(0);
|
||||
rl.EndShaderMode();
|
||||
}
|
||||
|
||||
pub fn size_row(self: *Font, str: []const u8, n: i32, max_width: f32) struct {rl.Vector2, f32, i32} {
|
||||
@@ -373,7 +368,7 @@ pub const Font = struct {
|
||||
};
|
||||
|
||||
fn my_kbts_ShapeRun(Context: ?*kb.kbts_shape_context, Run: [*c]kb.kbts_run) c_int {
|
||||
const zone = ztracy.ZoneNC(@src(), "my_kbts_ShapeRun", 0x00_ff_00_00);
|
||||
const zone = tracy.ZoneNC(@src(), "my_kbts_ShapeRun", 0x00_ff_00_00);
|
||||
defer zone.End();
|
||||
return kb.kbts_ShapeRun(Context, Run);
|
||||
}
|
||||
+157
-240
@@ -1,20 +1,22 @@
|
||||
const std = @import("std");
|
||||
const zm = @import("zmath");
|
||||
const znet = @import("znet");
|
||||
const rl = @import("raylib");
|
||||
const bufzilla = @import("bufzilla");
|
||||
const ft = @import("mach-freetype");
|
||||
const ztracy = @import("ztracy");
|
||||
// const bufzilla = @import("bufzilla");
|
||||
const ft = @import("freetype");
|
||||
const tracy = @import("tracy");
|
||||
const kb = @import("kb");
|
||||
|
||||
const shared = @import("shared");
|
||||
|
||||
const c = @import("c.zig").c;
|
||||
const enet = @import("c.zig").enet;
|
||||
const rl = @import("c.zig").rl;
|
||||
const client = @import("client.zig");
|
||||
const entity = @import("entity.zig");
|
||||
const misc = @import("misc.zig");
|
||||
const font = @import("font.zig");
|
||||
const chunk = @import("chunk.zig");
|
||||
|
||||
const dt : f32 = 1.0 / 200.0;
|
||||
const dt : f32 = 1.0 / 240.0;
|
||||
var t : f32 = 0;
|
||||
var gt : f32 = 0;
|
||||
var accumulator : f32 = 0;
|
||||
@@ -28,10 +30,10 @@ var running: bool = true;
|
||||
|
||||
var dbg_allocator = std.heap.DebugAllocator(.{}){};
|
||||
|
||||
// var connection: ?std.net.Stream = undefined;
|
||||
var the_chunk : shared.chunk.Chunk = undefined;
|
||||
|
||||
pub fn main() !void {
|
||||
const tracy_zone = ztracy.ZoneNC(@src(), "main", 0x00_ff_00_00);
|
||||
const tracy_zone = tracy.ZoneNC(@src(), "main", 0x00_ff_00_00);
|
||||
defer tracy_zone.End();
|
||||
|
||||
const allocator = dbg_allocator.allocator();
|
||||
@@ -39,8 +41,6 @@ pub fn main() !void {
|
||||
const deinit_status = dbg_allocator.deinit();
|
||||
if (deinit_status == .leak) {
|
||||
@panic("LEAKED!");
|
||||
} else {
|
||||
// @panic("SUCCESS!");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,22 +48,24 @@ pub fn main() !void {
|
||||
|
||||
_ = try stdout.write("Hello, Client!\n");
|
||||
|
||||
try znet.init();
|
||||
defer znet.deinit();
|
||||
// rl.setConfigFlags(.{ .window_highdpi = true, .vsync_hint = true });
|
||||
rl.initWindow(screen_width, screen_height, "zzz");
|
||||
defer rl.closeWindow();
|
||||
if (enet.enet_initialize() != 0) {
|
||||
std.log.info("Failed to load ENet", .{});
|
||||
return;
|
||||
}
|
||||
|
||||
defer enet.enet_deinitialize();
|
||||
|
||||
rl.SetConfigFlags(rl.FLAG_WINDOW_HIGHDPI);
|
||||
rl.InitWindow(screen_width, screen_height, "zzz");
|
||||
defer rl.CloseWindow();
|
||||
|
||||
font.ft_lib = try ft.Library.init();
|
||||
|
||||
const sizes = [_]i32{
|
||||
26,
|
||||
30,
|
||||
};
|
||||
|
||||
var vollkorn: [sizes.len]font.Font = undefined;
|
||||
var inconsolata: [sizes.len]font.Font = undefined;
|
||||
var arabic: [sizes.len]font.Font = undefined;
|
||||
// var japanese: [sizes.len]font.Font = undefined;
|
||||
|
||||
for (sizes, 0..) |pt, i| {
|
||||
vollkorn[i] = try font.Font.init(
|
||||
@@ -71,88 +73,27 @@ pub fn main() !void {
|
||||
pt,
|
||||
allocator
|
||||
);
|
||||
inconsolata[i] = try font.Font.init(
|
||||
"assets/fonts/Inconsolata/static/Inconsolata-Regular.ttf",
|
||||
@intCast(pt),
|
||||
allocator
|
||||
);
|
||||
arabic[i] = try font.Font.init(
|
||||
"assets/fonts/Amiri/Amiri-Regular.ttf",
|
||||
@intCast(pt),
|
||||
allocator
|
||||
);
|
||||
// japanese[i] = try font.Font.init(
|
||||
// "assets/fonts/Noto_Sans_JP/static/NotoSansJP-Regular.ttf",
|
||||
// @intCast(pt),
|
||||
// allocator
|
||||
// );
|
||||
}
|
||||
|
||||
defer {
|
||||
for (&vollkorn) |*f| f.deinit(allocator);
|
||||
for (&inconsolata) |*f| f.deinit(allocator);
|
||||
for (&arabic) |*f| f.deinit(allocator);
|
||||
// for (&japanese) |*f| f.deinit(allocator);
|
||||
}
|
||||
|
||||
font.shader = try rl.loadShader(null, "assets/text.frag");
|
||||
// const test_shader1 = try c.LoadShader(null, "assets/test_1.frag");
|
||||
// const test_shader2 = try c.LoadShader(null, "assets/test_2.frag");
|
||||
font.shader = rl.LoadShader(null, "assets/text.frag");
|
||||
// const test_shader1 = try rl.LoadShader(null, "assets/test_1.frag");
|
||||
// const test_shader2 = try rl.LoadShader(null, "assets/test_2.frag");
|
||||
|
||||
// font.shader = try rl.loadShader(null, "assets/text.frag");
|
||||
// const test_shader1 = try rl.loadShader(null, "assets/test_1.frag");
|
||||
// const test_shader2 = try rl.loadShader(null, "assets/test_2.frag");
|
||||
const host = enet.enet_host_create(null, 32, 2, 0, 0);
|
||||
defer enet.enet_host_destroy(host);
|
||||
|
||||
// const img = rl.genImageColor(32, 32, .blank);
|
||||
// const tx = try rl.loadTextureFromImage(img);
|
||||
// rl.unloadImage(img);
|
||||
var address = enet.ENetAddress{ .port = shared.protocol_v1.SERVER_PORT };
|
||||
_ = enet.enet_address_set_host(&address, "localhost");
|
||||
|
||||
const host = try znet.Host.init(.{
|
||||
.addr = null,
|
||||
.peer_limit = 1,
|
||||
.channel_limit = .max,
|
||||
.incoming_bandwidth = .unlimited,
|
||||
.outgoing_bandwidth = .unlimited,
|
||||
});
|
||||
defer host.deinit();
|
||||
const peer = enet.enet_host_connect(host, &address, 2, 0);
|
||||
defer enet.enet_peer_reset(peer);
|
||||
|
||||
// const peer = try host.connect(.{
|
||||
// .addr = try .init(.{
|
||||
// .ip = .{ .ipv4 = "127.0.0.1" },
|
||||
// .port = .{ .uint = 5000 },
|
||||
// }),
|
||||
// .channel_limit = .max,
|
||||
// .data = 0,
|
||||
// });
|
||||
|
||||
// connect() catch |err| switch (err) {
|
||||
// error.ConnectionRefused => {
|
||||
// std.log.err("server refused connection", .{});
|
||||
// },
|
||||
// else => {
|
||||
// std.log.err("unexpected connect error: {}", .{err});
|
||||
// return err;
|
||||
// },
|
||||
// };
|
||||
|
||||
// try stdout.flush();
|
||||
|
||||
// var the_chunk = try shared.chunk.initChunk(allocator);
|
||||
// defer shared.chunk.deinitChunk(&the_chunk, allocator);
|
||||
|
||||
// shared.chunk.updateChunk(&the_chunk);
|
||||
|
||||
//var elf = entity.Elf.init();
|
||||
|
||||
// var send_buf: [1024]u8 = undefined;
|
||||
// var writer = if (connection) |*conn| conn.writer(&send_buf) else return;
|
||||
|
||||
// try shared.protocol.sendHello(&writer.interface, .{ .msg = "Hello from client" });
|
||||
|
||||
// var recv_buf: [1024]u8 = undefined;
|
||||
// var reader = if (connection) |*conn| conn.reader(&recv_buf) else return;
|
||||
// const line = try reader.interface().takeDelimiterExclusive('\n');
|
||||
// std.log.info("{s}", .{line});
|
||||
the_chunk = try shared.chunk.Chunk.init(allocator);
|
||||
defer the_chunk.deinit(allocator);
|
||||
|
||||
// const camera = rl.Camera{
|
||||
// .fovy = 45,
|
||||
@@ -175,15 +116,13 @@ pub fn main() !void {
|
||||
// rl.playMusicStream(music);
|
||||
// std.log.info("is music playing? {}", .{rl.isMusicStreamPlaying(music)});
|
||||
|
||||
var old_time : f32 = @floatCast(rl.getTime());
|
||||
// var old_time : f32 = @floatCast(rl.getTime());
|
||||
var old_time : f32 = @floatCast(rl.GetTime());
|
||||
|
||||
while (!rl.windowShouldClose()) {
|
||||
const tracy_main_zone = ztracy.ZoneNC(@src(), "loop", 0x00_ff_00_00);
|
||||
while (!rl.WindowShouldClose()) {
|
||||
const tracy_main_zone = tracy.ZoneNC(@src(), "loop", 0x00_aa_33_10);
|
||||
defer tracy_main_zone.End();
|
||||
|
||||
const new_time : f32 = @floatCast(rl.getTime());
|
||||
// const new_time : f32 = @floatCast(rl.getTime());
|
||||
const new_time : f32 = @floatCast(rl.GetTime());
|
||||
var frame_time = new_time - old_time;
|
||||
old_time = new_time;
|
||||
|
||||
@@ -193,31 +132,31 @@ pub fn main() !void {
|
||||
t += frame_time;
|
||||
accumulator += frame_time * k;
|
||||
|
||||
// std.log.info("t: {}", .{t});
|
||||
|
||||
while (try host.service(0)) |event| switch (event) {
|
||||
.connect => |data| {
|
||||
_ = data;
|
||||
// std.log.info("{}", .{data.peer});
|
||||
},
|
||||
.disconnect => |data| {
|
||||
_ = data;
|
||||
// std.log.info("{}", .{data.peer});
|
||||
},
|
||||
.receive => |data| {
|
||||
defer data.packet.deinit();
|
||||
var event = enet.ENetEvent{};
|
||||
while (enet.enet_host_service(host, &event, 0) > 0) {
|
||||
switch (event.type) {
|
||||
enet.ENET_EVENT_TYPE_CONNECT => {
|
||||
std.log.info("A new client connected from {d}:{d}.", .{
|
||||
event.peer.*.address.host,
|
||||
event.peer.*.address.port
|
||||
});
|
||||
|
||||
const slice = data.packet.dataSlice();
|
||||
event.peer.*.data = @constCast(@ptrCast("Client information"));
|
||||
},
|
||||
enet.ENET_EVENT_TYPE_RECEIVE => {
|
||||
try on_packet(allocator, event.packet, event.peer, event.channelID);
|
||||
|
||||
var reader = bufzilla.Reader(.{}).init(slice);
|
||||
enet.enet_packet_destroy(event.packet);
|
||||
},
|
||||
enet.ENET_EVENT_TYPE_DISCONNECT => {
|
||||
std.log.info("disconnect", .{});
|
||||
},
|
||||
else => {}
|
||||
}
|
||||
}
|
||||
|
||||
const id = try reader.readPath("id");
|
||||
|
||||
std.log.info("{any}", .{id});
|
||||
},
|
||||
};
|
||||
|
||||
rl.pollInputEvents();
|
||||
rl.PollInputEvents();
|
||||
|
||||
// if (peer.state() == .connected) {
|
||||
// const packet = try znet.Packet.init("Hello, Server!", 0, .reliable);
|
||||
@@ -228,137 +167,39 @@ pub fn main() !void {
|
||||
// rl.updateMusicStream(music);
|
||||
|
||||
while (accumulator > dt * k) {
|
||||
// update(dt * cast(float) k);
|
||||
the_chunk.update(dt * k);
|
||||
accumulator -= dt * k;
|
||||
gt += dt * k;
|
||||
}
|
||||
|
||||
rl.beginDrawing();
|
||||
rl.clearBackground(.sky_blue);
|
||||
const drawing_zone = tracy.ZoneNC(@src(), "Drawing", 0x00_ff_00_00);
|
||||
|
||||
rl.BeginDrawing();
|
||||
rl.ClearBackground(rl.SKYBLUE);
|
||||
|
||||
// const lorem = @embedFile("embeds/lorem.txt");
|
||||
|
||||
|
||||
for (the_chunk.entities.items) |e| {
|
||||
switch (e) {
|
||||
.Soldier => |soldier| {
|
||||
entity.render_soldier(soldier);
|
||||
},
|
||||
.Alien => |alien| {
|
||||
entity.render_alien(alien);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vollkorn[0].render_text(
|
||||
"The night is long and cold outside.",
|
||||
rl.Vector2{ .x = 0, .y = 0 },
|
||||
true,
|
||||
.white,
|
||||
.blank,
|
||||
rl.WHITE,
|
||||
rl.BLANK,
|
||||
false,
|
||||
true
|
||||
);
|
||||
|
||||
// arabic[0].render_text(
|
||||
// "الليل طويل وبارد في الخارج",
|
||||
// rl.Vector2{ .x = 0, .y = 100},
|
||||
// true,
|
||||
// .white,
|
||||
// .blank,
|
||||
// false,
|
||||
// true
|
||||
// );
|
||||
|
||||
// var y : f32 = 0;
|
||||
// var it = std.mem.splitScalar(u8, lorem, '\n');
|
||||
// while (it.next()) |line| {
|
||||
// vollkorn[0].render_text(
|
||||
// line,
|
||||
// rl.Vector2{ .x = 0, .y = y},
|
||||
// true,
|
||||
// .white,
|
||||
// .blank,
|
||||
// false,
|
||||
// true
|
||||
// );
|
||||
|
||||
// const font_linegap : f32 = @floatFromInt(vollkorn[0].face.size().metrics().height >> 6);
|
||||
// const dpi_font_linegap = font_linegap / rl.getWindowScaleDPI().y;
|
||||
|
||||
// y += dpi_font_linegap;
|
||||
// }
|
||||
|
||||
|
||||
// for (&vollkorn) |*f| {
|
||||
// f.render_text(
|
||||
// "Whereas, disregard and contempt for human rights have resulted!",
|
||||
// rl.Vector2{ .x = 0, .y = y},
|
||||
// true,
|
||||
// .white,
|
||||
// .blank,
|
||||
// false,
|
||||
// true
|
||||
// );
|
||||
|
||||
// // const font_ascent : f32 = @floatFromInt(f.face.size().metrics().ascender >> 6);
|
||||
// // const dpi_font_ascent = font_ascent / rl.getWindowScaleDPI().y;
|
||||
|
||||
// // const font_descent : f32 = @floatFromInt(f.face.size().metrics().descender >> 6);
|
||||
// // const dpi_font_descent = font_descent / rl.getWindowScaleDPI().y;
|
||||
|
||||
// const font_linegap : f32 = @floatFromInt(f.face.size().metrics().height >> 6);
|
||||
// const dpi_font_linegap = font_linegap / rl.getWindowScaleDPI().y;
|
||||
|
||||
// y += dpi_font_linegap;
|
||||
// }
|
||||
|
||||
// for (&inconsolata) |*f| {
|
||||
// f.render_text(
|
||||
// "Whereas, disregard and contempt for human rights have resulted!",
|
||||
// rl.Vector2{ .x = 0, .y = y},
|
||||
// true,
|
||||
// .white,
|
||||
// .blank,
|
||||
// false,
|
||||
// true
|
||||
// );
|
||||
|
||||
// // const font_ascent : f32 = @floatFromInt(f.face.size().metrics().ascender >> 6);
|
||||
// // const dpi_font_ascent = font_ascent / rl.getWindowScaleDPI().y;
|
||||
|
||||
// // const font_descent : f32 = @floatFromInt(f.face.size().metrics().descender >> 6);
|
||||
// // const dpi_font_descent = font_descent / rl.getWindowScaleDPI().y;
|
||||
|
||||
// const font_linegap : f32 = @floatFromInt(f.face.size().metrics().height >> 6);
|
||||
// const dpi_font_linegap = font_linegap / rl.getWindowScaleDPI().y;
|
||||
|
||||
// y += dpi_font_linegap;
|
||||
// }
|
||||
|
||||
// for (&japanese) |*f| {
|
||||
// f.render_text(
|
||||
// "外は夜が長くて寒い",
|
||||
// c.Vector2{ .x = 0, .y = y},
|
||||
// true,
|
||||
// c.WHITE,
|
||||
// c.BLANK,
|
||||
// false,
|
||||
// true
|
||||
// );
|
||||
|
||||
// const font_ascent : f32 = @floatFromInt(f.face.size().metrics().ascender >> 6);
|
||||
// const dpi_font_ascent = font_ascent / c.GetWindowScaleDPI().y;
|
||||
|
||||
// y += dpi_font_ascent;
|
||||
// }
|
||||
|
||||
// for (&arabic) |*f| {
|
||||
|
||||
|
||||
// const font_ascent : f32 = @floatFromInt(f.face.size().metrics().ascender >> 6);
|
||||
// const dpi_font_ascent = font_ascent / rl.getWindowScaleDPI().y;
|
||||
|
||||
// y += dpi_font_ascent;
|
||||
// }
|
||||
// f.render_text(
|
||||
// "Whereas, disregard and contempt for human rights have resulted!",
|
||||
// rl.Vector2.init(0, 0),
|
||||
// true,
|
||||
// rl.Color.white,
|
||||
// rl.Color.blank,
|
||||
// false,
|
||||
// true
|
||||
// );
|
||||
|
||||
// rl.beginShaderMode(test_shader1);
|
||||
// rl.gl.rlBegin(rl.gl.rl_quads);
|
||||
|
||||
@@ -482,20 +323,96 @@ pub fn main() !void {
|
||||
// rl.drawSphere(.{ .x = 0, .y = 0, .z = 0 }, 1, .red);
|
||||
// rl.endMode3D();
|
||||
|
||||
rl.endDrawing();
|
||||
rl.EndDrawing();
|
||||
drawing_zone.End();
|
||||
|
||||
const swap_zone = ztracy.ZoneNC(@src(), "swapScreenBuffer", 0x00_ff_00_00);
|
||||
rl.swapScreenBuffer();
|
||||
const swap_zone = tracy.ZoneNC(@src(), "SwapScreenBuffer", 0x00_ff_00_00);
|
||||
rl.SwapScreenBuffer();
|
||||
swap_zone.End();
|
||||
|
||||
frame += 1;
|
||||
|
||||
ztracy.FrameMark();
|
||||
tracy.FrameMark();
|
||||
}
|
||||
}
|
||||
|
||||
fn on_packet(allocator: std.mem.Allocator, packet: *enet.ENetPacket, peer: *enet.ENetPeer, channelID: i32) !void {
|
||||
// std.log.info("A packet of length {d} containing {s} was received from {s} on channel {d}.", .{
|
||||
// packet.*.dataLength,
|
||||
// packet.*.data,
|
||||
// @as([*:0]const u8, @ptrCast(peer.*.data.?)),
|
||||
// channelID});
|
||||
|
||||
_ = peer;
|
||||
_ = channelID;
|
||||
|
||||
const bytes: []const u8 = packet.*.data[0 .. packet.*.dataLength];
|
||||
|
||||
var reader = shared.bits.BitReader.init(bytes);
|
||||
|
||||
const msg : shared.protocol_v1.Message = try reader.deserialize(allocator, shared.protocol_v1.Message);
|
||||
|
||||
try on_message(allocator, msg);
|
||||
}
|
||||
|
||||
fn on_message(allocator: std.mem.Allocator, msg: shared.protocol_v1.Message) !void {
|
||||
switch (msg) {
|
||||
.spawn_entity => |se| { try on_spawn_entity(allocator, se); },
|
||||
.update_entity => |ue| { on_update_entity(ue); },
|
||||
.despawn_entity => |de| { on_despawn_entity(allocator, de); },
|
||||
}
|
||||
}
|
||||
|
||||
fn on_spawn_entity(allocator: std.mem.Allocator, p: shared.protocol_v1.EntityPayload) !void {
|
||||
// _ = allocator; _ = se;
|
||||
switch (p) {
|
||||
.soldier => |s| {
|
||||
const soldier = shared.entity.Soldier{
|
||||
.id = s.id,
|
||||
.hp = s.hp,
|
||||
.pos = s.pos,
|
||||
.vel = s.vel,
|
||||
};
|
||||
_ = try chunk.spawn(&the_chunk, allocator, shared.entity.Soldier, soldier);
|
||||
},
|
||||
.alien => |a| {
|
||||
const alien = shared.entity.Alien{
|
||||
.id = a.id,
|
||||
.hp = a.hp,
|
||||
.pos = a.pos,
|
||||
};
|
||||
_ = try chunk.spawn(&the_chunk, allocator, shared.entity.Alien, alien);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn on_update_entity(p: shared.protocol_v1.EntityPayload) void {
|
||||
switch (p) {
|
||||
.soldier => |s| {
|
||||
if (chunk.findT(&the_chunk, shared.entity.Soldier, s.id)) |soldier| {
|
||||
soldier.hp = s.hp;
|
||||
soldier.pos = s.pos;
|
||||
soldier.vel = s.vel;
|
||||
}
|
||||
},
|
||||
.alien => |a| {
|
||||
if (chunk.findT(&the_chunk, shared.entity.Alien, a.id)) |alien| {
|
||||
alien.hp = a.hp;
|
||||
alien.pos = a.pos;
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn on_despawn_entity(allocator: std.mem.Allocator, p: shared.protocol_v1.EntityPayload) void {
|
||||
switch (p) {
|
||||
.soldier => |s| { _ = chunk.despawn(&the_chunk, allocator, s.id); },
|
||||
.alien => |a| { _ = chunk.despawn(&the_chunk, allocator, a.id); },
|
||||
}
|
||||
}
|
||||
|
||||
fn connect() !void {
|
||||
// const address = try std.net.Address.parseIp4("127.0.0.1", shared.protocol.SERVER_PORT);
|
||||
// const address = try std.net.Address.parseIp4("127.0.0.1", shared.protocol_v1.SERVER_PORT);
|
||||
|
||||
// connection = try std.net.tcpConnectToAddress(address);
|
||||
|
||||
|
||||
+7
-17
@@ -1,4 +1,4 @@
|
||||
const rl = @import("raylib");
|
||||
const rl = @import("c.zig").rl;
|
||||
|
||||
const FPS_CAPTURE_FRAMES_COUNT : i32 = 30; // 30 captures
|
||||
const FPS_AVERAGE_TIME_SECONDS : f32 = 0.5; // 500 milliseconds
|
||||
@@ -10,33 +10,23 @@ var average : f32 = 0;
|
||||
var last : f32 = 0;
|
||||
|
||||
pub fn drawFPS(posX : i32, posY : i32, fpsFrame : f32) void {
|
||||
var color : rl.Color = .lime; // Good FPS
|
||||
var color : rl.Color = rl.LIME; // Good FPS
|
||||
const fps : i32 = getFPS(fpsFrame);
|
||||
|
||||
if ((fps < 30) and (fps >= 15)) {color = .orange;} // Warning FPS
|
||||
else if (fps < 15) color = .red; // Low FPS
|
||||
if ((fps < 30) and (fps >= 15)) {color = rl.ORANGE;} // Warning FPS
|
||||
else if (fps < 15) color = rl.RED; // Low FPS
|
||||
|
||||
rl.drawText(rl.textFormat("%2i FPS", .{fps}), posX, posY, 20, color);
|
||||
rl.DrawText(rl.TextFormat("%2i FPS", fps), posX, posY, 20, color);
|
||||
}
|
||||
|
||||
pub fn getFPS(fpsFrame : f32) i32 {
|
||||
var fps : i32 = 0;
|
||||
|
||||
// if we reset the window, reset the FPS info
|
||||
// if (frame == 0)
|
||||
// {
|
||||
// average = 0;
|
||||
// last = 0;
|
||||
// index = 0;
|
||||
|
||||
// for (0..FPS_CAPTURE_FRAMES_COUNT) |i| history[i] = 0;
|
||||
// }
|
||||
|
||||
if (fpsFrame == 0) return 0;
|
||||
|
||||
if ((rl.getTime() - last) > FPS_STEP)
|
||||
if ((rl.GetTime() - last) > FPS_STEP)
|
||||
{
|
||||
last = @floatCast(rl.getTime());
|
||||
last = @floatCast(rl.GetTime());
|
||||
index = (index + 1) % FPS_CAPTURE_FRAMES_COUNT;
|
||||
average -= history[index];
|
||||
history[index] = fpsFrame / FPS_CAPTURE_FRAMES_COUNT;
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
pub const enet = @cImport({
|
||||
@cInclude("enet/enet.h");
|
||||
});
|
||||
+36
-23
@@ -1,43 +1,56 @@
|
||||
const std = @import("std");
|
||||
const znet = @import("znet");
|
||||
const bufzilla = @import("bufzilla");
|
||||
// const bufzilla = @import("bufzilla");
|
||||
|
||||
const shared = @import("shared");
|
||||
const server = @import("server.zig");
|
||||
const enet = @import("c.zig").enet;
|
||||
|
||||
pub fn spawn(chunk: *shared.chunk.Chunk, comptime T: type, allocator: std.mem.Allocator, value: T) !void {
|
||||
pub fn spawn(self: *shared.chunk.Chunk, allocator: std.mem.Allocator, host: *enet.ENetHost, comptime T: type, value: T) !shared.entity.id {
|
||||
std.debug.assert(value.id == shared.entity.INVALID_ID);
|
||||
|
||||
const id = server.next_entity_id;
|
||||
server.next_entity_id += 1;
|
||||
|
||||
var entity = value;
|
||||
entity.id = id;
|
||||
const ptr = try allocator.create(T);
|
||||
errdefer allocator.destroy(ptr);
|
||||
|
||||
inline for (@typeInfo(shared.chunk.Chunk).@"struct".fields) |field| {
|
||||
if (field.type == shared.chunk.Storage(T)) {
|
||||
try @field(chunk, field.name).items.append(allocator, entity);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ptr.* = value;
|
||||
ptr.id = id;
|
||||
|
||||
const ref = shared.entity.makeRef(T, ptr);
|
||||
|
||||
try self.entities.append(allocator, ref);
|
||||
|
||||
_ = host;
|
||||
|
||||
|
||||
// std.log.info("{}", .{shared.protocol.makeSpawnMessage(T, entity)});
|
||||
|
||||
// serialize entity
|
||||
var buffer: [128]u8 = undefined;
|
||||
var fixed = std.io.Writer.fixed(&buffer);
|
||||
// const msg = shared.protocol.makeSpawnMessage(T, entity);
|
||||
|
||||
const msg = shared.protocol.makeSpawnMessage(T, entity);
|
||||
// const data = fixed.buffered();
|
||||
// const packet = enet.enet_packet_create(data.ptr, data.len + 1, enet.ENET_PACKET_FLAG_RELIABLE);
|
||||
|
||||
var writer = bufzilla.Writer.init(&fixed);
|
||||
try writer.writeAny(msg);
|
||||
// enet.enet_host_broadcast(host, 0, packet);
|
||||
|
||||
const encoded = fixed.buffered();
|
||||
return ptr.id;
|
||||
}
|
||||
|
||||
const packet = try znet.Packet.init(encoded, 0, .reliable);
|
||||
var iterator = server.host.iterPeers();
|
||||
pub fn broadcastChanges(chunk: *shared.chunk.Chunk, allocator: std.mem.Allocator, host: *enet.ENetHost) !void {
|
||||
var aw = try std.ArrayList(u8).initCapacity(allocator, 128);
|
||||
defer aw.deinit(allocator);
|
||||
|
||||
while (iterator.next()) |peer| {
|
||||
if (peer.state() == .connected) {
|
||||
try peer.send(packet);
|
||||
}
|
||||
var writer = shared.bits.BitWriter.init(&aw);
|
||||
|
||||
for (chunk.entities.items) |e| {
|
||||
const msg = shared.protocol_v1.makeMessage(.update_entity, e);
|
||||
try writer.serialize(allocator, msg);
|
||||
}
|
||||
|
||||
const encoded = writer.written();
|
||||
|
||||
const packet = enet.enet_packet_create(encoded.ptr, encoded.len, enet.ENET_PACKET_FLAG_RELIABLE);
|
||||
|
||||
enet.enet_host_broadcast(host, 0, packet);
|
||||
}
|
||||
+118
-62
@@ -1,84 +1,101 @@
|
||||
const std = @import("std");
|
||||
const zm = @import("zmath");
|
||||
const znet = @import("znet");
|
||||
const std = @import("std");
|
||||
const zm = @import("zmath");
|
||||
const enet = @import("c.zig").enet;
|
||||
// const bufzilla = @import("bufzilla");
|
||||
|
||||
const shared = @import("shared");
|
||||
|
||||
const chunk = @import("chunk.zig");
|
||||
const chunk = @import("chunk.zig");
|
||||
const server = @import("server.zig");
|
||||
|
||||
const dt : f32 = 1.0 / 200.0;
|
||||
const dt : f32 = 1.0 / 240.0;
|
||||
var t : f32 = 0;
|
||||
var gt : f32 = 0;
|
||||
var accumulator : f32 = 0;
|
||||
var k : f32 = 1.0;
|
||||
var frame : i32 = 0;
|
||||
|
||||
var stdout: *std.io.Writer = undefined;
|
||||
const frame_dt_ns: i128 = std.time.ns_per_s / 10;
|
||||
|
||||
var dbg_allocator = std.heap.DebugAllocator(.{}){};
|
||||
|
||||
const log = std.log.scoped(.server);
|
||||
|
||||
pub fn main() !void {
|
||||
std.log.info("Hello Server!", .{});
|
||||
var dbg_allocator = std.heap.DebugAllocator(.{}).init;
|
||||
defer _ = dbg_allocator.deinit();
|
||||
|
||||
const allocator = dbg_allocator.allocator();
|
||||
defer {
|
||||
const deinit_status = dbg_allocator.deinit();
|
||||
if (deinit_status == .leak) {
|
||||
@panic("LEAKED!");
|
||||
}
|
||||
}
|
||||
|
||||
var stdout_buffer: [1024]u8 = undefined;
|
||||
var stdout_writer = std.fs.File.stdout().writer(&stdout_buffer);
|
||||
stdout = &stdout_writer.interface;
|
||||
var stdout = std.fs.File.stdout();
|
||||
_ = try stdout.write("Hello, Server!\n");
|
||||
|
||||
try stdout.flush();
|
||||
if (enet.enet_initialize() != 0) {
|
||||
log.info("Failed to load ENet", .{});
|
||||
return;
|
||||
}
|
||||
defer enet.enet_deinitialize();
|
||||
|
||||
try znet.init();
|
||||
defer znet.deinit();
|
||||
const address = enet.ENetAddress{ .host = enet.ENET_HOST_ANY, .port = shared.protocol_v1.SERVER_PORT };
|
||||
const host = enet.enet_host_create(&address, 32, 2, 0, 0);
|
||||
if (host == null) {
|
||||
@panic("host is null");
|
||||
}
|
||||
defer enet.enet_host_destroy(host);
|
||||
|
||||
server.host = try znet.Host.init(.{
|
||||
.addr = try .init(.{
|
||||
.ip = .any,
|
||||
.port = .{ .uint = 5000 },
|
||||
}),
|
||||
.peer_limit = 32,
|
||||
.channel_limit = .max,
|
||||
.incoming_bandwidth = .unlimited,
|
||||
.outgoing_bandwidth = .unlimited,
|
||||
});
|
||||
var the_chunk = try shared.chunk.Chunk.init(allocator);
|
||||
defer the_chunk.deinit(allocator);
|
||||
|
||||
// const address = try std.net.Address.parseIp4("127.0.0.1", shared.protocol.SERVER_PORT);
|
||||
// var tcp_server = try address.listen(.{});
|
||||
_ = try chunk.spawn(
|
||||
&the_chunk,
|
||||
allocator,
|
||||
host,
|
||||
shared.entity.Soldier,
|
||||
.{
|
||||
.hp = 10,
|
||||
.pos = zm.f32x4(5.0, 0, 0, 0),
|
||||
.vel = zm.f32x4(0, 0, 0, 0),
|
||||
}
|
||||
);
|
||||
|
||||
// defer tcp_server.deinit();
|
||||
var last_time: i128 = std.time.nanoTimestamp();
|
||||
var next_frame_deadline: i128 = last_time + frame_dt_ns;
|
||||
|
||||
var the_chunk = try shared.chunk.initChunk(allocator);
|
||||
defer shared.chunk.deinitChunk(&the_chunk, allocator);
|
||||
|
||||
var old_time = std.time.nanoTimestamp();
|
||||
var accumulator: f32 = 0;
|
||||
|
||||
while (true) {
|
||||
const new_time = std.time.nanoTimestamp();
|
||||
var frame_time : f32 = @as(f32, @floatFromInt(new_time - old_time)) / 1_000_000_000.0;
|
||||
old_time = new_time;
|
||||
const now = std.time.nanoTimestamp();
|
||||
var delta_ns = now - last_time;
|
||||
last_time = now;
|
||||
|
||||
if (frame_time > 0.25)
|
||||
frame_time = 0.25;
|
||||
if (delta_ns > std.time.ns_per_s / 4)
|
||||
delta_ns = std.time.ns_per_s / 4;
|
||||
|
||||
t += frame_time;
|
||||
accumulator += frame_time * k;
|
||||
const delta_s: f32 = @floatCast(@as(f64, @floatFromInt(delta_ns)) / 1e9);
|
||||
|
||||
// std.log.info("t: {}", .{t});
|
||||
t += delta_s;
|
||||
accumulator += delta_s * k;
|
||||
|
||||
while (try server.host.service(0)) |event| switch (event) {
|
||||
.connect => |data| {
|
||||
_ = data;
|
||||
// std.log.info("{}", .{data.peer});
|
||||
},
|
||||
.disconnect => |data| {
|
||||
_ = data;
|
||||
// std.log.info("{}", .{data.peer});
|
||||
},
|
||||
.receive => |data| {
|
||||
std.log.info("{s}", .{data.packet.dataSlice()});
|
||||
defer data.packet.deinit();
|
||||
},
|
||||
};
|
||||
log.info("Starting a the frame {} at time {}", .{frame, t});
|
||||
|
||||
var event = enet.ENetEvent{};
|
||||
while (enet.enet_host_service(host, &event, 0) > 0) {
|
||||
switch (event.type) {
|
||||
enet.ENET_EVENT_TYPE_CONNECT => {
|
||||
try on_connect(allocator, host, event.peer, &the_chunk);
|
||||
},
|
||||
enet.ENET_EVENT_TYPE_RECEIVE => {
|
||||
log.info("receive", .{});
|
||||
},
|
||||
enet.ENET_EVENT_TYPE_DISCONNECT => {
|
||||
log.info("disconnect", .{});
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
|
||||
// const connection = try tcp_server.accept();
|
||||
// defer connection.stream.close();
|
||||
@@ -87,18 +104,13 @@ pub fn main() !void {
|
||||
// var reader = connection.stream.reader(&recv_buffer);
|
||||
|
||||
// const line = try reader.interface().takeDelimiterExclusive('\n');
|
||||
// std.log.info("Received: {s}", .{line});
|
||||
// log.info("Received: {s}", .{line});
|
||||
|
||||
// var send_buffer: [4096]u8 = undefined;
|
||||
// var writer = connection.stream.writer(&send_buffer);
|
||||
// const w = &writer.interface;
|
||||
// try shared.protocol.sendHello(w, .{ .msg = "Hello from server!" });
|
||||
|
||||
try chunk.spawn(&the_chunk, shared.entity.Elf, allocator, .{
|
||||
.pos = zm.f32x4(1, 1, 0, 0),
|
||||
.hp = 10,
|
||||
});
|
||||
|
||||
// try chunk.spawn(&the_chunk, shared.entity.Monster, allocator, .{
|
||||
// .pos = zm.f32x4(1, 1, 0, 0),
|
||||
// .hp = 20,
|
||||
@@ -109,10 +121,54 @@ pub fn main() !void {
|
||||
// .vel = zm.f32x4(0.2, 0, 0, 0),
|
||||
// }, w);
|
||||
|
||||
shared.chunk.updateChunk(&the_chunk);
|
||||
while (accumulator > dt * k) {
|
||||
the_chunk.update(dt * k);
|
||||
|
||||
accumulator -= dt * k;
|
||||
gt += dt * k;
|
||||
}
|
||||
|
||||
try chunk.broadcastChanges(&the_chunk, allocator, host);
|
||||
|
||||
const spin_ns: i128 = 100_000; // 0.1 ms
|
||||
|
||||
while (true) {
|
||||
const _t = std.time.nanoTimestamp();
|
||||
const remaining = next_frame_deadline - _t;
|
||||
|
||||
if (remaining <= 0)
|
||||
break;
|
||||
|
||||
if (remaining > spin_ns)
|
||||
std.Thread.sleep(@intCast(remaining - spin_ns));
|
||||
}
|
||||
|
||||
next_frame_deadline += frame_dt_ns;
|
||||
|
||||
frame += 1;
|
||||
}
|
||||
}
|
||||
|
||||
fn on_connect(allocator: std.mem.Allocator, host: *enet.ENetHost, peer: *enet.ENetPeer, the_chunk: *shared.chunk.Chunk) !void {
|
||||
var aw = try std.ArrayList(u8).initCapacity(allocator, 128);
|
||||
defer aw.deinit(allocator);
|
||||
|
||||
_ = peer;
|
||||
|
||||
var writer = shared.bits.BitWriter.init(&aw);
|
||||
|
||||
for (the_chunk.entities.items) |e| {
|
||||
const msg = shared.protocol_v1.makeMessage(.spawn_entity, e);
|
||||
try writer.serialize(allocator, msg);
|
||||
}
|
||||
|
||||
const encoded = writer.written();
|
||||
|
||||
const packet = enet.enet_packet_create(encoded.ptr, encoded.len, enet.ENET_PACKET_FLAG_RELIABLE);
|
||||
|
||||
enet.enet_host_broadcast(host, 0, packet);
|
||||
}
|
||||
|
||||
//fn handle_connection(connection: std.net.Server.Connection) !void {}
|
||||
|
||||
// test "simple test" {
|
||||
|
||||
@@ -0,0 +1,286 @@
|
||||
const std = @import("std");
|
||||
|
||||
// pub fn serialize(writer: *BitWriter, allocator: std.mem.Allocator, comptime T: type, value: T) !void {
|
||||
// const info = @typeInfo(T);
|
||||
|
||||
// switch (info) {
|
||||
// .int, .bool => {
|
||||
// try writer.write(allocator, T, value);
|
||||
// },
|
||||
|
||||
// .@"struct" => |s| {
|
||||
// if (!s.is_packed)
|
||||
// @compileError("serialize only supports packed structs (got " ++ @typeName(T) ++ ")");
|
||||
|
||||
// inline for (s.fields) |field| {
|
||||
// const field_value = @field(value, field.name);
|
||||
// try serialize(writer, allocator, field_value);
|
||||
// }
|
||||
// },
|
||||
|
||||
// .@"union" => |u| {
|
||||
// if (u.layout != .@"packed")
|
||||
// @compileError("serialize only supports packed structs (got " ++ @typeName(T) ++ ")");
|
||||
|
||||
// inline for (u.fields) |field| {
|
||||
// const field_value = @field(value, field.name);
|
||||
// try serialize(writer, allocator, field_value);
|
||||
// }
|
||||
// },
|
||||
|
||||
// else => @compileError("Unsupported type in serialize: " ++ @typeName(T)),
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
pub const BitWriter = struct {
|
||||
// We store a pointer to the ArrayList so we can grow it
|
||||
bytes: *std.ArrayList(u8),
|
||||
bit_offset: usize = 0,
|
||||
|
||||
pub fn init(bytes: *std.ArrayList(u8)) BitWriter {
|
||||
return .{ .bytes = bytes };
|
||||
}
|
||||
|
||||
pub fn serialize(self: *BitWriter, allocator: std.mem.Allocator, value: anytype) !void {
|
||||
const T = @TypeOf(value);
|
||||
const info = @typeInfo(T);
|
||||
|
||||
switch (info) {
|
||||
.@"struct" => |s| {
|
||||
inline for (s.fields) |f|
|
||||
try self.serialize(allocator, @field(value, f.name));
|
||||
},
|
||||
.@"union" => |u| {
|
||||
const E = u.tag_type orelse @compileError(std.fmt.comptimePrint("Union {s} has to tag type.", .{@typeName(T)}));
|
||||
try self.serialize(allocator, @as(E, value));
|
||||
switch (value) {
|
||||
inline else => |f| try self.serialize(allocator, f),
|
||||
}
|
||||
},
|
||||
.@"enum" => try self.serialize(allocator, @intFromEnum(value)),
|
||||
.pointer => |p| switch (p.size) {
|
||||
.one => try self.serialize(allocator, value.*),
|
||||
.slice => {
|
||||
try self.serialize(allocator, value.len);
|
||||
for (value) |e|
|
||||
try self.serialize(allocator, e);
|
||||
},
|
||||
.many, .c => @compileError(std.fmt.comptimePrint("Unsupported type: {}", .{T})),
|
||||
},
|
||||
.int, .bool, .float, => try self.write(allocator, value),
|
||||
.void => {},
|
||||
.array => |a| if (@sizeOf(a.child) == 1) {
|
||||
try self.write(allocator, @ptrCast(&value));
|
||||
} else {
|
||||
for (value) |e|
|
||||
try self.serialize(allocator, e);
|
||||
},
|
||||
.optional => if (value) |_t| {
|
||||
try self.serialize(allocator, true);
|
||||
try self.serialize(allocator, _t);
|
||||
} else {
|
||||
try self.serialize(allocator, false);
|
||||
},
|
||||
.vector => |v| try self.serialize(allocator, @as([v.len]v.child, value)),
|
||||
else => @compileError(std.fmt.comptimePrint("Unsupported type: {}", .{T})),
|
||||
}
|
||||
}
|
||||
|
||||
fn write(self: *BitWriter, allocator: std.mem.Allocator, value: anytype) !void {
|
||||
const T = @TypeOf(value);
|
||||
const bit_width = @bitSizeOf(T);
|
||||
|
||||
const UnsignedT = std.meta.Int(.unsigned, bit_width);
|
||||
const bits_to_write = @as(UnsignedT, @bitCast(value));
|
||||
|
||||
var remaining : usize = bit_width;
|
||||
while (remaining > 0) {
|
||||
const byte_index = self.bit_offset / 8;
|
||||
const bit_in_byte = self.bit_offset % 8;
|
||||
|
||||
// If we are moving into a new byte, grow the ArrayList
|
||||
if (byte_index >= self.bytes.items.len) {
|
||||
try self.bytes.append(allocator, 0);
|
||||
}
|
||||
|
||||
const space_in_byte = 8 - bit_in_byte;
|
||||
const chunk_size = @min(remaining, space_in_byte);
|
||||
|
||||
const mask : u8 = std.math.shr(u8, 0xFF, 8 - chunk_size);
|
||||
|
||||
const bits : u8 = @truncate(std.math.shr(UnsignedT, bits_to_write, remaining - chunk_size) & mask);
|
||||
|
||||
self.bytes.items[byte_index] |= std.math.shl(u8, bits, space_in_byte - chunk_size);
|
||||
|
||||
self.bit_offset += chunk_size;
|
||||
remaining -= chunk_size;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn written(self: *BitWriter) []const u8 {
|
||||
const bytes_used = (self.bit_offset + 7) / 8; // round up bits → bytes
|
||||
return self.bytes.items[0..bytes_used];
|
||||
}
|
||||
};
|
||||
|
||||
pub const BitReader = struct {
|
||||
bytes: []const u8,
|
||||
bit_offset: usize = 0,
|
||||
|
||||
pub fn init(bytes: []const u8) BitReader {
|
||||
return .{ .bytes = bytes };
|
||||
}
|
||||
|
||||
pub fn deserialize(self: *BitReader, allocator: std.mem.Allocator, T: type) !T {
|
||||
return switch (@typeInfo(T)) {
|
||||
.@"struct" => |s| b: {
|
||||
var data: T = undefined;
|
||||
inline for (s.fields) |f|
|
||||
@field(data, f.name) = try self.deserialize(allocator, f.type);
|
||||
break :b data;
|
||||
},
|
||||
.@"union" => |u| switch (try self.deserialize(allocator, u.tag_type.?)) {
|
||||
inline else => |t| b: {
|
||||
var data: T = @unionInit(T, @tagName(t), undefined);
|
||||
const field = &@field(data, @tagName(t));
|
||||
field.* = try self.deserialize(allocator, @TypeOf(field.*));
|
||||
break :b data;
|
||||
},
|
||||
},
|
||||
.@"enum" => |e| @enumFromInt(try self.deserialize(allocator, e.tag_type)),
|
||||
.pointer => |p| switch (p.size) {
|
||||
.one => b: {
|
||||
const ptr = try allocator.create(p.child);
|
||||
errdefer allocator.destroy(ptr);
|
||||
ptr.* = try self.deserialize(allocator, p.child);
|
||||
break :b ptr;
|
||||
},
|
||||
.slice => b: {
|
||||
const slice = try allocator.alloc(p.child, try self.deserialize(allocator, usize));
|
||||
errdefer allocator.free(slice);
|
||||
for (slice) |*e|
|
||||
e.* = try self.deserialize(allocator, p.child);
|
||||
break :b slice;
|
||||
},
|
||||
.many, .c => @compileError(std.fmt.comptimePrint("Unsupported type: {}", .{T})),
|
||||
},
|
||||
.int, .bool, .float => self.read(T),
|
||||
.void => {},
|
||||
.array => |a| b: {
|
||||
var array: T = undefined;
|
||||
if (@sizeOf(a.child) == 1) {
|
||||
try self.read(&array);
|
||||
} else {
|
||||
for (&array) |*e|
|
||||
e.* = try self.deserialize(allocator, a.child);
|
||||
}
|
||||
break :b array;
|
||||
},
|
||||
.optional => |o| if (try self.deserialize(allocator, bool))
|
||||
try self.deserialize(o.child, allocator)
|
||||
else
|
||||
null,
|
||||
.vector => |v| try self.deserialize(allocator, [v.len]v.child),
|
||||
else => @compileError(std.fmt.comptimePrint("Unsupported type: {}", .{T})),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn read(self: *BitReader, comptime T: type) T {
|
||||
// const info = @typeInfo(T);
|
||||
|
||||
const bit_width = @bitSizeOf(T);
|
||||
|
||||
const UnsignedT = std.meta.Int(.unsigned, bit_width);
|
||||
|
||||
var remaining: usize = bit_width;
|
||||
var result: UnsignedT = 0;
|
||||
|
||||
while (remaining > 0) {
|
||||
const byte_index = self.bit_offset / 8;
|
||||
const bit_in_byte = self.bit_offset % 8;
|
||||
|
||||
const space_in_byte = 8 - bit_in_byte;
|
||||
const chunk_size = @min(remaining, space_in_byte);
|
||||
|
||||
const mask: u8 = std.math.shr(u8, 0xFF, 8 - chunk_size);
|
||||
|
||||
// Extract chunk MSB-first from current byte
|
||||
const shift_from_byte = space_in_byte - chunk_size;
|
||||
|
||||
const bits: u8 = std.math.shr(u8, self.bytes[byte_index], shift_from_byte) & mask;
|
||||
|
||||
// Shift into result (from MSB side)
|
||||
result |= std.math.shl(UnsignedT, @intCast(bits), remaining - chunk_size);
|
||||
|
||||
self.bit_offset += chunk_size;
|
||||
remaining -= chunk_size;
|
||||
}
|
||||
|
||||
return @bitCast(result);
|
||||
}
|
||||
};
|
||||
|
||||
test "Bit Stream" {
|
||||
std.debug.print("Bit Stream\n", .{});
|
||||
const allocator = std.testing.allocator;
|
||||
|
||||
var aw = try std.ArrayList(u8).initCapacity(allocator, 128);
|
||||
defer aw.deinit(allocator);
|
||||
|
||||
var writer = BitWriter.init(&aw);
|
||||
|
||||
const _a : u3 = 0x5;
|
||||
const _b : bool = true;
|
||||
const _c : u3 = 0x1;
|
||||
const _d : u4 = 0xE;
|
||||
const _e : u32 = 0xFFFFFFFA;
|
||||
const _f : i32 = -3;
|
||||
const _g : f32 = 6.667;
|
||||
|
||||
const ts = struct {
|
||||
a: i32,
|
||||
n: []const u8,
|
||||
|
||||
pub fn format(self: @This(), w: *std.io.Writer) !void {
|
||||
|
||||
try w.print(".{{ .a = {}, .n = \"{s}\" }}", .{ self.a, self.n });
|
||||
}
|
||||
};
|
||||
|
||||
const _h : ts = .{
|
||||
.a = 44,
|
||||
.n = "hello",
|
||||
};
|
||||
|
||||
try writer.serialize(allocator, _a);
|
||||
try writer.serialize(allocator, _b);
|
||||
try writer.serialize(allocator, _c);
|
||||
try writer.serialize(allocator, _d);
|
||||
try writer.serialize(allocator, _e);
|
||||
try writer.serialize(allocator, _f);
|
||||
try writer.serialize(allocator, _g);
|
||||
try writer.serialize(allocator, _h);
|
||||
|
||||
var reader = BitReader.init(writer.written());
|
||||
|
||||
const _1 : u3 = try reader.deserialize(allocator, u3);
|
||||
const _2 : bool = try reader.deserialize(allocator, bool);
|
||||
const _3 : u3 = try reader.deserialize(allocator, u3);
|
||||
const _4 : u4 = try reader.deserialize(allocator, u4);
|
||||
const _5 : u32 = try reader.deserialize(allocator, u32);
|
||||
const _6 : i32 = try reader.deserialize(allocator, i32);
|
||||
const _7 = try reader.deserialize(allocator, f32);
|
||||
const _8 = try reader.deserialize(allocator, ts);
|
||||
defer allocator.free(_8.n);
|
||||
|
||||
try std.testing.expectEqual(_a, _1);
|
||||
try std.testing.expectEqual(_b, _2);
|
||||
try std.testing.expectEqual(_c, _3);
|
||||
try std.testing.expectEqual(_d, _4);
|
||||
try std.testing.expectEqual(_e, _5);
|
||||
try std.testing.expectEqual(_f, _6);
|
||||
try std.testing.expectEqual(_g, _7);
|
||||
|
||||
try std.testing.expectEqualDeep(_h, _8);
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
pub const enet = @cImport({
|
||||
@cInclude("enet/enet.h");
|
||||
});
|
||||
+104
-77
@@ -1,94 +1,121 @@
|
||||
const std = @import("std");
|
||||
const std = @import("std");
|
||||
const entity = @import("entity.zig");
|
||||
const misc = @import("misc.zig");
|
||||
const misc = @import("misc.zig");
|
||||
|
||||
pub fn Storage(comptime T: type) type {
|
||||
return struct {
|
||||
items: std.ArrayList(T),
|
||||
// pub fn Storage(comptime T: type) type {
|
||||
// return struct {
|
||||
// items: std.ArrayList(T),
|
||||
|
||||
pub fn init(allocator: std.mem.Allocator) !@This() {
|
||||
return .{
|
||||
.items = try std.ArrayList(T).initCapacity(allocator, 32),
|
||||
};
|
||||
}
|
||||
// pub fn init(allocator: std.mem.Allocator) !@This() {
|
||||
// return .{
|
||||
// .items = try std.ArrayList(T).initCapacity(allocator, 32),
|
||||
// };
|
||||
// }
|
||||
|
||||
pub fn deinit(self: *@This(), allocator: std.mem.Allocator) void {
|
||||
self.items.deinit(allocator);
|
||||
}
|
||||
// pub fn deinit(self: *@This(), allocator: std.mem.Allocator) void {
|
||||
// self.items.deinit(allocator);
|
||||
// }
|
||||
|
||||
pub fn update(self: *@This()) void {
|
||||
for (self.items.items, 0..) |*item, i| {
|
||||
_ = i;
|
||||
if (@hasDecl(T, "update"))
|
||||
item.update();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
// pub fn update(self: *@This()) void {
|
||||
// for (self.items.items, 0..) |*item, i| {
|
||||
// _ = i;
|
||||
// if (@hasDecl(T, "update"))
|
||||
// item.update();
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
// }
|
||||
|
||||
pub const Chunk = _Chunk();
|
||||
// pub const Chunk = _Chunk();
|
||||
|
||||
fn _Chunk() type {
|
||||
const FieldCount = entity.EntityKinds.len;
|
||||
// fn _Chunk() type {
|
||||
// const FieldCount = entity.EntityKinds.len;
|
||||
|
||||
var fields: [FieldCount]std.builtin.Type.StructField = undefined;
|
||||
// var fields: [FieldCount]std.builtin.Type.StructField = undefined;
|
||||
|
||||
inline for (entity.EntityKinds, 0..) |T, i| {
|
||||
fields[i] = .{
|
||||
.name = misc.short_type_name(T),
|
||||
.type = Storage(T),
|
||||
.default_value_ptr = null,
|
||||
.is_comptime = false,
|
||||
.alignment = @alignOf(Storage(T)),
|
||||
// inline for (entity.EntityKinds, 0..) |T, i| {
|
||||
// fields[i] = .{
|
||||
// .name = misc.short_type_name(T),
|
||||
// .type = std.ArrayList(T),
|
||||
// .default_value_ptr = null,
|
||||
// .is_comptime = false,
|
||||
// .alignment = @alignOf(std.ArrayList(T)),
|
||||
// };
|
||||
// }
|
||||
|
||||
// return @Type(.{
|
||||
// .@"struct" = .{
|
||||
// .layout = .auto,
|
||||
// .fields = &fields,
|
||||
// .decls = &.{},
|
||||
// .is_tuple = false,
|
||||
// },
|
||||
// });
|
||||
// }
|
||||
|
||||
// pub fn initChunk(allocator: std.mem.Allocator) !Chunk {
|
||||
// var chunk: Chunk = undefined;
|
||||
|
||||
// inline for (@typeInfo(Chunk).@"struct".fields) |field| {
|
||||
// const ListT = field.type;
|
||||
// @field(chunk, field.name) = try ListT.initCapacity(allocator, 32);
|
||||
// }
|
||||
|
||||
// return chunk;
|
||||
// }
|
||||
|
||||
// pub fn deinitChunk(chunk: *Chunk, allocator: std.mem.Allocator) void {
|
||||
// switch (@typeInfo(Chunk)) {
|
||||
// .@"struct" => |s| {
|
||||
// inline for (s.fields) |field| {
|
||||
// @field(chunk, field.name).deinit(allocator);
|
||||
// }
|
||||
// },
|
||||
// else => unreachable,
|
||||
// }
|
||||
// }
|
||||
|
||||
// pub fn updateChunk(chunk: *Chunk) void {
|
||||
// inline for (@typeInfo(Chunk).@"struct".fields) |field| {
|
||||
// const list = &@field(chunk, field.name);
|
||||
|
||||
// for (list.items, 0..) |*item, i| {
|
||||
// _ = i;
|
||||
// if (@hasDecl(@TypeOf(item.*), "update"))
|
||||
// item.update();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
pub const Chunk = struct {
|
||||
entities : std.ArrayList(entity.Ref),
|
||||
|
||||
pub fn init(allocator: std.mem.Allocator) !Chunk {
|
||||
return .{
|
||||
.entities = try std.ArrayList(entity.Ref).initCapacity(allocator, 128),
|
||||
};
|
||||
}
|
||||
|
||||
return @Type(.{
|
||||
.@"struct" = .{
|
||||
.layout = .auto,
|
||||
.fields = &fields,
|
||||
.decls = &.{},
|
||||
.is_tuple = false,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
pub fn initChunk(allocator: std.mem.Allocator) !Chunk {
|
||||
var chunk: Chunk = undefined;
|
||||
|
||||
switch (@typeInfo(Chunk)) {
|
||||
.@"struct" => |s| {
|
||||
inline for (s.fields) |field| {
|
||||
const StorageT = field.type;
|
||||
@field(chunk, field.name) = try StorageT.init(allocator);
|
||||
pub fn deinit(self: *@This(), allocator: std.mem.Allocator) void {
|
||||
for (self.entities.items) |ref| {
|
||||
switch (ref) {
|
||||
inline else => |ptr| allocator.destroy(ptr),
|
||||
}
|
||||
},
|
||||
else => unreachable,
|
||||
}
|
||||
|
||||
self.entities.deinit(allocator);
|
||||
}
|
||||
|
||||
return chunk;
|
||||
}
|
||||
|
||||
pub fn deinitChunk(chunk: *Chunk, allocator: std.mem.Allocator) void {
|
||||
switch (@typeInfo(Chunk)) {
|
||||
.@"struct" => |s| {
|
||||
inline for (s.fields) |field| {
|
||||
@field(chunk, field.name).deinit(allocator);
|
||||
pub fn update(self: *@This(), dt: f32) void {
|
||||
for (self.entities.items) |e| {
|
||||
switch (e) {
|
||||
.Soldier => |s| {
|
||||
s.update(dt);
|
||||
},
|
||||
.Alien => |a| {
|
||||
a.update(dt);
|
||||
},
|
||||
}
|
||||
},
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn updateChunk(chunk: *Chunk) void {
|
||||
const info = @typeInfo(Chunk);
|
||||
|
||||
switch (info) {
|
||||
.@"struct" => |s| {
|
||||
inline for (s.fields) |field| {
|
||||
@field(chunk, field.name).update();
|
||||
}
|
||||
},
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
};
|
||||
+87
-27
@@ -1,43 +1,103 @@
|
||||
const std = @import("std");
|
||||
const zm = @import("zmath");
|
||||
const protocol = @import("protocol.zig");
|
||||
const std = @import("std");
|
||||
const zm = @import("zmath");
|
||||
const misc = @import("misc.zig");
|
||||
|
||||
pub const id = u64;
|
||||
pub const INVALID_ID: id = 0;
|
||||
|
||||
pub const EntityKinds = .{
|
||||
Elf,
|
||||
Monster,
|
||||
Projectile,
|
||||
Soldier,
|
||||
Alien,
|
||||
};
|
||||
|
||||
pub const Elf = struct {
|
||||
const Entity = struct {
|
||||
|
||||
};
|
||||
|
||||
pub const Soldier = struct {
|
||||
id: id = INVALID_ID,
|
||||
pos: zm.Vec,
|
||||
hp: i32,
|
||||
hp: i32 = 0,
|
||||
pos: zm.Vec = .{0, 0, 0, 0},
|
||||
vel: zm.Vec = .{0, 0, 0, 0},
|
||||
|
||||
pub fn update(self: *Elf) void {
|
||||
self.pos += zm.f32x4(1, 1, 0, 0);
|
||||
}
|
||||
|
||||
pub fn to_message(self: *Elf) protocol.Elf_v1 {
|
||||
return protocol.Elf_v1.init(self);
|
||||
pub fn update(self: *@This(), dt: f32) void {
|
||||
self.pos = self.pos + self.vel * zm.splat(zm.Vec, dt);
|
||||
}
|
||||
};
|
||||
|
||||
pub const Monster = struct {
|
||||
pub const Alien = struct {
|
||||
id: id = INVALID_ID,
|
||||
pos: zm.Vec,
|
||||
hp: i32,
|
||||
};
|
||||
hp: i32 = 0,
|
||||
pos: zm.Vec = .{0, 0, 0, 0},
|
||||
vel: zm.Vec = .{0, 0, 0, 0},
|
||||
|
||||
pub const Projectile = struct {
|
||||
id: id = INVALID_ID,
|
||||
pos: zm.Vec,
|
||||
vel: zm.Vec,
|
||||
|
||||
pub fn update(self: *Projectile) void {
|
||||
self.pos = self.pos + self.vel;
|
||||
std.log.info("pos=({})", .{self.pos});
|
||||
pub fn update(self: *@This(), dt: f32) void {
|
||||
self.pos = self.pos + self.vel * zm.splat(zm.Vec, dt);
|
||||
}
|
||||
};
|
||||
|
||||
fn _Ref() type {
|
||||
const FieldCount = EntityKinds.len;
|
||||
|
||||
var tag_fields: [FieldCount]std.builtin.Type.EnumField = undefined;
|
||||
|
||||
inline for (EntityKinds, 0..) |T, i| {
|
||||
tag_fields[i] = .{
|
||||
.name = misc.short_type_name(T),
|
||||
.value = i,
|
||||
};
|
||||
}
|
||||
|
||||
const Tag = @Type(.{
|
||||
.@"enum" = .{
|
||||
.tag_type = u8,
|
||||
.fields = &tag_fields,
|
||||
.decls = &.{},
|
||||
.is_exhaustive = true,
|
||||
},
|
||||
});
|
||||
|
||||
var fields: [FieldCount]std.builtin.Type.UnionField = undefined;
|
||||
|
||||
inline for (EntityKinds, 0..) |T, i| {
|
||||
fields[i] = .{
|
||||
.name = misc.short_type_name(T),
|
||||
.type = *T,
|
||||
.alignment = @alignOf(*T),
|
||||
};
|
||||
}
|
||||
|
||||
return @Type(.{
|
||||
.@"union" = .{
|
||||
.layout = .auto,
|
||||
.fields = &fields,
|
||||
.decls = &.{},
|
||||
.tag_type = Tag,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
pub const Ref = _Ref();
|
||||
|
||||
pub fn setPos(self: Ref, pos: zm.Vec) void {
|
||||
switch (self) {
|
||||
.Soldier => |s| { s.pos = pos; },
|
||||
.Alien => |a| { a.pos = pos; },
|
||||
else => unreachable
|
||||
}
|
||||
}
|
||||
|
||||
pub fn makeRef(comptime T: type, ptr: *T) Ref {
|
||||
inline for (EntityKinds) |U| {
|
||||
if (T == U) {
|
||||
return @unionInit(
|
||||
Ref,
|
||||
misc.short_type_name(U),
|
||||
ptr,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@compileError("Type not in EntityKinds: " ++ @typeName(T));
|
||||
}
|
||||
|
||||
@@ -1,146 +0,0 @@
|
||||
const std = @import("std");
|
||||
const zm = @import("zmath");
|
||||
const bufzilla = @import("bufzilla");
|
||||
|
||||
const entity = @import("entity.zig");
|
||||
|
||||
pub const SERVER_PORT: u16 = 1337;
|
||||
|
||||
pub const Message = union(enum) {
|
||||
spawn_entity: SpawnEntity,
|
||||
// later: despawn_entity, update_entity, snapshot, etc.
|
||||
};
|
||||
|
||||
pub const SpawnEntity = union(enum) {
|
||||
elf_v1: Elf_v1,
|
||||
monster_v1: Monster_v1,
|
||||
projectile_v1: Projectile_v1,
|
||||
};
|
||||
|
||||
pub fn makeSpawnMessage(comptime T: type, e: T) Message {
|
||||
if (T == entity.Elf) {
|
||||
return .{ .spawn_entity = .{ .elf_v1 = Elf_v1.init(e) } };
|
||||
} else if (T == entity.Monster) {
|
||||
return .{ .spawn_entity = .{ .monster_v1 = Monster_v1.init(e) } };
|
||||
} else if (T == entity.Projectile) {
|
||||
return .{ .spawn_entity = .{ .projectile_v1 = Projectile_v1.init(e) } };
|
||||
}
|
||||
}
|
||||
|
||||
// pub fn write_message(writer: *std.Io.Writer, msg_type: MessageType, payload: []const u8) !void {
|
||||
// try writer.writeByte(@intFromEnum(msg_type));
|
||||
// try writer.writeInt(u32, @intCast(payload.len), .little);
|
||||
// try writer.writeAll(payload);
|
||||
// }
|
||||
|
||||
// pub fn read_message(reader: *std.Io.Reader, allocator: std.mem.Allocator) !struct {
|
||||
// msg_type: MessageType,
|
||||
// payload: []u8,
|
||||
// } {
|
||||
// const msg_type = try reader.readByte();
|
||||
// const size = try reader.readInt(u32, .little);
|
||||
|
||||
// const payload = try allocator.alloc(u8, size);
|
||||
// errdefer allocator.free(payload);
|
||||
|
||||
// try reader.readNoEof(payload);
|
||||
|
||||
// return .{
|
||||
// .msg_type = @enumFromInt(msg_type),
|
||||
// .payload = payload,
|
||||
// };
|
||||
// }
|
||||
|
||||
pub const Elf_v1 = struct {
|
||||
id: entity.id = entity.INVALID_ID,
|
||||
pos: zm.Vec,
|
||||
hp: i32,
|
||||
|
||||
pub fn init(elf: entity.Elf) Elf_v1 {
|
||||
return .{
|
||||
.id = elf.id,
|
||||
.pos = elf.pos,
|
||||
.hp = elf.hp,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn decode(r: *bufzilla.Reader) !Elf_v1 {
|
||||
_ = r;
|
||||
return .{
|
||||
// .id = try r.readInt(u64, .little),
|
||||
// .pos = try readVec4(r),
|
||||
// .vel = try readVec4(r),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub const Monster_v1 = struct {
|
||||
id: entity.id = entity.INVALID_ID,
|
||||
pos: zm.Vec,
|
||||
hp: i32,
|
||||
|
||||
pub fn init(monster: entity.Monster) Monster_v1 {
|
||||
return .{
|
||||
.id = monster.id,
|
||||
.pos = monster.pos,
|
||||
.hp = monster.hp,
|
||||
};
|
||||
}
|
||||
|
||||
// pub fn encode(self: Monster_v1, w: *std.Io.Writer) !void {
|
||||
// try w.writeInt(u64, self.id, .little);
|
||||
// try writeVec4(w, self.pos);
|
||||
// try writeVec4(w, self.vel);
|
||||
// }
|
||||
|
||||
pub fn decode(r: *std.Io.Reader) !Monster_v1 {
|
||||
return .{
|
||||
.id = try r.readInt(u64, .little),
|
||||
.pos = try readVec4(r),
|
||||
.vel = try readVec4(r),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub const Projectile_v1 = struct {
|
||||
id: entity.id = entity.INVALID_ID,
|
||||
pos: zm.Vec,
|
||||
vel: zm.Vec,
|
||||
|
||||
pub fn init(projectile: entity.Projectile) Projectile_v1 {
|
||||
return .{
|
||||
.id = projectile.id,
|
||||
.pos = projectile.pos,
|
||||
.vel = projectile.vel,
|
||||
};
|
||||
}
|
||||
|
||||
// pub fn encode(self: Projectile_v1, w: *std.Io.Writer) !void {
|
||||
// try w.writeInt(u64, self.id, .little);
|
||||
// try writeVec4(w, self.pos);
|
||||
// try writeVec4(w, self.vel);
|
||||
// }
|
||||
|
||||
pub fn decode(r: *std.Io.Reader) !Projectile_v1 {
|
||||
return .{
|
||||
.id = try r.readInt(u64, .little),
|
||||
.pos = try readVec4(r),
|
||||
.vel = try readVec4(r),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
fn writeVec4(w: *std.Io.Writer, v: zm.Vec) !void {
|
||||
const a = zm.vecToArr4(v);
|
||||
inline for (a) |f| {
|
||||
try w.writeFloat(f32, f, .little);
|
||||
}
|
||||
}
|
||||
|
||||
fn readVec4(r: *std.Io.Reader) !zm.Vec4 {
|
||||
var a: [4]f32 = undefined;
|
||||
inline for (&a) |*f| {
|
||||
f.* = try r.readFloat(f32, .little);
|
||||
}
|
||||
return zm.loadArr4(a);
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
const std = @import("std");
|
||||
const zm = @import("zmath");
|
||||
// const bufzilla = @import("bufzilla");
|
||||
|
||||
const entity = @import("entity.zig");
|
||||
const bits = @import("bits.zig");
|
||||
|
||||
pub const SERVER_PORT: u16 = 1337;
|
||||
|
||||
const MessageKind = enum(c_char) {
|
||||
spawn_entity,
|
||||
update_entity,
|
||||
despawn_entity,
|
||||
};
|
||||
|
||||
pub const Message = union(MessageKind) {
|
||||
spawn_entity: EntityPayload,
|
||||
update_entity: EntityPayload,
|
||||
despawn_entity: EntityPayload,
|
||||
};
|
||||
|
||||
|
||||
pub fn makeMessage(kind: MessageKind, e: anytype) Message {
|
||||
const payload = payloadFromEntity(e);
|
||||
|
||||
return switch (kind) {
|
||||
.spawn_entity => .{ .spawn_entity = payload },
|
||||
.update_entity => .{ .update_entity = payload },
|
||||
.despawn_entity => .{ .despawn_entity = payload },
|
||||
};
|
||||
}
|
||||
|
||||
pub fn payloadFromEntity(e: entity.Ref) EntityPayload {
|
||||
return switch (e) {
|
||||
.Soldier => |s| .{ .soldier = Soldier.init(s.*) },
|
||||
.Alien => |a| .{ .alien = Alien.init(a.*) },
|
||||
};
|
||||
}
|
||||
|
||||
const EntityKind = enum(c_char) {
|
||||
soldier,
|
||||
alien,
|
||||
};
|
||||
|
||||
pub const EntityPayload = union(EntityKind) {
|
||||
soldier: Soldier,
|
||||
alien: Alien,
|
||||
};
|
||||
|
||||
pub const Soldier = struct {
|
||||
id: entity.id = entity.INVALID_ID,
|
||||
hp: i32,
|
||||
pos: zm.Vec,
|
||||
vel: zm.Vec,
|
||||
|
||||
pub fn init(soldier: entity.Soldier) Soldier {
|
||||
return .{
|
||||
.id = soldier.id,
|
||||
.hp = soldier.hp,
|
||||
.pos = soldier.pos,
|
||||
.vel = soldier.vel,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub const Alien = struct {
|
||||
id: entity.id = entity.INVALID_ID,
|
||||
hp: i32,
|
||||
pos: zm.Vec,
|
||||
|
||||
pub fn init(alien: entity.Alien) Alien {
|
||||
return .{
|
||||
.id = alien.id,
|
||||
.pos = alien.pos,
|
||||
.hp = alien.hp,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
test "Protocol" {
|
||||
std.debug.print("Protocol\n", .{});
|
||||
|
||||
const s = entity.Soldier{
|
||||
.hp = 66,
|
||||
.pos = .{1, 2, 3, 4},
|
||||
.vel = .{5, 6, 7, 8},
|
||||
};
|
||||
|
||||
const msg = makeMessage(.spawn_entity, s);
|
||||
|
||||
const allocator = std.testing.allocator;
|
||||
|
||||
var aw = try std.ArrayList(u8).initCapacity(allocator, 128);
|
||||
defer aw.deinit(allocator);
|
||||
|
||||
var writer = bits.BitWriter.init(&aw);
|
||||
|
||||
try writer.serialize(allocator, msg);
|
||||
|
||||
var reader = bits.BitReader.init(writer.written());
|
||||
|
||||
const recv = try reader.deserialize(allocator, Message);
|
||||
|
||||
std.debug.print("msg: {}\n", .{msg});
|
||||
|
||||
std.debug.print("recv: {}\n", .{recv});
|
||||
|
||||
try std.testing.expectEqual(msg, recv);
|
||||
}
|
||||
+10
-4
@@ -1,4 +1,10 @@
|
||||
pub const entity = @import("entity.zig");
|
||||
pub const chunk = @import("chunk.zig");
|
||||
pub const misc = @import("misc.zig");
|
||||
pub const protocol = @import("protocol.zig");
|
||||
pub const entity = @import("entity.zig");
|
||||
pub const chunk = @import("chunk.zig");
|
||||
pub const misc = @import("misc.zig");
|
||||
pub const protocol_v1 = @import("protocol_v1.zig");
|
||||
pub const bits = @import("bits.zig");
|
||||
|
||||
test {
|
||||
const std = @import("std");
|
||||
std.testing.refAllDecls(@This());
|
||||
}
|
||||
Vendored
+74
@@ -0,0 +1,74 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn build(b: *std.Build) !void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
|
||||
const enet_src = b.dependency("enet_src", .{});
|
||||
|
||||
const lib = b.addLibrary(.{
|
||||
.name = "enet",
|
||||
.linkage = .static,
|
||||
.root_module = b.createModule(.{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
}),
|
||||
});
|
||||
|
||||
var flags = try std.ArrayList([]const u8).initCapacity(b.allocator, 0);
|
||||
|
||||
switch (target.result.os.tag) {
|
||||
.linux, .macos => {
|
||||
try flags.append(b.allocator, "-DHAS_FCNTL=1");
|
||||
try flags.append(b.allocator, "-DHAS_POLL=1");
|
||||
try flags.append(b.allocator, "-DHAS_GETADDRINFO=1");
|
||||
try flags.append(b.allocator, "-DHAS_GETNAMEINFO=1");
|
||||
try flags.append(b.allocator, "-DHAS_INET_PTON=1");
|
||||
try flags.append(b.allocator, "-DHAS_INET_NTOP=1");
|
||||
try flags.append(b.allocator, "-DHAS_MSGHDR_FLAGS=1");
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
|
||||
try flags.append(b.allocator, "-DHAS_OFFSETOF=1");
|
||||
try flags.append(b.allocator, "-DHAS_SOCKLEN_T=1");
|
||||
|
||||
lib.root_module.addCSourceFiles(.{
|
||||
.root = enet_src.path(""),
|
||||
.files = &[_][]const u8{
|
||||
"callbacks.c",
|
||||
"compress.c",
|
||||
"host.c",
|
||||
"list.c",
|
||||
"packet.c",
|
||||
"peer.c",
|
||||
"protocol.c",
|
||||
"unix.c",
|
||||
"win32.c",
|
||||
},
|
||||
.flags = &[_][]const u8{
|
||||
"-DHAS_OFFSETOF=1",
|
||||
"-DHAS_SOCKLEN_T=1",
|
||||
"-DHAS_FCNTL=1",
|
||||
"-DHAS_POLL=1",
|
||||
"-DHAS_GETADDRINFO=1",
|
||||
"-DHAS_GETNAMEINFO=1",
|
||||
"-DHAS_INET_PTON=1",
|
||||
"-DHAS_INET_NTOP=1",
|
||||
"-DHAS_MSGHDR_FLAGS=1",
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
if (target.result.os.tag == .windows) {
|
||||
lib.root_module.linkSystemLibrary("ws2_32", .{});
|
||||
lib.root_module.linkSystemLibrary("winmm", .{});
|
||||
}
|
||||
|
||||
lib.root_module.addIncludePath(enet_src.path("include"));
|
||||
lib.root_module.link_libc = true;
|
||||
|
||||
lib.installHeadersDirectory(enet_src.path("include/enet"), "enet", .{});
|
||||
|
||||
b.installArtifact(lib);
|
||||
}
|
||||
Vendored
+19
@@ -0,0 +1,19 @@
|
||||
.{
|
||||
.name = .enet,
|
||||
.fingerprint = 0x201714c0933cd1fc,
|
||||
.version = "0.1.0",
|
||||
.minimum_zig_version = "0.15.2",
|
||||
.paths = .{
|
||||
"build.zig",
|
||||
"build.zig.zon",
|
||||
"libs",
|
||||
"src",
|
||||
"README.md",
|
||||
},
|
||||
.dependencies = .{
|
||||
.enet_src = .{
|
||||
.url = "https://github.com/lsalzman/enet/archive/refs/heads/master.tar.gz",
|
||||
.hash = "N-V-__8AAOfEBQDV0QE6f1lRiGiqZa9k3-ZkthJHdwGIp3Zh",
|
||||
},
|
||||
},
|
||||
}
|
||||
Vendored
+145
@@ -0,0 +1,145 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
|
||||
// const use_system_zlib = b.option(bool, "use_system_zlib", "Use system zlib") orelse false;
|
||||
// const enable_brotli = b.option(bool, "enable_brotli", "Build Brotli") orelse true;
|
||||
|
||||
const freetype_src = b.dependency("freetype_src", .{ .target = target, .optimize = optimize });
|
||||
|
||||
const lib = b.addLibrary(.{
|
||||
.name = "freetype",
|
||||
.linkage = .static,
|
||||
.root_module = b.createModule(.{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
}),
|
||||
});
|
||||
|
||||
lib.root_module.link_libc = true;
|
||||
lib.addIncludePath(b.path("include"));
|
||||
lib.root_module.addCMacro("FT2_BUILD_LIBRARY", "1");
|
||||
|
||||
// if (use_system_zlib) {
|
||||
// lib.root_module.addCMacro("FT_CONFIG_OPTION_SYSTEM_ZLIB", "1");
|
||||
// }
|
||||
|
||||
// if (enable_brotli) {
|
||||
// lib.root_module.addCMacro("FT_CONFIG_OPTION_USE_BROTLI", "1");
|
||||
// if (b.lazyDependency("brotli", .{
|
||||
// .target = target,
|
||||
// .optimize = optimize,
|
||||
// })) |dep| lib.linkLibrary(dep.artifact("brotli"));
|
||||
// }
|
||||
|
||||
lib.root_module.addCMacro("HAVE_UNISTD_H", "1");
|
||||
lib.root_module.addCSourceFile(.{ .file = freetype_src.path("src/autofit/autofit.c") });
|
||||
lib.root_module.addCSourceFile(.{ .file = freetype_src.path("src/base/ftbase.c") });
|
||||
lib.root_module.addCSourceFile(.{ .file = freetype_src.path("src/base/ftsystem.c") });
|
||||
lib.root_module.addCSourceFile(.{ .file = freetype_src.path("src/base/ftdebug.c") });
|
||||
lib.root_module.addCSourceFile(.{ .file = freetype_src.path("src/base/ftbbox.c") });
|
||||
lib.root_module.addCSourceFile(.{ .file = freetype_src.path("src/base/ftbdf.c") });
|
||||
lib.root_module.addCSourceFile(.{ .file = freetype_src.path("src/base/ftbitmap.c") });
|
||||
lib.root_module.addCSourceFile(.{ .file = freetype_src.path("src/base/ftcid.c") });
|
||||
lib.root_module.addCSourceFile(.{ .file = freetype_src.path("src/base/ftfstype.c") });
|
||||
lib.root_module.addCSourceFile(.{ .file = freetype_src.path("src/base/ftgasp.c") });
|
||||
lib.root_module.addCSourceFile(.{ .file = freetype_src.path("src/base/ftglyph.c") });
|
||||
lib.root_module.addCSourceFile(.{ .file = freetype_src.path("src/base/ftgxval.c") });
|
||||
lib.root_module.addCSourceFile(.{ .file = freetype_src.path("src/base/ftinit.c") });
|
||||
lib.root_module.addCSourceFile(.{ .file = freetype_src.path("src/base/ftmm.c") });
|
||||
lib.root_module.addCSourceFile(.{ .file = freetype_src.path("src/base/ftotval.c") });
|
||||
lib.root_module.addCSourceFile(.{ .file = freetype_src.path("src/base/ftpatent.c") });
|
||||
lib.root_module.addCSourceFile(.{ .file = freetype_src.path("src/base/ftpfr.c") });
|
||||
lib.root_module.addCSourceFile(.{ .file = freetype_src.path("src/base/ftstroke.c") });
|
||||
lib.root_module.addCSourceFile(.{ .file = freetype_src.path("src/base/ftsynth.c") });
|
||||
lib.root_module.addCSourceFile(.{ .file = freetype_src.path("src/base/fttype1.c") });
|
||||
lib.root_module.addCSourceFile(.{ .file = freetype_src.path("src/base/ftwinfnt.c") });
|
||||
lib.root_module.addCSourceFile(.{ .file = freetype_src.path("src/bdf/bdf.c") });
|
||||
lib.root_module.addCSourceFile(.{ .file = freetype_src.path("src/bzip2/ftbzip2.c") });
|
||||
lib.root_module.addCSourceFile(.{ .file = freetype_src.path("src/cache/ftcache.c") });
|
||||
lib.root_module.addCSourceFile(.{ .file = freetype_src.path("src/cff/cff.c") });
|
||||
lib.root_module.addCSourceFile(.{ .file = freetype_src.path("src/cid/type1cid.c") });
|
||||
lib.root_module.addCSourceFile(.{ .file = freetype_src.path("src/gzip/ftgzip.c") });
|
||||
lib.root_module.addCSourceFile(.{ .file = freetype_src.path("src/lzw/ftlzw.c") });
|
||||
lib.root_module.addCSourceFile(.{ .file = freetype_src.path("src/pcf/pcf.c") });
|
||||
lib.root_module.addCSourceFile(.{ .file = freetype_src.path("src/pfr/pfr.c") });
|
||||
lib.root_module.addCSourceFile(.{ .file = freetype_src.path("src/psaux/psaux.c") });
|
||||
lib.root_module.addCSourceFile(.{ .file = freetype_src.path("src/pshinter/pshinter.c") });
|
||||
lib.root_module.addCSourceFile(.{ .file = freetype_src.path("src/psnames/psnames.c") });
|
||||
lib.root_module.addCSourceFile(.{ .file = freetype_src.path("src/raster/raster.c") });
|
||||
lib.root_module.addCSourceFile(.{ .file = freetype_src.path("src/sdf/sdf.c") });
|
||||
lib.root_module.addCSourceFile(.{ .file = freetype_src.path("src/sfnt/sfnt.c") });
|
||||
lib.root_module.addCSourceFile(.{ .file = freetype_src.path("src/smooth/smooth.c") });
|
||||
lib.root_module.addCSourceFile(.{ .file = freetype_src.path("src/svg/svg.c") });
|
||||
lib.root_module.addCSourceFile(.{ .file = freetype_src.path("src/truetype/truetype.c") });
|
||||
lib.root_module.addCSourceFile(.{ .file = freetype_src.path("src/type1/type1.c") });
|
||||
lib.root_module.addCSourceFile(.{ .file = freetype_src.path("src/type42/type42.c") });
|
||||
lib.root_module.addCSourceFile(.{ .file = freetype_src.path("src/winfonts/winfnt.c") });
|
||||
|
||||
lib.root_module.addIncludePath(freetype_src.path("include"));
|
||||
|
||||
// lib.addCSourceFiles(.{ .files = &sources, .flags = &.{} });
|
||||
if (target.result.os.tag == .macos)
|
||||
lib.addCSourceFile(.{
|
||||
.file = freetype_src.path("src/base/ftmac.c"),
|
||||
.flags = &.{},
|
||||
});
|
||||
lib.installHeadersDirectory(freetype_src.path("include/freetype"), "freetype", .{});
|
||||
lib.installHeader(freetype_src.path("include/ft2build.h"), "ft2build.h");
|
||||
b.installArtifact(lib);
|
||||
|
||||
const freetype = b.addModule("freetype", .{
|
||||
.root_source_file = b.path("src/freetype.zig"),
|
||||
.imports = &.{
|
||||
},
|
||||
});
|
||||
|
||||
freetype.linkLibrary(lib);
|
||||
}
|
||||
|
||||
// const sources = [_][]const u8{
|
||||
// "src/autofit/autofit.c",
|
||||
// "src/base/ftbase.c",
|
||||
// "src/base/ftsystem.c",
|
||||
// "src/base/ftdebug.c",
|
||||
// "src/base/ftbbox.c",
|
||||
// "src/base/ftbdf.c",
|
||||
// "src/base/ftbitmap.c",
|
||||
// "src/base/ftcid.c",
|
||||
// "src/base/ftfstype.c",
|
||||
// "src/base/ftgasp.c",
|
||||
// "src/base/ftglyph.c",
|
||||
// "src/base/ftgxval.c",
|
||||
// "src/base/ftinit.c",
|
||||
// "src/base/ftmm.c",
|
||||
// "src/base/ftotval.c",
|
||||
// "src/base/ftpatent.c",
|
||||
// "src/base/ftpfr.c",
|
||||
// "src/base/ftstroke.c",
|
||||
// "src/base/ftsynth.c",
|
||||
// "src/base/fttype1.c",
|
||||
// "src/base/ftwinfnt.c",
|
||||
// "src/bdf/bdf.c",
|
||||
// "src/bzip2/ftbzip2.c",
|
||||
// "src/cache/ftcache.c",
|
||||
// "src/cff/cff.c",
|
||||
// "src/cid/type1cid.c",
|
||||
// "src/gzip/ftgzip.c",
|
||||
// "src/lzw/ftlzw.c",
|
||||
// "src/pcf/pcf.c",
|
||||
// "src/pfr/pfr.c",
|
||||
// "src/psaux/psaux.c",
|
||||
// "src/pshinter/pshinter.c",
|
||||
// "src/psnames/psnames.c",
|
||||
// "src/raster/raster.c",
|
||||
// "src/sdf/sdf.c",
|
||||
// "src/sfnt/sfnt.c",
|
||||
// "src/smooth/smooth.c",
|
||||
// "src/svg/svg.c",
|
||||
// "src/truetype/truetype.c",
|
||||
// "src/type1/type1.c",
|
||||
// "src/type42/type42.c",
|
||||
// "src/winfonts/winfnt.c",
|
||||
// };
|
||||
Vendored
+19
@@ -0,0 +1,19 @@
|
||||
.{
|
||||
.name = .freetype,
|
||||
.fingerprint = 0xac2059b69e282536,
|
||||
.version = "0.1.0",
|
||||
.minimum_zig_version = "0.15.2",
|
||||
.paths = .{
|
||||
"build.zig",
|
||||
"build.zig.zon",
|
||||
"libs",
|
||||
"src",
|
||||
"README.md",
|
||||
},
|
||||
.dependencies = .{
|
||||
.freetype_src = .{
|
||||
.url = "https://github.com/freetype/freetype/archive/refs/heads/master.tar.gz",
|
||||
.hash = "N-V-__8AAGJyqgCBGp-ibrZFNycPitwyNbU5U83UzSNGyJnT",
|
||||
},
|
||||
},
|
||||
}
|
||||
File renamed without changes.
-1293
File diff suppressed because it is too large.
Load diff
Vendored
+121
@@ -0,0 +1,121 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
|
||||
const options = .{
|
||||
.enable_tracy = b.option(
|
||||
bool,
|
||||
"enable_tracy",
|
||||
"Enable Tracy profile markers",
|
||||
) orelse false,
|
||||
.enable_fibers = b.option(
|
||||
bool,
|
||||
"enable_fibers",
|
||||
"Enable Tracy fiber support",
|
||||
) orelse false,
|
||||
.on_demand = b.option(
|
||||
bool,
|
||||
"on_demand",
|
||||
"Build tracy with TRACY_ON_DEMAND",
|
||||
) orelse false,
|
||||
.callstack = b.option(
|
||||
u32,
|
||||
"callstack",
|
||||
"If > 0, Builds tracy with TRACY_USE_CALLSTACK and sets TRACY_CALLSTACK to the depth provided.",
|
||||
) orelse 0,
|
||||
.shared = b.option(
|
||||
bool,
|
||||
"shared",
|
||||
"Build as shared library",
|
||||
) orelse false,
|
||||
};
|
||||
|
||||
const options_step = b.addOptions();
|
||||
inline for (std.meta.fields(@TypeOf(options))) |field| {
|
||||
options_step.addOption(field.type, field.name, @field(options, field.name));
|
||||
}
|
||||
|
||||
const options_module = options_step.createModule();
|
||||
|
||||
const tracy_src = b.dependency("tracy_src", .{ .target = target, .optimize = optimize });
|
||||
|
||||
const translate_c = b.addTranslateC(.{
|
||||
.root_source_file = tracy_src.path("public/tracy/TracyC.h"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.link_libc = true,
|
||||
});
|
||||
translate_c.addIncludePath(tracy_src.path("public/tracy"));
|
||||
translate_c.defineCMacro("TRACY_ENABLE", "");
|
||||
translate_c.defineCMacro("TRACY_IMPORTS", "");
|
||||
if (options.callstack > 0) {
|
||||
translate_c.defineCMacro("TRACY_USE_CALLSTACK", "");
|
||||
var callstack_buffer: [64]u8 = undefined;
|
||||
const callstack_str_len = std.fmt.printInt(&callstack_buffer, @as(u32, options.callstack), 10, .lower, .{});
|
||||
translate_c.defineCMacro("TRACY_CALLSTACK", callstack_buffer[0..callstack_str_len]);
|
||||
}
|
||||
|
||||
const tracy_lib = b.addLibrary(.{
|
||||
.name = "tracy",
|
||||
.linkage = if (options.shared) .dynamic else .static,
|
||||
.root_module = b.createModule(.{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
}),
|
||||
});
|
||||
|
||||
if (options.shared) tracy_lib.root_module.addCMacro("TRACY_EXPORTS", "");
|
||||
|
||||
if (target.result.os.tag == .windows) tracy_lib.root_module.addCMacro("_WIN32_WINNT", "0x0601");
|
||||
|
||||
if (options.enable_tracy) tracy_lib.root_module.addCMacro("TRACY_ENABLE", "");
|
||||
if (options.enable_fibers) tracy_lib.root_module.addCMacro("TRACY_FIBERS", "");
|
||||
if (options.on_demand) tracy_lib.root_module.addCMacro("TRACY_ON_DEMAND", "");
|
||||
|
||||
tracy_lib.root_module.addIncludePath(tracy_src.path("public"));
|
||||
tracy_lib.root_module.addIncludePath(tracy_src.path("public/tracy"));
|
||||
tracy_lib.root_module.addIncludePath(tracy_src.path("public/common"));
|
||||
tracy_lib.root_module.addIncludePath(tracy_src.path("public/client"));
|
||||
tracy_lib.root_module.addCSourceFile(.{
|
||||
.file = tracy_src.path("public/TracyClient.cpp"),
|
||||
.flags = &.{
|
||||
"-fno-sanitize=undefined",
|
||||
},
|
||||
});
|
||||
|
||||
tracy_lib.root_module.link_libc = true;
|
||||
if (target.result.abi != .msvc) {
|
||||
tracy_lib.root_module.link_libcpp = true;
|
||||
} else {
|
||||
tracy_lib.root_module.addCMacro("fileno", "_fileno");
|
||||
}
|
||||
|
||||
// switch (target.result.os.tag) {
|
||||
// .windows => {
|
||||
// tracy_lib.root_module.linkSystemLibrary("ws2_32", .{});
|
||||
// tracy_lib.root_module.linkSystemLibrary("dbghelp", .{});
|
||||
// tracy_lib.root_module.linkSystemLibrary("secur32", .{}); // Provides GetUserNameExA
|
||||
// tracy_lib.root_module.linkSystemLibrary("user32", .{}); // Often needed for other system calls
|
||||
// tracy_lib.root_module.linkSystemLibrary("advapi32", .{});
|
||||
// },
|
||||
// // .macos => {
|
||||
// // if (b.lazyDependency("system_sdk", .{})) |system_sdk| {
|
||||
// // tracy_lib.root_module.addFrameworkPath(system_sdk.path("System/Library/Frameworks"));
|
||||
// // }
|
||||
// // },
|
||||
// else => {},
|
||||
// }
|
||||
|
||||
b.installArtifact(tracy_lib);
|
||||
|
||||
const tracy = b.addModule("tracy", .{
|
||||
.root_source_file = b.path("src/tracy.zig"),
|
||||
.imports = &.{
|
||||
.{ .name = "tracy_options", .module = options_module },
|
||||
},
|
||||
});
|
||||
tracy.addImport("c", translate_c.createModule());
|
||||
tracy.linkLibrary(tracy_lib);
|
||||
}
|
||||
Vendored
+19
@@ -0,0 +1,19 @@
|
||||
.{
|
||||
.name = .tracy,
|
||||
.fingerprint = 0x255a89ee2e5fcfa8,
|
||||
.version = "0.1.0",
|
||||
.minimum_zig_version = "0.15.2",
|
||||
.paths = .{
|
||||
"build.zig",
|
||||
"build.zig.zon",
|
||||
"libs",
|
||||
"src",
|
||||
"README.md",
|
||||
},
|
||||
.dependencies = .{
|
||||
.tracy_src = .{
|
||||
.url = "https://github.com/wolfpld/tracy/archive/8f0c83dbf90faa982624e005ce76ff0fd5c77153.zip",
|
||||
.hash = "N-V-__8AAAF7OgG5ck73SkEmLbQPExC4jddnsDCAMtBAIBXy",
|
||||
},
|
||||
},
|
||||
}
|
||||
Vendored
+395
@@ -0,0 +1,395 @@
|
||||
const std = @import("std");
|
||||
const Src = std.builtin.SourceLocation;
|
||||
|
||||
const c = @import("c");
|
||||
const has_callstack_support = @hasDecl(c, "TRACY_HAS_CALLSTACK") and @hasDecl(c, "TRACY_CALLSTACK");
|
||||
const callstack_depth: c_int = if (has_callstack_support) c.TRACY_CALLSTACK else 0;
|
||||
|
||||
const debug_verify_stack_order = false;
|
||||
threadlocal var stack_depth: if (debug_verify_stack_order) usize else u0 = 0;
|
||||
|
||||
pub const ZoneCtx = struct {
|
||||
_zone: c.___tracy_c_zone_context,
|
||||
_token: if (debug_verify_stack_order) usize else void,
|
||||
|
||||
pub inline fn Text(self: ZoneCtx, text: []const u8) void {
|
||||
if (debug_verify_stack_order) {
|
||||
if (stack_depth != self._token) {
|
||||
std.debug.panic(
|
||||
"Error: expected Value() at stack depth {} but was {}\n",
|
||||
.{ self._token, stack_depth },
|
||||
);
|
||||
}
|
||||
}
|
||||
c.___tracy_emit_zone_text(self._zone, text.ptr, text.len);
|
||||
}
|
||||
pub inline fn Name(self: ZoneCtx, name: []const u8) void {
|
||||
if (debug_verify_stack_order) {
|
||||
if (stack_depth != self._token) {
|
||||
std.debug.panic(
|
||||
"Error: expected Value() at stack depth {} but was {}\n",
|
||||
.{ self._token, stack_depth },
|
||||
);
|
||||
}
|
||||
}
|
||||
c.___tracy_emit_zone_name(self._zone, name.ptr, name.len);
|
||||
}
|
||||
pub inline fn Value(self: ZoneCtx, val: u64) void {
|
||||
if (debug_verify_stack_order) {
|
||||
if (stack_depth != self._token) {
|
||||
std.debug.panic(
|
||||
"Error: expected Value() at stack depth {} but was {}\n",
|
||||
.{ self._token, stack_depth },
|
||||
);
|
||||
}
|
||||
}
|
||||
c.___tracy_emit_zone_value(self._zone, val);
|
||||
}
|
||||
pub inline fn End(self: ZoneCtx) void {
|
||||
if (debug_verify_stack_order) {
|
||||
if (stack_depth != self._token) {
|
||||
std.debug.panic(
|
||||
"Error: expected End() at stack depth {} but was {}\n",
|
||||
.{ self._token, stack_depth },
|
||||
);
|
||||
}
|
||||
stack_depth -= 1;
|
||||
}
|
||||
c.___tracy_emit_zone_end(self._zone);
|
||||
}
|
||||
};
|
||||
|
||||
inline fn initZone(comptime src: Src, name: ?[*:0]const u8, color: u32, depth: c_int) ZoneCtx {
|
||||
// Tracy uses pointer identity to identify contexts.
|
||||
// The `src` parameter being comptime ensures that
|
||||
// each zone gets its own unique global location for this
|
||||
// struct.
|
||||
const static = struct {
|
||||
var loc: c.___tracy_source_location_data = undefined;
|
||||
|
||||
// Ensure that a unique struct type is generated for each unique `src`. See
|
||||
// https://github.com/ziglang/zig/issues/18816
|
||||
comptime {
|
||||
// https://github.com/ziglang/zig/issues/19274
|
||||
_ = @sizeOf(@TypeOf(src));
|
||||
}
|
||||
};
|
||||
static.loc = .{
|
||||
.name = name,
|
||||
.function = src.fn_name.ptr,
|
||||
.file = src.file.ptr,
|
||||
.line = src.line,
|
||||
.color = color,
|
||||
};
|
||||
|
||||
const zone = if (has_callstack_support)
|
||||
c.___tracy_emit_zone_begin_callstack(&static.loc, depth, 1)
|
||||
else
|
||||
c.___tracy_emit_zone_begin(&static.loc, 1);
|
||||
|
||||
if (debug_verify_stack_order) {
|
||||
stack_depth += 1;
|
||||
return ZoneCtx{ ._zone = zone, ._token = stack_depth };
|
||||
} else {
|
||||
return ZoneCtx{ ._zone = zone, ._token = {} };
|
||||
}
|
||||
}
|
||||
|
||||
pub inline fn SetThreadName(name: [*:0]const u8) void {
|
||||
c.___tracy_set_thread_name(name);
|
||||
}
|
||||
|
||||
pub inline fn Zone(comptime src: Src) ZoneCtx {
|
||||
return initZone(src, null, 0, callstack_depth);
|
||||
}
|
||||
pub inline fn ZoneN(comptime src: Src, name: [*:0]const u8) ZoneCtx {
|
||||
return initZone(src, name, 0, callstack_depth);
|
||||
}
|
||||
pub inline fn ZoneC(comptime src: Src, color: u32) ZoneCtx {
|
||||
return initZone(src, null, color, callstack_depth);
|
||||
}
|
||||
pub inline fn ZoneNC(comptime src: Src, name: [*:0]const u8, color: u32) ZoneCtx {
|
||||
return initZone(src, name, color, callstack_depth);
|
||||
}
|
||||
pub inline fn ZoneS(comptime src: Src, depth: i32) ZoneCtx {
|
||||
return initZone(src, null, 0, depth);
|
||||
}
|
||||
pub inline fn ZoneNS(comptime src: Src, name: [*:0]const u8, depth: i32) ZoneCtx {
|
||||
return initZone(src, name, 0, depth);
|
||||
}
|
||||
pub inline fn ZoneCS(comptime src: Src, color: u32, depth: i32) ZoneCtx {
|
||||
return initZone(src, null, color, depth);
|
||||
}
|
||||
pub inline fn ZoneNCS(comptime src: Src, name: [*:0]const u8, color: u32, depth: i32) ZoneCtx {
|
||||
return initZone(src, name, color, depth);
|
||||
}
|
||||
|
||||
pub inline fn Alloc(ptr: ?*const anyopaque, size: usize) void {
|
||||
if (has_callstack_support) {
|
||||
c.___tracy_emit_memory_alloc_callstack(ptr, size, callstack_depth, 0);
|
||||
} else {
|
||||
c.___tracy_emit_memory_alloc(ptr, size, 0);
|
||||
}
|
||||
}
|
||||
pub inline fn Free(ptr: ?*const anyopaque) void {
|
||||
if (has_callstack_support) {
|
||||
c.___tracy_emit_memory_free_callstack(ptr, callstack_depth, 0);
|
||||
} else {
|
||||
c.___tracy_emit_memory_free(ptr, 0);
|
||||
}
|
||||
}
|
||||
pub inline fn SecureAlloc(ptr: ?*const anyopaque, size: usize) void {
|
||||
if (has_callstack_support) {
|
||||
c.___tracy_emit_memory_alloc_callstack(ptr, size, callstack_depth, 1);
|
||||
} else {
|
||||
c.___tracy_emit_memory_alloc(ptr, size, 1);
|
||||
}
|
||||
}
|
||||
pub inline fn SecureFree(ptr: ?*const anyopaque) void {
|
||||
if (has_callstack_support) {
|
||||
c.___tracy_emit_memory_free_callstack(ptr, callstack_depth, 1);
|
||||
} else {
|
||||
c.___tracy_emit_memory_free(ptr, 1);
|
||||
}
|
||||
}
|
||||
pub inline fn AllocS(ptr: ?*const anyopaque, size: usize, depth: c_int) void {
|
||||
if (has_callstack_support) {
|
||||
c.___tracy_emit_memory_alloc_callstack(ptr, size, depth, 0);
|
||||
} else {
|
||||
c.___tracy_emit_memory_alloc(ptr, size, 0);
|
||||
}
|
||||
}
|
||||
pub inline fn FreeS(ptr: ?*const anyopaque, depth: c_int) void {
|
||||
if (has_callstack_support) {
|
||||
c.___tracy_emit_memory_free_callstack(ptr, depth, 0);
|
||||
} else {
|
||||
c.___tracy_emit_memory_free(ptr, 0);
|
||||
}
|
||||
}
|
||||
pub inline fn SecureAllocS(ptr: ?*const anyopaque, size: usize, depth: c_int) void {
|
||||
if (has_callstack_support) {
|
||||
c.___tracy_emit_memory_alloc_callstack(ptr, size, depth, 1);
|
||||
} else {
|
||||
c.___tracy_emit_memory_alloc(ptr, size, 1);
|
||||
}
|
||||
}
|
||||
pub inline fn SecureFreeS(ptr: ?*const anyopaque, depth: c_int) void {
|
||||
if (has_callstack_support) {
|
||||
c.___tracy_emit_memory_free_callstack(ptr, depth, 1);
|
||||
} else {
|
||||
c.___tracy_emit_memory_free(ptr, 1);
|
||||
}
|
||||
}
|
||||
|
||||
pub inline fn AllocN(ptr: ?*const anyopaque, size: usize, name: [*:0]const u8) void {
|
||||
if (has_callstack_support) {
|
||||
c.___tracy_emit_memory_alloc_callstack_named(ptr, size, callstack_depth, 0, name);
|
||||
} else {
|
||||
c.___tracy_emit_memory_alloc_named(ptr, size, 0, name);
|
||||
}
|
||||
}
|
||||
pub inline fn FreeN(ptr: ?*const anyopaque, name: [*:0]const u8) void {
|
||||
if (has_callstack_support) {
|
||||
c.___tracy_emit_memory_free_callstack_named(ptr, callstack_depth, 0, name);
|
||||
} else {
|
||||
c.___tracy_emit_memory_free_named(ptr, 0, name);
|
||||
}
|
||||
}
|
||||
pub inline fn SecureAllocN(ptr: ?*const anyopaque, size: usize, name: [*:0]const u8) void {
|
||||
if (has_callstack_support) {
|
||||
c.___tracy_emit_memory_alloc_callstack_named(ptr, size, callstack_depth, 1, name);
|
||||
} else {
|
||||
c.___tracy_emit_memory_alloc_named(ptr, size, 1, name);
|
||||
}
|
||||
}
|
||||
pub inline fn SecureFreeN(ptr: ?*const anyopaque, name: [*:0]const u8) void {
|
||||
if (has_callstack_support) {
|
||||
c.___tracy_emit_memory_free_callstack_named(ptr, callstack_depth, 1, name);
|
||||
} else {
|
||||
c.___tracy_emit_memory_free_named(ptr, 1, name);
|
||||
}
|
||||
}
|
||||
pub inline fn AllocNS(ptr: ?*const anyopaque, size: usize, depth: c_int, name: [*:0]const u8) void {
|
||||
if (has_callstack_support) {
|
||||
c.___tracy_emit_memory_alloc_callstack_named(ptr, size, depth, 0, name);
|
||||
} else {
|
||||
c.___tracy_emit_memory_alloc_named(ptr, size, 0, name);
|
||||
}
|
||||
}
|
||||
pub inline fn FreeNS(ptr: ?*const anyopaque, depth: c_int, name: [*:0]const u8) void {
|
||||
if (has_callstack_support) {
|
||||
c.___tracy_emit_memory_free_callstack_named(ptr, depth, 0, name);
|
||||
} else {
|
||||
c.___tracy_emit_memory_free_named(ptr, 0, name);
|
||||
}
|
||||
}
|
||||
pub inline fn SecureAllocNS(ptr: ?*const anyopaque, size: usize, depth: c_int, name: [*:0]const u8) void {
|
||||
if (has_callstack_support) {
|
||||
c.___tracy_emit_memory_alloc_callstack_named(ptr, size, depth, 1, name);
|
||||
} else {
|
||||
c.___tracy_emit_memory_alloc_named(ptr, size, 1, name);
|
||||
}
|
||||
}
|
||||
pub inline fn SecureFreeNS(ptr: ?*const anyopaque, depth: c_int, name: [*:0]const u8) void {
|
||||
if (has_callstack_support) {
|
||||
c.___tracy_emit_memory_free_callstack_named(ptr, depth, 1, name);
|
||||
} else {
|
||||
c.___tracy_emit_memory_free_named(ptr, 1, name);
|
||||
}
|
||||
}
|
||||
|
||||
pub inline fn Message(text: []const u8) void {
|
||||
c.___tracy_emit_message(text.ptr, text.len, callstack_depth);
|
||||
}
|
||||
pub inline fn MessageL(text: [*:0]const u8, color: u32) void {
|
||||
c.___tracy_emit_messageL(text, color, callstack_depth);
|
||||
}
|
||||
pub inline fn MessageC(text: []const u8, color: u32) void {
|
||||
c.___tracy_emit_messageC(text.ptr, text.len, color, callstack_depth);
|
||||
}
|
||||
pub inline fn MessageLC(text: [*:0]const u8, color: u32) void {
|
||||
c.___tracy_emit_messageLC(text, color, callstack_depth);
|
||||
}
|
||||
pub inline fn MessageS(text: []const u8, depth: c_int) void {
|
||||
const inner_depth: c_int = if (has_callstack_support) depth else 0;
|
||||
c.___tracy_emit_message(text.ptr, text.len, inner_depth);
|
||||
}
|
||||
pub inline fn MessageLS(text: [*:0]const u8, depth: c_int) void {
|
||||
const inner_depth: c_int = if (has_callstack_support) depth else 0;
|
||||
c.___tracy_emit_messageL(text, inner_depth);
|
||||
}
|
||||
pub inline fn MessageCS(text: []const u8, color: u32, depth: c_int) void {
|
||||
const inner_depth: c_int = if (has_callstack_support) depth else 0;
|
||||
c.___tracy_emit_messageC(text.ptr, text.len, color, inner_depth);
|
||||
}
|
||||
pub inline fn MessageLCS(text: [*:0]const u8, color: u32, depth: c_int) void {
|
||||
const inner_depth: c_int = if (has_callstack_support) depth else 0;
|
||||
c.___tracy_emit_messageLC(text, color, inner_depth);
|
||||
}
|
||||
|
||||
pub inline fn FrameMark() void {
|
||||
c.___tracy_emit_frame_mark(null);
|
||||
}
|
||||
pub inline fn FrameMarkNamed(name: [*:0]const u8) void {
|
||||
c.___tracy_emit_frame_mark(name);
|
||||
}
|
||||
pub inline fn FrameMarkStart(name: [*:0]const u8) void {
|
||||
c.___tracy_emit_frame_mark_start(name);
|
||||
}
|
||||
pub inline fn FrameMarkEnd(name: [*:0]const u8) void {
|
||||
c.___tracy_emit_frame_mark_end(name);
|
||||
}
|
||||
pub inline fn FrameImage(image: ?*const anyopaque, width: u16, height: u16, offset: u8, flip: c_int) void {
|
||||
c.___tracy_emit_frame_image(image, width, height, offset, flip);
|
||||
}
|
||||
|
||||
pub inline fn FiberEnter(name: [*:0]const u8) void {
|
||||
c.___tracy_fiber_enter(name);
|
||||
}
|
||||
pub inline fn FiberLeave() void {
|
||||
c.___tracy_fiber_leave();
|
||||
}
|
||||
|
||||
pub inline fn PlotF(name: [*:0]const u8, val: f64) void {
|
||||
c.___tracy_emit_plot(name, val);
|
||||
}
|
||||
pub inline fn PlotU(name: [*:0]const u8, val: u64) void {
|
||||
c.___tracy_emit_plot(name, @as(f64, @floatFromInt(val)));
|
||||
}
|
||||
pub inline fn PlotI(name: [*:0]const u8, val: i64) void {
|
||||
c.___tracy_emit_plot(name, @as(f64, @floatFromInt(val)));
|
||||
}
|
||||
pub inline fn AppInfo(text: []const u8) void {
|
||||
c.___tracy_emit_message_appinfo(text.ptr, text.len);
|
||||
}
|
||||
|
||||
pub const TracyAllocator = struct {
|
||||
child_allocator: std.mem.Allocator,
|
||||
|
||||
pub fn init(child_allocator: std.mem.Allocator) TracyAllocator {
|
||||
return .{
|
||||
.child_allocator = child_allocator,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn allocator(self: *TracyAllocator) std.mem.Allocator {
|
||||
return .{
|
||||
.ptr = self,
|
||||
.vtable = &.{
|
||||
.alloc = alloc,
|
||||
.resize = resize,
|
||||
.remap = remap,
|
||||
.free = free,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
fn alloc(
|
||||
ctx: *anyopaque,
|
||||
len: usize,
|
||||
alignment: std.mem.Alignment,
|
||||
ra: usize,
|
||||
) ?[*]u8 {
|
||||
const self: *TracyAllocator = @ptrCast(@alignCast(ctx));
|
||||
const result = self.child_allocator.rawAlloc(len, alignment, ra);
|
||||
if (result) |addr| {
|
||||
Alloc(addr, len);
|
||||
} else {
|
||||
var buffer: [128]u8 = undefined;
|
||||
const msg = std.fmt.bufPrint(&buffer, "alloc failed requesting {d}", .{len}) catch return result;
|
||||
Message(msg);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
fn resize(
|
||||
ctx: *anyopaque,
|
||||
buf: []u8,
|
||||
alignment: std.mem.Alignment,
|
||||
new_len: usize,
|
||||
ra: usize,
|
||||
) bool {
|
||||
const self: *TracyAllocator = @ptrCast(@alignCast(ctx));
|
||||
const result = self.child_allocator.rawResize(buf, alignment, new_len, ra);
|
||||
if (result) {
|
||||
Free(buf.ptr);
|
||||
Alloc(buf.ptr, new_len);
|
||||
} else {
|
||||
var buffer: [128]u8 = undefined;
|
||||
const msg = std.fmt.bufPrint(&buffer, "resize failed requesting {d} -> {d}", .{ buf.len, new_len }) catch return result;
|
||||
Message(msg);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
fn remap(
|
||||
ctx: *anyopaque,
|
||||
buf: []u8,
|
||||
alignment: std.mem.Alignment,
|
||||
new_len: usize,
|
||||
ra: usize,
|
||||
) ?[*]u8 {
|
||||
const self: *TracyAllocator = @ptrCast(@alignCast(ctx));
|
||||
const result = self.child_allocator.rawRemap(buf, alignment, new_len, ra);
|
||||
if (result) |data| {
|
||||
Free(buf.ptr);
|
||||
Alloc(data, new_len);
|
||||
} else {
|
||||
var buffer: [128]u8 = undefined;
|
||||
const msg = std.fmt.bufPrint(&buffer, "remap failed requesting {d} -> {d}", .{ buf.len, new_len }) catch return result;
|
||||
Message(msg);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
fn free(
|
||||
ctx: *anyopaque,
|
||||
buf: []u8,
|
||||
alignment: std.mem.Alignment,
|
||||
ra: usize,
|
||||
) void {
|
||||
const self: *TracyAllocator = @ptrCast(@alignCast(ctx));
|
||||
self.child_allocator.rawFree(buf, alignment, ra);
|
||||
Free(buf.ptr);
|
||||
}
|
||||
};
|
||||
Vendored
+229
@@ -0,0 +1,229 @@
|
||||
const std = @import("std");
|
||||
const Src = std.builtin.SourceLocation;
|
||||
|
||||
pub const ZoneCtx = struct {
|
||||
pub inline fn Text(self: ZoneCtx, text: []const u8) void {
|
||||
_ = self;
|
||||
_ = text;
|
||||
}
|
||||
pub inline fn Name(self: ZoneCtx, name: []const u8) void {
|
||||
_ = self;
|
||||
_ = name;
|
||||
}
|
||||
pub inline fn Value(self: ZoneCtx, value: u64) void {
|
||||
_ = self;
|
||||
_ = value;
|
||||
}
|
||||
pub inline fn End(self: ZoneCtx) void {
|
||||
_ = self;
|
||||
}
|
||||
};
|
||||
|
||||
pub inline fn SetThreadName(name: [*:0]const u8) void {
|
||||
_ = name;
|
||||
}
|
||||
|
||||
pub inline fn Zone(comptime src: Src) ZoneCtx {
|
||||
_ = src;
|
||||
return .{};
|
||||
}
|
||||
pub inline fn ZoneN(comptime src: Src, name: [*:0]const u8) ZoneCtx {
|
||||
_ = src;
|
||||
_ = name;
|
||||
return .{};
|
||||
}
|
||||
pub inline fn ZoneC(comptime src: Src, color: u32) ZoneCtx {
|
||||
_ = src;
|
||||
_ = color;
|
||||
return .{};
|
||||
}
|
||||
pub inline fn ZoneNC(comptime src: Src, name: [*:0]const u8, color: u32) ZoneCtx {
|
||||
_ = src;
|
||||
_ = name;
|
||||
_ = color;
|
||||
return .{};
|
||||
}
|
||||
pub inline fn ZoneS(comptime src: Src, depth: i32) ZoneCtx {
|
||||
_ = src;
|
||||
_ = depth;
|
||||
return .{};
|
||||
}
|
||||
pub inline fn ZoneNS(comptime src: Src, name: [*:0]const u8, depth: i32) ZoneCtx {
|
||||
_ = src;
|
||||
_ = name;
|
||||
_ = depth;
|
||||
return .{};
|
||||
}
|
||||
pub inline fn ZoneCS(comptime src: Src, color: u32, depth: i32) ZoneCtx {
|
||||
_ = src;
|
||||
_ = color;
|
||||
_ = depth;
|
||||
return .{};
|
||||
}
|
||||
pub inline fn ZoneNCS(comptime src: Src, name: [*:0]const u8, color: u32, depth: i32) ZoneCtx {
|
||||
_ = src;
|
||||
_ = name;
|
||||
_ = color;
|
||||
_ = depth;
|
||||
return .{};
|
||||
}
|
||||
|
||||
pub inline fn Alloc(ptr: ?*const anyopaque, size: usize) void {
|
||||
_ = ptr;
|
||||
_ = size;
|
||||
}
|
||||
pub inline fn Free(ptr: ?*const anyopaque) void {
|
||||
_ = ptr;
|
||||
}
|
||||
pub inline fn SecureAlloc(ptr: ?*const anyopaque, size: usize) void {
|
||||
_ = ptr;
|
||||
_ = size;
|
||||
}
|
||||
pub inline fn SecureFree(ptr: ?*const anyopaque) void {
|
||||
_ = ptr;
|
||||
}
|
||||
pub inline fn AllocS(ptr: ?*const anyopaque, size: usize, depth: c_int) void {
|
||||
_ = ptr;
|
||||
_ = size;
|
||||
_ = depth;
|
||||
}
|
||||
pub inline fn FreeS(ptr: ?*const anyopaque, depth: c_int) void {
|
||||
_ = ptr;
|
||||
_ = depth;
|
||||
}
|
||||
pub inline fn SecureAllocS(ptr: ?*const anyopaque, size: usize, depth: c_int) void {
|
||||
_ = ptr;
|
||||
_ = size;
|
||||
_ = depth;
|
||||
}
|
||||
pub inline fn SecureFreeS(ptr: ?*const anyopaque, depth: c_int) void {
|
||||
_ = ptr;
|
||||
_ = depth;
|
||||
}
|
||||
|
||||
pub inline fn AllocN(ptr: ?*const anyopaque, size: usize, name: [*:0]const u8) void {
|
||||
_ = ptr;
|
||||
_ = size;
|
||||
_ = name;
|
||||
}
|
||||
pub inline fn FreeN(ptr: ?*const anyopaque, name: [*:0]const u8) void {
|
||||
_ = ptr;
|
||||
_ = name;
|
||||
}
|
||||
pub inline fn SecureAllocN(ptr: ?*const anyopaque, size: usize, name: [*:0]const u8) void {
|
||||
_ = ptr;
|
||||
_ = size;
|
||||
_ = name;
|
||||
}
|
||||
pub inline fn SecureFreeN(ptr: ?*const anyopaque, name: [*:0]const u8) void {
|
||||
_ = ptr;
|
||||
_ = name;
|
||||
}
|
||||
pub inline fn AllocNS(ptr: ?*const anyopaque, size: usize, depth: c_int, name: [*:0]const u8) void {
|
||||
_ = ptr;
|
||||
_ = size;
|
||||
_ = depth;
|
||||
_ = name;
|
||||
}
|
||||
pub inline fn FreeNS(ptr: ?*const anyopaque, depth: c_int, name: [*:0]const u8) void {
|
||||
_ = ptr;
|
||||
_ = depth;
|
||||
_ = name;
|
||||
}
|
||||
pub inline fn SecureAllocNS(ptr: ?*const anyopaque, size: usize, depth: c_int, name: [*:0]const u8) void {
|
||||
_ = ptr;
|
||||
_ = size;
|
||||
_ = depth;
|
||||
_ = name;
|
||||
}
|
||||
pub inline fn SecureFreeNS(ptr: ?*const anyopaque, depth: c_int, name: [*:0]const u8) void {
|
||||
_ = ptr;
|
||||
_ = depth;
|
||||
_ = name;
|
||||
}
|
||||
|
||||
pub inline fn Message(text: []const u8) void {
|
||||
_ = text;
|
||||
}
|
||||
pub inline fn MessageL(text: [*:0]const u8) void {
|
||||
_ = text;
|
||||
}
|
||||
pub inline fn MessageC(text: []const u8, color: u32) void {
|
||||
_ = text;
|
||||
_ = color;
|
||||
}
|
||||
pub inline fn MessageLC(text: [*:0]const u8, color: u32) void {
|
||||
_ = text;
|
||||
_ = color;
|
||||
}
|
||||
pub inline fn MessageS(text: []const u8, depth: c_int) void {
|
||||
_ = text;
|
||||
_ = depth;
|
||||
}
|
||||
pub inline fn MessageLS(text: [*:0]const u8, depth: c_int) void {
|
||||
_ = text;
|
||||
_ = depth;
|
||||
}
|
||||
pub inline fn MessageCS(text: []const u8, color: u32, depth: c_int) void {
|
||||
_ = text;
|
||||
_ = color;
|
||||
_ = depth;
|
||||
}
|
||||
pub inline fn MessageLCS(text: [*:0]const u8, color: u32, depth: c_int) void {
|
||||
_ = text;
|
||||
_ = color;
|
||||
_ = depth;
|
||||
}
|
||||
|
||||
pub inline fn FrameMark() void {}
|
||||
pub inline fn FrameMarkNamed(name: [*:0]const u8) void {
|
||||
_ = name;
|
||||
}
|
||||
pub inline fn FrameMarkStart(name: [*:0]const u8) void {
|
||||
_ = name;
|
||||
}
|
||||
pub inline fn FrameMarkEnd(name: [*:0]const u8) void {
|
||||
_ = name;
|
||||
}
|
||||
pub inline fn FrameImage(image: ?*const anyopaque, width: u16, height: u16, offset: u8, flip: c_int) void {
|
||||
_ = image;
|
||||
_ = width;
|
||||
_ = height;
|
||||
_ = offset;
|
||||
_ = flip;
|
||||
}
|
||||
|
||||
pub inline fn FiberEnter(name: [*:0]const u8) void {
|
||||
_ = name;
|
||||
}
|
||||
pub inline fn FiberLeave() void {}
|
||||
|
||||
pub inline fn PlotF(name: [*:0]const u8, val: f64) void {
|
||||
_ = name;
|
||||
_ = val;
|
||||
}
|
||||
pub inline fn PlotU(name: [*:0]const u8, val: u64) void {
|
||||
_ = name;
|
||||
_ = val;
|
||||
}
|
||||
pub inline fn PlotI(name: [*:0]const u8, val: i64) void {
|
||||
_ = name;
|
||||
_ = val;
|
||||
}
|
||||
pub inline fn AppInfo(text: []const u8) void {
|
||||
_ = text;
|
||||
}
|
||||
|
||||
pub const TracyAllocator = struct {
|
||||
child_allocator: std.mem.Allocator,
|
||||
|
||||
pub fn init(child_allocator: std.mem.Allocator) TracyAllocator {
|
||||
return .{
|
||||
.child_allocator = child_allocator,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn allocator(self: *TracyAllocator) std.mem.Allocator {
|
||||
return self.child_allocator;
|
||||
}
|
||||
};
|
||||
Vendored
+84
@@ -0,0 +1,84 @@
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
|
||||
// check for a decl named tracy_enabled in root or build_options
|
||||
pub const enabled = blk: {
|
||||
var build_enable: ?bool = null;
|
||||
|
||||
if (!builtin.is_test) {
|
||||
// Don't try to include build_options in tests.
|
||||
// Otherwise `zig test` doesn't work.
|
||||
const options = @import("tracy_options");
|
||||
if (@hasDecl(options, "enable_tracy")) {
|
||||
build_enable = options.enable_tracy;
|
||||
}
|
||||
}
|
||||
|
||||
break :blk build_enable orelse false;
|
||||
};
|
||||
|
||||
const stub = @import("stub.zig");
|
||||
const impl = @import("impl.zig");
|
||||
|
||||
pub const ZoneCtx = if (enabled) impl.ZoneCtx else stub.ZoneCtx;
|
||||
|
||||
pub const SetThreadName = if (enabled) impl.SetThreadName else stub.SetThreadName;
|
||||
|
||||
pub const Zone = if (enabled) impl.Zone else stub.Zone;
|
||||
pub const ZoneN = if (enabled) impl.ZoneN else stub.ZoneN;
|
||||
pub const ZoneC = if (enabled) impl.ZoneC else stub.ZoneC;
|
||||
pub const ZoneNC = if (enabled) impl.ZoneNC else stub.ZoneNC;
|
||||
pub const ZoneS = if (enabled) impl.ZoneS else stub.ZoneS;
|
||||
pub const ZoneNS = if (enabled) impl.ZoneNS else stub.ZoneNS;
|
||||
pub const ZoneCS = if (enabled) impl.ZoneCS else stub.ZoneCS;
|
||||
pub const ZoneNCS = if (enabled) impl.ZoneNCS else stub.ZoneNCS;
|
||||
|
||||
pub const Alloc = if (enabled) impl.Alloc else stub.Alloc;
|
||||
pub const Free = if (enabled) impl.Free else stub.Free;
|
||||
pub const SecureAlloc = if (enabled) impl.SecureAlloc else stub.SecureAlloc;
|
||||
pub const SecureFree = if (enabled) impl.SecureFree else stub.SecureFree;
|
||||
|
||||
pub const AllocS = if (enabled) impl.AllocS else stub.AllocS;
|
||||
pub const FreeS = if (enabled) impl.FreeS else stub.FreeS;
|
||||
pub const SecureAllocS = if (enabled) impl.SecureAllocS else stub.SecureAllocS;
|
||||
pub const SecureFreeS = if (enabled) impl.SecureFreeS else stub.SecureFreeS;
|
||||
|
||||
pub const AllocN = if (enabled) impl.AllocN else stub.AllocN;
|
||||
pub const FreeN = if (enabled) impl.FreeN else stub.FreeN;
|
||||
pub const SecureAllocN = if (enabled) impl.SecureAllocN else stub.SecureAllocN;
|
||||
pub const SecureFreeN = if (enabled) impl.SecureFreeN else stub.SecureFreeN;
|
||||
|
||||
pub const AllocNS = if (enabled) impl.AllocNS else stub.AllocNS;
|
||||
pub const FreeNS = if (enabled) impl.FreeNS else stub.FreeNS;
|
||||
pub const SecureAllocNS = if (enabled) impl.SecureAllocNS else stub.SecureAllocNS;
|
||||
pub const SecureFreeNS = if (enabled) impl.SecureFreeNS else stub.SecureFreeNS;
|
||||
|
||||
pub const Message = if (enabled) impl.Message else stub.Message;
|
||||
pub const MessageL = if (enabled) impl.MessageL else stub.MessageL;
|
||||
pub const MessageC = if (enabled) impl.MessageC else stub.MessageC;
|
||||
pub const MessageLC = if (enabled) impl.MessageLC else stub.MessageLC;
|
||||
pub const MessageS = if (enabled) impl.MessageS else stub.MessageS;
|
||||
pub const MessageLS = if (enabled) impl.MessageLS else stub.MessageLS;
|
||||
pub const MessageCS = if (enabled) impl.MessageCS else stub.MessageCS;
|
||||
pub const MessageLCS = if (enabled) impl.MessageLCS else stub.MessageLCS;
|
||||
|
||||
pub const FrameMark = if (enabled) impl.FrameMark else stub.FrameMark;
|
||||
pub const FrameMarkNamed = if (enabled) impl.FrameMarkNamed else stub.FrameMarkNamed;
|
||||
pub const FrameMarkStart = if (enabled) impl.FrameMarkStart else stub.FrameMarkStart;
|
||||
pub const FrameMarkEnd = if (enabled) impl.FrameMarkEnd else stub.FrameMarkEnd;
|
||||
pub const FrameImage = if (enabled) impl.FrameImage else stub.FrameImage;
|
||||
|
||||
pub const FiberEnter = if (enabled) impl.FiberEnter else stub.FiberEnter;
|
||||
pub const FiberLeave = if (enabled) impl.FiberLeave else stub.FiberLeave;
|
||||
|
||||
pub const PlotF = if (enabled) impl.PlotF else stub.PlotF;
|
||||
pub const PlotU = if (enabled) impl.PlotU else stub.PlotU;
|
||||
pub const PlotI = if (enabled) impl.PlotI else stub.PlotI;
|
||||
|
||||
pub const AppInfo = if (enabled) impl.AppInfo else stub.AppInfo;
|
||||
|
||||
pub const TracyAllocator = if (enabled) impl.TracyAllocator else stub.TracyAllocator;
|
||||
|
||||
test {
|
||||
std.testing.refAllDeclsRecursive(@This());
|
||||
}
|
||||
Reference in new issue
Block a user