pub export fn startup(p_allocator: *anyopaque, p_a: ?*anyopaque) bool { const allocator = core.modulePreamble(p_allocator, p_a) catch return false; _ = allocator; imgui.setupFromModule(); platform.setupFromModule(); rend.setupFromModule(); backlog.physics.setupFromModule(); // TODO backlog.setupFromModule start_module(core.startup_getArgs(p_a.?)) catch return false; return true; } pub export fn add(a: i32, b: i32) i32 { return a + b; } pub export fn subtract(a: i32, b: i32) i32 { return a + b; } var gAllocator: std.mem.Allocator = undefined; pub fn start_module(args: core.ModuleLoaderArgs) !void { if (args.firstLoad) { _ = core.createObject(ExternGameObject, .{}) catch {}; return; } core.logDisplay("externGame", "extern game reloaded ", .{}); core.logDisplay("externGame", "hello mother fucker", .{}); core.logDisplay("externGame", "accessing old object at {x} same object? {d}", .{ @intFromPtr(core.EngineObject(ExternGameObject).get()), @sizeOf(ExternGameObject) }); // getting rid of dumb comment //log("gonna try something dumb- lets patch the vtable of that old object with my vtable's values", .{}); const ref = core.getEngineObjectRef(ExternGameObject).?; const vtable: *core.EngineObjectVTable = @constCast(ref.vtable); vtable.* = ExternGameObject.NeonObjectTable; core.PatchStruct(ExternGameObject, @ptrCast(@alignCast(ref.ptr)), ref.vtable.fieldList.?); } pub const ExternGameObject = struct { pub var NeonObjectTable = core.EngineObjectVTable.from(@This(), "game.ExternGameObject"); pub const Slack = core.SlackStruct(@This(), 512); allocator: std.mem.Allocator = undefined, consoleWindow: imgui.utils.ConsoleWindow = undefined, tbMap: ?*bsp.maploader.TBMap = null, physicsObjectsWindow: *extras.PhysicsObjectList = undefined, fireTraceFilter: physics.IgnoreFixedBodiesFilter = .{}, //lmao: bool = false, //lmao2: bool = true, a: bool = false, // lib: bool = false, //s: u32 = 0x42, pub fn loadMap2(self: *@This()) !void { if (self.tbMap) |tbMap| { core.engine_log("killing the map", .{}); tbMap.destroy(); } self.tbMap = try bsp.maploader.LoadTrenchbroomMap(self.allocator, .{ .rotation = core.Rotation.eulerX(core.radians(-90.0)), .mapName = "bsp/testmap.map", }); core.engine_log("map loaded", .{}); } pub fn create(allocator: std.mem.Allocator) !*@This() { const self = try Slack.create(allocator); self.* = .{ .allocator = allocator, .consoleWindow = imgui.utils.ConsoleWindow.init(allocator), }; imgui.utils.addMenuFunc(self, "Input Stack Viewer", extras.inputDebugger.windowOpen); self.physicsObjectsWindow = try extras.PhysicsObjectList.create(self.allocator); self.consoleWindow.setup(); const fireInput = try core.ActionBinding.create(core.MakeName("fire")); fireInput.addKey(.Mouse1, .keyDown); _ = fireInput.data.addListener(self, onFire); fireInput.activate(); const settings: physics.ShapeSettings = .{ .box = try physics.BoxShapeSettings.create(.{ 1.0, 1.0, 1.0 }) }; defer settings.release(); try physics.addShape("ph_small_box", settings); return self; } pub fn addBox(position: core.Vectorf) !void { const box2 = try core.createEntity(); const scene = box2.addComponent(core.Scene).?; const mesh = box2.addComponent(rend.MeshComponent).?; mesh.setMesh("m_crate"); mesh.setTexture("t_crate"); scene.setPosition(position); scene.setScaleV(core.Vectorf.fromInt(1.0)); scene.setMobility(.moveable); const collider = box2.addComponent(physics.PhysicsCollider).?; try collider.setupByShapeName(core.MakeName("ph_small_box"), .{ .motion_type = .dynamic, .object_layer = physics.ObjectLayers.moving, .friction = 0.8, .mass_properties_override = .{ .mass = 12 }, .override_mass_properties = .calc_inertia, }); } fn onFire(ctx: ?*anyopaque, _: core.ActionEvent) void { const self: *@This() = @ptrCast(@alignCast(ctx)); if (platform.context().isCursorEnabled()) { core.engine_logs("moving light "); const ray = rend.context().activeCamera.?.getNormalRayFromScreen(platform.getCursorPosition()); if (physics.traceLine(ray.start, ray.dir.fmul(10000), .{ .bodyFilter = &self.fireTraceFilter, .getNormalsSlow = true })) |r| { if (r.normal) |n| { const p = r.point.add(n.fmul(0.2)); core.debugSphere(p, 0.2, .{ .color = .{ .y = 1.0 }, .duration = 10.0 }); addBox(p.add(n.fmul(1.0))) catch unreachable; rend.context().lightPosition = p; } // core.debugLine(ray.start, ray.start.add(ray.dir.fmul(1000)), .{ .duration = 2.5 }); // physics.applyForce(r.body, ray.dir.fmul(400), r.point); } } } pub fn tick(self: *@This(), dt: f64) void { const rctx = rend.context(); _ = rctx; _ = dt; if (core.getEngineObject(imgui.utils.TopBar)) |topbar| { topbar.menuOpen = platform.context().isCursorEnabled(); } if (platform.context().isCursorEnabled()) { if (ig.begin("meh", null, .{})) { // if (ig.checkbox("move lights ", null)) {} ig.textFmt("info: - WASD to move, mouse to look,\n- Q and E to go up and down", .{}) catch return; ig.textFmt("- shift to slow down camera speed", .{}) catch return; ig.textFmt("- T to enable/disable mouse cursor", .{}) catch return; ig.textFmt("- f2 to route all inputs to the doom player", .{}) catch return; ig.textFmt("- movingLight checkbox makes the light stop moving with you", .{}) catch return; if (ig.smallButton("reload map")) { self.loadMap2() catch unreachable; } if (ig.smallButton("destroy map")) { if (self.tbMap) |tbMap| { core.engine_log("killing the map", .{}); tbMap.destroy(); self.tbMap = null; } } } ig.end(); if (platform.context().isCursorEnabled()) { if (rend.context().activeCamera) |cam| { const ray = cam.getNormalRayFromScreen(platform.getCursorPosition()); if (physics.traceLine(ray.start, ray.dir.fmul(10000), .{ .bodyFilter = &self.fireTraceFilter, .getNormalsSlow = false })) |r| { core.debugSphere(r.point, 0.2, .{ .color = .{ .x = 1.0 }, .duration = 0 }); } } } } //_ = self; // imgui.utils.structHexView(self); // imgui.utils.structHexView(rctx.activeCamera.?); // if (ig.begin("external game object", null, .{})) { // ig.textf("sup", .{}); // _ = ig.sliderFloat("skybox strength", &rctx.skyboxSystem.brightnessFactor, 0, 10, null, .{}); // if (rctx.activeCamera) |camera| { // const forwardVector = camera.forward(); // ig.textf("forward vector x:{d} y:{d} z:{d}", .{ forwardVector.x, forwardVector.y, forwardVector.z }); // } // } // ig.end(); // if (ig.begin("list of textures", null, .{})) { // var iterator = rctx.textureList.map.iterator(); // while (iterator.next()) |i| { // ig.textf("{s}", .{i.value_ptr.*.name.utf8()}); // } // } // ig.end(); // if (ig.begin("list of meshes", null, .{})) { // ig.textf("number of meshes: {d}", .{rctx.meshPool.installedMeshes.count()}); // var iterator = rctx.meshPool.installedMeshes.iterator(); // while (iterator.next()) |i| { // ig.textf("{s}", .{i.value_ptr.*.name.utf8()}); // } // } // ig.end(); } pub fn destroy(self: *@This()) void { self.allocator.destroy(Slack.fromPtr(self)); } }; pub export fn shutdown() void {} const std = @import("std"); const backlog = @import("backlog"); const core = backlog.core; const imgui = backlog.imgui; const physics = backlog.physics; const rend = backlog.rend; const ig = imgui.api; const platform = backlog.platform; const extras = @import("gameExtras"); const bsp = @import("bsp");