added support for config files and added default config file for sample game
This commit is contained in:
parent
126b4f978d
commit
19e4bf629a
|
|
@ -134,14 +134,6 @@ pub fn initializeAndRunStandardProgram(comptime GameContext: type, comptime spec
|
||||||
core.engine_logs("Using vulkan validation");
|
core.engine_logs("Using vulkan validation");
|
||||||
}
|
}
|
||||||
|
|
||||||
// graphics.setStartupSettings("vulkanValidation", args.vulkanValidation);
|
|
||||||
|
|
||||||
if (@hasField(@TypeOf(spec), "windowName")) {
|
|
||||||
platform.setWindowSettings(.{ .windowName = spec.windowName });
|
|
||||||
} else {
|
|
||||||
platform.setWindowSettings(.{ .windowName = spec.name });
|
|
||||||
}
|
|
||||||
|
|
||||||
try start_everything(spec, allocator, args);
|
try start_everything(spec, allocator, args);
|
||||||
defer shutdown_everything(allocator);
|
defer shutdown_everything(allocator);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
|
||||||
|
# comments look like this and are ignored
|
||||||
|
|
||||||
|
[platform]
|
||||||
|
windowName = "lmao 2 nova"
|
||||||
|
extent.width = 1920
|
||||||
|
extent.height = 1080
|
||||||
|
|
@ -0,0 +1,334 @@
|
||||||
|
var gConfigsObject: *ConfigRegistry = undefined;
|
||||||
|
|
||||||
|
pub const ConfigRegistry = struct {
|
||||||
|
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This());
|
||||||
|
|
||||||
|
allocator: std.mem.Allocator,
|
||||||
|
configMap: ?ConfigMap = null,
|
||||||
|
|
||||||
|
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||||
|
const self = try allocator.create(@This());
|
||||||
|
|
||||||
|
self.* = .{
|
||||||
|
.allocator = allocator,
|
||||||
|
};
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
// by convention this should be in the root
|
||||||
|
// content path
|
||||||
|
//
|
||||||
|
// with the name <programName>.toml
|
||||||
|
pub fn loadConfigFile(self: *@This(), configName: []const u8) !void {
|
||||||
|
const configFile = core.fs().loadFile(configName) catch {
|
||||||
|
core.engine_log("unable to load configuration file {s}", .{configName});
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
defer core.fs().unmap(configFile);
|
||||||
|
|
||||||
|
const parser = try Parser.create(self.allocator);
|
||||||
|
parser.fileName = configName;
|
||||||
|
defer parser.destroy();
|
||||||
|
|
||||||
|
self.configMap = try parser.parseBytes(self.allocator, configFile.bytesNoEnd());
|
||||||
|
|
||||||
|
core.engine_log("config file loaded {d} keys set", .{self.configMap.?.mapValues.count()});
|
||||||
|
|
||||||
|
// parse and tokenize the config file
|
||||||
|
// self.tokenizeConfigFile();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn destroy(self: *@This()) void {
|
||||||
|
if (self.configMap) |*map| {
|
||||||
|
map.deinit();
|
||||||
|
}
|
||||||
|
self.allocator.destroy(self);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn configVar(comptime T: type, configName: []const u8, default: T) T {
|
||||||
|
return getConfigVar(T, configName) orelse default;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getConfigVar(comptime T: type, configName: []const u8) ?T {
|
||||||
|
const ctx = gConfigsObject;
|
||||||
|
|
||||||
|
if (ctx.configMap) |map| {
|
||||||
|
if (map.mapValues.get(configName)) |v| {
|
||||||
|
switch (v.value) {
|
||||||
|
.number => |number| {
|
||||||
|
switch (@typeInfo(T)) {
|
||||||
|
.int => {
|
||||||
|
return @intFromFloat(number);
|
||||||
|
},
|
||||||
|
.float => {
|
||||||
|
return @floatCast(number);
|
||||||
|
},
|
||||||
|
else => {
|
||||||
|
core.engine_err("tried to get config {s} but it isn't a number", .{configName});
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.string => |string| {
|
||||||
|
switch (@typeInfo(T)) {
|
||||||
|
.pointer => |pointerInfo| {
|
||||||
|
if (pointerInfo.child == u8) {
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
else => {
|
||||||
|
core.engine_err("tried to get config {s} but it isn't a string", .{configName});
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const lastSetBy_referenceInit: []const u8 = "reference";
|
||||||
|
const lastSetBy_configFile: []const u8 = "config file";
|
||||||
|
|
||||||
|
pub const ConfigValueEntry = struct {
|
||||||
|
lastSetBy: []const u8 = lastSetBy_referenceInit,
|
||||||
|
value: union(enum(u8)) {
|
||||||
|
number: f64,
|
||||||
|
string: []const u8,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const ConfigMap = struct {
|
||||||
|
backingAllocator: std.mem.Allocator,
|
||||||
|
mapValues: std.StringHashMapUnmanaged(ConfigValueEntry) = .{},
|
||||||
|
arena: std.heap.ArenaAllocator,
|
||||||
|
//stringList: std.ArrayListUnmanaged([]const u8) = .{},
|
||||||
|
|
||||||
|
pub fn init(allocator: std.mem.Allocator) !@This() {
|
||||||
|
return .{
|
||||||
|
.backingAllocator = allocator,
|
||||||
|
.arena = std.heap.ArenaAllocator.init(allocator),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pushMapValue(self: *@This(), key: []const u8, value: []const u8) !void {
|
||||||
|
// take ownership of both strings
|
||||||
|
const allocator = self.arena.allocator();
|
||||||
|
|
||||||
|
const k = try allocator.dupe(u8, key);
|
||||||
|
|
||||||
|
var mapValue: ConfigValueEntry = .{ .value = undefined };
|
||||||
|
mapValue.lastSetBy = lastSetBy_configFile;
|
||||||
|
|
||||||
|
if (value[0] == '"') {
|
||||||
|
if (value[value.len - 1] != '"') {
|
||||||
|
return error.MissingClosingQuote;
|
||||||
|
}
|
||||||
|
|
||||||
|
mapValue.value = .{
|
||||||
|
.string = try allocator.dupe(u8, value[1 .. value.len - 1]),
|
||||||
|
};
|
||||||
|
} else if (std.fmt.parseFloat(f64, value) catch null) |flt| {
|
||||||
|
mapValue.value = .{ .number = flt };
|
||||||
|
} else {
|
||||||
|
return error.UnableToParse;
|
||||||
|
}
|
||||||
|
|
||||||
|
try self.mapValues.put(allocator, k, mapValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deinit(self: *@This()) void {
|
||||||
|
self.arena.deinit();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// A Very nonstandard and very dumb ini parser
|
||||||
|
pub const Parser = struct {
|
||||||
|
backingAllocator: std.mem.Allocator,
|
||||||
|
arena: std.heap.ArenaAllocator,
|
||||||
|
allocator: std.mem.Allocator = undefined,
|
||||||
|
|
||||||
|
fileName: []const u8 = "unknown file",
|
||||||
|
lineNumber: usize = 0,
|
||||||
|
lineEnd: usize = 0,
|
||||||
|
lineStart: usize = 0,
|
||||||
|
bytes: []const u8 = undefined,
|
||||||
|
outputMap: ?ConfigMap = null,
|
||||||
|
|
||||||
|
configSection: ?[]const u8 = null,
|
||||||
|
|
||||||
|
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||||
|
const self = try allocator.create(@This());
|
||||||
|
|
||||||
|
self.* = .{
|
||||||
|
.backingAllocator = allocator,
|
||||||
|
.arena = std.heap.ArenaAllocator.init(allocator),
|
||||||
|
};
|
||||||
|
self.allocator = self.arena.allocator();
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn nextLine(self: *@This()) ?[]const u8 {
|
||||||
|
while (std.ascii.isWhitespace(self.bytes[self.lineEnd])) : (self.lineEnd += 1) {
|
||||||
|
if (self.lineEnd + 1 >= self.bytes.len) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.lineStart = self.lineEnd;
|
||||||
|
|
||||||
|
while (self.bytes[self.lineEnd] != '\r' and self.bytes[self.lineEnd] != '\n') : (self.lineEnd += 1) {
|
||||||
|
if (self.lineEnd + 1 >= self.bytes.len) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.lineNumber += 1;
|
||||||
|
|
||||||
|
return self.bytes[self.lineStart..self.lineEnd];
|
||||||
|
}
|
||||||
|
|
||||||
|
fn stripWhiteSpace(l: []const u8) []const u8 {
|
||||||
|
if (l.len == 0) {
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
var s: usize = 0;
|
||||||
|
var e: usize = l.len;
|
||||||
|
|
||||||
|
while (std.ascii.isWhitespace(l[s]) and s < l.len) : (s += 1) {}
|
||||||
|
|
||||||
|
while (std.ascii.isWhitespace(l[e - 1]) and e - 1 > 0) : (e -= 1) {}
|
||||||
|
|
||||||
|
return l[s..e];
|
||||||
|
}
|
||||||
|
|
||||||
|
fn printError(self: *@This(), comptime fmt: []const u8, args: anytype) !void {
|
||||||
|
if (core.getLogger()) |logger| {
|
||||||
|
try logger.print(fmt, args);
|
||||||
|
try logger.print("[Config ]: Config File Parse Error> {s}:{d} \n", .{ self.fileName, self.lineNumber });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parseLabel(self: *@This(), l: []const u8) !?[]const u8 {
|
||||||
|
if (l[l.len - 1] != ']') {
|
||||||
|
core.engine_err("\n expected closing brace ] in label..\n fatal error\n{d}: {s} \n{s}:{d}", .{ self.lineNumber, l, self.fileName, self.lineNumber });
|
||||||
|
try self.printError("expected closing brace ] in label statement. fatal.", .{});
|
||||||
|
return error.UnableToParse;
|
||||||
|
}
|
||||||
|
|
||||||
|
var line = l[1 .. l.len - 1];
|
||||||
|
line = stripWhiteSpace(line);
|
||||||
|
// core.engine_log("label : '{s}'", .{line});
|
||||||
|
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parseStatement(self: *@This(), line: []const u8) !?struct { left: []const u8, right: []const u8 } {
|
||||||
|
var s: usize = 0;
|
||||||
|
|
||||||
|
while (s < line.len and line[s] != '=') : (s += 1) {}
|
||||||
|
|
||||||
|
if (s == line.len) {
|
||||||
|
try self.printError("missing right hand side of assignment after '=' {s} skipping..", .{line});
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const left = stripWhiteSpace(line[0..s]);
|
||||||
|
const right = stripWhiteSpace(line[s + 1 .. line.len]);
|
||||||
|
|
||||||
|
// core.engine_log("statement : left '{s}' '{s}'", .{ left, right });
|
||||||
|
|
||||||
|
return .{ .left = left, .right = right };
|
||||||
|
}
|
||||||
|
|
||||||
|
// line should already be whitespace stripped
|
||||||
|
pub fn parseLine(self: *@This(), l: []const u8) !void {
|
||||||
|
var i: usize = 0;
|
||||||
|
var line = l;
|
||||||
|
|
||||||
|
// strip comments
|
||||||
|
while (i < line.len) : (i += 1) {
|
||||||
|
if (line[i] == '#') {
|
||||||
|
line = line[0..i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
while (i < line.len) : (i += 1) {
|
||||||
|
if (line[i] == '[') {
|
||||||
|
const section = try self.parseLabel(line[i..line.len]);
|
||||||
|
if (section) |sect| {
|
||||||
|
self.configSection = sect;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (line[i] == '=') {
|
||||||
|
if (try self.parseStatement(line)) |statement| {
|
||||||
|
var fullVarName = statement.left;
|
||||||
|
defer self.allocator.free(fullVarName);
|
||||||
|
if (self.configSection) |section| {
|
||||||
|
// use temporary allocator
|
||||||
|
fullVarName = try std.fmt.allocPrint(self.allocator, "{s}.{s}", .{ section, fullVarName });
|
||||||
|
}
|
||||||
|
|
||||||
|
// takes ownership of both strings;
|
||||||
|
try self.outputMap.?.pushMapValue(fullVarName, statement.right);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parseBytes(self: *@This(), allocator: std.mem.Allocator, bytes: []const u8) !ConfigMap {
|
||||||
|
self.outputMap = try ConfigMap.init(allocator);
|
||||||
|
|
||||||
|
self.bytes = bytes;
|
||||||
|
if (self.bytes.len == 0) {
|
||||||
|
return self.outputMap.?;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.lineStart = 0;
|
||||||
|
self.lineEnd = 0;
|
||||||
|
|
||||||
|
while (self.nextLine()) |line| {
|
||||||
|
// core.engine_log("ConfigParser > {s}", .{line});
|
||||||
|
self.parseLine(line) catch break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.outputMap.?;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn destroy(self: *@This()) void {
|
||||||
|
self.arena.deinit();
|
||||||
|
self.backingAllocator.destroy(self);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn setupConfigs(configFilePath: []const u8) !void {
|
||||||
|
gConfigsObject = try core.createObject(ConfigRegistry, .{});
|
||||||
|
try gConfigsObject.loadConfigFile(configFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ConfigEntry(comptime T: type) type {
|
||||||
|
return struct {
|
||||||
|
value: ?T = null,
|
||||||
|
default: T,
|
||||||
|
configName: []const u8,
|
||||||
|
|
||||||
|
pub fn make(name: []const u8, default: T) void {
|
||||||
|
return .{ .default = default, .name = name };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const core = @import("core.zig");
|
||||||
|
const std = @import("std");
|
||||||
|
|
@ -122,9 +122,17 @@ pub fn start_module(comptime programSpec: anytype, args: anytype, allocator: std
|
||||||
try script.start_lua(allocator);
|
try script.start_lua(allocator);
|
||||||
// LUA END
|
// LUA END
|
||||||
gPackerFS = try PackerFS.init(allocator, .{});
|
gPackerFS = try PackerFS.init(allocator, .{});
|
||||||
|
|
||||||
|
// load configs.
|
||||||
|
const name = if (@hasField(@TypeOf(programSpec), "configName")) programSpec.configName else programSpec.name;
|
||||||
|
|
||||||
|
logging.engine_logs("loading configs with name" ++ name);
|
||||||
|
|
||||||
gEngine = try allocator.create(Engine);
|
gEngine = try allocator.create(Engine);
|
||||||
gEngine.* = try Engine.init(allocator);
|
gEngine.* = try Engine.init(allocator);
|
||||||
|
|
||||||
|
try configVars.setupConfigs(name ++ "Engine.ini");
|
||||||
|
|
||||||
if (@hasField(@TypeOf(args), "unitTest") and args.unitTest) {} else {
|
if (@hasField(@TypeOf(args), "unitTest") and args.unitTest) {} else {
|
||||||
try logging.setupLogging(gEngine);
|
try logging.setupLogging(gEngine);
|
||||||
}
|
}
|
||||||
|
|
@ -227,3 +235,8 @@ pub fn getEngineUptime() f64 {
|
||||||
pub const modules = @import("modules.zig");
|
pub const modules = @import("modules.zig");
|
||||||
pub const isModuleEnabled = modules.isModuleEnabled;
|
pub const isModuleEnabled = modules.isModuleEnabled;
|
||||||
pub const ModuleDescription = modules.ModuleDescription;
|
pub const ModuleDescription = modules.ModuleDescription;
|
||||||
|
|
||||||
|
pub const configVars = @import("configVars.zig");
|
||||||
|
|
||||||
|
pub const getConfigVar = configVars.getConfigVar;
|
||||||
|
pub const configVar = configVars.configVar;
|
||||||
|
|
|
||||||
|
|
@ -15,11 +15,34 @@ test "simple systems setup for core" {
|
||||||
|
|
||||||
std.debug.print("Starting up \n", .{});
|
std.debug.print("Starting up \n", .{});
|
||||||
engine_logs("systems starting");
|
engine_logs("systems starting");
|
||||||
try core.start_module(.{}, .{ .unitTest = true }, allocator);
|
try core.start_module(.{ .name = "test" }, .{ .unitTest = true }, allocator);
|
||||||
defer core.shutdown_module(allocator);
|
defer core.shutdown_module(allocator);
|
||||||
|
|
||||||
engine_logs("systems started, shutting down");
|
engine_logs("systems started, shutting down");
|
||||||
memory.MTPrintStatsDelta();
|
memory.MTPrintStatsDelta();
|
||||||
|
try test_loadingConfigs();
|
||||||
|
|
||||||
try memory.dumpTimeline("test-core-timeline.txt");
|
try memory.dumpTimeline("test-core-timeline.txt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn test_loadingConfigs() !void {
|
||||||
|
if (core.getConfigVar(u32, "platform.extent.width")) |width| {
|
||||||
|
core.engine_log("config: {d}", .{width});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (core.getConfigVar(u64, "platform.extent.height")) |height| {
|
||||||
|
core.engine_log("config: {d}", .{height});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (core.getConfigVar(f32, "platform.extent.height")) |height| {
|
||||||
|
core.engine_log("config f32: {d}", .{height});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (core.getConfigVar(f64, "platform.extent.height")) |height| {
|
||||||
|
core.engine_log("config f64: {d}", .{height});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (core.getConfigVar([]const u8, "platform.windowName")) |height| {
|
||||||
|
core.engine_log("config string: {s}", .{height});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,44 +31,43 @@ pub const Impl = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn processSDLEvents(event: *sdl3.Event) void {
|
pub fn processSDLEvents(event: *sdl3.Event) void {
|
||||||
c.Imgui_SDL3_ProcessEvent(@ptrCast(event));
|
if (platform.getInstance().enableImguiEvents) {
|
||||||
|
c.Imgui_SDL3_ProcessEvent(@ptrCast(event));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn onPreDraw(p: *anyopaque, cmd: *gpu.GPUCommandBuffer) void {
|
pub fn onPreDraw(p: *anyopaque, cmd: *gpu.GPUCommandBuffer) void {
|
||||||
const self: *@This() = @ptrCast(@alignCast(p));
|
const self: *@This() = @ptrCast(@alignCast(p));
|
||||||
ig.render();
|
ig.render();
|
||||||
self.drawData = ig.getDrawData();
|
|
||||||
|
|
||||||
c.Imgui_SDL3_PrepareRender(@ptrCast(self.drawData), @ptrCast(cmd));
|
if (platform.getInstance().imguiVisible) {
|
||||||
|
self.drawData = ig.getDrawData();
|
||||||
|
|
||||||
|
c.Imgui_SDL3_PrepareRender(@ptrCast(self.drawData), @ptrCast(cmd));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn postRender(p: *anyopaque, cmd: *gpu.GPUCommandBuffer) void {
|
pub fn postRender(p: *anyopaque, cmd: *gpu.GPUCommandBuffer) void {
|
||||||
const self: *@This() = @ptrCast(@alignCast(p));
|
const self: *@This() = @ptrCast(@alignCast(p));
|
||||||
|
if (platform.getInstance().imguiVisible) {
|
||||||
|
|
||||||
//const renderpass = cmd.beginGPURenderPass(color_target_infos: [*c]const GPUColorTargetInfo, num_color_targets: u32, depth_stencil_target_info: [*c]const GPUDepthStencilTargetInfo);
|
//const renderpass = cmd.beginGPURenderPass(color_target_infos: [*c]const GPUColorTargetInfo, num_color_targets: u32, depth_stencil_target_info: [*c]const GPUDepthStencilTargetInfo);
|
||||||
|
|
||||||
var targetInfo: gpu.GPUColorTargetInfo = std.mem.zeroes(gpu.GPUColorTargetInfo);
|
var targetInfo: gpu.GPUColorTargetInfo = std.mem.zeroes(gpu.GPUColorTargetInfo);
|
||||||
targetInfo.texture = rend.context().swapchainTexture.?;
|
targetInfo.texture = rend.context().swapchainTexture.?;
|
||||||
targetInfo.clear_color = .{ .r = 0.0, .g = 0.0, .b = 0.0, .a = 0.0 };
|
targetInfo.clear_color = .{ .r = 0.0, .g = 0.0, .b = 0.0, .a = 0.0 };
|
||||||
targetInfo.load_op = .loadopLoad;
|
targetInfo.load_op = .loadopLoad;
|
||||||
targetInfo.store_op = .storeopStore;
|
targetInfo.store_op = .storeopStore;
|
||||||
const renderpass = cmd.beginGPURenderPass(&targetInfo, 1, null);
|
const renderpass = cmd.beginGPURenderPass(&targetInfo, 1, null);
|
||||||
// SDL_GPUColorTargetInfo target_info = {};
|
|
||||||
// target_info.texture = swapchain_texture;
|
|
||||||
// target_info.clear_color = SDL_FColor { clear_color.x, clear_color.y, clear_color.z, clear_color.w };
|
|
||||||
// target_info.load_op = SDL_GPU_LOADOP_CLEAR;
|
|
||||||
// target_info.store_op = SDL_GPU_STOREOP_STORE;
|
|
||||||
// target_info.mip_level = 0;
|
|
||||||
// target_info.layer_or_depth_plane = 0;
|
|
||||||
// target_info.cycle = false;
|
|
||||||
|
|
||||||
c.ImGui_SDLGPU3_RenderDrawData(
|
c.ImGui_SDLGPU3_RenderDrawData(
|
||||||
@ptrCast(self.drawData),
|
@ptrCast(self.drawData),
|
||||||
@ptrCast(cmd),
|
@ptrCast(cmd),
|
||||||
@ptrCast(renderpass),
|
@ptrCast(renderpass),
|
||||||
);
|
);
|
||||||
|
|
||||||
renderpass.endGPURenderPass();
|
renderpass.endGPURenderPass();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn preTick(_: *@This(), _: f64) core.EngineDataEventError!void {
|
pub fn preTick(_: *@This(), _: f64) core.EngineDataEventError!void {
|
||||||
|
|
|
||||||
|
|
@ -13,16 +13,11 @@ pub const Module: core.ModuleDescription = .{
|
||||||
};
|
};
|
||||||
|
|
||||||
var gPlatformInstance: *windowing.PlatformInstance = undefined;
|
var gPlatformInstance: *windowing.PlatformInstance = undefined;
|
||||||
var gStartupParams: windowing.PlatformParams = .{};
|
|
||||||
|
|
||||||
pub fn context() *windowing.PlatformInstance {
|
pub fn context() *windowing.PlatformInstance {
|
||||||
return gPlatformInstance;
|
return gPlatformInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setWindowSettings(params: windowing.PlatformParams) void {
|
|
||||||
gStartupParams = params;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn getCursorPosition() core.Vector2f {
|
pub fn getCursorPosition() core.Vector2f {
|
||||||
return gPlatformInstance.getCursorPosition();
|
return gPlatformInstance.getCursorPosition();
|
||||||
}
|
}
|
||||||
|
|
@ -39,6 +34,10 @@ pub fn setMouseRelativeMode(relativeMode: bool) void {
|
||||||
gPlatformInstance.setMouseRelativeMode(relativeMode);
|
gPlatformInstance.setMouseRelativeMode(relativeMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn setImguiVisible(visible: bool) void {
|
||||||
|
gPlatformInstance.imguiVisible = visible;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn start_module(comptime programSpec: anytype, args: anytype, allocator: std.mem.Allocator) !void {
|
pub fn start_module(comptime programSpec: anytype, args: anytype, allocator: std.mem.Allocator) !void {
|
||||||
_ = args;
|
_ = args;
|
||||||
_ = programSpec;
|
_ = programSpec;
|
||||||
|
|
@ -46,8 +45,10 @@ pub fn start_module(comptime programSpec: anytype, args: anytype, allocator: std
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const parameters = windowing.PlatformParams.init();
|
||||||
|
|
||||||
gPlatformInstance = try allocator.create(windowing.PlatformInstance);
|
gPlatformInstance = try allocator.create(windowing.PlatformInstance);
|
||||||
gPlatformInstance.* = try windowing.PlatformInstance.init(allocator, gStartupParams);
|
gPlatformInstance.* = try windowing.PlatformInstance.init(allocator, parameters);
|
||||||
|
|
||||||
try gPlatformInstance.setupWindow();
|
try gPlatformInstance.setupWindow();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,12 +44,25 @@ pub const RawInputObjectRef = struct {
|
||||||
};
|
};
|
||||||
|
|
||||||
// We are having some serious issues with this events pump.
|
// We are having some serious issues with this events pump.
|
||||||
|
|
||||||
pub const PlatformParams = struct {
|
pub const PlatformParams = struct {
|
||||||
extent: core.Vector2c = .{ .x = 1600, .y = 900 },
|
extent: core.Vector2c = .{ .x = 1600, .y = 900 },
|
||||||
windowName: []const u8 = "sample window",
|
windowName: []const u8,
|
||||||
icon: []const u8 = "textures/icon.png",
|
icon: []const u8 = "textures/icon.png",
|
||||||
hasVideo: bool = true,
|
hasVideo: bool = true,
|
||||||
|
|
||||||
|
pub fn init() @This() {
|
||||||
|
const rv = @This(){
|
||||||
|
.extent = .{
|
||||||
|
.x = core.configVar(c_int, "platform.window.width", 1600),
|
||||||
|
.y = core.configVar(c_int, "platform.window.height", 900),
|
||||||
|
},
|
||||||
|
.windowName = core.configVar([]const u8, "platform.window.name", "Backlog Engine"),
|
||||||
|
.icon = core.configVar([]const u8, "platform.window.icon", "textures/icon.png"),
|
||||||
|
};
|
||||||
|
|
||||||
|
core.engine_log("platform settings {any}", .{rv});
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub var gPlatformSettings: struct {
|
pub var gPlatformSettings: struct {
|
||||||
|
|
@ -74,6 +87,9 @@ pub const PlatformInstance = struct {
|
||||||
windowName: [:0]u8,
|
windowName: [:0]u8,
|
||||||
iconPath: [:0]u8,
|
iconPath: [:0]u8,
|
||||||
|
|
||||||
|
enableImguiEvents: bool = true,
|
||||||
|
imguiVisible: bool = true,
|
||||||
|
|
||||||
windowDestroyed: bool = false,
|
windowDestroyed: bool = false,
|
||||||
|
|
||||||
processFuncs: std.ArrayListUnmanaged(*const fn (*sdl3.Event) void) = .{},
|
processFuncs: std.ArrayListUnmanaged(*const fn (*sdl3.Event) void) = .{},
|
||||||
|
|
@ -116,6 +132,8 @@ pub const PlatformInstance = struct {
|
||||||
// _ = sdl3.c.SDL_SetHint(sdl3.c.SDL_HINT_MOUSE_RELATIVE_MODE_CENTER, "1");
|
// _ = sdl3.c.SDL_SetHint(sdl3.c.SDL_HINT_MOUSE_RELATIVE_MODE_CENTER, "1");
|
||||||
_ = sdl3.c.SDL_SetWindowRelativeMouseMode(self.window, relativeMode);
|
_ = sdl3.c.SDL_SetWindowRelativeMouseMode(self.window, relativeMode);
|
||||||
_ = sdl3.c.SDL_SetWindowMouseRect(self.window, null);
|
_ = sdl3.c.SDL_SetWindowMouseRect(self.window, null);
|
||||||
|
|
||||||
|
self.enableImguiEvents = !relativeMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn addSDLProcessFunction(self: *@This(), processFunc: *const fn (*sdl3.Event) void) !void {
|
pub fn addSDLProcessFunction(self: *@This(), processFunc: *const fn (*sdl3.Event) void) !void {
|
||||||
|
|
|
||||||
|
|
@ -36,10 +36,12 @@ float3 BlinnPhong(float3 normal, float3 fragPos, float3 lightPos, float3 lightCo
|
||||||
{
|
{
|
||||||
attenuation = 1.0;
|
attenuation = 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(length(normal) < 0.1)
|
if(length(normal) < 0.1)
|
||||||
{
|
{
|
||||||
return fragPos * lightColor * (1 / (dist * dist)) * attenuation;
|
return fragPos * lightColor * attenuation;
|
||||||
}
|
}
|
||||||
|
|
||||||
// diffuse parameter
|
// diffuse parameter
|
||||||
float3 lightDir = normalize(lightPos - fragPos);
|
float3 lightDir = normalize(lightPos - fragPos);
|
||||||
float diff = max(dot(lightDir, normal), 0.0);
|
float diff = max(dot(lightDir, normal), 0.0);
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ pub const Renderer = struct {
|
||||||
testPipeline: *gpu.GPUGraphicsPipeline = undefined,
|
testPipeline: *gpu.GPUGraphicsPipeline = undefined,
|
||||||
meshPipe: *gpu.GPUGraphicsPipeline = undefined,
|
meshPipe: *gpu.GPUGraphicsPipeline = undefined,
|
||||||
|
|
||||||
scissor: gpu.Rect = .{ .x = 0, .y = 0, .w = 1600, .h = 900 },
|
scissor: gpu.Rect = undefined, // .{ .x = 0, .y = 0, .w = 1600, .h = 900 },
|
||||||
colorBuffer: *gpu.GPUBuffer = undefined,
|
colorBuffer: *gpu.GPUBuffer = undefined,
|
||||||
colorBufferTransfer: *gpu.GPUTransferBuffer = undefined,
|
colorBufferTransfer: *gpu.GPUTransferBuffer = undefined,
|
||||||
window: *sdl3.Window = undefined,
|
window: *sdl3.Window = undefined,
|
||||||
|
|
@ -75,6 +75,7 @@ pub const Renderer = struct {
|
||||||
}, true, null);
|
}, true, null);
|
||||||
|
|
||||||
self.window = platform.getInstance().window;
|
self.window = platform.getInstance().window;
|
||||||
|
self.scissor = .{ .x = 0, .y = 0, .w = platform.getInstance().windowExtent.x, .h = platform.getInstance().windowExtent.y };
|
||||||
|
|
||||||
if (!self.device.claimWindowForGPUDevice(self.window))
|
if (!self.device.claimWindowForGPUDevice(self.window))
|
||||||
return error.UnableToClaimGpu;
|
return error.UnableToClaimGpu;
|
||||||
|
|
@ -254,11 +255,6 @@ pub const Renderer = struct {
|
||||||
self.meshPipe = self.device.createGPUGraphicsPipeline(&pci);
|
self.meshPipe = self.device.createGPUGraphicsPipeline(&pci);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn preTick(self: *@This(), dt: f64) !void {
|
|
||||||
_ = self;
|
|
||||||
_ = dt;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn createBuffers(self: *@This()) !void {
|
pub fn createBuffers(self: *@This()) !void {
|
||||||
|
|
||||||
// ssbo buffer
|
// ssbo buffer
|
||||||
|
|
@ -389,6 +385,10 @@ pub const Renderer = struct {
|
||||||
|
|
||||||
// self.device.unmapGPUTransferBuffer(self.colorBufferTransfer);
|
// self.device.unmapGPUTransferBuffer(self.colorBufferTransfer);
|
||||||
|
|
||||||
|
if (self.activeCamera) |camera| {
|
||||||
|
camera.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
const copyPass = cmd.beginGPUCopyPass();
|
const copyPass = cmd.beginGPUCopyPass();
|
||||||
// copyPass.uploadToGPUBuffer(&.{ .transfer_buffer = self.colorBufferTransfer, .offset = 0 }, &.{
|
// copyPass.uploadToGPUBuffer(&.{ .transfer_buffer = self.colorBufferTransfer, .offset = 0 }, &.{
|
||||||
// .buffer = self.colorBuffer,
|
// .buffer = self.colorBuffer,
|
||||||
|
|
@ -415,10 +415,6 @@ pub const Renderer = struct {
|
||||||
pub fn tick(self: *@This(), dt: f64) void {
|
pub fn tick(self: *@This(), dt: f64) void {
|
||||||
self.totalTime += dt;
|
self.totalTime += dt;
|
||||||
|
|
||||||
if (self.activeCamera) |camera| {
|
|
||||||
camera.resolve();
|
|
||||||
}
|
|
||||||
|
|
||||||
const cmd = self.device.acquireGPUCommandBuffer();
|
const cmd = self.device.acquireGPUCommandBuffer();
|
||||||
self.frameUploads();
|
self.frameUploads();
|
||||||
try self.uploadUniforms(cmd);
|
try self.uploadUniforms(cmd);
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -31,13 +31,12 @@ fragment main0_out main0(main0_in in [[stage_in]], constant type_Uniforms& Unifo
|
||||||
{
|
{
|
||||||
discard_fragment();
|
discard_fragment();
|
||||||
}
|
}
|
||||||
float3 _118;
|
float3 _117;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
float3 _74 = Uniforms.lightPosition.xyz - in.in_var_TEXCOORD1;
|
float3 _74 = Uniforms.lightPosition.xyz - in.in_var_TEXCOORD1;
|
||||||
float _75 = length(_74);
|
float _75 = length(_74);
|
||||||
float _76 = _75 * _75;
|
float _76 = _75 * _75;
|
||||||
float _77 = 1.0 / _76;
|
|
||||||
float _82;
|
float _82;
|
||||||
if (_75 > 2.0)
|
if (_75 > 2.0)
|
||||||
{
|
{
|
||||||
|
|
@ -45,7 +44,7 @@ fragment main0_out main0(main0_in in [[stage_in]], constant type_Uniforms& Unifo
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_82 = _77;
|
_82 = 1.0 / _76;
|
||||||
}
|
}
|
||||||
float _87;
|
float _87;
|
||||||
if (_75 > 4.0)
|
if (_75 > 4.0)
|
||||||
|
|
@ -60,14 +59,14 @@ fragment main0_out main0(main0_in in [[stage_in]], constant type_Uniforms& Unifo
|
||||||
float _91 = (_89 > 1.0) ? 1.0 : _89;
|
float _91 = (_89 > 1.0) ? 1.0 : _89;
|
||||||
if (length(in.in_var_TEXCOORD2) < 0.100000001490116119384765625)
|
if (length(in.in_var_TEXCOORD2) < 0.100000001490116119384765625)
|
||||||
{
|
{
|
||||||
_118 = ((in.in_var_TEXCOORD1 * float3(0.800000011920928955078125, 0.800000011920928955078125, 0.5)) * _77) * _91;
|
_117 = (in.in_var_TEXCOORD1 * float3(0.800000011920928955078125, 0.800000011920928955078125, 0.5)) * _91;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
float3 _99 = fast::normalize(_74);
|
float3 _98 = fast::normalize(_74);
|
||||||
_118 = ((float3(0.800000011920928955078125, 0.800000011920928955078125, 0.5) * precise::max(dot(_99, in.in_var_TEXCOORD2), 0.0)) * _91) + (((float3(0.800000011920928955078125, 0.800000011920928955078125, 0.5) * powr(precise::max(dot(in.in_var_TEXCOORD2, fast::normalize(_99 + fast::normalize(in.in_var_TEXCOORD1 - Uniforms.viewPos.xyz))), 0.0), 30.0)) * 2.0) * _91);
|
_117 = ((float3(0.800000011920928955078125, 0.800000011920928955078125, 0.5) * precise::max(dot(_98, in.in_var_TEXCOORD2), 0.0)) * _91) + (((float3(0.800000011920928955078125, 0.800000011920928955078125, 0.5) * powr(precise::max(dot(in.in_var_TEXCOORD2, fast::normalize(_98 + fast::normalize(in.in_var_TEXCOORD1 - Uniforms.viewPos.xyz))), 0.0), 30.0)) * 2.0) * _91);
|
||||||
break;
|
break;
|
||||||
} while(false);
|
} while(false);
|
||||||
out.out_var_SV_Target0 = float4(powr(_59.xyz * ((mix(float3(0.00999999977648258209228515625, 0.00999999977648258209228515625, 0.0030000000260770320892333984375), float3(0.0040000001899898052215576171875, 0.0040000001899898052215576171875, 0.0599999986588954925537109375), float3(in.in_var_TEXCOORD2.y)) * 0.001000000047497451305389404296875) + _118), float3(0.4545454680919647216796875)), _60);
|
out.out_var_SV_Target0 = float4(powr(_59.xyz * ((mix(float3(0.00999999977648258209228515625, 0.00999999977648258209228515625, 0.0030000000260770320892333984375), float3(0.0040000001899898052215576171875, 0.0040000001899898052215576171875, 0.0599999986588954925537109375), float3(in.in_var_TEXCOORD2.y)) * 0.001000000047497451305389404296875) + _117), float3(0.4545454680919647216796875)), _60);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -0,0 +1,4 @@
|
||||||
|
[platform.window]
|
||||||
|
name="Sample Game"
|
||||||
|
width=1920
|
||||||
|
height=1080
|
||||||
|
|
@ -69,7 +69,6 @@ pub fn prepare(self: *@This()) !void {
|
||||||
try script.runScriptFile("scripts/prepare.lua");
|
try script.runScriptFile("scripts/prepare.lua");
|
||||||
|
|
||||||
try assets.loadList(assetReferences);
|
try assets.loadList(assetReferences);
|
||||||
platform.setMouseRelativeMode(true);
|
|
||||||
|
|
||||||
const exitInput = try core.ActionBinding.create(core.MakeName("exit"));
|
const exitInput = try core.ActionBinding.create(core.MakeName("exit"));
|
||||||
exitInput.addKey(.escape, .keyDown);
|
exitInput.addKey(.escape, .keyDown);
|
||||||
|
|
@ -130,15 +129,6 @@ pub fn prepare(self: *@This()) !void {
|
||||||
_ = self.moveInput.data.addListener(self, onMove);
|
_ = self.moveInput.data.addListener(self, onMove);
|
||||||
self.moveInput.activate();
|
self.moveInput.activate();
|
||||||
|
|
||||||
{
|
|
||||||
const i = try core.Axis1dBinding.create(core.MakeName("movementRotation"));
|
|
||||||
i.addKey(.z, 1.0);
|
|
||||||
i.addKey(.x, -1.0);
|
|
||||||
|
|
||||||
_ = i.data.addListener(self, cameraRotate);
|
|
||||||
i.activate();
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
const i = try core.Axis1dBinding.create(core.MakeName("rotPitch"));
|
const i = try core.Axis1dBinding.create(core.MakeName("rotPitch"));
|
||||||
i.addKey(.f, 1.0);
|
i.addKey(.f, 1.0);
|
||||||
|
|
@ -177,12 +167,14 @@ pub fn prepare(self: *@This()) !void {
|
||||||
_ = input.data.addListener(self, toggleMouseLook);
|
_ = input.data.addListener(self, toggleMouseLook);
|
||||||
input.activate();
|
input.activate();
|
||||||
}
|
}
|
||||||
|
self.updateMouseLook();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn onMouseLook(ctx: ?*anyopaque, axis: core.Vector2f) void {
|
fn onMouseLook(ctx: ?*anyopaque, axis: core.Vector2f) void {
|
||||||
const self: *@This() = @ptrCast(@alignCast(ctx));
|
const self: *@This() = @ptrCast(@alignCast(ctx));
|
||||||
|
|
||||||
self.mouseMove = axis;
|
if (self.mouseLook)
|
||||||
|
self.mouseMove = axis;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn toggleMouseLook(ctx: ?*anyopaque, action: core.ActionEvent) void {
|
fn toggleMouseLook(ctx: ?*anyopaque, action: core.ActionEvent) void {
|
||||||
|
|
@ -190,12 +182,13 @@ fn toggleMouseLook(ctx: ?*anyopaque, action: core.ActionEvent) void {
|
||||||
_ = action;
|
_ = action;
|
||||||
|
|
||||||
self.mouseLook = !self.mouseLook;
|
self.mouseLook = !self.mouseLook;
|
||||||
|
|
||||||
self.updateMouseLook();
|
self.updateMouseLook();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn updateMouseLook(self: *@This()) void {
|
fn updateMouseLook(self: *@This()) void {
|
||||||
core.engine_log("{s}", .{if (self.mouseLook) "true" else "false"});
|
platform.setMouseRelativeMode(self.mouseLook);
|
||||||
platform.setCursorVisible(self.mouseLook);
|
platform.setImguiVisible(!self.mouseLook);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn onShaderReload(ctx: ?*anyopaque, action: core.ActionEvent) void {
|
fn onShaderReload(ctx: ?*anyopaque, action: core.ActionEvent) void {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue