527 lines
15 KiB
Zig
527 lines
15 KiB
Zig
allocator: std.mem.Allocator,
|
|
moveInput: *core.Axis2dBinding = undefined,
|
|
|
|
cameraSpeed: f32 = 10.0,
|
|
moveVector: core.Vectorf = .{},
|
|
mouseMove: core.Vector2f = .{},
|
|
verticalMove: f32 = 0.0,
|
|
|
|
centerDist: f32 = 2.0,
|
|
centerDistMove: f32 = 2.0,
|
|
|
|
mouseLook: bool = true,
|
|
showWindow: bool = true,
|
|
|
|
fpcamera: *FpCamera = undefined,
|
|
|
|
// videoplayer: *VideoPlayer = undefined,
|
|
// videoplayerObject: core.Entity = undefined,
|
|
|
|
objectSpawner: *extras.ObjectSpawner = undefined,
|
|
|
|
inputEnabled: bool = true,
|
|
videoFullbright: bool = false,
|
|
|
|
//moveLight: bool = true,
|
|
|
|
tbMap: ?*bsp.maploader.TBMap = null,
|
|
|
|
// addFunc: ?*const fn (i32, i32) callconv(.c) i32 = undefined,
|
|
|
|
engineTool: *extras.EngineTool = undefined,
|
|
|
|
modules: std.AutoHashMapUnmanaged(u32, []const u8) = .{},
|
|
|
|
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "SampleGame");
|
|
|
|
pub fn init(allocator: std.mem.Allocator) !*@This() {
|
|
const self = try allocator.create(@This());
|
|
self.* = .{
|
|
.allocator = allocator,
|
|
};
|
|
return self;
|
|
}
|
|
|
|
const assetReferences = [_]assets.AssetImportReference{
|
|
assets.MakeImportRefOptions(
|
|
"Mesh",
|
|
"m_skybox",
|
|
.{ .path = "meshes/skybox.obj" },
|
|
),
|
|
assets.MakeImportRefOptions(
|
|
"Skeleton",
|
|
"sk_fox",
|
|
.{ .path = "gltf-samples/Fox/glTF/skeleton.ozz" },
|
|
),
|
|
assets.MakeImportRefOptions(
|
|
"Animation",
|
|
"a_fox_survey",
|
|
.{ .path = "gltf-samples/Fox/glTF/Survey.ozz" },
|
|
),
|
|
// assets.MakeImportRefOptions(
|
|
// "Sound",
|
|
// "s_macintosh",
|
|
// .{ .path = "sounds/MACINTOSHPLUS.wav" },
|
|
// ),
|
|
assets.MakeImportRefOptions(
|
|
"Mesh",
|
|
"m_fox",
|
|
.{ .path = "gltf-samples/Fox/glTF/Fox.gltf" },
|
|
),
|
|
assets.MakeImportRefOptions(
|
|
"Texture",
|
|
"t_fox",
|
|
.{ .path = "gltf-samples/Fox/glTF/Texture.png" },
|
|
),
|
|
assets.MakeImportRefOptions(
|
|
"Texture",
|
|
"t_pixelSmoke",
|
|
.{ .path = "textures/PixelSmoke.png" },
|
|
),
|
|
assets.MakeImportRefOptions("Texture", "t_crate", .{
|
|
.path = "textures/Crate.png",
|
|
}),
|
|
assets.MakeImportRefOptions(
|
|
"Mesh",
|
|
"m_crate",
|
|
.{ .path = "meshes/Crate.obj" },
|
|
),
|
|
assets.MakeImportRefOptions(
|
|
"Texture",
|
|
"t_dark_skybox",
|
|
.{
|
|
.textureCube = true,
|
|
.textureList = &.{
|
|
"textures/DarkGrey.png", // cubemapfacePositivex, right
|
|
"textures/DarkGrey.png", // cubemapfacePositivex, right
|
|
"textures/DarkGrey.png", // cubemapfacePositivex, right
|
|
"textures/DarkGrey.png", // cubemapfacePositivex, right
|
|
"textures/DarkGrey.png", // cubemapfacePositivex, right
|
|
"textures/DarkGrey.png", // cubemapfacePositivex, right
|
|
//"sky_air/cube_right.png", // cubemapfacePositivex, right
|
|
//"sky_air/cube_left.png", // cubemapfacePositivex, right
|
|
//"sky_air/cube_up.png", // cubemapfacePositivex, right
|
|
//"sky_air/cube_down.png", // cubemapfacePositivex, right
|
|
//"sky_air/cube_back.png", // cubemapfacePositivex, right
|
|
//"sky_air/cube_front.png", // cubemapfacePositivex, right
|
|
},
|
|
},
|
|
),
|
|
assets.MakeImportRefOptions(
|
|
"Texture",
|
|
"t_skybox",
|
|
.{
|
|
.textureCube = true,
|
|
.textureList = &.{
|
|
"sky_air/cube_right.png", // cubemapfacePositivex, right
|
|
"sky_air/cube_left.png", // cubemapfacePositivex, right
|
|
"sky_air/cube_up.png", // cubemapfacePositivex, right
|
|
"sky_air/cube_down.png", // cubemapfacePositivex, right
|
|
"sky_air/cube_back.png", // cubemapfacePositivex, right
|
|
"sky_air/cube_front.png", // cubemapfacePositivex, right
|
|
},
|
|
},
|
|
),
|
|
};
|
|
|
|
pub const ParticleObject = struct {
|
|
data: core.GameObjectData = undefined,
|
|
entity: core.Entity,
|
|
|
|
pub fn create(alloc: std.mem.Allocator) !*@This() {
|
|
const self = try alloc.create(@This());
|
|
const e = try core.createEntity();
|
|
|
|
const particle = e.addComponent(rend.ParticleEmitter).?;
|
|
particle.start();
|
|
particle.gravity = .{ .y = -9.8 };
|
|
var name = core.MakeName("t_pixelSmoke");
|
|
particle.texture = rend.getTexture(&name).?;
|
|
|
|
self.entity = e;
|
|
|
|
return self;
|
|
}
|
|
|
|
pub fn getEntity(self: *@This()) core.Entity {
|
|
return self.entity;
|
|
}
|
|
|
|
pub fn destroy(self: *@This()) void {
|
|
self.entity.destroy();
|
|
self.data.release(self);
|
|
}
|
|
};
|
|
|
|
pub const FoxObject = struct {
|
|
entity: core.Entity,
|
|
|
|
pub const MessageHandlers: []const []const u8 = &.{
|
|
"onGameModeMessage",
|
|
};
|
|
|
|
pub fn create(alloc: std.mem.Allocator, entity: core.Entity, p: core.SpawnParameters) !*@This() {
|
|
const self = try alloc.create(@This());
|
|
//const fox = try core.createEntity();
|
|
const fox = entity;
|
|
const scene = fox.addComponent(core.Scene).?;
|
|
|
|
var pr = p.posRot;
|
|
pr.scale = pr.scale.fmul(0.01);
|
|
scene.setPosRot(pr);
|
|
scene.updateTransform();
|
|
scene.setMobility(.moveable);
|
|
|
|
const mesh = fox.addComponent(rend.MeshComponent).?;
|
|
mesh.setMesh("m_fox");
|
|
mesh.setTexture("t_fox");
|
|
|
|
const animator = fox.addComponent(rend.Animator).?;
|
|
animator.setSkeleton("sk_fox");
|
|
animator.setAnimation("a_fox_survey");
|
|
|
|
self.entity = fox;
|
|
|
|
return self;
|
|
}
|
|
|
|
pub fn onGameModeMessage(self: *@This(), messageInfo: *const core.MessageInfo, gameModeMessage: *extras.GameModeMessage) void {
|
|
_ = self;
|
|
_ = messageInfo;
|
|
_ = gameModeMessage;
|
|
}
|
|
|
|
pub fn getEntity(self: *@This()) core.Entity {
|
|
return self.entity;
|
|
}
|
|
|
|
pub fn destroy(self: *@This(), allocator: std.mem.Allocator) void {
|
|
allocator.destroy(self);
|
|
core.engine_logs("destroying fox");
|
|
}
|
|
};
|
|
|
|
pub const DamagedHelmet = struct {
|
|
data: core.GameObjectData = undefined,
|
|
entity: core.Entity,
|
|
|
|
var first: bool = true;
|
|
pub fn create(alloc: std.mem.Allocator) !*@This() {
|
|
const refs = [_]assets.AssetImportReference{ assets.MakeImportRefOptions(
|
|
"Mesh",
|
|
"m_damagedHelmet",
|
|
.{ .path = "gltf-samples/DamagedHelmet/glTF/DamagedHelmet.gltf" },
|
|
), assets.MakeImportRefOptions(
|
|
"Texture",
|
|
"t_damagedHelmet",
|
|
.{ .path = "gltf-samples/DamagedHelmet/glTF/Default_albedo.png" },
|
|
) };
|
|
|
|
if (first) {
|
|
first = false;
|
|
try assets.loadList(refs);
|
|
}
|
|
|
|
const self = try alloc.create(@This());
|
|
self.entity = try core.createEntity();
|
|
const scene = self.entity.addComponent(core.Scene).?;
|
|
_ = scene;
|
|
|
|
// scene.setScale(0.01, 0.01, 0.01);
|
|
const mesh = self.entity.addComponent(rend.MeshComponent).?;
|
|
mesh.setMesh("m_damagedHelmet");
|
|
mesh.setTexture("t_damagedHelmet");
|
|
|
|
return self;
|
|
}
|
|
|
|
pub fn getEntity(self: *@This()) core.Entity {
|
|
return self.entity;
|
|
}
|
|
|
|
pub fn destroy(self: *@This()) void {
|
|
self.entity.destroy();
|
|
self.data.release(self);
|
|
}
|
|
};
|
|
|
|
pub fn prepare(self: *@This()) !void {
|
|
core.engine_log(">>>>>>> game prepare", .{});
|
|
var z = core.tracy.ZoneN(@src(), "PREPARING GAME");
|
|
defer z.End();
|
|
try core.fs().addContentPath("sampleGame");
|
|
|
|
try audio.loadBuiltinSounds();
|
|
|
|
// try core.loadModule("externGame", true);
|
|
|
|
try backlog.loadDynamicModules();
|
|
|
|
self.engineTool = try extras.EngineTool.create(self.allocator);
|
|
|
|
// core.fs().watchPath("zig-out/modules");
|
|
// try core.fs().addFileChangedCallback(core.sharedLibName("externGame"), moduleChangedCallback, self);
|
|
|
|
const rendererDebug = try core.createObject(extras.RendererDebug, .{});
|
|
try rendererDebug.skyboxes.append(rendererDebug.allocator, core.MakeName("t_skybox"));
|
|
try rendererDebug.skyboxes.append(rendererDebug.allocator, core.MakeName("t_dark_skybox"));
|
|
|
|
try core.getEngineObject(core.GameObjectSystem).?.registerObject("foxObject", FoxObject);
|
|
core.PatchOrCreateObject(extras.games.GameList, .{});
|
|
|
|
try assets.loadList(assetReferences);
|
|
// self.videoplayer = try VideoPlayer.create(self.allocator);
|
|
// try self.videoplayer.startPlayback("LAPWING2.ogv");
|
|
// self.videoplayerObject = try self.videoplayer.createVideoPlayerEntity();
|
|
|
|
try extras.addGame("Default", self, @This());
|
|
extras.beginGame("Default");
|
|
|
|
rend.setSkyboxTexture("t_skybox");
|
|
// beginPlay(@ptrCast(self));
|
|
}
|
|
|
|
pub fn beginPlay(p: ?*anyopaque) void {
|
|
const self = core.cast(*@This(), p.?);
|
|
self._beginPlay() catch {
|
|
core.engine_errs("unable to beginPlay sampleagme");
|
|
};
|
|
}
|
|
|
|
fn _beginPlay(self: *@This()) !void {
|
|
const exitInput = try core.ActionBinding.create(core.MakeName("exit"));
|
|
exitInput.addKey(.escape, .keyDown);
|
|
_ = exitInput.data.addListener(@This(), "onExit", self);
|
|
exitInput.activate();
|
|
|
|
{
|
|
const inp = try core.ActionBinding.create(core.MakeName("slow"));
|
|
inp.addKey(.lshift, .keyDown);
|
|
inp.addKey(.lshift, .keyUp);
|
|
_ = inp.data.addListener(@This(), "slowDown", self);
|
|
inp.activate();
|
|
}
|
|
|
|
self.fpcamera = try FpCamera.create(self.allocator);
|
|
self.fpcamera.setPosition(.{ .z = 15 });
|
|
self.fpcamera.activateCamera();
|
|
|
|
const moveInput = try core.Axis2dBinding.create(core.MakeName("movement"));
|
|
|
|
moveInput.addKey(.w, 1.0, .y);
|
|
moveInput.addKey(.s, -1.0, .y);
|
|
moveInput.addKey(.d, 1.0, .x);
|
|
moveInput.addKey(.a, -1.0, .x);
|
|
|
|
_ = moveInput.data.addListener(@This(), "onMove", self);
|
|
moveInput.activate();
|
|
|
|
{
|
|
const i = try core.Axis1dBinding.create(core.MakeName("rotPitch"));
|
|
i.addKey(.f, 1.0);
|
|
i.addKey(.v, -1.0);
|
|
|
|
_ = i.data.addListener(@This(), "distanceMove", self);
|
|
i.activate();
|
|
}
|
|
|
|
{
|
|
const verticalInput = try core.Axis1dBinding.create(core.MakeName("movementVertical"));
|
|
verticalInput.addKey(.e, 1.0);
|
|
verticalInput.addKey(.q, -1.0);
|
|
|
|
_ = verticalInput.data.addListener(@This(), "verticalMovement", self);
|
|
verticalInput.activate();
|
|
}
|
|
|
|
{
|
|
const mouseLook = try core.Axis2dBinding.create(core.MakeName("mouseLook"));
|
|
mouseLook.enableMouseRelative();
|
|
_ = mouseLook.data.addListener(@This(), "onMouseLook", self);
|
|
mouseLook.activate();
|
|
}
|
|
|
|
{
|
|
const shaderReload = try core.ActionBinding.create(core.MakeName("shaderReload"));
|
|
shaderReload.addKey(.r, .keyDown);
|
|
_ = shaderReload.data.addListener(@This(), "onShaderReload", self);
|
|
shaderReload.activate();
|
|
}
|
|
|
|
{
|
|
const input = try core.ActionBinding.create(core.MakeName("toggleDoom"));
|
|
input.addKey(.f2, .keyDown);
|
|
_ = input.data.addListener(@This(), "toggleDoom", self);
|
|
input.activate();
|
|
}
|
|
|
|
{
|
|
const input = try core.ActionBinding.create(core.MakeName("toggleMouseLook"));
|
|
input.addKey(.t, .keyDown);
|
|
_ = input.data.addListener(@This(), "toggleMouseLook", self);
|
|
input.activate();
|
|
}
|
|
|
|
self.updateMouseLook();
|
|
}
|
|
|
|
pub fn endPlay(p: ?*anyopaque) void {
|
|
const self = core.cast(*@This(), p.?);
|
|
_ = self;
|
|
}
|
|
|
|
pub fn onMouseLook(ctx: ?*anyopaque, axis: core.Vector2f) void {
|
|
const self: *@This() = @ptrCast(@alignCast(ctx));
|
|
|
|
if (self.inputEnabled) {
|
|
self.fpcamera.addMouseMovement(axis);
|
|
}
|
|
}
|
|
|
|
pub fn toggleDoom(ctx: ?*anyopaque, action: core.ActionEvent) void {
|
|
const self: *@This() = @ptrCast(@alignCast(ctx));
|
|
_ = action;
|
|
|
|
self.inputEnabled = !self.inputEnabled;
|
|
|
|
if (DoomPlayer.gDoom) |c| {
|
|
c.inputEnabled = !self.inputEnabled;
|
|
}
|
|
}
|
|
|
|
pub fn toggleMouseLook(ctx: ?*anyopaque, action: core.ActionEvent) void {
|
|
const self: *@This() = @ptrCast(@alignCast(ctx));
|
|
_ = action;
|
|
|
|
self.mouseLook = !self.mouseLook;
|
|
if (!self.mouseLook)
|
|
self.showWindow = true;
|
|
|
|
self.updateMouseLook();
|
|
}
|
|
|
|
pub fn updateMouseLook(self: *@This()) void {
|
|
self.fpcamera.mouseLookEnabled = self.mouseLook;
|
|
platform.setMouseRelativeMode(self.mouseLook);
|
|
// platform.setImguiVisible(!self.mouseLook);
|
|
}
|
|
|
|
pub fn onShaderReload(ctx: ?*anyopaque, action: core.ActionEvent) void {
|
|
_ = ctx;
|
|
_ = action;
|
|
|
|
core.engine_log("reloading shaders, this is gonna cause some leaks but thats ok", .{});
|
|
rend.renderer.reloadShaders() catch {
|
|
core.engine_log("unable to reload shaders", .{});
|
|
};
|
|
}
|
|
|
|
pub fn slowDown(ctx: ?*anyopaque, action: core.ActionEvent) void {
|
|
const self: *@This() = @ptrCast(@alignCast(ctx));
|
|
|
|
if (action == .keyUp) {
|
|
self.cameraSpeed = 10.0;
|
|
}
|
|
if (action == .keyDown) {
|
|
self.cameraSpeed = 4.0;
|
|
}
|
|
}
|
|
|
|
pub fn distanceMove(ctx: ?*anyopaque, axis: f32) void {
|
|
const self: *@This() = @ptrCast(@alignCast(ctx));
|
|
self.centerDistMove = axis;
|
|
}
|
|
|
|
pub fn verticalMovement(ctx: ?*anyopaque, axis: f32) void {
|
|
const self: *@This() = @ptrCast(@alignCast(ctx));
|
|
self.verticalMove = axis;
|
|
}
|
|
|
|
pub fn onMove(ctx: ?*anyopaque, axis: core.Vector2f) void {
|
|
const self: *@This() = @ptrCast(@alignCast(ctx));
|
|
self.moveVector = .{ .x = axis.x, .z = axis.y, .y = 0.0 };
|
|
}
|
|
|
|
pub fn onExit(ctx: ?*anyopaque, action: core.ActionEvent) void {
|
|
_ = ctx;
|
|
_ = action;
|
|
|
|
core.exitNow();
|
|
}
|
|
|
|
pub fn getMouseMovement(self: *@This()) core.Vector2f {
|
|
const rv = self.mouseMove;
|
|
self.mouseMove = .{};
|
|
|
|
return rv;
|
|
}
|
|
|
|
pub fn tick(self: *@This(), dt: f64) void {
|
|
const fdt: f32 = @floatCast(dt);
|
|
|
|
const z4 = tracy.ZoneN(@src(), "fpCamera");
|
|
self.fpcamera.tick(dt);
|
|
z4.End();
|
|
|
|
const z5 = tracy.ZoneN(@src(), "doomplayer");
|
|
DoomPlayer.maybeTick(dt);
|
|
z5.End();
|
|
|
|
var movement = self.fpcamera.getForwardXZ().fmul(self.moveVector.z * fdt * self.cameraSpeed);
|
|
movement = movement.add(self.fpcamera.getRightXZ().fmul(self.moveVector.x * fdt * self.cameraSpeed));
|
|
movement = movement.add(.{ .y = self.verticalMove * fdt * self.cameraSpeed });
|
|
self.centerDist += self.centerDistMove * fdt;
|
|
|
|
const pos = self.fpcamera.getPosition().add(movement);
|
|
|
|
if (self.inputEnabled) {
|
|
self.fpcamera.setPosition(pos);
|
|
}
|
|
|
|
self.fpcamera.resolve();
|
|
}
|
|
|
|
pub fn deinit(self: *@This()) void {
|
|
self.modules.deinit(self.allocator);
|
|
// self.rendererDebugger.destroy();
|
|
DoomPlayer.DoomCanvas.cleanupDoom();
|
|
self.fpcamera.destroy();
|
|
self.engineTool.destroy();
|
|
|
|
// self.videoplayer.destroy();
|
|
self.allocator.destroy(self);
|
|
}
|
|
|
|
pub fn main() anyerror!void {
|
|
var spec = try backlog.getSpec("sampleGame");
|
|
// try spec.put("useGPA", .{ .boolean = false });
|
|
_ = backlog.startEngine(&NeonObjectTable, &spec);
|
|
|
|
// try backlog.initializeAndRunStandardProgram(@This(), .{
|
|
// .name = "sampleGame",
|
|
// .enabledModules = .{
|
|
// .imgui = true,
|
|
// .physics = true,
|
|
// .audio = true,
|
|
// },
|
|
//});
|
|
}
|
|
|
|
const DoomPlayer = @import("doomplayer");
|
|
//const VideoPlayer = @import("videoplayer");
|
|
const extras = @import("gameExtras");
|
|
const bsp = @import("bsp");
|
|
|
|
const FpCamera = extras.FpCamera;
|
|
const std = @import("std");
|
|
const backlog = @import("backlog");
|
|
const assets = backlog.assets;
|
|
const platform = backlog.platform;
|
|
const core = backlog.core;
|
|
const ig = backlog.imgui.api;
|
|
const audio = backlog.audio;
|
|
const rend = backlog.rend;
|
|
const script = core.script;
|
|
const tracy = core.tracy;
|
|
const ui = backlog.ui;
|