soooo much work done on infrastructure

This commit is contained in:
peterino2 2025-10-04 18:18:39 -07:00
parent 84c289ee2a
commit 81f7ef6a26
30 changed files with 595 additions and 142 deletions

View File

@ -11,19 +11,19 @@ const tracy = core.tracy;
const ma = @import("miniaudio"); const ma = @import("miniaudio");
pub fn sound_log(comptime fmt: []const u8, args: anytype) void { pub fn sound_log(comptime fmt: []const u8, args: anytype) void {
core.printInner("[SOUND ]: " ++ fmt ++ "\n", args); core.printInner(core.defaultHighlight, "[SOUND ]: " ++ fmt ++ "\n", args);
} }
pub fn sound_logs(comptime fmt: []const u8) void { pub fn sound_logs(comptime fmt: []const u8) void {
core.printInner("[SOUND ]: " ++ fmt ++ "\n", .{}); core.printInner(core.defaultHighlight, "[SOUND ]: " ++ fmt ++ "\n", .{});
} }
pub fn sound_err(comptime fmt: []const u8, args: anytype) void { pub fn sound_err(comptime fmt: []const u8, args: anytype) void {
core.printInner("[SOUND ]: ERROR!! " ++ fmt ++ "\n", args); core.printInner(core.errorHighlight, "[SOUND ]: ERROR!! " ++ fmt ++ "\n", args);
} }
pub fn sound_errs(comptime fmt: []const u8) void { pub fn sound_errs(comptime fmt: []const u8) void {
core.printInner("[SOUND ]: ERROR!!" ++ fmt ++ "\n", .{}); core.printInner(core.errorHighlight, "[SOUND ]: ERROR!!" ++ fmt ++ "\n", .{});
} }
pub const SoundLoader = struct { pub const SoundLoader = struct {

View File

@ -215,8 +215,8 @@ pub const Parser = struct {
fn printError(self: *@This(), comptime fmt: []const u8, args: anytype) !void { fn printError(self: *@This(), comptime fmt: []const u8, args: anytype) !void {
if (core.getLogger()) |logger| { if (core.getLogger()) |logger| {
try logger.print(fmt, args); try logger.print(core.colors.Color.Red, fmt, args);
try logger.print("[Config ]: Config File Parse Error> {s}:{d} \n", .{ self.fileName, self.lineNumber }); try logger.print(core.colors.Color.Red, "[Config ]: Config File Parse Error> {s}:{d} \n", .{ self.fileName, self.lineNumber });
} }
} }

View File

@ -16,6 +16,7 @@ pub const ActionBinding = inputs.ActionBinding;
pub const IOEvent = inputs.IOEvent; pub const IOEvent = inputs.IOEvent;
pub const debug_draw = @import("debug_draw.zig"); pub const debug_draw = @import("debug_draw.zig");
pub const debugTextLog = debug_draw.debugTextLog;
pub const DebugDrawParams = debug_draw.DebugDrawParams; pub const DebugDrawParams = debug_draw.DebugDrawParams;
pub const DebugDrawInterface = debug_draw.DebugDrawInterface; pub const DebugDrawInterface = debug_draw.DebugDrawInterface;
pub const installDebugDrawInterface = debug_draw.installDebugDrawInterface; pub const installDebugDrawInterface = debug_draw.installDebugDrawInterface;

View File

@ -7,12 +7,24 @@ pub const DebugDrawParams = struct {
rotation: core.Quat = .{ 0, 0, 0, 1 }, rotation: core.Quat = .{ 0, 0, 0, 1 },
}; };
pub const DebugLogParamsInner = struct {
slice: []const u8,
duration: f64,
color: core.colors.Color = core.colors.Color.Yellow,
};
pub const DebugLogParams = struct {
color: core.colors.Color = core.colors.Color.Yellow,
};
pub const DebugDrawInterface = struct { pub const DebugDrawInterface = struct {
debugSphereFn: *const fn (pos: core.Vectorf, radius: f32, DebugDrawParams) void, debugSphereFn: *const fn (pos: core.Vectorf, radius: f32, DebugDrawParams) void,
debugBoxFn: *const fn (pos: core.Vectorf, extents: core.Vectorf, DebugDrawParams) void, debugBoxFn: *const fn (pos: core.Vectorf, extents: core.Vectorf, DebugDrawParams) void,
debugLineFn: *const fn (start: core.Vectorf, end: core.Vectorf, DebugDrawParams) void, debugLineFn: *const fn (start: core.Vectorf, end: core.Vectorf, DebugDrawParams) void,
}; };
pub const DebugLogDelegate = core.EngineObjectDelegate(*const fn (*anyopaque, DebugLogParamsInner) void);
pub var gDebugDrawInterface: ?*DebugDrawInterface = null; pub var gDebugDrawInterface: ?*DebugDrawInterface = null;
var gDebugDrawAllocator: ?std.mem.Allocator = null; var gDebugDrawAllocator: ?std.mem.Allocator = null;
@ -40,6 +52,11 @@ pub fn debugBox(pos: core.Vectorf, extents: core.Vectorf, params: DebugDrawParam
} }
} }
pub fn installDebugLogInterface(ptr: anytype) void {
const interface = DebugLogDelegate.make(ptr, "onDebugLog");
core.get(core.LoggerSys).debugLogInterface = interface;
}
pub fn installDebugDrawInterface(allocator: std.mem.Allocator, newInterface: DebugDrawInterface) !void { pub fn installDebugDrawInterface(allocator: std.mem.Allocator, newInterface: DebugDrawInterface) !void {
gDebugDrawInterface = try allocator.create(DebugDrawInterface); gDebugDrawInterface = try allocator.create(DebugDrawInterface);
gDebugDrawAllocator = allocator; gDebugDrawAllocator = allocator;
@ -54,3 +71,16 @@ pub fn shutdownDrawInterface() void {
gDebugDrawAllocator.?.destroy(interface); gDebugDrawAllocator.?.destroy(interface);
} }
} }
pub fn debugTextLog(slice: []const u8, duration: f64, params: DebugLogParams) void {
if (core.getEngineObject(core.LoggerSys)) |logger| {
if (logger.debugLogInterface) |*interface| {
const p = DebugLogParamsInner{
.slice = slice,
.duration = duration,
.color = params.color,
};
interface.call(p);
}
}
}

View File

@ -127,6 +127,18 @@ pub fn EngineObjectDelegate(comptime T: type) type {
version: i32 = -1, version: i32 = -1,
vtable: *EngineObjectVTable, vtable: *EngineObjectVTable,
pub fn make(ptr: anytype, comptime funcName: []const u8) @This() {
const TargetType = @typeInfo(@TypeOf(ptr)).pointer.child;
const func = @field(TargetType, funcName);
return .{
.func = func,
.functionName = funcName,
.target = ptr,
.vtable = &TargetType.NeonObjectTable,
};
}
pub fn call(self: *@This(), args: anytype) void { pub fn call(self: *@This(), args: anytype) void {
//if (!core.BuildOption("static_build")) { todo; disable this vtable check in non-static builds //if (!core.BuildOption("static_build")) { todo; disable this vtable check in non-static builds
if (self.vtable.version != self.version) { if (self.vtable.version != self.version) {

View File

@ -170,13 +170,26 @@ pub const ActionBinding = struct {
return self; return self;
} }
pub fn addToLayer(self: *@This(), layer: *BindingLayer) !void {
try layer.addBindingByName(self.data.name, self);
}
pub fn removeFromLayer(self: *@This(), layer: *BindingLayer) !void {
try layer.removeBindingByName(self.data.name);
}
// pushes this binding to the active layer // pushes this binding to the active layer
pub fn activate(self: *@This()) void { pub fn activate(self: *@This()) void {
getInputStack().active.addBindingByName(self.data.name, self) catch unreachable; if (getInputStack().active) |active| {
active.addBindingByName(self.data.name, self) catch unreachable;
}
} }
pub fn deactivate(self: *@This()) void { pub fn deactivate(self: *@This()) void {
getInputStack().active.removeBindingByName(self.data.name); if (getInputStack().active) |active| {
active.removeBindingByName(self.data.name);
}
} }
pub fn addKey(self: *@This(), key: Key, event: ActionEvent) void { pub fn addKey(self: *@This(), key: Key, event: ActionEvent) void {
@ -224,9 +237,19 @@ pub const Axis1dBinding = struct {
return self; return self;
} }
pub fn addToLayer(self: *@This(), layer: *BindingLayer) !void {
try layer.addBindingByName(self.data.name, self);
}
pub fn removeFromLayer(self: *@This(), layer: *BindingLayer) !void {
try layer.removeBindingByName(self.data.name);
}
// pushes this binding to the active layer // pushes this binding to the active layer
pub fn activate(self: *@This()) void { pub fn activate(self: *@This()) void {
getInputStack().active.addBindingByName(self.data.name, self) catch unreachable; if (getInputStack().active) |active| {
active.addBindingByName(self.data.name, self) catch unreachable;
}
} }
pub fn setClamp(self: *@This(), clampValue: ?f32) void { pub fn setClamp(self: *@This(), clampValue: ?f32) void {
@ -234,7 +257,9 @@ pub const Axis1dBinding = struct {
} }
pub fn deactivate(self: *@This()) void { pub fn deactivate(self: *@This()) void {
getInputStack().active.removeBindingByName(self.data.name); if (getInputStack().active) |active| {
active.removeBindingByName(self.data.name);
}
} }
pub fn addKey(self: *@This(), key: Key, magnitude: f32) void { pub fn addKey(self: *@This(), key: Key, magnitude: f32) void {
@ -270,6 +295,14 @@ pub const Axis2dBinding = struct {
// func: Axis2dFunc, // func: Axis2dFunc,
// }; // };
pub fn addToLayer(self: *@This(), layer: *BindingLayer) !void {
try layer.addBindingByName(self.data.name, self);
}
pub fn removeFromLayer(self: *@This(), layer: *BindingLayer) !void {
try layer.removeBindingByName(self.data.name);
}
pub fn create(name: core.Name) !*@This() { pub fn create(name: core.Name) !*@This() {
const allocator = arenaAlloc(); const allocator = arenaAlloc();
const self = try allocator.create(@This()); const self = try allocator.create(@This());
@ -296,11 +329,15 @@ pub const Axis2dBinding = struct {
// pushes this binding to the active layer // pushes this binding to the active layer
pub fn activate(self: *@This()) void { pub fn activate(self: *@This()) void {
getInputStack().active.addBindingByName(self.data.name, self) catch unreachable; if (getInputStack().active) |active| {
active.addBindingByName(self.data.name, self) catch unreachable;
}
} }
pub fn deactivate(self: *@This()) void { pub fn deactivate(self: *@This()) void {
getInputStack().active.removeBindingByName(self.data.name); if (getInputStack().active) |active| {
active.removeBindingByName(self.data.name);
}
} }
pub fn addKey(self: *@This(), key: Key, magnitude: f32, axis: enum { x, y }) void { pub fn addKey(self: *@This(), key: Key, magnitude: f32, axis: enum { x, y }) void {
@ -581,7 +618,8 @@ pub const BindingLayer = struct {
pub const InputStack = struct { pub const InputStack = struct {
allocator: std.mem.Allocator, allocator: std.mem.Allocator,
active: *BindingLayer, active: ?*BindingLayer,
bindingStack: std.ArrayListUnmanaged(*BindingLayer) = .{},
arena: std.heap.ArenaAllocator, arena: std.heap.ArenaAllocator,
keysDown: std.AutoHashMapUnmanaged(Key, bool) = .{}, keysDown: std.AutoHashMapUnmanaged(Key, bool) = .{},
@ -610,36 +648,49 @@ pub const InputStack = struct {
} }
pub fn updatePreviousInputs(self: *@This()) void { pub fn updatePreviousInputs(self: *@This()) void {
if (self.active.bindingStack.items.len == 0) { if (self.active == null) {
return;
}
const active = self.active.?;
if (active.bindingStack.items.len == 0) {
return; return;
} }
var i: i32 = @intCast(self.active.bindingStack.items.len - 1); var i: i32 = @intCast(active.bindingStack.items.len - 1);
while (i >= 0) : (i -= 1) { while (i >= 0) : (i -= 1) {
const binding = &self.active.bindingStack.items[@intCast(i)]; const binding = &active.bindingStack.items[@intCast(i)];
binding.processHeldKeys(); binding.processHeldKeys();
} }
} }
pub fn sendAxisUpdates(self: *@This()) void { pub fn sendAxisUpdates(self: *@This()) void {
for (self.active.bindingStack.items) |binding| { if (self.active == null) {
return;
}
const active = self.active.?;
for (active.bindingStack.items) |binding| {
binding.sendAxisUpdates(); binding.sendAxisUpdates();
} }
} }
fn routeKeyEvent(self: *@This(), key: Key, event: ActionEvent) void { fn routeKeyEvent(self: *@This(), key: Key, event: ActionEvent) void {
if (self.active == null) {
return;
}
const active = self.active.?;
// for all bindings in reverse order from this layer, route the input, stop the // for all bindings in reverse order from this layer, route the input, stop the
// route if the input was consumed // route if the input was consumed
// core.engine_log(" >> {any} > routeKeyEvent 1", .{key}); // core.engine_log(" >> {any} > routeKeyEvent 1", .{key});
if (self.active.bindingStack.items.len == 0) { if (active.bindingStack.items.len == 0) {
return; return;
} }
// core.engine_log(" >> {any} > routeKeyEvent 2", .{key}); // core.engine_log(" >> {any} > routeKeyEvent 2", .{key});
var i: i32 = @intCast(self.active.bindingStack.items.len - 1); var i: i32 = @intCast(active.bindingStack.items.len - 1);
// core.engine_log(" >> {any} > routeKeyEvent 2 binding count : {d}", .{ key, i }); // core.engine_log(" >> {any} > routeKeyEvent 2 binding count : {d}", .{ key, i });
while (i >= 0) : (i -= 1) { while (i >= 0) : (i -= 1) {
const binding = self.active.bindingStack.items[@intCast(i)]; const binding = active.bindingStack.items[@intCast(i)];
var consumed: bool = false; var consumed: bool = false;
var routed: bool = false; var routed: bool = false;
@ -662,13 +713,17 @@ pub const InputStack = struct {
} }
fn routeMouseRelative(self: *@This(), move: core.Vector2f) void { fn routeMouseRelative(self: *@This(), move: core.Vector2f) void {
if (self.active.bindingStack.items.len == 0) { if (self.active == null) {
return; return;
} }
var i: i32 = @intCast(self.active.bindingStack.items.len - 1); const active = self.active.?;
if (active.bindingStack.items.len == 0) {
return;
}
var i: i32 = @intCast(active.bindingStack.items.len - 1);
// core.engine_log(" >> {any} > routeKeyEvent 2 binding count : {d}", .{ key, i }); // core.engine_log(" >> {any} > routeKeyEvent 2 binding count : {d}", .{ key, i });
while (i >= 0) : (i -= 1) { while (i >= 0) : (i -= 1) {
const binding = self.active.bindingStack.items[@intCast(i)]; const binding = active.bindingStack.items[@intCast(i)];
switch (binding) { switch (binding) {
// only axis2d handles mouse relative right now, // only axis2d handles mouse relative right now,
@ -700,7 +755,9 @@ pub const InputStack = struct {
pub fn deinit(self: *@This()) void { pub fn deinit(self: *@This()) void {
self.arena.deinit(); self.arena.deinit();
self.active.destroy(); if (self.active) |active| {
active.destroy();
}
self.allocator.destroy(self); self.allocator.destroy(self);
} }
}; };

View File

@ -36,6 +36,9 @@ pub const LogBuffer = struct {
} }
}; };
pub const defaultHighlight = core.colors.Color.Yellow;
pub const errorHighlight = core.colors.Color.Red;
pub fn printRaw(comptime fmt: []const u8, args: anytype) void { pub fn printRaw(comptime fmt: []const u8, args: anytype) void {
if (zero_logging) { if (zero_logging) {
return; return;
@ -45,14 +48,14 @@ pub fn printRaw(comptime fmt: []const u8, args: anytype) void {
std.debug.print(fmt, args); std.debug.print(fmt, args);
} else { } else {
if (gLoggerSys) |loggerSys| { if (gLoggerSys) |loggerSys| {
loggerSys.print(fmt, args) catch std.debug.print("!> " ++ fmt, args); loggerSys.print(defaultHighlight, fmt, args) catch std.debug.print("!> " ++ fmt, args);
} else { } else {
std.debug.print(fmt, args); std.debug.print(fmt, args);
} }
} }
} }
pub fn printInner(comptime fmt: []const u8, args: anytype) void { pub fn printInner(highlight: core.colors.Color, comptime fmt: []const u8, args: anytype) void {
if (zero_logging) { if (zero_logging) {
return; return;
} }
@ -61,7 +64,7 @@ pub fn printInner(comptime fmt: []const u8, args: anytype) void {
std.debug.print("> " ++ fmt, args); std.debug.print("> " ++ fmt, args);
} else { } else {
if (gLoggerSys) |loggerSys| { if (gLoggerSys) |loggerSys| {
loggerSys.print(fmt, args) catch std.debug.print("!> " ++ fmt, args); loggerSys.print(highlight, fmt, args) catch std.debug.print("!> " ++ fmt, args);
} else { } else {
std.debug.print("> " ++ fmt, args); std.debug.print("> " ++ fmt, args);
} }
@ -70,63 +73,63 @@ pub fn printInner(comptime fmt: []const u8, args: anytype) void {
// new logging API // new logging API
pub fn logDisplay(comptime prefix: []const u8, comptime fmt: []const u8, args: anytype) void { pub fn logDisplay(comptime prefix: []const u8, comptime fmt: []const u8, args: anytype) void {
printInner("[" ++ prefix ++ "]: " ++ fmt ++ "\n", args); printInner(defaultHighlight, "[" ++ prefix ++ "]: " ++ fmt ++ "\n", args);
} }
pub fn game_log(comptime fmt: []const u8, args: anytype) void { pub fn game_log(comptime fmt: []const u8, args: anytype) void {
printInner("[GAME ]: " ++ fmt ++ "\n", args); printInner(defaultHighlight, "[GAME ]: " ++ fmt ++ "\n", args);
} }
pub fn game_logs(comptime fmt: []const u8) void { pub fn game_logs(comptime fmt: []const u8) void {
printInner("[GAME ]: " ++ fmt ++ "\n", .{}); printInner(defaultHighlight, "[GAME ]: " ++ fmt ++ "\n", .{});
} }
pub fn ui_log(comptime fmt: []const u8, args: anytype) void { pub fn ui_log(comptime fmt: []const u8, args: anytype) void {
printInner("[UI ]: " ++ fmt ++ "\n", args); printInner(defaultHighlight, "[UI ]: " ++ fmt ++ "\n", args);
} }
pub fn ui_logs(comptime fmt: []const u8) void { pub fn ui_logs(comptime fmt: []const u8) void {
printInner("[UI ]: " ++ fmt ++ "\n", .{}); printInner(defaultHighlight, "[UI ]: " ++ fmt ++ "\n", .{});
} }
pub fn console_log(comptime fmt: []const u8, args: anytype) void { pub fn console_log(comptime fmt: []const u8, args: anytype) void {
printInner("[CONSOLE ]: " ++ fmt ++ "\n", args); printInner(defaultHighlight, "[CONSOLE ]: " ++ fmt ++ "\n", args);
} }
pub fn console_logs(comptime fmt: []const u8) void { pub fn console_logs(comptime fmt: []const u8) void {
printInner("[CONSOLE ]: " ++ fmt ++ "\n"); printInner(defaultHighlight, "[CONSOLE ]: " ++ fmt ++ "\n");
} }
pub fn engine_log(comptime fmt: []const u8, args: anytype) void { pub fn engine_log(comptime fmt: []const u8, args: anytype) void {
printInner("[ENGINE ]: " ++ fmt ++ "\n", args); printInner(defaultHighlight, "[ENGINE ]: " ++ fmt ++ "\n", args);
} }
pub fn engine_logs(comptime fmt: []const u8) void { pub fn engine_logs(comptime fmt: []const u8) void {
printInner("[ENGINE ]: " ++ fmt ++ "\n", .{}); printInner(defaultHighlight, "[ENGINE ]: " ++ fmt ++ "\n", .{});
} }
pub fn engine_err(comptime fmt: []const u8, args: anytype) void { pub fn engine_err(comptime fmt: []const u8, args: anytype) void {
printInner("[ENGINE ]: ERROR!! " ++ fmt ++ "\n", args); printInner(errorHighlight, "[ENGINE ]: ERROR!! " ++ fmt ++ "\n", args);
} }
pub fn engine_errs(comptime fmt: []const u8) void { pub fn engine_errs(comptime fmt: []const u8) void {
printInner("[ENGINE ]: ERROR!! " ++ fmt ++ "\n", .{}); printInner(errorHighlight, "[ENGINE ]: ERROR!! " ++ fmt ++ "\n", .{});
} }
pub fn test_log(comptime fmt: []const u8, args: anytype) void { pub fn test_log(comptime fmt: []const u8, args: anytype) void {
printInner("[TEST ]: " ++ fmt ++ "\n", args); printInner(defaultHighlight, "[TEST ]: " ++ fmt ++ "\n", args);
} }
pub fn test_logs(comptime fmt: []const u8) void { pub fn test_logs(comptime fmt: []const u8) void {
printInner("[TEST ]: " ++ fmt ++ "\n", .{}); printInner(defaultHighlight, "[TEST ]: " ++ fmt ++ "\n", .{});
} }
pub fn graphics_log(comptime fmt: []const u8, args: anytype) void { pub fn graphics_log(comptime fmt: []const u8, args: anytype) void {
printInner("[GRAPHICS ]: " ++ fmt ++ "\n", args); printInner(defaultHighlight, "[GRAPHICS ]: " ++ fmt ++ "\n", args);
} }
pub fn graphics_logs(comptime fmt: []const u8) void { pub fn graphics_logs(comptime fmt: []const u8) void {
printInner("[GRAPHICS ]: " ++ fmt ++ "\n", .{}); printInner(defaultHighlight, "[GRAPHICS ]: " ++ fmt ++ "\n", .{});
} }
pub const FileLog = struct { pub const FileLog = struct {
@ -198,6 +201,8 @@ pub const LoggerSys = struct {
lock: std.Thread.Mutex = .{}, lock: std.Thread.Mutex = .{},
flushing: std.atomic.Value(bool) = std.atomic.Value(bool).init(false), flushing: std.atomic.Value(bool) = std.atomic.Value(bool).init(false),
debugLogInterface: ?core.debug_draw.DebugLogDelegate = null,
sessionBuffer: ?*LogBuffer = null, // disabled in release modes sessionBuffer: ?*LogBuffer = null, // disabled in release modes
pub fn flush(self: *@This()) !void { pub fn flush(self: *@This()) !void {
@ -264,14 +269,25 @@ pub const LoggerSys = struct {
self.lock.unlock(); self.lock.unlock();
} }
pub fn print(self: *@This(), comptime fmt: []const u8, args: anytype) !void { var slice: [4096]u8 = undefined;
pub fn print(self: *@This(), highlight: core.colors.Color, comptime fmt: []const u8, args: anytype) !void {
self.lock.lock(); self.lock.lock();
try self.writeOutBuffer.writer().print(fmt, args); try self.writeOutBuffer.writer().print(fmt, args);
self.lock.unlock(); self.lock.unlock();
if (self.sessionBuffer != null and !core.getEngine().isShuttingDown()) { blk: {
self.sessionBuffer.?.lockWriter().print(fmt, args) catch {}; if (self.sessionBuffer != null and !core.getEngine().isShuttingDown()) {
self.sessionBuffer.?.unlock(); self.sessionBuffer.?.lockWriter().print(fmt, args) catch {
self.sessionBuffer.?.unlock();
break :blk;
};
self.sessionBuffer.?.unlock();
const s = std.fmt.bufPrint(&slice, fmt, args) catch {
break :blk;
};
core.debugTextLog(s, 3.5, .{ .color = highlight });
}
} }
if (self.writeOutBuffer.items.len > LogBufferSize) { if (self.writeOutBuffer.items.len > LogBufferSize) {

View File

@ -25,13 +25,21 @@ pub const Impl = struct {
return self; return self;
} }
const ImguiArgs = struct { imguiIni: []const u8 = "imgui.ini" };
pub fn setup(self: *@This()) !void { pub fn setup(self: *@This()) !void {
core.graphics_log("imgui startup", .{}); core.graphics_log("imgui startup", .{});
self.device = rend.context().device; self.device = rend.context().device;
try rend.registerRendererObject(@This(), self); try rend.registerRendererObject(@This(), self);
const args = try core.ParseArgs(ImguiArgs);
c.Imgui_SDL3_Init(@ptrCast(platform.getInstance().window), @ptrCast(self.device)); c.Imgui_SDL3_Init(@ptrCast(platform.getInstance().window), @ptrCast(self.device));
ig.getIO().?.ini_file_name = @ptrCast(args.imguiIni.ptr);
ig.loadIniSettingsFromDisk(@ptrCast(args.imguiIni.ptr));
try platform.getInstance().addSDLProcessFunction(processSDLEvents); try platform.getInstance().addSDLProcessFunction(processSDLEvents);
core.engine_log("using imgui ini: {s}", .{args.imguiIni});
self.context = ig.getCurrentContext().?; self.context = ig.getCurrentContext().?;
self.setupBeginCount(); self.setupBeginCount();

View File

@ -39,8 +39,10 @@ pub fn windowOpen(entry: *imgui.utils.MenuEntry, dt: f64) void {
items = self.buffer.buffer.items[if (items.len > 10000) items.len - 10000 else 0..items.len]; items = self.buffer.buffer.items[if (items.len > 10000) items.len - 10000 else 0..items.len];
ig.textSlice(items); ig.textSlice(items);
if (self.lastLength != self.buffer.buffer.items.len) const b = self.buffer.buffer.items;
if (self.lastLength != b.len and b.len > 0) {
ig.setScrollHereY(1.0); ig.setScrollHereY(1.0);
}
} }
ig.end(); ig.end();

View File

@ -1,7 +1,7 @@
pub var TransportInterfaceVTable = net.TransportInterface.Implement(@This()); pub var TransportInterfaceVTable = net.TransportInterface.Implement(@This());
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "net.ENetTransport"); pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "net.ENetTransport");
allocator: std.mem.Allocator, allocator: std.mem.Allocator = undefined,
sessions: std.ArrayListUnmanaged(*net.Session) = .{}, sessions: std.ArrayListUnmanaged(*net.Session) = .{},
deadSessions: std.ArrayListUnmanaged(*net.Session) = .{}, deadSessions: std.ArrayListUnmanaged(*net.Session) = .{},
@ -59,6 +59,12 @@ const ENetLinkData = struct {
}) catch unreachable; }) catch unreachable;
} }
pub fn sendPacketChannelDebug(self: *@This(), bytes: []const u8, reliable: bool, channel: u8) void {
if (enet.enet_packet_create(bytes.ptr, bytes.len, if (reliable) enet.ENET_PACKET_FLAG_RELIABLE else 0)) |packet| {
_ = enet.enet_peer_send(self.peer, channel, packet);
}
}
// raw access to sendPacket // raw access to sendPacket
pub fn sendPacket(self: *@This(), bytes: []const u8, reliable: bool) void { pub fn sendPacket(self: *@This(), bytes: []const u8, reliable: bool) void {
if (enet.enet_packet_create(bytes.ptr, bytes.len, if (reliable) enet.ENET_PACKET_FLAG_RELIABLE else 0)) |packet| { if (enet.enet_packet_create(bytes.ptr, bytes.len, if (reliable) enet.ENET_PACKET_FLAG_RELIABLE else 0)) |packet| {
@ -106,12 +112,17 @@ const ENetSessionData = struct {
enet.ENET_EVENT_TYPE_RECEIVE => { enet.ENET_EVENT_TYPE_RECEIVE => {
self.messageCount += 1; self.messageCount += 1;
const data = @as([*]u8, @ptrCast(event.packet.*.data))[0..event.packet.*.dataLength]; const data = @as([*]u8, @ptrCast(event.packet.*.data))[0..event.packet.*.dataLength];
// core.engine_log("Received message #{}: '{s}' echoing it back", .{ self.messageCount, data }); core.engine_log("Received message #{d} channel {d}: '{s}' echoing it back", .{ self.messageCount, event.channelID, data });
if (self.findLinkByPeer(event.peer)) |link| { if (self.findLinkByPeer(event.peer)) |link| {
const linkData = getLinkData(link); const linkData = getLinkData(link);
if (link.linkType == .server) { if (link.linkType == .server) {
linkData.queuePacketData(data, true); // linkData.queuePacketData(data, true);
if (std.mem.startsWith(u8, data, "cname:")) {
const ipAsString = net.ip2String(net.netAllocator(), event.peer.*.address.host) catch unreachable;
const id = std.fmt.allocPrint(net.netAllocator(), "{s}@{s}", .{ data[6..data.len], ipAsString }) catch unreachable;
link.idString = id;
}
} }
if (link.linkType == .client) { if (link.linkType == .client) {
if (!std.mem.startsWith(u8, data, "msg:")) { if (!std.mem.startsWith(u8, data, "msg:")) {
@ -143,6 +154,8 @@ const ENetSessionData = struct {
net.netAllocator().free(queuedData.bytes); net.netAllocator().free(queuedData.bytes);
} }
} }
enet.enet_host_flush(self.host);
} }
}; };

View File

@ -4,19 +4,19 @@ const std = @import("std");
pub const EnetTransport = @import("enet/EnetTransport.zig"); pub const EnetTransport = @import("enet/EnetTransport.zig");
pub fn net_log(comptime fmt: []const u8, args: anytype) void { pub fn net_log(comptime fmt: []const u8, args: anytype) void {
core.printInner("[NET ]: " ++ fmt ++ "\n", args); core.printInner(core.defaultHighlight, "[NET ]: " ++ fmt ++ "\n", args);
} }
pub fn net_logs(comptime fmt: []const u8) void { pub fn net_logs(comptime fmt: []const u8) void {
core.printInner("[NET ]: " ++ fmt ++ "\n", .{}); core.printInner(core.defaultHighlight, "[NET ]: " ++ fmt ++ "\n", .{});
} }
pub fn net_err(comptime fmt: []const u8, args: anytype) void { pub fn net_err(comptime fmt: []const u8, args: anytype) void {
core.printInner("[NET ]: ERROR!! " ++ fmt ++ "\n", args); core.printInner(core.errorHighlight, "[NET ]: ERROR!! " ++ fmt ++ "\n", args);
} }
pub fn net_errs(comptime fmt: []const u8) void { pub fn net_errs(comptime fmt: []const u8) void {
core.printInner("[NET ]: ERROR!! " ++ fmt ++ "\n", .{}); core.printInner(core.errorHighlight, "[NET ]: ERROR!! " ++ fmt ++ "\n", .{});
} }
pub const TransportRef = core.Reference(net.TransportInterface); pub const TransportRef = core.Reference(net.TransportInterface);

View File

@ -66,7 +66,7 @@ pub fn testHits(self: *@This()) !void {
const cursorPos = ctx.currentCursorPosition; const cursorPos = ctx.currentCursorPosition;
self.cursorResults = trg.testHit(cursorPos); self.cursorResults = trg.testHit(cursorPos);
if (self.cursorResults) |hr| { if (self.cursorResults) |hr| {
try self.ctx.pushDebugText("text entry hittest found found: line={d} index={d}", .{ hr.line, hr.index }); try self.ctx.pushDebugText("text entry hittest found found: line={d} index={d}", .{ hr.line, hr.index }, null);
self.insertIndex = hr.index; self.insertIndex = hr.index;
} }
} }

View File

@ -87,7 +87,7 @@ pub const LocText = struct {
}; };
} }
pub fn fromUtf8Z(text: []const u8) @This() { pub fn fromUtf8Z(text: [:0]const u8) @This() {
for (text, 0..) |ch, i| { for (text, 0..) |ch, i| {
if (ch == 0) { if (ch == 0) {
var slice: []const u8 = undefined; var slice: []const u8 = undefined;

View File

@ -419,13 +419,20 @@ pub const Context = struct {
_displayLayout: std.ArrayListUnmanaged(LayoutInfo) = .{}, _displayLayout: std.ArrayListUnmanaged(LayoutInfo) = .{},
_horizontalLayout: std.AutoHashMapUnmanaged(NodeHandle, HorizontalLayoutInfo) = .{}, _horizontalLayout: std.AutoHashMapUnmanaged(NodeHandle, HorizontalLayoutInfo) = .{},
debugText: std.ArrayList([]u8), debugText: std.ArrayList(DebugLogTextEntry),
debugTextCount: u32 = 0,
drawDebug: bool = false, drawDebug: bool = false,
debugEnabled: bool = false,
debugFontSize: f32 = 12,
debugMousePick: bool = false, debugMousePick: bool = false,
rootNodes: std.ArrayList(NodeHandle), rootNodes: std.ArrayList(NodeHandle),
stringArena: std.heap.ArenaAllocator,
const debugTextMax = 32; const debugTextMax = 32;
const DebugLogTextEntry = struct {
text: []u8,
color: Color,
};
pub fn tick(self: *@This(), deltaTime: f64) !void { pub fn tick(self: *@This(), deltaTime: f64) !void {
self.clearDebugText(); self.clearDebugText();
@ -438,7 +445,7 @@ pub const Context = struct {
pub fn tickDebug(self: *@This(), deltaTime: f64) !void { pub fn tickDebug(self: *@This(), deltaTime: f64) !void {
_ = deltaTime; _ = deltaTime;
try self.pushDebugText("mouse Position: {d}, {d}", .{ self.currentCursorPosition.x, self.currentCursorPosition.y }); try self.pushDebugText("mouse Position: {d}, {d}", .{ self.currentCursorPosition.x, self.currentCursorPosition.y }, null);
if (self.debugMousePick) { if (self.debugMousePick) {
if (self.mousePick.selected_node) |node| { if (self.mousePick.selected_node) |node| {
const n = self.getRead(node); const n = self.getRead(node);
@ -452,14 +459,14 @@ pub const Context = struct {
layout.pos.y, layout.pos.y,
layout.size.x, layout.size.x,
layout.size.y, layout.size.y,
}); }, null);
} }
} }
} }
pub fn create(backingAllocator: std.mem.Allocator, ctx: *PapyrusRuntime) !*@This() { pub fn create(backingAllocator: std.mem.Allocator, ctx: *PapyrusRuntime) !*@This() {
var self = try backingAllocator.create(@This()); var self = try backingAllocator.create(@This());
var allocator = backingAllocator; const allocator = backingAllocator;
self.* = .{ self.* = .{
.allocator = allocator, .allocator = allocator,
@ -475,16 +482,12 @@ pub const Context = struct {
._layout = .{}, ._layout = .{},
._layoutNodes = .{}, ._layoutNodes = .{},
._horizontalLayout = .{}, ._horizontalLayout = .{},
.debugText = std.ArrayList([]u8).init(allocator), .debugText = std.ArrayList(DebugLogTextEntry).init(allocator),
.mousePick = Layout.init(allocator), .mousePick = Layout.init(allocator),
.rootNodes = std.ArrayList(NodeHandle).init(allocator), .rootNodes = std.ArrayList(NodeHandle).init(allocator),
.stringArena = std.heap.ArenaAllocator.init(allocator),
}; };
for (0..debugTextMax) |_| {
const textBuffer = try allocator.alloc(u8, 512);
try self.debugText.append(textBuffer);
}
// constructing the root node // constructing the root node
_ = try self.nodes.new(.{ _ = try self.nodes.new(.{
.text = MakeText("root"), .text = MakeText("root"),
@ -492,20 +495,35 @@ pub const Context = struct {
.nodeType = .{ .Slot = .{} }, .nodeType = .{ .Slot = .{} },
}); });
try self.pushDebugText("mouse position: {d}, {d}", .{ 0, 0 }); try self.pushDebugText("mouse position: {d}, {d}", .{ 0, 0 }, null);
return self; return self;
} }
pub fn pushDebugText(self: *@This(), comptime fmt: []const u8, args: anytype) !void { pub fn pushDebugTextSlice(self: *@This(), slice: []const u8, _color: ?Color) !void {
if (self.debugTextCount < debugTextMax) { const color = if (_color == null) Color.Yellow else _color.?;
_ = try std.fmt.bufPrintZ(self.debugText.items[self.debugTextCount], fmt, args); if (self.debugText.items.len < debugTextMax) {
self.debugTextCount += 1; try self.debugText.append(.{
.text = self.stringArena.allocator().dupe(slice) catch "",
.color = color,
});
}
}
pub fn pushDebugText(self: *@This(), comptime fmt: []const u8, args: anytype, _color: ?Color) !void {
const color = if (_color == null) Color.Yellow else _color.?;
if (self.debugText.items.len < debugTextMax) {
try self.debugText.append(.{
.text = std.fmt.allocPrint(self.stringArena.allocator(), fmt, args) catch "",
.color = color,
});
} }
} }
pub fn clearDebugText(self: *@This()) void { pub fn clearDebugText(self: *@This()) void {
self.debugTextCount = 0; _ = self.stringArena.reset(.retain_capacity);
self.debugText.clearRetainingCapacity();
} }
pub const destroy = deinit; pub const destroy = deinit;
@ -536,8 +554,9 @@ pub const Context = struct {
// self._layoutPositions.deinit(self.allocator); // self._layoutPositions.deinit(self.allocator);
self._displayLayout.deinit(self.allocator); self._displayLayout.deinit(self.allocator);
self.stringArena.deinit();
for (self.debugText.items) |text| { for (self.debugText.items) |text| {
self.allocator.free(text); _ = text;
} }
self.debugText.deinit(); self.debugText.deinit();
self.allocator.destroy(self); self.allocator.destroy(self);
@ -1191,12 +1210,18 @@ pub const Context = struct {
} }
} }
if (self.drawDebug) { if (self.debugEnabled) {
try self.addDebugInfo(drawList); if (self.drawDebug) {
} try self.addDebugInfo(drawList);
}
if (self.debugMousePick) { if (self.debugMousePick) {
try self.mousePick.addMousePickInfo(self, drawList); try self.mousePick.addMousePickInfo(self, drawList);
}
// if (self.debugLogText.items.len) {
// try self.addDebugLogText(drawList);
// }
} }
for (0..drawList.items.len) |i| { for (0..drawList.items.len) |i| {
@ -1209,10 +1234,37 @@ pub const Context = struct {
} }
} }
// fn addDebugLogText(self: *@This()) !void
// {
// const defaultHeight = 16;
// const sizePerLine: f32 = defaultHeight + 2;
// const yOffsetPerLine: f32 = defaultHeight + 1;
// var yOffset: f32 = sizePerLine * 2;
// const width = defaultHeight / 2 * 120;
// const fontHandle = self.fontCache.defaultMonoFont.atlas.fontHandle;
// for (self.debugLogText.items)|logTextEntry|
// {
//
// }
// try drawList.append(.{
// .node = .{},
// .primitive = .{
// .Rect = .{
// .tl = .{ .x = 30 - 5, .y = yOffset - 5 },
// .size = .{ .x = width + 5, .y = sizePerLine * @as(f32, @floatFromInt(self.debugTextCount + 2)) },
// .borderColor = Color.fromRGBA(0x444444ee),
// .backgroundColor = Color.fromRGBA2(0.05, 0.05, 0.08, 0.88),
// },
// },
// });
// }
fn addDebugInfo(self: @This(), drawList: *DrawList) !void { fn addDebugInfo(self: @This(), drawList: *DrawList) !void {
const defaultHeight = 16; const defaultHeight = self.debugFontSize;
const sizePerLine: f32 = defaultHeight + 2;
const yOffsetPerLine: f32 = defaultHeight + 1; const yOffsetPerLine: f32 = defaultHeight + 1;
const sizePerLine: f32 = yOffsetPerLine + (yOffsetPerLine / 4);
var yOffset: f32 = sizePerLine * 2; var yOffset: f32 = sizePerLine * 2;
const width = defaultHeight / 2 * 120; const width = defaultHeight / 2 * 120;
@ -1223,9 +1275,9 @@ pub const Context = struct {
.primitive = .{ .primitive = .{
.Rect = .{ .Rect = .{
.tl = .{ .x = 30 - 5, .y = yOffset - 5 }, .tl = .{ .x = 30 - 5, .y = yOffset - 5 },
.size = .{ .x = width + 5, .y = sizePerLine * @as(f32, @floatFromInt(self.debugTextCount + 2)) }, .size = .{ .x = width + 5, .y = sizePerLine * @as(f32, @floatFromInt(self.debugText.items.len)) + 0.5 },
.borderColor = Color.fromRGBA(0x444444ee), .borderColor = Color.fromRGBA(0x444444ee),
.backgroundColor = Color.fromRGBA2(0.05, 0.05, 0.08, 0.88), .backgroundColor = Color.fromRGBA2(0.05, 0.05, 0.08, 0.68),
}, },
}, },
}); });
@ -1251,7 +1303,7 @@ pub const Context = struct {
// yOffset += yOffsetPerLine; // yOffset += yOffsetPerLine;
for (self.debugText.items, 0..) |textData, i| { for (self.debugText.items, 0..) |textData, i| {
if (i >= self.debugTextCount) { if (i >= self.debugText.items.len) {
break; break;
} }
@ -1259,11 +1311,11 @@ pub const Context = struct {
.node = .{ .index = @intCast(i) }, .node = .{ .index = @intCast(i) },
.primitive = .{ .primitive = .{
.Text = .{ .Text = .{
.text = LocText.fromUtf8Z(textData), .text = LocText.fromUtf8(textData.text),
.tl = .{ .x = 30, .y = yOffset }, .tl = .{ .x = 30, .y = yOffset },
.size = .{ .x = width, .y = 30 }, .size = .{ .x = width, .y = 30 },
.renderMode = .NoControl, .renderMode = .NoControl,
.color = Color.Yellow, .color = textData.color,
.textSize = defaultHeight, .textSize = defaultHeight,
.fontHandle = fontHandle, .fontHandle = fontHandle,
.flags = .{ .flags = .{

View File

@ -90,14 +90,59 @@ pub const PlatformInstance = struct {
processFuncs: std.ArrayListUnmanaged(*const fn (*sdl3.Event) void) = .{}, processFuncs: std.ArrayListUnmanaged(*const fn (*sdl3.Event) void) = .{},
platformRequests: std.ArrayListUnmanaged(PlatformRequest) = .{},
cursorPos: core.Vector2f = .{}, cursorPos: core.Vector2f = .{},
pub var NeonObjectTable = core.EngineObjectVTable.from(@This(), "platform.Instance"); pub var NeonObjectTable = core.EngineObjectVTable.from(@This(), "platform.Instance");
pub const PlatformRequest = union(enum(u32)) {
setMouseRelativeMode: struct { relativeMode: bool },
setMousePosition: struct { pos: core.Vector2f },
setCursorVisible: struct { visible: bool },
setWindowSize: struct { size: core.Vector2u },
maximizeWindow: struct {},
setWindowPosition: struct { pos: core.Vector2u },
};
pub fn pushRequest(self: *@This(), req: PlatformRequest) void {
self.platformRequests.append(self.allocator, req) catch {
core.engine_err("unable to issue request", .{});
};
}
pub fn handlePlatformRequests(self: *@This()) void {
for (self.platformRequests.items) |req| {
switch (req) {
.setMouseRelativeMode => |p| {
self.setMouseRelativeMode(p.relativeMode);
},
.setMousePosition => |p| {
self.setMousePosition(p.pos);
},
.setCursorVisible => |p| {
self.setCursorVisible(p.visible);
},
.setWindowSize => |p| {
self.setWindowSize(p.size);
},
.maximizeWindow => {
self.maximizeWindow();
},
.setWindowPosition => |p| {
self.setWindowPosition(p.pos);
},
}
}
self.platformRequests.clearRetainingCapacity();
}
pub fn deinit(self: *@This()) void { pub fn deinit(self: *@This()) void {
self.allocator.free(self.windowName); self.allocator.free(self.windowName);
self.allocator.free(self.iconPath); self.allocator.free(self.iconPath);
self.processFuncs.deinit(self.allocator); self.processFuncs.deinit(self.allocator);
self.platformRequests.deinit(self.allocator);
self.allocator.destroy(self); self.allocator.destroy(self);
// shutdown // shutdown
} }
@ -181,9 +226,10 @@ pub const PlatformInstance = struct {
pub fn procEvents(ptr: *anyopaque, frameNumber: u64) core.EngineDataEventError!void { pub fn procEvents(ptr: *anyopaque, frameNumber: u64) core.EngineDataEventError!void {
_ = frameNumber; _ = frameNumber;
const self: *@This() = @ptrCast(@alignCast(ptr)); const self: *@This() = @ptrCast(@alignCast(ptr));
self.handlePlatformRequests();
// const self: *@This() = @ptrCast(@alignCast(ptr)); // const self: *@This() = @ptrCast(@alignCast(ptr));
var t1 = tracy.ZoneN(@src(), "Pumping Events"); var t1 = tracy.ZoneN(@src(), "Pumping Events");
defer t1.End(); defer t1.End();
@ -198,6 +244,7 @@ pub const PlatformInstance = struct {
if (event.type == sdl3.events.window_resized) { if (event.type == sdl3.events.window_resized) {
self.extent.x = @floatFromInt(event.window.data1); self.extent.x = @floatFromInt(event.window.data1);
self.extent.y = @floatFromInt(event.window.data2); self.extent.y = @floatFromInt(event.window.data2);
core.engine_log("engine resized {d}x{d}", self.extent);
} }
for (self.processFuncs.items) |func| { for (self.processFuncs.items) |func| {
@ -245,6 +292,22 @@ pub const PlatformInstance = struct {
sdl3.hideCursor(); sdl3.hideCursor();
} }
} }
pub fn setWindowSize(self: *@This(), size: core.Vector2u) void {
if (sdl3.c.SDL_SetWindowSize(self.window, @intCast(size.x), @intCast(size.y))) {
_ = sdl3.c.SDL_SyncWindow(self.window);
} else {
core.engine_log("unable to set window size {s}", .{sdl3.getError()});
}
}
pub fn maximizeWindow(self: *@This()) void {
_ = sdl3.c.SDL_MaximizeWindow(self.window);
}
pub fn setWindowPosition(self: *@This(), pos: core.Vector2u) void {
_ = sdl3.c.SDL_SetWindowPosition(self.window, @intCast(pos.x), @intCast(pos.y));
}
}; };
pub const IOEvent = core.IOEvent; pub const IOEvent = core.IOEvent;

View File

@ -19,7 +19,6 @@ pub const SubprocessTask = struct {
mutex: std.Thread.Mutex = .{}, mutex: std.Thread.Mutex = .{},
allocator: std.mem.Allocator, allocator: std.mem.Allocator,
args: []const []const u8,
child: ?std.process.Child = null, child: ?std.process.Child = null,
completed: bool = false, completed: bool = false,
@ -30,6 +29,9 @@ pub const SubprocessTask = struct {
stdout: std.ArrayListUnmanaged(u8) = .{}, stdout: std.ArrayListUnmanaged(u8) = .{},
stderr: std.ArrayListUnmanaged(u8) = .{}, stderr: std.ArrayListUnmanaged(u8) = .{},
argsOwned: std.ArrayListUnmanaged([]const u8) = .{},
argsArena: std.heap.ArenaAllocator,
pub fn run(task: *@This()) !void { pub fn run(task: *@This()) !void {
const L = struct { const L = struct {
self: *SubprocessTask, self: *SubprocessTask,
@ -40,12 +42,8 @@ pub const SubprocessTask = struct {
self.stderr = .{}; self.stderr = .{};
self.stdout = .{}; self.stdout = .{};
core.engine_log("running task", .{}); core.engine_log("running task", .{});
for (self.args) |arg| {
core.engine_log("{s}", .{arg});
}
core.engine_log("cwd = {s}", .{self.workingDir.?}); core.engine_log("cwd = {s}", .{self.workingDir.?});
self.child = std.process.Child.init(self.args, self.allocator); self.child = std.process.Child.init(self.argsOwned.items, self.allocator);
self.child.?.stdout_behavior = .Inherit; self.child.?.stdout_behavior = .Inherit;
self.child.?.stderr_behavior = .Inherit; self.child.?.stderr_behavior = .Inherit;
self.child.?.cwd = self.workingDir; self.child.?.cwd = self.workingDir;
@ -67,14 +65,20 @@ pub const SubprocessTask = struct {
self.* = .{ self.* = .{
.child = null, .child = null,
.allocator = allocator, .allocator = allocator,
.args = argv, .argsArena = std.heap.ArenaAllocator.init(allocator),
}; };
for (argv) |a| {
const v = try self.argsArena.allocator().dupe(u8, a);
try self.argsOwned.append(self.allocator, v);
}
return self; return self;
} }
pub fn destroy(self: *@This()) void { pub fn destroy(self: *@This()) void {
self.mutex.lock(); self.mutex.lock();
self.argsArena.deinit();
self.argsOwned.deinit(self.allocator);
if (self.child) |*child| { if (self.child) |*child| {
_ = child; _ = child;
core.engine_log("destroying child process", .{}); core.engine_log("destroying child process", .{});

View File

@ -58,7 +58,7 @@ float4 main(
// so 1 + 0.5*4 = 3 is the divisor // so 1 + 0.5*4 = 3 is the divisor
alpha = (alpha + 0.5 * asum) / 3.0; alpha = (alpha + 0.5 * asum) / 3.0;
textColor = float4(textColor.xyz, alpha);//textColor.* alpha); textColor = float4(textColor.xyz, alpha * textColor.w);//textColor.* alpha);
textColor.xyz = pow(textColor.xyz, 2.2); // gamma correction textColor.xyz = pow(textColor.xyz, 2.2); // gamma correction
// Premultiplied alpha output. // Premultiplied alpha output.
@ -68,7 +68,7 @@ float4 main(
{ {
float alpha = 1.0; float alpha = 1.0;
float gray = dot(textColor.xyz, float3(0.2126, 0.7152, 0.0722)); float gray = dot(textColor.xyz, float3(0.2126, 0.7152, 0.0722));
o = float4(textColor.xyz , pow(tex.x / gray, 1/(2.2)) );//textColor.* alpha); o = float4(textColor.xyz , pow(tex.x / gray, 1/(2.2)) * textColor.w );//textColor.* alpha);
//outFragColor = vec4(1.0, 0.0, 0.0, 1.0); //outFragColor = vec4(1.0, 0.0, 0.0, 1.0);
} }
@ -78,7 +78,7 @@ float4 main(
if(!rect(pixelPosition, position, size)) if(!rect(pixelPosition, position, size))
{ {
} }
outFragColor = float4(1.0, 0.0, 0.0, 1.0); outFragColor = float4(1.0, 0.0, 0.0, textColor.w);
return outFragColor + o * 0.00001; return outFragColor + o * 0.00001;
#else #else

View File

@ -14,6 +14,7 @@ quadMesh: ?rend.IndexedMesh = null,
quadMeshName: core.Name, quadMeshName: core.Name,
stringArena: std.heap.ArenaAllocator, stringArena: std.heap.ArenaAllocator,
debugStringArena: std.heap.ArenaAllocator,
drawList: papyrus.DrawList, drawList: papyrus.DrawList,
first: bool = true, first: bool = true,
@ -29,6 +30,14 @@ reloadingShaders: bool = false,
lastEventsCount: u64 = 0, lastEventsCount: u64 = 0,
debugTextQueue: core.RingQueue(DebugTextCommand) = undefined,
const DebugTextCommand = struct {
text: []u8,
color: core.colors.Color,
duration: f32,
};
const DrawCommand = union(enum(u8)) { const DrawCommand = union(enum(u8)) {
rect: struct { rect: struct {
ssboIndex: u32, ssboIndex: u32,
@ -119,17 +128,36 @@ pub fn create(allocator: std.mem.Allocator) !*@This() {
.screenContext = undefined, .screenContext = undefined,
.runtime = try papyrus.PapyrusRuntime.create(allocator), .runtime = try papyrus.PapyrusRuntime.create(allocator),
.stringArena = std.heap.ArenaAllocator.init(allocator), .stringArena = std.heap.ArenaAllocator.init(allocator),
.debugStringArena = std.heap.ArenaAllocator.init(allocator),
.quadMeshName = core.MakeName("m_screenPlane"), .quadMeshName = core.MakeName("m_screenPlane"),
.drawList = papyrus.DrawList.init(allocator), .drawList = papyrus.DrawList.init(allocator),
.debugTextQueue = try @TypeOf(self.debugTextQueue).init(allocator, 4096),
.screenBuffers = undefined, .screenBuffers = undefined,
}; };
self.screenContext = try self.runtime.addContext(); self.screenContext = try self.runtime.addContext();
try self.textRenderers.put(allocator, self.screenContext, try TextRenderer.create(allocator)); try self.textRenderers.put(allocator, self.screenContext, try TextRenderer.create(allocator));
self.screenContext.debugEnabled = true;
core.debug_draw.installDebugLogInterface(self);
return self; return self;
} }
pub fn onDebugLog(ctx: ?*anyopaque, params: core.debug_draw.DebugLogParamsInner) void {
const self = core.cast(*@This(), ctx.?);
// std.debug.print("================\n", .{});
// std.debug.print("{s}", .{params.slice});
// std.debug.print("==============\n", .{});
const s = self.debugStringArena.allocator().dupe(u8, params.slice) catch {
return;
};
self.debugTextQueue.pushLocked(.{ .text = s, .duration = @floatCast(params.duration), .color = params.color }) catch {};
}
pub fn tick(self: *@This(), dt: f64) void { pub fn tick(self: *@This(), dt: f64) void {
const inputStack = core.getInputStack(); const inputStack = core.getInputStack();
self.screenContext.setCursorLocation(.{ self.screenContext.setCursorLocation(.{
@ -141,26 +169,64 @@ pub fn tick(self: *@This(), dt: f64) void {
core.engine_errs("unable to tick papyrus"); core.engine_errs("unable to tick papyrus");
}; };
self.screenContext.pushDebugText("fps: {d:.2} ({d:.4}ms)", .{ 1 / core.getEngine().averageFrameTime, core.getEngine().averageFrameTime }) catch {}; self.screenContext.pushDebugText("fps: {d:.2} ({d:.4}ms)", .{ 1 / core.getEngine().averageFrameTime, core.getEngine().averageFrameTime }, null) catch {};
if (core.MemoryTracker.MTGet()) |tracker| { if (core.MemoryTracker.MTGet()) |tracker| {
self.screenContext.pushDebugText("memory used: {d:.4} MiB in {d} allocations {d} events per frame", .{ self.screenContext.pushDebugText("memory used: {d:.4} MiB in {d} allocations {d} events per frame", .{
@as(f64, @floatFromInt(tracker.totalAllocSize)) / 1024 / 1024, @as(f64, @floatFromInt(tracker.totalAllocSize)) / 1024 / 1024,
tracker.allocationsCount, tracker.allocationsCount,
tracker.eventsCount - self.lastEventsCount, tracker.eventsCount - self.lastEventsCount,
}) catch {}; }, null) catch {};
self.screenContext.pushDebugText("untracked allocations: {d:.4} MiB in {d} allocations", .{ self.screenContext.pushDebugText("untracked allocations: {d:.4} MiB in {d} allocations", .{
@as(f64, @floatFromInt(tracker.untrackedAllocationsSize)) / 1024 / 1024, @as(f64, @floatFromInt(tracker.untrackedAllocationsSize)) / 1024 / 1024,
tracker.untrackedAllocationsCount, tracker.untrackedAllocationsCount,
}) catch {}; }, null) catch {};
self.screenContext.pushDebugText("total {d:.4} MiB", .{ self.screenContext.pushDebugText("total {d:.4} MiB", .{
@as(f64, @floatFromInt(tracker.getTotalMemoryUsed())) / 1024 / 1024, @as(f64, @floatFromInt(tracker.getTotalMemoryUsed())) / 1024 / 1024,
}) catch {}; }, null) catch {};
self.lastEventsCount = tracker.eventsCount; self.lastEventsCount = tracker.eventsCount;
} }
const fdt: f32 = @floatCast(dt);
var offset: usize = 0;
self.debugTextQueue.lock();
defer self.debugTextQueue.unlock();
const count = self.debugTextQueue.count();
while (offset < count and offset < 32) {
const display = self.debugTextQueue.queue.at(count - offset - 1).?;
var color = display.color;
if (display.duration < 1.5) {
color.a = display.duration / 1.5;
}
// in terms of rendering, we gonna just
self.screenContext.pushDebugText("{s}", .{
display.text,
}, color) catch {};
offset += 1;
}
offset = 0;
while (offset < count) {
var next = self.debugTextQueue.popFromUnlocked().?;
next.duration -= fdt;
if (next.duration >= 0) {
self.debugTextQueue.queue.push(next) catch {};
} else {
self.debugStringArena.allocator().free(next.text);
}
offset += 1;
}
} }
pub fn setup(self: *@This()) !void { pub fn setup(self: *@This()) !void {
@ -205,10 +271,12 @@ pub fn destroy(self: *@This()) void {
next.*.destroy(); next.*.destroy();
} }
self.debugTextQueue.deinit();
self.fontTextures.deinit(self.allocator); self.fontTextures.deinit(self.allocator);
self.textRenderers.deinit(self.allocator); self.textRenderers.deinit(self.allocator);
self.screenContext.destroy(); self.screenContext.destroy();
self.stringArena.deinit(); self.stringArena.deinit();
self.debugStringArena.deinit();
self.runtime.destroy(); self.runtime.destroy();
self.drawList.deinit(); self.drawList.deinit();
self.tempDrawCommand.deinit(self.allocator); self.tempDrawCommand.deinit(self.allocator);
@ -340,8 +408,8 @@ pub fn drawToTarget(self: *@This(), cmd: *gpu.GPUCommandBuffer, ctx: *papyrus.Co
const stashedDrawDebug = ctx.drawDebug; const stashedDrawDebug = ctx.drawDebug;
if (self.reloadingShaders) { if (self.reloadingShaders) {
ctx.pushDebugText("recompiling shaders...", .{}) catch {}; ctx.pushDebugText("recompiling shaders...", .{}, null) catch {};
ctx.pushDebugText("...", .{}) catch {}; ctx.pushDebugText("...", .{}, null) catch {};
} }
ctx.drawDebug = stashedDrawDebug or self.reloadingShaders; ctx.drawDebug = stashedDrawDebug or self.reloadingShaders;

View File

@ -239,7 +239,7 @@ pub const TextRenderer = struct {
.x = baseMetrics.x / @as(f32, @floatFromInt(atlas.atlasSize.x)), .x = baseMetrics.x / @as(f32, @floatFromInt(atlas.atlasSize.x)),
.y = baseMetrics.y / @as(f32, @floatFromInt(atlas.atlasSize.y)), .y = baseMetrics.y / @as(f32, @floatFromInt(atlas.atlasSize.y)),
}, // uv size }, // uv size
.{ .r = color.r, .g = color.g, .b = color.b }, // color .{ .r = color.r, .g = color.g, .b = color.b, .a = color.a }, // color
// uvSize: core.Vector2f, // uvSize: core.Vector2f,
// color: core.colors.Color, // color: core.colors.Color,
// vertex: *TextBufferList(TextMeshVertex), // vertex: *TextBufferList(TextMeshVertex),

View File

@ -12,12 +12,11 @@ pub const ModuleLoader = @import("debuggers/modulesLoader.zig");
pub const browser = @import("debuggers/fileBrowser.zig"); pub const browser = @import("debuggers/fileBrowser.zig");
pub fn setup() !void { pub const GameList = games.GameList;
_ = try core.createObject(games.GameList, .{});
}
pub const GameModeMessage = games.GameModeMessage; pub const GameModeMessage = games.GameModeMessage;
pub const GameModeState = games.GameModeState; pub const GameModeState = games.GameModeState;
pub const addGame = games.addGame;
pub const getGame = games.getGame; pub const getGame = games.getGame;
pub const beginGame = games.beginGame; pub const beginGame = games.beginGame;
pub const endGame = games.endGame; pub const endGame = games.endGame;

View File

@ -20,7 +20,7 @@ pub const GameInterface = struct {
pub const GameList = struct { pub const GameList = struct {
pub var NeonObjectTable = core.EngineObjectVTable.from(@This(), "extras.GameList"); pub var NeonObjectTable = core.EngineObjectVTable.from(@This(), "extras.GameList");
allocator: std.mem.Allocator, allocator: std.mem.Allocator = undefined,
games: std.StringHashMapUnmanaged(*GameInterface) = .{}, games: std.StringHashMapUnmanaged(*GameInterface) = .{},
gamesByTag: std.AutoHashMapUnmanaged(u32, GameInterfaceList) = .{}, gamesByTag: std.AutoHashMapUnmanaged(u32, GameInterfaceList) = .{},
@ -87,16 +87,24 @@ pub const GameList = struct {
}; };
pub fn beginGame(name: []const u8) void { pub fn beginGame(name: []const u8) void {
getGame(name).beginPlay(); if (getGame(name)) |game| {
game.beginPlay();
} else {
core.engine_log("unable to begin game {s}", .{name});
}
} }
pub fn endGame(name: []const u8) void { pub fn endGame(name: []const u8) void {
getGame(name).endPlay(); if (getGame(name)) |game| {
game.endPlay();
} else {
core.engine_log("unable to endPlay game {s}", .{name});
}
} }
pub fn getGame(name: []const u8) *GameInterface { pub fn getGame(name: []const u8) ?*GameInterface {
core.engine_log("getting Game {s}", .{name}); core.engine_log("getting Game {s}", .{name});
return core.EngineObject(GameList).get().games.get(name).?; return core.EngineObject(GameList).get().games.get(name);
} }
pub fn addGame(name: []const u8, p: *anyopaque, comptime T: type) !void { pub fn addGame(name: []const u8, p: *anyopaque, comptime T: type) !void {

View File

@ -27,8 +27,8 @@ pub fn RingQueue(comptime T: type) type {
pub fn pushLocked(self: *@This(), newValue: T) RingQueueError!void { pub fn pushLocked(self: *@This(), newValue: T) RingQueueError!void {
self.mutex.lock(); self.mutex.lock();
try self.queue.push(newValue);
defer self.mutex.unlock(); defer self.mutex.unlock();
try self.queue.push(newValue);
} }
// only call this if you have locked already // only call this if you have locked already

View File

@ -293,7 +293,7 @@ pub const PackerFS = struct {
self.lock.lock(); self.lock.lock();
defer self.lock.unlock(); defer self.lock.unlock();
std.debug.print("loading file: {s}", .{path}); // std.debug.print("loading file: {s}", .{path});
var pathName = Name.Make(path); var pathName = Name.Make(path);
if (self.fileHandlesByName.get(pathName.handle())) |fileNameHandle| { if (self.fileHandlesByName.get(pathName.handle())) |fileNameHandle| {
// std.debug.print("{s} maps to index {d}\n", .{ path, fileNameHandle }); // std.debug.print("{s} maps to index {d}\n", .{ path, fileNameHandle });
@ -308,7 +308,7 @@ pub const PackerFS = struct {
for (self.contentPaths.items) |contentPath| { for (self.contentPaths.items) |contentPath| {
if (try self.loadFileDirect(contentPath, path)) |mapping| { if (try self.loadFileDirect(contentPath, path)) |mapping| {
std.debug.print("loading directly: {s}, {s}", .{ contentPath, path }); // std.debug.print("loading directly: {s}, {s}", .{ contentPath, path });
return mapping; return mapping;
} }
} }

View File

@ -16,8 +16,6 @@ struct type_StructuredBuffer_FontInfo
FontInfo _m0[1]; FontInfo _m0[1];
}; };
constant float _59 = {};
struct main0_out struct main0_out
{ {
float4 out_var_SV_Target0 [[color(0)]]; float4 out_var_SV_Target0 [[color(0)]];
@ -80,24 +78,25 @@ fragment main0_out main0(main0_in in [[stage_in]], const device type_StructuredB
float _110 = float(in.in_var_TEXCOORD0 & 255u) * 0.0039215688593685626983642578125; float _110 = float(in.in_var_TEXCOORD0 & 255u) * 0.0039215688593685626983642578125;
float _114 = float((in.in_var_TEXCOORD0 >> 8u) & 255u) * 0.0039215688593685626983642578125; float _114 = float((in.in_var_TEXCOORD0 >> 8u) & 255u) * 0.0039215688593685626983642578125;
float _118 = float((in.in_var_TEXCOORD0 >> 16u) & 255u) * 0.0039215688593685626983642578125; float _118 = float((in.in_var_TEXCOORD0 >> 16u) & 255u) * 0.0039215688593685626983642578125;
float4 _181; float _122 = float((in.in_var_TEXCOORD0 >> 24u) & 255u) * 0.0039215688593685626983642578125;
float4 _187;
if (fontBuffer._m0[in.in_var_TEXCOORD3].isSdf == 1u) if (fontBuffer._m0[in.in_var_TEXCOORD3].isSdf == 1u)
{ {
float _124 = _67.x; float _128 = _67.x;
float _125 = fwidth(_124); float _129 = fwidth(_128);
float _126 = 0.529411792755126953125 - _125; float _130 = 0.529411792755126953125 - _129;
float _127 = 0.529411792755126953125 + _125; float _131 = 0.529411792755126953125 + _129;
float2 _133 = (dfdx(in.in_var_TEXCOORD1) + dfdy(in.in_var_TEXCOORD1)) * 0.3540000021457672119140625; float2 _137 = (dfdx(in.in_var_TEXCOORD1) + dfdy(in.in_var_TEXCOORD1)) * 0.3540000021457672119140625;
float4 _140 = float4(in.in_var_TEXCOORD1 - _133, in.in_var_TEXCOORD1 + _133); float4 _144 = float4(in.in_var_TEXCOORD1 - _137, in.in_var_TEXCOORD1 + _137);
float4 _171 = float4(_110, _114, _118, (fast::clamp(smoothstep(_126, _127, _124), 0.0, 1.0) + (0.5 * (((fast::clamp(smoothstep(_126, _127, Texture0.sample(Sampler0, _140.xy).x), 0.0, 1.0) + fast::clamp(smoothstep(_126, _127, Texture0.sample(Sampler0, _140.zw).x), 0.0, 1.0)) + fast::clamp(smoothstep(_126, _127, Texture0.sample(Sampler0, _140.xw).x), 0.0, 1.0)) + fast::clamp(smoothstep(_126, _127, Texture0.sample(Sampler0, _140.zy).x), 0.0, 1.0)))) * 0.3333333432674407958984375); float4 _176 = float4(_110, _114, _118, ((fast::clamp(smoothstep(_130, _131, _128), 0.0, 1.0) + (0.5 * (((fast::clamp(smoothstep(_130, _131, Texture0.sample(Sampler0, _144.xy).x), 0.0, 1.0) + fast::clamp(smoothstep(_130, _131, Texture0.sample(Sampler0, _144.zw).x), 0.0, 1.0)) + fast::clamp(smoothstep(_130, _131, Texture0.sample(Sampler0, _144.xw).x), 0.0, 1.0)) + fast::clamp(smoothstep(_130, _131, Texture0.sample(Sampler0, _144.zy).x), 0.0, 1.0)))) * 0.3333333432674407958984375) * _122);
float3 _173 = powr(_171.xyz, float3(2.2000000476837158203125)); float3 _178 = powr(_176.xyz, float3(2.2000000476837158203125));
_181 = float4(_173.x, _173.y, _173.z, _171.w); _187 = float4(_178.x, _178.y, _178.z, _176.w);
} }
else else
{ {
_181 = float4(_110, _114, _118, powr(_67.x / dot(float4(_110, _114, _118, _59).xyz, float3(0.2125999927520751953125, 0.715200006961822509765625, 0.072200000286102294921875)), 0.4545454680919647216796875)); _187 = float4(_110, _114, _118, powr(_67.x / dot(float4(_110, _114, _118, _122).xyz, float3(0.2125999927520751953125, 0.715200006961822509765625, 0.072200000286102294921875)), 0.4545454680919647216796875) * _122);
} }
out.out_var_SV_Target0 = _181; out.out_var_SV_Target0 = _187;
return out; return out;
} }

View File

@ -26,10 +26,13 @@ pub export fn subtract(a: i32, b: i32) i32 {
var gAllocator: std.mem.Allocator = undefined; var gAllocator: std.mem.Allocator = undefined;
pub fn start_module(args: core.ModuleLoaderArgs) !void { pub fn start_module(args: core.ModuleLoaderArgs) !void {
core.PatchOrCreateObject(extras.GameList, .{});
core.PatchOrCreateObject(extras.ModuleLoader, .{}); core.PatchOrCreateObject(extras.ModuleLoader, .{});
core.PatchOrCreateObject(extras.ObjectSystemSpawner, .{}); core.PatchOrCreateObject(extras.ObjectSystemSpawner, .{});
core.PatchOrCreateObject(net.EnetTransport, .{});
core.PatchOrCreateObject(ExternGameObject, .{}); core.PatchOrCreateObject(ExternGameObject, .{});
core.PatchOrCreateObject(imgui.utils.ConsoleWindow, .{}); core.PatchOrCreateObject(imgui.utils.ConsoleWindow, .{});
core.PatchOrCreateObject(@import("fpgame/fpgame.zig"), .{});
_ = args; _ = args;
core.logDisplay("externGame", "accessing old object at {x} same object? {d}", .{ @intFromPtr(core.EngineObject(ExternGameObject).get()), @sizeOf(ExternGameObject) }); core.logDisplay("externGame", "accessing old object at {x} same object? {d}", .{ @intFromPtr(core.EngineObject(ExternGameObject).get()), @sizeOf(ExternGameObject) });
@ -83,6 +86,12 @@ pub const BoxObject = struct {
} }
}; };
pub const ExternGameArgs = struct {
clientTarget: []const u8 = "127.0.0.1",
clientIndex: u32 = 0,
asClient: bool = false,
};
pub const ExternGameObject = struct { pub const ExternGameObject = struct {
pub var NeonObjectTable = core.EngineObjectVTable.from(@This(), "game.ExternGameObject"); pub var NeonObjectTable = core.EngineObjectVTable.from(@This(), "game.ExternGameObject");
pub const Slack = core.SlackStruct(@This(), 1024); pub const Slack = core.SlackStruct(@This(), 1024);
@ -95,10 +104,13 @@ pub const ExternGameObject = struct {
session: ?*net.Session = null, session: ?*net.Session = null,
clientLink: ?*net.Link = null, clientLink: ?*net.Link = null,
launchAsClient: ?[]const u8 = null,
recompiling: bool = false, recompiling: bool = false,
firstTick: bool = true, firstTick: bool = true,
fpcamera: *extras.FpCamera = undefined,
fireInput: ?*core.ActionBinding = null, fireInput: ?*core.ActionBinding = null,
altFireInput: ?*core.ActionBinding = null, altFireInput: ?*core.ActionBinding = null,
reloadInput: ?*core.ActionBinding = null, reloadInput: ?*core.ActionBinding = null,
@ -116,10 +128,16 @@ pub const ExternGameObject = struct {
spawnedEntities: std.ArrayListUnmanaged(core.Entity) = .{}, spawnedEntities: std.ArrayListUnmanaged(core.Entity) = .{},
clientIndex: u32 = 0,
autoAddClients: bool = true,
clientsToAdd: u32 = 1,
displayVectorsTest: bool = false, displayVectorsTest: bool = false,
pub fn beginPlay(p: *anyopaque) void { pub fn beginPlay(p: *anyopaque) void {
const self = core.cast(*@This(), p); const self = core.cast(*@This(), p);
ui.context().screenContext.drawDebug = true;
self._beginPlay() catch { self._beginPlay() catch {
core.engine_errs("unable to beginplay"); core.engine_errs("unable to beginplay");
}; };
@ -232,6 +250,24 @@ pub const ExternGameObject = struct {
self.physicsObjectsWindow = try extras.PhysicsObjectList.create(self.allocator); self.physicsObjectsWindow = try extras.PhysicsObjectList.create(self.allocator);
const args = try core.ParseArgs(ExternGameArgs);
if (args.asClient) {
self.launchAsClient = args.clientTarget;
self.clientIndex = args.clientIndex;
core.engine_log("starting up as client connecting to {s}", .{args.clientTarget});
platform.context().pushRequest(.{ .setWindowSize = .{ .size = .{ .x = 1000, .y = 562 } } });
platform.context().pushRequest(.{ .setWindowPosition = .{ .pos = .{ .x = 1000 * args.clientIndex, .y = 30 } } });
const ctx = ui.getScreen();
const text = try ctx.addText(.{}, "client");
ctx.get(text).pos = .{ .x = 0, .y = 10 };
ctx.get(text).size = .{ .x = 400, .y = 300 };
ui.context().screenContext.debugFontSize = 20;
self.connectClient();
}
try core.registerObject(BoxObject, "Box"); try core.registerObject(BoxObject, "Box");
try core.registerObjectAdvanced(BoxObject, "BoxSmoky", "createSmoky"); try core.registerObjectAdvanced(BoxObject, "BoxSmoky", "createSmoky");
@ -263,8 +299,7 @@ pub const ExternGameObject = struct {
} }
} }
try extras.games.addGame("ExternGame", self, @This()); try extras.addGame("ExternGame", self, @This());
extras.beginGame("ExternGame"); extras.beginGame("ExternGame");
return self; return self;
@ -391,6 +426,7 @@ pub const ExternGameObject = struct {
if (platform.context().isCursorEnabled()) { if (platform.context().isCursorEnabled()) {
core.engine_logs("moving light"); core.engine_logs("moving light");
core.debugTextLog("moving light", 3.5, .{ .color = core.colors.Color.Green });
const ray = rend.context().activeCamera.?.getNormalRayFromScreen(platform.getCursorPosition()); const ray = rend.context().activeCamera.?.getNormalRayFromScreen(platform.getCursorPosition());
if (physics.traceLine(ray.start, ray.dir.fmul(10000), .{ .bodyFilter = &self.fireTraceFilter, .getNormalsSlow = true })) |r| { if (physics.traceLine(ray.start, ray.dir.fmul(10000), .{ .bodyFilter = &self.fireTraceFilter, .getNormalsSlow = true })) |r| {
if (r.normal) |n| { if (r.normal) |n| {
@ -469,6 +505,22 @@ pub const ExternGameObject = struct {
ig.textf("lmao", .{}); ig.textf("lmao", .{});
if (ig.smallButton("800x450")) {
platform.context().pushRequest(.{ .setWindowSize = .{ .size = .{ .x = 800, .y = 450 } } });
}
if (ig.smallButton("1600x900")) {
platform.context().pushRequest(.{ .setWindowSize = .{ .size = .{ .x = 1600, .y = 900 } } });
}
if (ig.smallButton("maximize")) {
platform.context().pushRequest(.{ .maximizeWindow = .{} });
}
if (ig.smallButton("setMousePos")) {
platform.context().pushRequest(.{ .setMousePosition = .{ .pos = .{ .x = 800, .y = 450 } } });
}
if (ig.smallButton("reload map")) { if (ig.smallButton("reload map")) {
self.loadMap2() catch unreachable; self.loadMap2() catch unreachable;
} }
@ -496,17 +548,61 @@ pub const ExternGameObject = struct {
audio.context().setVolume(self.volume / 100); audio.context().setVolume(self.volume / 100);
} }
_ = ig.checkbox("addClients", &self.autoAddClients);
ig.sameLine(0, 10);
if (self.autoAddClients) {
_ = ig.inputInt("clientCount", @ptrCast(&self.clientsToAdd), 1, 1, .{});
}
if (ig.smallButton("host")) { if (ig.smallButton("host")) {
self.session = net.hostSession(&.{"7777"}) catch unreachable; self.session = blk: {
const s = net.hostSession(&.{"7777"}) catch {
core.engine_err("host server failed", .{});
break :blk null;
};
break :blk s;
};
if (self.session) |session| {
_ = session;
var fmt: [256]u8 = undefined;
var fmt2: [256]u8 = undefined;
for (0..self.clientsToAdd) |i| {
const ci = std.fmt.bufPrint(&fmt, "--clientIndex={d}", .{i}) catch {
core.engine_err("unable to create client {d} out of memory?", .{i});
break;
};
const igIni = std.fmt.bufPrint(&fmt2, "--imguiIni=client{d}.ini", .{i}) catch {
core.engine_err("unable to create client {d} out of memory?", .{i});
break;
};
_ = sys.SubprocessTask.runCommand(
self.allocator,
&.{ "zig-out/bin/sampleGame.exe", "--asClient=True", ci, igIni },
".",
) catch {
core.engine_err("unable to create client {d}", .{i});
break;
};
}
}
} }
if (ig.smallButton("connect")) { if (ig.smallButton("connect")) {
self.clientLink = net.connect("127.0.0.1:7777") catch unreachable; self.connectClient();
} }
if (self.clientLink) |link| { if (self.clientLink) |link| {
if (ig.smallButton("sendMessageToServer")) { if (ig.smallButton("sendMessageToServer")) {
link.sendMessage("hello from client", true) catch {}; link.sendMessage("hello from client", true) catch {};
link.sendMessage("hello from client (unreliable)", false) catch {};
const linkData = net.EnetTransport.getLinkData(link);
linkData.sendPacketChannelDebug("debug: unreliable over channel 0", false, 0);
linkData.sendPacketChannelDebug("debug: reliable over channel 1", true, 1);
} }
} }
} }
@ -524,8 +620,16 @@ pub const ExternGameObject = struct {
self.particleDebugger.particleDebug(); self.particleDebugger.particleDebug();
} }
if (self.session) |session| { if (self.session) |session| {
if (session.links.items.len > 0) { if (ig.begin("host session", null, .{})) {
const linkData = net.EnetTransport.getLinkData(session.links.items[0]); for (session.links.items) |link| {
const linkData = net.EnetTransport.getLinkData(link);
ig.textf("{s} {d}ms", .{ link.idString, linkData.peer.*.roundTripTime });
}
}
ig.end();
for (session.links.items) |link| {
const linkData = net.EnetTransport.getLinkData(link);
if (rend.context().activeCamera) |camera| { if (rend.context().activeCamera) |camera| {
linkData.testLinkPosition = camera.entity.fetch(core.Scene).?.getPosition(); linkData.testLinkPosition = camera.entity.fetch(core.Scene).?.getPosition();
} }
@ -540,6 +644,21 @@ pub const ExternGameObject = struct {
} }
} }
fn connectClient(self: *@This()) void {
self.clientLink = net.connect("127.0.0.1:7777") catch unreachable;
var fmt: [256]u8 = undefined;
if (self.clientLink) |link| {
const nameMsg = std.fmt.bufPrint(&fmt, "cname:client{d}", .{self.clientIndex}) catch {
core.engine_err("unable to create client message, out of memory?", .{});
return;
};
link.sendMessage(nameMsg, true) catch {
core.engine_err("unable to send message?", .{});
};
}
}
pub fn destroy(self: *@This()) void { pub fn destroy(self: *@This()) void {
if (self.clientLink) |link| { if (self.clientLink) |link| {
link.destroy(); link.destroy();

View File

@ -251,8 +251,6 @@ pub fn prepare(self: *@This()) !void {
defer z.End(); defer z.End();
try core.fs().addContentPath("sampleGame"); try core.fs().addContentPath("sampleGame");
try extras.setup();
try audio.loadBuiltinSounds(); try audio.loadBuiltinSounds();
// try core.loadModule("externGame", true); // try core.loadModule("externGame", true);
@ -269,17 +267,21 @@ pub fn prepare(self: *@This()) !void {
try rendererDebug.skyboxes.append(rendererDebug.allocator, core.MakeName("t_dark_skybox")); try rendererDebug.skyboxes.append(rendererDebug.allocator, core.MakeName("t_dark_skybox"));
try core.getEngineObject(core.GameObjectSystem).?.registerObject("foxObject", FoxObject); try core.getEngineObject(core.GameObjectSystem).?.registerObject("foxObject", FoxObject);
core.PatchOrCreateObject(extras.games.GameList, .{});
try assets.loadList(assetReferences); try assets.loadList(assetReferences);
// self.videoplayer = try VideoPlayer.create(self.allocator); // self.videoplayer = try VideoPlayer.create(self.allocator);
// try self.videoplayer.startPlayback("LAPWING2.ogv"); // try self.videoplayer.startPlayback("LAPWING2.ogv");
// self.videoplayerObject = try self.videoplayer.createVideoPlayerEntity(); // self.videoplayerObject = try self.videoplayer.createVideoPlayerEntity();
try extras.addGame("Default", self, @This());
extras.beginGame("Default");
rend.setSkyboxTexture("t_skybox"); rend.setSkyboxTexture("t_skybox");
beginPlay(@ptrCast(self)); // beginPlay(@ptrCast(self));
} }
fn beginPlay(p: ?*anyopaque) void { pub fn beginPlay(p: ?*anyopaque) void {
const self = core.cast(*@This(), p.?); const self = core.cast(*@This(), p.?);
self._beginPlay() catch { self._beginPlay() catch {
core.engine_errs("unable to beginPlay sampleagme"); core.engine_errs("unable to beginPlay sampleagme");
@ -363,7 +365,7 @@ fn _beginPlay(self: *@This()) !void {
self.updateMouseLook(); self.updateMouseLook();
} }
pub fn game_endPlay(p: ?*anyopaque) void { pub fn endPlay(p: ?*anyopaque) void {
const self = core.cast(*@This(), p.?); const self = core.cast(*@This(), p.?);
_ = self; _ = self;
} }

View File

@ -62,7 +62,7 @@ pub fn tick(self: *@This(), dt: f64) void {
if (self.activeCommand) |cmd| { if (self.activeCommand) |cmd| {
ig.textf("current command: ", .{}); ig.textf("current command: ", .{});
for (cmd.args) |arg| { for (cmd.argsOwned.items) |arg| {
ig.textf("{s}", .{arg}); ig.textf("{s}", .{arg});
ig.sameLine(0, 4); ig.sameLine(0, 4);
} }

View File

@ -93,7 +93,7 @@ pub fn tick(self: *@This(), dt: f64) void {
if (self.activeCommand) |cmd| { if (self.activeCommand) |cmd| {
ig.textf("current command: ", .{}); ig.textf("current command: ", .{});
for (cmd.args) |arg| { for (cmd.argsOwned.items) |arg| {
ig.textf("{s}", .{arg}); ig.textf("{s}", .{arg});
ig.sameLine(0, 4); ig.sameLine(0, 4);
} }