Merge pull request #1 from peterino2/dev/peterino

Dev/peterino
This commit is contained in:
Peter Li 2025-10-12 02:40:35 -07:00 committed by GitHub
commit cc259fe9bc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
21 changed files with 259 additions and 33 deletions

37
.github/workflows/build.yml vendored Normal file
View File

@ -0,0 +1,37 @@
name: Build Projects
on:
push:
branches: [ main, integration ]
pull_request:
branches: [ main, integration ]
jobs:
build:
runs-on: ${{ matrix.target.os }}
strategy:
matrix:
target:
- zig: x86_64-linux-gnu
os: self-hosted-linux
- zig: x86_64-windows
os: self-hosted-windows
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: recursive
- name: Build projects
working-directory: ./projects
run: zig build install -Dtarget=${{ matrix.target.zig }}
- name: Upload build artifacts
uses: actions/upload-artifact@v4
if: success()
with:
name: build-artifacts-${{ matrix.target.zig }}
path: |
projects/zig-out/
retention-days: 7

View File

@ -256,9 +256,9 @@ const DynamicDepList: []const struct { dep: []const u8, artifact: []const u8 } =
.{ .dep = "sdl3", .artifact = "SDL3" },
.{ .dep = "spng", .artifact = "spng_c" },
.{ .dep = "lua", .artifact = "luac" },
.{ .dep = "miniaudio", .artifact = "miniaudio_c" },
// .{ .dep = "miniaudio", .artifact = "miniaudio_c" },
.{ .dep = "zphysics", .artifact = "joltc" },
.{ .dep = "enet", .artifact = "enet_c" },
// .{ .dep = "enet", .artifact = "enet_c" },
.{ .dep = "ozz", .artifact = "ozz_cpp" },
};
@ -401,6 +401,7 @@ pub const Program = struct {
for (self.gameModules.items) |*m| {
if (std.mem.eql(u8, m.name, module)) {
m.enabled = enable;
std.debug.print("enabling module {s} {any}\n", .{ module, enable });
return;
}
}

View File

@ -468,3 +468,36 @@ pub fn PatchOrCreateObject(comptime T: type, args: engine.NeonObjectParams) void
logging.engine_err("Unable to create object", .{});
};
}
pub const u32a = std.atomic.Value(u32);
pub const i32a = std.atomic.Value(u32);
var gBarrierCount: u32a = u32a.init(0);
pub fn setBarrierCount(count: u32) void {
gBarrierCount.store(count, .seq_cst);
}
pub fn getBarrierCount() u32 {
return gBarrierCount.load(.acquire);
}
pub fn jobCount() u32 {
return getEngine().jobManager.numWorkers;
}
pub fn waitSeconds(wait: f64) void {
const start = getEngineTime();
while (getEngineTime() - start < wait) {
std.Thread.sleep(10_000_000);
}
}
pub fn itof32(i: anytype) f32 {
return @as(f32, @floatFromInt(i));
}
pub fn itof64(i: anytype) f32 {
return @as(f32, @floatFromInt(i));
}

View File

