Backlog/projects/sampleGame/externGame/externGame.zig

337 lines
13 KiB
Zig

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", "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,
editParticle: ?core.Entity = null,
savedGravity: core.Vectorf = .{},
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", .{});
}
const ItemWidth = 80;
pub fn displayRandRangeImgui(comptime Name: []const u8, range: *rend.particles.ParticleRandRangef) void {
ig.textFmt(Name, .{}) catch {};
ig.sameLine(0, 10);
ig.setNextItemWidth(ItemWidth);
_ = ig.inputFloat("Min##particleEd" ++ Name, &range.min, 1.0, 5.0, null, .{});
ig.sameLine(0, 10);
ig.setNextItemWidth(ItemWidth);
_ = ig.inputFloat("Max##particleEd" ++ Name, &range.max, 1.0, 5.0, null, .{});
}
pub fn editVector(comptime Name: []const u8, range: *core.Vectorf) void {
ig.textFmt(Name, .{}) catch {};
ig.sameLine(0, 10);
ig.setNextItemWidth(ItemWidth);
_ = ig.inputFloat("X##particleEd" ++ Name, &range.x, 1.0, 5.0, null, .{});
ig.sameLine(0, 10);
ig.setNextItemWidth(ItemWidth);
_ = ig.inputFloat("Y##particleEd" ++ Name, &range.y, 1.0, 5.0, null, .{});
ig.sameLine(0, 10);
ig.setNextItemWidth(ItemWidth);
_ = ig.inputFloat("Z##particleEd" ++ Name, &range.z, 1.0, 5.0, null, .{});
}
pub fn particleDebug(self: *@This()) void {
if (ig.begin("particleDebugger", null, .{})) {
var buffer: [256]u8 = undefined;
for (rend.ParticleEmitter.BaseContainer.dense.items, 0..) |*emitter, i| {
ig.textFmt("emitter {d}", .{emitter.sparseIndex.index}) catch {};
if (ig.smallButton(std.fmt.bufPrintZ(&buffer, "edit##{d}", .{i}) catch unreachable)) {
self.editParticle = emitter.value.entity;
}
}
}
ig.end();
var checkbox: bool = true;
if (self.editParticle) |edit| {
if (edit.fetch(rend.ParticleEmitter)) |emitter| {
if (ig.begin("editParticle", null, .{})) {
displayRandRangeImgui("Acceleration", &emitter.particleAcceleration);
displayRandRangeImgui("Velocity", &emitter.particleVelocity);
displayRandRangeImgui("Life", &emitter.particleLife);
displayRandRangeImgui("Size", &emitter.particleSizeSpawn);
displayRandRangeImgui("spawnRate", &emitter.spawnRate);
if (emitter.gravity != null) {
checkbox = true;
} else {
checkbox = false;
}
if (ig.checkbox("hasGravity", &checkbox)) {
if (!checkbox) {
self.savedGravity = emitter.gravity.?;
emitter.gravity = null;
}
if (checkbox) {
emitter.gravity = self.savedGravity;
}
}
if (emitter.gravity != null) {
editVector("gravity", &emitter.gravity.?);
}
_ = ig.inputInt("maxParticles##particleEd", @ptrCast(&emitter.maxParticles), 1, 5, .{});
_ = ig.checkbox("showDebug", &emitter._showDebug);
}
ig.end();
}
}
}
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 altFireInput = try core.ActionBinding.create(core.MakeName("altFire"));
altFireInput.addKey(.Mouse3, .keyDown);
_ = altFireInput.data.addListener(self, onAltFire);
altFireInput.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);
if (false) {
const ctx = ui.getScreen();
const panel2 = try ctx.addPanel(.{});
ctx.drawDebug = true;
{
ctx.getPanel(panel2).hasTitle = true;
//ctx.get(panel2).anchor = .TopRight;
// ctx.get(panel2).fill = .FillY; todo, this is a bug. why.
ctx.get(panel2).pos = .{ .x = 900, .y = 200 };
ctx.get(panel2).size = .{ .x = 300, .y = 400 };
ctx.get(panel2).style.backgroundColor = ui.ModernStyle.GreyDark;
ctx.getPanel(panel2).titleColor = ui.ModernStyle.GreyDark;
// add some text to this panel
const text = try ctx.addText(panel2, "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.");
ctx.get(text).pos = .{ .x = 2, .y = 2 };
ctx.get(text).size = ctx.get(panel2).size.sub(.{ .x = 4, .y = 36 });
}
}
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,
});
const particle = box2.addComponent(rend.ParticleEmitter).?;
particle.start();
particle.gravity = .{ .y = 1.0 };
particle.particleVelocity = .{ .min = 0.6, .max = 1.2 };
particle.particleLife = .{ .min = 5, .max = 6 };
var name = core.MakeName("t_pixelSmoke");
particle.texture = rend.getTexture(&name).?;
}
fn onAltFire(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 });
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);
}
}
}
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));
addBox(p.add(n.fmul(1.0))) catch unreachable;
}
}
}
}
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 lol", .{}) 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;
}
}
if (ig.smallButton("dumpTimeline")) {
core.MemoryTracker.dumpTimeline("timeline.txt") catch unreachable;
}
}
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.particleDebug();
}
}
pub fn destroy(self: *@This()) void {
if (self.tbMap) |map| {
map.destroy();
}
self.consoleWindow.deinit();
self.physicsObjectsWindow.destroy();
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 ui = backlog.ui;
const platform = backlog.platform;
const extras = @import("gameExtras");
const bsp = @import("bsp");