@ -38,6 +38,7 @@ pub fn MakeTypeName(comptime TargetType: type) Name {
pub const EngineDataEventError = error{
UnknownStatePanic,
BadInit,
JobsAbortShutdown,
UnknownError,
OutOfMemory,
};

View File

@ -1,6 +1,8 @@
const std = @import("std");
// todo need a better timing system than this
const core = @import("core.zig");
// todo, replace with monotonic timer
pub fn getEngineTime() f64 {
return @as(f64, @floatFromInt(std.time.milliTimestamp())) / 1000;
}

View File

@ -68,8 +68,8 @@ pub const LoadedModule = struct {
const stagedPath = self.stagedPaths.getLast();
var lib = try std.DynLib.open(stagedPath);
var mod = ModuleInterface{};
mod.startup = lib.lookup(@TypeOf(mod.startup), "startup") orelse return error.BadModule;
mod.shutdown = lib.lookup(@TypeOf(mod.shutdown), "shutdown") orelse return error.BadModule;
mod.startup = lib.lookup(@TypeOf(mod.startup), "startup_module") orelse return error.BadModule;
mod.shutdown = lib.lookup(@TypeOf(mod.shutdown), "shutdown_module") orelse return error.BadModule;
try self.loaded.append(allocator, mod);
}

View File

@ -88,12 +88,7 @@ pub const GameObjectSystem = struct {
return self;
}
pub fn spawnObject(
self: *@This(),
comptime T: type,
objectName: []const u8,
parameters: SpawnParameters,
) !*T {
pub fn spawnObject(self: *@This(), comptime T: type, objectName: []const u8, parameters: SpawnParameters) !*T {
var n = core.MakeName(objectName);
return self.spawnObjectByName(T, &n, parameters);
}

View File

@ -16,6 +16,7 @@ pub const JobManager = struct {
jobQueueConcurrent: core.ConcurrentQueueU(JobContext),
workers: []*JobWorker,
numCpus: usize,
numWorkers: u32 = 0,
pub fn create(allocator: std.mem.Allocator) !*@This() {
var self = try allocator.create(@This());
@ -29,6 +30,7 @@ pub const JobManager = struct {
};
self.workers = self.allocator.alloc(*JobWorker, @max(self.numCpus - 2, 4)) catch unreachable;
self.numWorkers = @intCast(self.workers.len);
core.engine_log("allocating worker count : {d}", .{self.workers.len});
var i: usize = 0;

View File

@ -129,8 +129,13 @@ pub const TextRenderer = struct {
return meshBuffer;
}
pub fn submitMeshBuffer(self: *@This(), meshBuffer: *TextMeshBuffer) void {
_ = self;
_ = meshBuffer;
}
pub fn updateMeshBuffer(self: *@This(), meshBuffer: *TextMeshBuffer, copyPass: *gpu.GPUCopyPass, text: papyrus.DrawCommand.PrimitiveText) !void {
var z = tracy.ZoneN(@src(), "meshBuffer updates");
var z = tracy.ZoneN(@src(), "papyrus meshBuffer updates");
defer z.End();
const string = text.text.getRead();
if (string.len == 0)

View File

@ -1,3 +1,3 @@
pub const c = @cImport({
@cInclude("pureDOOM.h");
@cInclude("PureDOOM.h");
});

View File

@ -4,7 +4,7 @@
#define DOOM_IMPLEMENT_PRINT
#define DOOM_IMPLEMENT_MALLOC
#define DOOM_IMPLEMENT_FILE_IO
#define DOOM_IMPLEMENT_SOCKETS
// #define DOOM_IMPLEMENT_SOCKETS
#define DOOM_IMPLEMENT_GETTIME
#define DOOM_IMPLEMENT_GETENV

6
lib/enet/build.zig vendored
View File

@ -4,9 +4,10 @@ pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
_ = static_build;
// am i good to always have enet as static?
const enet = if (static_build and false) b.addStaticLibrary(.{
const enet = if (true) b.addStaticLibrary(.{
.name = "enet_c",
.target = target,
.optimize = optimize,
@ -28,8 +29,8 @@ pub fn build(b: *std.Build) void {
"packet.c",
"peer.c",
"protocol.c",
"unix.c",
"win32.c",
"unix.c",
},
.flags = &.{"-DHAS_OFFSETOF=1"},
});
@ -41,6 +42,7 @@ pub fn build(b: *std.Build) void {
.windows => {
enet.linkSystemLibrary("ws2_32");
enet.linkSystemLibrary("winmm");
// Use .def file to control exports and avoid CRT symbol conflicts
},
.linux, .macos => {
// Unix platforms - no additional libraries needed

View File

@ -5,7 +5,7 @@ pub fn build(b: *std.Build) void {
const optimize = b.standardOptimizeOption(.{});
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
const miniaudio_c = if (static_build) b.addStaticLibrary(.{
const miniaudio_c = if (static_build or true) b.addStaticLibrary(.{
.name = "miniaudio_c",
.target = target,
.optimize = optimize,
@ -18,7 +18,7 @@ pub fn build(b: *std.Build) void {
});
b.installArtifact(miniaudio_c);
miniaudio_c.addCSourceFile(.{ .file = b.path("src/miniaudio.cpp"), .flags = &.{"-fno-sanitize=all"} });
miniaudio_c.addCSourceFile(.{ .file = b.path("src/miniaudio.cpp"), .flags = &.{"-fno-sanitize=all"}, .language = .c });
miniaudio_c.addIncludePath(b.path("include"));
const mod = b.addModule("miniaudio", .{ .target = target, .optimize = optimize, .root_source_file = b.path("src/miniaudio.zig") });

3
lib/tracy/build.zig vendored
View File

@ -11,7 +11,7 @@ pub fn build(b: *std.Build) void {
//const tracy_enabled = b.option(bool, "tracy", "Enables tracy integration") orelse false;
const tracy_enabled: bool = false; //if (b.graph.env_map.hash_map.get("WITH_TRACY") != null) true else false;
const tracy_enabled: bool = true; //if (b.graph.env_map.hash_map.get("WITH_TRACY") != null) true else false;
// if (b.graph.env_map.hash_map.get("WITH_TRACY")) |with_tracy| {
// tracy_enabled = with_tracy;
// }
@ -31,6 +31,7 @@ pub fn build(b: *std.Build) void {
.file = b.path(tracy_path ++ "/TracyClient.cpp"),
.flags = &[_][]const u8{
"-DTRACY_ENABLE",
"-DTRACY_NO_EXIT",
// MinGW doesn't have all the newfangled windows features,
// so we need to pretend to have an older windows version.
// "-D_WIN32_WINNT=0x601",

1
lib/tracy/tracy.zig vendored
View File

@ -223,6 +223,7 @@ const tracy_stub = struct {
const tracy_full = struct {
const c = @cImport({
@cDefine("TRACY_ENABLE", "");
@cDefine("TRACY_NO_EXIT", "");
@cInclude("TracyC.h");
});

View File

@ -60,6 +60,7 @@ pub fn build(b: *std.Build) void {
toolbox.setModuleEnabled("imgui", true);
toolbox.setModuleEnabled("audio", false);
toolbox.setModuleEnabled("sys", true);
toolbox.setModuleEnabled("net", false);
toolbox.addExtraModule("gameExtras");
const toolboxExe = toolbox.compileInstall();
@ -76,9 +77,12 @@ pub fn build(b: *std.Build) void {
.desc = "headless program, core-only",
.root_source_file = b.path("headless/main.zig"),
});
std.debug.print("headless", .{});
headless.setModuleEnabled("assets", false);
headless.setModuleEnabled("platform", false);
headless.setModuleEnabled("audio", false);
headless.setModuleEnabled("net", false);
headless.setModuleEnabled("rend", false);
_ = headless.compileInstall();

View File

@ -1797,6 +1797,15 @@
( 3808 11088 17264 ) ( 3809 11088 17264 ) ( 3808 11088 17265 ) mapping_defaults/ProtoDark 0 0 0 0.25 0.25
( 3808 11088 17264 ) ( 3808 11088 17265 ) ( 3808 11089 17264 ) mapping_defaults/ProtoDark 0 0 0 0.25 0.25
}
// brush 200
{
( -6544 -240 -64 ) ( -6544 -239 -64 ) ( -6544 -240 -63 ) mapping_defaults/ProtoDarkBlue 0 -192 0 0.25 0.25
( 192 -6992 -64 ) ( 192 -6992 -63 ) ( 193 -6992 -64 ) mapping_defaults/ProtoDarkBlue 0 -192 0 0.25 0.25
( 192 -240 -64 ) ( 193 -240 -64 ) ( 192 -239 -64 ) mapping_defaults/ProtoDarkBlue 0 0 0 0.25 0.25
( 400 -128 -48 ) ( 400 -127 -48 ) ( 401 -128 -48 ) mapping_defaults/ProtoDarkBlue 0 0 0 0.25 0.25
( 400 4784 -48 ) ( 401 4784 -48 ) ( 400 4784 -47 ) mapping_defaults/ProtoDarkBlue 0 -192 0 0.25 0.25
( 4240 -128 -48 ) ( 4240 -128 -47 ) ( 4240 -127 -48 ) mapping_defaults/ProtoDarkBlue 0 -192 0 0.25 0.25
}
}
// entity 1
{

View File

@ -1,5 +1,6 @@
allocator: std.mem.Allocator = undefined,
timeLeft: f64 = 5.0,
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "Headless");
pub fn create(allocator: std.mem.Allocator) !*@This() {
@ -11,20 +12,110 @@ pub fn create(allocator: std.mem.Allocator) !*@This() {
}
pub fn prepare(self: *@This()) !void {
_ = self;
try self.testThing();
}
pub fn tick(self: *@This(), dt: f64) void {
_ = self;
_ = dt;
// std.time.sleep(1000_000);
self.timeLeft -= dt;
core.exitNow();
if (self.timeLeft < 0)
core.exitNow();
const start = core.getEngineTime();
// wait 10 ms
while (core.getEngineTime() - start < 0.010) {
std.Thread.sleep(10_000_000);
}
}
pub fn deinit(self: *@This()) void {
self.allocator.destroy(self);
}
const Src = std.builtin.SourceLocation;
pub fn Barrier(src: Src) type {
return struct {
pub const Src = src;
pub var count: u32 = 0;
pub var generation: u32 = 0;
pub var mutex: std.Thread.Mutex = .{};
pub var cv: std.Thread.Condition = .{};
pub fn sync(threadId: u32) !void {
_ = threadId;
const barrierCount = core.getBarrierCount();
mutex.lock();
defer mutex.unlock();
count += 1;
if (count == barrierCount) {
// 2 second timeout
count = 0;
generation += 1;
cv.broadcast();
} else {
try cv.timedWait(&mutex, 1000 * 1000 * 1000 * 2);
}
}
};
}
const MultiJob = struct {
pub var WorkGroupData = WorkGroupData.from(@This());
threadId: u32 = 0,
threadName: []const u8,
pub var cv: std.Thread.Condition = .{};
pub var mutex: std.Thread.Mutex = .{};
pub fn func(ctx: @This(), job: *core.JobContext) void {
_ = job;
core.tracy.SetThreadName(@ptrCast(ctx.threadName.ptr));
ctx.loop() catch {};
if (core.getEngine().isShuttingDown()) {}
}
pub fn loop(ctx: @This()) !void {
while (!core.getEngine().isShuttingDown()) {
try Barrier(@src()).sync(ctx.threadId);
try ctx.tick();
if (ctx.threadId == 0) {
const z = core.tracy.ZoneN(@src(), "Thread 0 sleep");
defer z.End();
core.waitSeconds(0.01);
}
}
}
pub fn tick(ctx: @This()) !void {
const z = core.tracy.ZoneN(@src(), "MultiJob Tick");
defer z.End();
// std.time.sleep(100_000 * ctx.threadId);
try Barrier(@src()).sync(ctx.threadId);
}
};
pub fn testThing(self: *@This()) !void {
_ = self;
const workerCount = 16;
core.setBarrierCount(workerCount);
for (0..workerCount) |i| {
const name = try std.fmt.allocPrintZ(std.heap.c_allocator, "MultiJob{d}", .{i});
try core.dispatchJob(MultiJob{ .threadName = name, .threadId = @intCast(i) });
}
}
pub fn main() anyerror!void {
var spec = try backlog.getSpec("headless");
// try spec.put("useGPA", .{ .boolean = false });

View File

@ -11,7 +11,7 @@ pub fn init(allocator: std.mem.Allocator) !*@This() {
}
pub fn prepare(self: *@This()) !void {
_ = self;
try self.fuckNazis();
core.engine_log("program ready", .{});
}

View File

@ -1,4 +1,4 @@
pub export fn startup(p_allocator: *anyopaque, p_a: ?*anyopaque) bool {
pub export fn startup_module(p_allocator: *anyopaque, p_a: ?*anyopaque) bool {
const allocator = core.modulePreamble(p_allocator, p_a) catch return false;
_ = allocator;
imgui.setupFromModule();
@ -118,7 +118,7 @@ pub const ExternGameObject = struct {
reloadMapInput: ?*core.ActionBinding = null,
volume: f32 = 100.0,
vo2lume: f32 = 100.0,
volume2: f32 = 100.0,
a: core.Vector2f = .{ .x = 1, .y = 4 },
b: core.Vector2f = .{ .x = 4, .y = 1 },
@ -145,6 +145,20 @@ pub const ExternGameObject = struct {
pub fn _beginPlay(self: *@This()) !void {
try self.setupInputs();
if (self.firstTick) {
self.loadMap2() catch unreachable;
self.firstTick = false;
}
// change this into a parallel for
for (0..300) |i| {
_ = try core.get(core.GameObjectSystem).spawnObject(BoxObject, "Box", .{
.posRot = .{
.position = .{ .x = core.itof32((i % 10)) * 2, .y = 15.0, .z = core.itof32(@divFloor(i, 10) * 2) },
},
});
}
}
pub fn onMapReload(ctx: ?*anyopaque, _: core.ActionEvent) void {
@ -477,11 +491,6 @@ pub const ExternGameObject = struct {
self.drawVector2Test();
}
if (self.firstTick) {
self.loadMap2() catch unreachable;
self.firstTick = false;
}
if (self.recompiling) {
if (ig.begin("recompiling", null, .{})) {
ig.textf("recompiling...", .{});
@ -490,7 +499,7 @@ pub const ExternGameObject = struct {
}
if (platform.context().isCursorEnabled()) {
// imgui.utils.structDebugWindow(self);
imgui.utils.structDebugWindow(self);
// imgui.utils.structDebugWindow(core.get(rend.renderer.Renderer));
@ -681,7 +690,7 @@ pub const ExternGameObject = struct {
}
};
pub export fn shutdown() void {}
pub export fn shutdown_module() void {}
const std = @import("std");
const backlog = @import("backlog");

View File

@ -0,0 +1,33 @@
pub const Slack = core.SlackStruct(@This(), 1024);
allocator: std.mem.Allocator = undefined,
entity: core.Entity = undefined,
camera: *extras.FpCamera = undefined,
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "extern.FpPlayer");
pub fn create(allocator: std.mem.Allocator) !*@This() {
const self = try Slack.create(allocator);
self.* = .{
.allocator = allocator,
.entity = try core.createEntity(),
.camera = try extras.FpCamera.create(allocator),
};
return self;
}
pub fn objectReload(self: *@This()) void {
_ = self;
}
pub fn destroy(self: *@This()) void {
self.camera.destroy();
self.allocator.destroy(Slack.fromPtr(self));
}
const backlog = @import("backlog");
const core = backlog.core;
const std = @import("std");
const extras = @import("gameExtras");