samplegame is now compiling on windows in both debug and static build modes on 0.15
This commit is contained in:
parent
7a6308454a
commit
02dff11242
|
|
@ -245,7 +245,7 @@ const DynamicDepList: []const struct { dep: []const u8, artifact: []const u8 } =
|
|||
.{ .dep = "sdl3", .artifact = "SDL3" },
|
||||
.{ .dep = "spng", .artifact = "spng_c" },
|
||||
.{ .dep = "lua", .artifact = "luac" },
|
||||
// .{ .dep = "miniaudio", .artifact = "miniaudio_c" },
|
||||
.{ .dep = "miniaudio", .artifact = "miniaudio_c" },
|
||||
.{ .dep = "zphysics", .artifact = "joltc" },
|
||||
// .{ .dep = "enet", .artifact = "enet_c" },
|
||||
.{ .dep = "ozz", .artifact = "ozz_cpp" },
|
||||
|
|
|
|||
|
|
@ -117,8 +117,8 @@ pub fn getExtension(path: []const u8) ?[]const u8 {
|
|||
pub fn generateCookFile(allocator: std.mem.Allocator, dir: std.fs.Dir, path: []const u8) !void {
|
||||
if (getExtension(path)) |extension| {
|
||||
if (gCookRegistry.typesByExt.get(extension)) |assetType| {
|
||||
var cookFilePath = std.ArrayList(u8).init(allocator);
|
||||
defer cookFilePath.deinit();
|
||||
var cookFilePath = std.ArrayList(u8){};
|
||||
defer cookFilePath.deinit(allocator);
|
||||
const generateFunction = gCookRegistry.generates.get(assetType).?;
|
||||
|
||||
var outPath: std.ArrayListUnmanaged(u8) = .{};
|
||||
|
|
@ -132,7 +132,10 @@ pub fn generateCookFile(allocator: std.mem.Allocator, dir: std.fs.Dir, path: []c
|
|||
const file = try dir.createFile(outPath.items, .{});
|
||||
defer file.close();
|
||||
|
||||
try file.writeAll(cookFilePath.items);
|
||||
var writeBuf: [4096]u8 = undefined;
|
||||
|
||||
var writer = file.writer(&writeBuf);
|
||||
try writer.interface.writeAll(cookFilePath.items);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ const Name = core.Name;
|
|||
const AutoHashMapUnmanaged = std.AutoHashMapUnmanaged;
|
||||
const tracy = core.tracy;
|
||||
|
||||
const ma = @import("miniaudio");
|
||||
const ma = @import("miniaudio").c;
|
||||
|
||||
pub fn sound_log(comptime fmt: []const u8, args: anytype) void {
|
||||
core.printInner(core.defaultHighlight, "[SOUND ]: " ++ fmt ++ "\n", args);
|
||||
|
|
|
|||
|
|
@ -105,6 +105,8 @@ pub const shell = p2.shell;
|
|||
|
||||
pub const algorithm = @import("p2");
|
||||
pub const math = @import("math.zig");
|
||||
|
||||
pub const Rayf = math.Rayf;
|
||||
pub const f32x4 = math.f32x4; // __m128_int
|
||||
pub const f32x8 = math.f32x8; // __m256_int
|
||||
pub const f32x16 = math.f32x16; // __m512_int
|
||||
|
|
@ -163,6 +165,11 @@ pub const graphics_log = logging.graphics_log;
|
|||
pub const engine_err = logging.engine_err;
|
||||
pub const engine_errs = logging.engine_errs;
|
||||
|
||||
pub const printInner = logging.printInner;
|
||||
|
||||
pub const errorHighlight = logging.errorHighlight;
|
||||
pub const defaultHighlight = logging.defaultHighlight;
|
||||
|
||||
pub const packer = @import("packer");
|
||||
|
||||
pub const FileSystem = packer.PackerFS;
|
||||
|
|
@ -398,6 +405,8 @@ pub fn exitNow() void {
|
|||
}
|
||||
|
||||
pub fn signalShutdown() void {
|
||||
// destroy all ecs entities first
|
||||
ecs.destroyAllEntities();
|
||||
gEngine.exit();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -115,6 +115,22 @@ pub fn createEntity() !Entity {
|
|||
return rv;
|
||||
}
|
||||
|
||||
pub fn destroyAllEntities() void {
|
||||
const registry = getRegistry();
|
||||
var elist = std.ArrayList(Entity){};
|
||||
defer elist.deinit(registry.allocator);
|
||||
|
||||
core.engine_log("sparse set length {d}", .{registry.baseSet.dense.items.len});
|
||||
for (registry.baseSet.dense.items) |dense| {
|
||||
// TODO: shutdown allocator
|
||||
elist.append(registry.allocator, Entity{ .handle = dense.sparseIndex }) catch {};
|
||||
}
|
||||
|
||||
for (elist.items) |h| {
|
||||
destroyEntity(h);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn destroyEntity(e: Entity) void {
|
||||
core.engine_log("entity destroyed: {d}", .{e.handle.index});
|
||||
const registry = getRegistry();
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ pub const LoadedModule = struct {
|
|||
}
|
||||
|
||||
pub fn load(self: *@This(), allocator: std.mem.Allocator) !void {
|
||||
core.engine_log("[ModuleLoader] loading module: ", .{});
|
||||
core.engine_log("[ModuleLoader] loading module: {s}", .{self.moduleName});
|
||||
self.lastLoad = std.time.microTimestamp();
|
||||
|
||||
try self.stageModule(allocator);
|
||||
|
|
|
|||
|
|
@ -51,8 +51,8 @@ pub const GameObject = struct {
|
|||
pub fn deinitECS(self: *@This(), handle: core.ObjectHandle) void {
|
||||
_ = handle;
|
||||
if (!self.destroyed) {
|
||||
self.destroyed = true;
|
||||
self.objectRef.table.destroy(self.objectRef.ptr, core.get(GameObjectSystem).allocator);
|
||||
self.destroyed = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ pub const LogBuffer = struct {
|
|||
|
||||
pub fn init(allocator: std.mem.Allocator) @This() {
|
||||
return .{
|
||||
.buffer = std.ArrayList(u8).init(allocator),
|
||||
.buffer = std.ArrayList(u8){},
|
||||
.allocator = allocator,
|
||||
};
|
||||
}
|
||||
|
|
@ -231,7 +231,7 @@ pub const LoggerSys = struct {
|
|||
|
||||
try core.dispatchJob(L{ .loggerSys = self });
|
||||
} else {
|
||||
//self.flushWriteBuffer();
|
||||
try self.flushWriteBuffer();
|
||||
}
|
||||
|
||||
self.lock.unlock();
|
||||
|
|
@ -252,6 +252,7 @@ pub const LoggerSys = struct {
|
|||
} else {
|
||||
var writer = self.consoleFile.writer(self.writerBuffer);
|
||||
try writer.interface.writeAll(self.writeOutBuffer.items);
|
||||
try writer.interface.flush();
|
||||
}
|
||||
self.writeOutBuffer.clearRetainingCapacity();
|
||||
self.lock.unlock();
|
||||
|
|
@ -266,6 +267,7 @@ pub const LoggerSys = struct {
|
|||
var writer = self.consoleFile.writer(self.writerBuffer);
|
||||
try writer.interface.writeAll(self.flushBuffer.items);
|
||||
try self.consoleFile.writeAll("");
|
||||
try writer.interface.flush();
|
||||
}
|
||||
self.flushBuffer.clearRetainingCapacity();
|
||||
self.lock.unlock();
|
||||
|
|
@ -327,6 +329,7 @@ pub const LoggerSys = struct {
|
|||
self.flushWriteBuffer() catch {};
|
||||
self.allocator.free(self.logFilePath);
|
||||
self.logFile.close();
|
||||
self.allocator.free(self.writerBuffer);
|
||||
|
||||
self.writeOutBuffer.deinit(self.allocator);
|
||||
self.flushBuffer.deinit(self.allocator);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
buffer: core.LogBuffer = undefined,
|
||||
buffer: core.logging.LogBuffer = undefined,
|
||||
allocator: std.mem.Allocator = undefined,
|
||||
lastLength: usize = 0,
|
||||
consoleBuffer: [1024]u8 = std.mem.zeroes([1024]u8),
|
||||
|
|
@ -10,7 +10,7 @@ pub fn init(allocator: std.mem.Allocator) !*@This() {
|
|||
const self = try allocator.create(@This());
|
||||
self.* = .{
|
||||
.allocator = allocator,
|
||||
.buffer = core.LogBuffer.init(allocator),
|
||||
.buffer = core.logging.LogBuffer.init(allocator),
|
||||
};
|
||||
|
||||
self.setup();
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ pub fn main() !void {
|
|||
core.engine_log("Working Dir set: {s}", .{try std.fs.cwd().realpath(".", &BUFFER)});
|
||||
}
|
||||
|
||||
panickers.attachSegfaultHandler();
|
||||
// panickers.attachSegfaultHandler();
|
||||
try realMain.main();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -262,7 +262,7 @@ pub fn parseConnectTarget(allocator: std.mem.Allocator, in: []const u8) !struct
|
|||
p = try std.fmt.parseInt(u16, ps, 10);
|
||||
}
|
||||
|
||||
return .{ .port = p, .address = try std.fmt.allocPrintZ(allocator, "{s}", .{base}) };
|
||||
return .{ .port = p, .address = try std.fmt.allocPrintSentinel(allocator, "{s}", .{base}, 0) };
|
||||
}
|
||||
|
||||
pub fn createLink(self: *@This(), session: *net.Session) !*net.Link {
|
||||
|
|
|
|||
|
|
@ -49,12 +49,12 @@ pub const TransportError = error{
|
|||
};
|
||||
|
||||
pub fn ip2String(allocator: std.mem.Allocator, ip: u32) ![:0]u8 {
|
||||
return try std.fmt.allocPrintZ(allocator, "{d}.{d}.{d}.{d}", .{
|
||||
return try std.fmt.allocPrintSentinel(allocator, "{d}.{d}.{d}.{d}", .{
|
||||
(ip >> 0) & 0xFF,
|
||||
(ip >> 8) & 0xFF,
|
||||
(ip >> 16) & 0xFF,
|
||||
(ip >> 24) & 0xFF,
|
||||
});
|
||||
}, 0);
|
||||
}
|
||||
|
||||
pub const TransportRef = netEngine.TransportRef;
|
||||
|
|
|
|||
|
|
@ -15,7 +15,12 @@ pub fn build(b: *std.Build) void {
|
|||
|
||||
const core_dep = b.dependency("core", .{ .target = target, .optimize = optimize, .static_build = static_build });
|
||||
|
||||
const zphysics_dep = b.dependency("zphysics", .{ .target = target, .optimize = optimize, .static_build = static_build });
|
||||
const zphysics_dep = b.dependency("zphysics", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.enable_cross_platform_determinism = false,
|
||||
.static_build = static_build,
|
||||
});
|
||||
|
||||
mod.addImport("core", core_dep.module("core"));
|
||||
mod.addImport("zphysics", zphysics_dep.module("root"));
|
||||
|
|
|
|||
|
|
@ -60,16 +60,9 @@ pub const IgnoreFixedBodiesFilter = extern struct {
|
|||
};
|
||||
|
||||
const BroadPhaseLayerInterface = extern struct {
|
||||
usingnamespace zphysics.BroadPhaseLayerInterface.Methods(@This());
|
||||
__v: *const zphysics.BroadPhaseLayerInterface.VTable = &vtable,
|
||||
|
||||
broad_phase_layer_interface: zphysics.BroadPhaseLayerInterface = .init(@This()),
|
||||
object_to_broad_phase: [ObjectLayers.len]zphysics.BroadPhaseLayer = undefined,
|
||||
|
||||
const vtable = zphysics.BroadPhaseLayerInterface.VTable{
|
||||
.getNumBroadPhaseLayers = _getNumBroadPhaseLayers,
|
||||
.getBroadPhaseLayer = _getBroadPhaseLayer,
|
||||
};
|
||||
|
||||
fn init() BroadPhaseLayerInterface {
|
||||
var layer_interface: BroadPhaseLayerInterface = .{};
|
||||
layer_interface.object_to_broad_phase[ObjectLayers.non_moving] = BroadPhaseLayers.non_moving;
|
||||
|
|
@ -77,26 +70,23 @@ const BroadPhaseLayerInterface = extern struct {
|
|||
return layer_interface;
|
||||
}
|
||||
|
||||
fn _getNumBroadPhaseLayers(_: *const zphysics.BroadPhaseLayerInterface) callconv(.c) u32 {
|
||||
pub fn getNumBroadPhaseLayers(_: *const zphysics.BroadPhaseLayerInterface) callconv(.c) u32 {
|
||||
return BroadPhaseLayers.len;
|
||||
}
|
||||
|
||||
fn _getBroadPhaseLayer(
|
||||
interface_self: *const zphysics.BroadPhaseLayerInterface,
|
||||
pub fn getBroadPhaseLayer(
|
||||
broad_phase_layer_interface: *const zphysics.BroadPhaseLayerInterface,
|
||||
object_layer: zphysics.ObjectLayer,
|
||||
) callconv(.c) zphysics.BroadPhaseLayer {
|
||||
const self: *const BroadPhaseLayerInterface = @ptrCast(interface_self);
|
||||
const self: *const BroadPhaseLayerInterface = @alignCast(@fieldParentPtr("broad_phase_layer_interface", broad_phase_layer_interface));
|
||||
return self.object_to_broad_phase[object_layer];
|
||||
}
|
||||
};
|
||||
|
||||
const ObjectVsBroadPhaseLayerFilter = extern struct {
|
||||
usingnamespace zphysics.ObjectVsBroadPhaseLayerFilter.Methods(@This());
|
||||
__v: *const zphysics.ObjectVsBroadPhaseLayerFilter.VTable = &vtable,
|
||||
object_vs_broad_phase_layer_filter: zphysics.ObjectVsBroadPhaseLayerFilter = .init(@This()),
|
||||
|
||||
const vtable = zphysics.ObjectVsBroadPhaseLayerFilter.VTable{ .shouldCollide = _shouldCollide };
|
||||
|
||||
fn _shouldCollide(
|
||||
pub fn shouldCollide(
|
||||
_: *const zphysics.ObjectVsBroadPhaseLayerFilter,
|
||||
object_layer: zphysics.ObjectLayer,
|
||||
broad_phase_layer: zphysics.BroadPhaseLayer,
|
||||
|
|
@ -110,12 +100,9 @@ const ObjectVsBroadPhaseLayerFilter = extern struct {
|
|||
};
|
||||
|
||||
const ObjectLayerPairFilter = extern struct {
|
||||
usingnamespace zphysics.ObjectLayerPairFilter.Methods(@This());
|
||||
__v: *const zphysics.ObjectLayerPairFilter.VTable = &vtable,
|
||||
object_layer_pair_filter: zphysics.ObjectLayerPairFilter = .init(@This()),
|
||||
|
||||
const vtable = zphysics.ObjectLayerPairFilter.VTable{ .shouldCollide = _shouldCollide };
|
||||
|
||||
fn _shouldCollide(
|
||||
pub fn shouldCollide(
|
||||
_: *const zphysics.ObjectLayerPairFilter,
|
||||
a: zphysics.ObjectLayer,
|
||||
b: zphysics.ObjectLayer,
|
||||
|
|
@ -304,40 +291,40 @@ pub const ShapeSettings = union(enum(u8)) {
|
|||
pub fn release(self: @This()) void {
|
||||
switch (self) {
|
||||
.convex => |x| {
|
||||
x.release();
|
||||
x.asShapeSettings().release();
|
||||
},
|
||||
.box => |x| {
|
||||
x.release();
|
||||
x.asShapeSettings().release();
|
||||
},
|
||||
.sphere => |x| {
|
||||
x.release();
|
||||
x.asShapeSettings().release();
|
||||
},
|
||||
.triangle => |x| {
|
||||
x.release();
|
||||
x.asShapeSettings().release();
|
||||
},
|
||||
.capsule => |x| {
|
||||
x.release();
|
||||
x.asShapeSettings().release();
|
||||
},
|
||||
.taperedCapsule => |x| {
|
||||
x.release();
|
||||
x.asShapeSettings().release();
|
||||
},
|
||||
.cylinder => |x| {
|
||||
x.release();
|
||||
x.asShapeSettings().release();
|
||||
},
|
||||
.convexHull => |x| {
|
||||
x.release();
|
||||
x.asShapeSettings().release();
|
||||
},
|
||||
.heightField => |x| {
|
||||
x.release();
|
||||
x.asShapeSettings().release();
|
||||
},
|
||||
.mesh => |x| {
|
||||
x.release();
|
||||
x.asShapeSettings().release();
|
||||
},
|
||||
.decorated => |x| {
|
||||
x.release();
|
||||
x.asShapeSettings().release();
|
||||
},
|
||||
.compound => |x| {
|
||||
x.release();
|
||||
x.asShapeSettings().release();
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
@ -345,40 +332,40 @@ pub const ShapeSettings = union(enum(u8)) {
|
|||
pub fn createShape(self: @This()) !*zphysics.Shape {
|
||||
switch (self) {
|
||||
.convex => |x| {
|
||||
return try x.createShape();
|
||||
return try x.asShapeSettings().createShape();
|
||||
},
|
||||
.box => |x| {
|
||||
return try x.createShape();
|
||||
return try x.asShapeSettings().createShape();
|
||||
},
|
||||
.sphere => |x| {
|
||||
return try x.createShape();
|
||||
return try x.asShapeSettings().createShape();
|
||||
},
|
||||
.triangle => |x| {
|
||||
return try x.createShape();
|
||||
return try x.asShapeSettings().createShape();
|
||||
},
|
||||
.capsule => |x| {
|
||||
return try x.createShape();
|
||||
return try x.asShapeSettings().createShape();
|
||||
},
|
||||
.taperedCapsule => |x| {
|
||||
return try x.createShape();
|
||||
return try x.asShapeSettings().createShape();
|
||||
},
|
||||
.cylinder => |x| {
|
||||
return try x.createShape();
|
||||
return try x.asShapeSettings().createShape();
|
||||
},
|
||||
.convexHull => |x| {
|
||||
return try x.createShape();
|
||||
return try x.asShapeSettings().createShape();
|
||||
},
|
||||
.heightField => |x| {
|
||||
return try x.createShape();
|
||||
return try x.asShapeSettings().createShape();
|
||||
},
|
||||
.mesh => |x| {
|
||||
return try x.createShape();
|
||||
return try x.asShapeSettings().createShape();
|
||||
},
|
||||
.decorated => |x| {
|
||||
return try x.createShape();
|
||||
return try x.asShapeSettings().createShape();
|
||||
},
|
||||
.compound => |x| {
|
||||
return try x.createShape();
|
||||
return try x.asShapeSettings().createShape();
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,8 +73,8 @@ pub fn getNormalRayFromScreen(
|
|||
const width = platform.context().extent.x;
|
||||
const height = platform.context().extent.y;
|
||||
|
||||
const sx = core.clamp(s.x, 0, width);
|
||||
const sy = core.clamp(s.y, 0, height);
|
||||
const sx = core.math.clamp(s.x, 0, width);
|
||||
const sy = core.math.clamp(s.y, 0, height);
|
||||
|
||||
const vec = core.Vectorf{
|
||||
.x = ((2.0 / width) * sx) - 1.0,
|
||||
|
|
@ -97,7 +97,7 @@ pub fn getNormalRayFromScreen(
|
|||
}
|
||||
|
||||
pub fn resolve(self: *@This()) void {
|
||||
const scene = self.entity.fetch(core.Scene).?;
|
||||
const scene = self.entity.fetch(core.Scene) orelse return;
|
||||
|
||||
self.updateProjections();
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ pub fn loadIndexedMeshForPoolingGltf(allocator: std.mem.Allocator, meshName: cor
|
|||
defer allocator.free(binaryPath);
|
||||
core.engine_log("{s}", .{binaryPath});
|
||||
binaryFile = try core.fs().loadFile(binaryPath);
|
||||
binaryBytes = binaryFile.?.bytes;
|
||||
binaryBytes = binaryFile.?.bytesNoEnd();
|
||||
}
|
||||
|
||||
defer if (binaryFile) |f| core.fs().unmap(f);
|
||||
|
|
@ -231,7 +231,7 @@ pub fn loadIndexedMeshForPoolingGltf(allocator: std.mem.Allocator, meshName: cor
|
|||
.y = texcoords.?[uvIndex + 1],
|
||||
} else core.Vector2f{};
|
||||
|
||||
const normal = if (normalIndex < normals.?.len) core.Vectorf{
|
||||
const normal = if (normals != null and normalIndex < normals.?.len) core.Vectorf{
|
||||
.x = normals.?[i],
|
||||
.y = normals.?[i + 1],
|
||||
.z = normals.?[i + 2],
|
||||
|
|
|
|||
|
|
@ -329,7 +329,7 @@ pub const Renderer = struct {
|
|||
// .address_mode_v = .sampleraddressmodeRepeat,
|
||||
// .address_mode_w = .sampleraddressmodeRepeat,
|
||||
//
|
||||
.mip_lod_bias = -1.0,
|
||||
.mip_lod_bias = 0.0,
|
||||
.min_lod = 0, // Clamps the minimum of the computed LOD value.
|
||||
.max_lod = 10, // Clamps the maximum of the computed LOD value.
|
||||
.address_mode_u = .sampleraddressmodeRepeat,
|
||||
|
|
|
|||
|
|
@ -150,8 +150,8 @@ fn findRootDir(allocator: std.mem.Allocator) ![]u8 {
|
|||
var current_dir = std.fs.cwd();
|
||||
|
||||
// Start from current directory and walk up
|
||||
var path_components = std.ArrayList([]const u8).init(allocator);
|
||||
defer path_components.deinit();
|
||||
var path_components = std.ArrayList([]const u8){};
|
||||
defer path_components.deinit(allocator);
|
||||
|
||||
// Try current directory first
|
||||
current_dir.access("content.txt", .{}) catch {
|
||||
|
|
|
|||
|
|
@ -376,10 +376,7 @@ pub const TextRenderer = struct {
|
|||
item.destroy(self.allocator);
|
||||
}
|
||||
|
||||
for (self.deadList.items) |item| {
|
||||
item.destroy(self.allocator);
|
||||
}
|
||||
|
||||
self.deadList.deinit(self.allocator);
|
||||
self.geo.destroy();
|
||||
self.linearBuffers.deinit(self.allocator);
|
||||
self.assignedBuffers.deinit(self.allocator);
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ const QuakeMap = @This();
|
|||
|
||||
worldspawn: Entity,
|
||||
entities: std.ArrayList(Entity),
|
||||
allocator: std.mem.Allocator,
|
||||
// uniqueMaterials: std.StringHashMap(u32), // counts for the number
|
||||
// of times a material is used.
|
||||
|
||||
|
|
@ -28,7 +29,7 @@ pub fn deinit(self: *@This()) void {
|
|||
|
||||
pub fn read(allocator: Allocator, data: []const u8, error_info: *ErrorInfo) !QuakeMap {
|
||||
var worldspawn: ?Entity = null;
|
||||
var entities = std.ArrayList(Entity).init(allocator);
|
||||
var entities = std.ArrayList(Entity){};
|
||||
var iter = std.mem.tokenizeAny(u8, data, "\r\n");
|
||||
error_info.line_number = 0;
|
||||
while (iter.next()) |line| {
|
||||
|
|
@ -40,7 +41,7 @@ pub fn read(allocator: Allocator, data: []const u8, error_info: *ErrorInfo) !Qua
|
|||
if (std.mem.eql(u8, entity.classname, "worldspawn")) {
|
||||
worldspawn = entity;
|
||||
} else {
|
||||
try entities.append(entity);
|
||||
try entities.append(allocator, entity);
|
||||
}
|
||||
},
|
||||
else => {
|
||||
|
|
@ -53,6 +54,7 @@ pub fn read(allocator: Allocator, data: []const u8, error_info: *ErrorInfo) !Qua
|
|||
return .{
|
||||
.worldspawn = worldspawn orelse return error.WorldSpawnNotFound,
|
||||
.entities = entities,
|
||||
.allocator = allocator,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -66,20 +68,23 @@ pub const Entity = struct {
|
|||
spawnflags: u32,
|
||||
properties: std.ArrayList(Property),
|
||||
solids: std.ArrayList(Solid),
|
||||
allocator: std.mem.Allocator,
|
||||
|
||||
pub fn deinit(self: *@This()) void {
|
||||
for (self.solids.items) |*solid| {
|
||||
solid.faces.deinit();
|
||||
}
|
||||
self.properties.deinit();
|
||||
self.solids.deinit(self.allocator);
|
||||
self.properties.deinit(self.allocator);
|
||||
}
|
||||
|
||||
pub fn init(allocator: Allocator) Entity {
|
||||
return .{
|
||||
.classname = &.{},
|
||||
.spawnflags = 0,
|
||||
.properties = std.ArrayList(Property).init(allocator),
|
||||
.solids = std.ArrayList(Solid).init(allocator),
|
||||
.allocator = allocator,
|
||||
.properties = std.ArrayList(Property){},
|
||||
.solids = std.ArrayList(Solid){},
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -124,13 +129,14 @@ pub const Entity = struct {
|
|||
|
||||
pub const Solid = struct {
|
||||
faces: std.ArrayList(Face),
|
||||
allocator: std.mem.Allocator,
|
||||
|
||||
fn init(allocator: Allocator) Solid {
|
||||
return .{ .faces = std.ArrayList(Face).init(allocator) };
|
||||
return .{ .faces = std.ArrayList(Face){}, .allocator = allocator };
|
||||
}
|
||||
|
||||
fn computeVertices(self: *Solid) !void {
|
||||
const allocator = self.faces.allocator;
|
||||
const allocator = self.allocator;
|
||||
var buffer: [64]Vec3d = undefined;
|
||||
var vertices = std.ArrayListUnmanaged(Vec3d).initBuffer(buffer[0..32]);
|
||||
var clipped = std.ArrayListUnmanaged(Vec3d).initBuffer(buffer[32..64]);
|
||||
|
|
@ -272,10 +278,10 @@ fn readEntity(allocator: Allocator, iter: *TokenIterator(u8, .any), error_info:
|
|||
} else if (std.mem.eql(u8, property.key, "spawnflags")) {
|
||||
entity.spawnflags = try std.fmt.parseInt(u32, property.value, 10);
|
||||
} else {
|
||||
try entity.properties.append(property);
|
||||
try entity.properties.append(entity.allocator, property);
|
||||
}
|
||||
},
|
||||
'{' => try entity.solids.append(try readSolid(allocator, iter, error_info)),
|
||||
'{' => try entity.solids.append(entity.allocator, try readSolid(allocator, iter, error_info)),
|
||||
'}' => break,
|
||||
else => {
|
||||
std.debug.print("error in line: {s}\n", .{line});
|
||||
|
|
@ -301,7 +307,7 @@ fn readSolid(allocator: Allocator, iter: *TokenIterator(u8, .any), error_info: *
|
|||
error_info.line_number += 1;
|
||||
switch (line[0]) {
|
||||
'/' => continue,
|
||||
'(' => try solid.faces.append(try readFace(line)),
|
||||
'(' => try solid.faces.append(solid.allocator, try readFace(line)),
|
||||
'}' => break,
|
||||
|
||||
else => {
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ pub const TBMap = struct {
|
|||
"Texture",
|
||||
textureName,
|
||||
// TODO don't hardcode the root path
|
||||
.{ .path = try std.fmt.bufPrint(&fmtBuf2, "textures/{s}.png", .{textureRef}) },
|
||||
.{ .path = try std.fmt.bufPrint(&fmtBuf2, "textures/{s}.png", .{textureRef}), .textureUseBlockySampler = false },
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
@ -92,7 +92,7 @@ pub const TBMap = struct {
|
|||
vertexCount,
|
||||
12,
|
||||
);
|
||||
defer settings.release();
|
||||
defer settings.asShapeSettings().release();
|
||||
|
||||
// settings.setMaxConvexRadius(0.1);
|
||||
var nameBuffer: [256]u8 = undefined;
|
||||
|
|
|
|||
|
|
@ -43,8 +43,8 @@ pub fn GenericVector(comptime dimensions: comptime_int, comptime T: type) type {
|
|||
else => unreachable,
|
||||
};
|
||||
|
||||
pub usingnamespace switch (dimensions) {
|
||||
2 => extern struct {
|
||||
pub const DimensionImpl = switch (dimensions) {
|
||||
2 => struct {
|
||||
/// Construct new vector.
|
||||
pub inline fn new(vx: T, vy: T) Self {
|
||||
return .{ .data = [2]T{ vx, vy } };
|
||||
|
|
@ -76,7 +76,7 @@ pub fn GenericVector(comptime dimensions: comptime_int, comptime T: type) type {
|
|||
return Self.new(vec4.x(), vec4.y());
|
||||
}
|
||||
},
|
||||
3 => extern struct {
|
||||
3 => struct {
|
||||
/// Construct new vector.
|
||||
pub inline fn new(vx: T, vy: T, vz: T) Self {
|
||||
return .{ .data = [3]T{ vx, vy, vz } };
|
||||
|
|
@ -92,12 +92,12 @@ pub fn GenericVector(comptime dimensions: comptime_int, comptime T: type) type {
|
|||
|
||||
/// Shorthand for (0, 0, 1).
|
||||
pub fn forward() Self {
|
||||
return new(0, 0, 1);
|
||||
return Self.new(0, 0, 1);
|
||||
}
|
||||
|
||||
/// Shorthand for (0, 0, -1).
|
||||
pub fn back() Self {
|
||||
return forward().negate();
|
||||
return Self.forward().negate();
|
||||
}
|
||||
|
||||
/// Construct the cross product (as vector) from two vectors.
|
||||
|
|
@ -113,7 +113,7 @@ pub fn GenericVector(comptime dimensions: comptime_int, comptime T: type) type {
|
|||
const result_x = (y1 * z2) - (z1 * y2);
|
||||
const result_y = (z1 * x2) - (x1 * z2);
|
||||
const result_z = (x1 * y2) - (y1 * x2);
|
||||
return new(result_x, result_y, result_z);
|
||||
return Self.new(result_x, result_y, result_z);
|
||||
}
|
||||
|
||||
pub inline fn toVec2(self: Self) GenericVector(2, T) {
|
||||
|
|
@ -132,7 +132,7 @@ pub fn GenericVector(comptime dimensions: comptime_int, comptime T: type) type {
|
|||
return Self.new(vec4.x(), vec4.y(), vec4.z());
|
||||
}
|
||||
},
|
||||
4 => extern struct {
|
||||
4 => struct {
|
||||
/// Construct new vector.
|
||||
pub inline fn new(vx: T, vy: T, vz: T, vw: T) Self {
|
||||
return .{ .data = [4]T{ vx, vy, vz, vw } };
|
||||
|
|
@ -140,12 +140,12 @@ pub fn GenericVector(comptime dimensions: comptime_int, comptime T: type) type {
|
|||
|
||||
/// Shorthand for (0, 0, 1, 0).
|
||||
pub fn forward() Self {
|
||||
return new(0, 0, 1, 0);
|
||||
return Self.new(0, 0, 1, 0);
|
||||
}
|
||||
|
||||
/// Shorthand for (0, 0, -1, 0).
|
||||
pub fn back() Self {
|
||||
return forward().negate();
|
||||
return Self.forward().negate();
|
||||
}
|
||||
|
||||
pub inline fn z(self: Self) T {
|
||||
|
|
@ -183,6 +183,8 @@ pub fn GenericVector(comptime dimensions: comptime_int, comptime T: type) type {
|
|||
else => unreachable,
|
||||
};
|
||||
|
||||
pub const new = DimensionImpl.new;
|
||||
|
||||
pub inline fn x(self: Self) T {
|
||||
return self.data[0];
|
||||
}
|
||||
|
|
@ -191,6 +193,9 @@ pub fn GenericVector(comptime dimensions: comptime_int, comptime T: type) type {
|
|||
return self.data[1];
|
||||
}
|
||||
|
||||
pub const z = DimensionImpl.z;
|
||||
pub const w = DimensionImpl.w;
|
||||
|
||||
pub inline fn xMut(self: *Self) *T {
|
||||
return &self.data[0];
|
||||
}
|
||||
|
|
@ -199,6 +204,9 @@ pub fn GenericVector(comptime dimensions: comptime_int, comptime T: type) type {
|
|||
return &self.data[1];
|
||||
}
|
||||
|
||||
pub const zMut = DimensionImpl.zMut;
|
||||
pub const wMut = DimensionImpl.wMut;
|
||||
|
||||
/// Set all components to the same given value.
|
||||
pub fn set(val: T) Self {
|
||||
const result: Data = @splat(val);
|
||||
|
|
@ -245,6 +253,9 @@ pub fn GenericVector(comptime dimensions: comptime_int, comptime T: type) type {
|
|||
return right().negate();
|
||||
}
|
||||
|
||||
pub const forward = DimensionImpl.forward;
|
||||
pub const back = DimensionImpl.back;
|
||||
|
||||
/// Negate the given vector.
|
||||
pub fn negate(self: Self) Self {
|
||||
return self.scale(-1);
|
||||
|
|
@ -255,7 +266,7 @@ pub fn GenericVector(comptime dimensions: comptime_int, comptime T: type) type {
|
|||
pub fn cast(self: Self, comptime dest_type: type) GenericVector(dimensions, dest_type) {
|
||||
const dest_info = @typeInfo(dest_type);
|
||||
|
||||
if (dest_info != .Float and dest_info != .Int) {
|
||||
if (dest_info != .float and dest_info != .int) {
|
||||
panic("Error, dest type should be integer or float.\n", .{});
|
||||
}
|
||||
|
||||
|
|
@ -273,6 +284,14 @@ pub fn GenericVector(comptime dimensions: comptime_int, comptime T: type) type {
|
|||
return .{ .data = result };
|
||||
}
|
||||
|
||||
pub const fromVec2 = DimensionImpl.fromVec2;
|
||||
pub const fromVec3 = DimensionImpl.fromVec3;
|
||||
pub const fromVec4 = DimensionImpl.fromVec4;
|
||||
|
||||
pub const toVec2 = DimensionImpl.toVec2;
|
||||
pub const toVec3 = DimensionImpl.toVec3;
|
||||
pub const toVec4 = DimensionImpl.toVec4;
|
||||
|
||||
/// Transform vector to array.
|
||||
pub fn toArray(self: Self) [dimensions]T {
|
||||
return self.data;
|
||||
|
|
@ -290,12 +309,24 @@ pub fn GenericVector(comptime dimensions: comptime_int, comptime T: type) type {
|
|||
return @sqrt(self.dot(self));
|
||||
}
|
||||
|
||||
/// Return the length (magnitude) squared of given vector.
|
||||
/// x^2 + y^2 + z^2 ...
|
||||
pub fn lengthSq(self: Self) T {
|
||||
return self.dot(self);
|
||||
}
|
||||
|
||||
/// Return the distance between two points.
|
||||
/// √[(x1 - x2)^2 + (y1 - y2)^2 + (z1 - z2)^2 ...]
|
||||
pub fn distance(first_vector: Self, second_vector: Self) T {
|
||||
return length(first_vector.sub(second_vector));
|
||||
}
|
||||
|
||||
/// Return the distance squared between two points.
|
||||
/// (x1 - x2)^2 + (y1 - y2)^2 + (z1 - z2)^2 ...
|
||||
pub fn distanceSq(first_vector: Self, second_vector: Self) T {
|
||||
return lengthSq(first_vector.sub(second_vector));
|
||||
}
|
||||
|
||||
/// Construct new normalized vector from a given one.
|
||||
pub fn norm(self: Self) Self {
|
||||
const l = self.length();
|
||||
|
|
@ -329,6 +360,12 @@ pub fn GenericVector(comptime dimensions: comptime_int, comptime T: type) type {
|
|||
return .{ .data = result };
|
||||
}
|
||||
|
||||
/// Component wise division betwen two given vector.
|
||||
pub fn div(first_vector: Self, second_vector: Self) Self {
|
||||
const result = first_vector.data / second_vector.data;
|
||||
return .{ .data = result };
|
||||
}
|
||||
|
||||
/// Construct vector from the max components in two vectors
|
||||
pub fn max(first_vector: Self, second_vector: Self) Self {
|
||||
const result = @max(first_vector.data, second_vector.data);
|
||||
|
|
@ -362,16 +399,41 @@ pub fn GenericVector(comptime dimensions: comptime_int, comptime T: type) type {
|
|||
return .{ .data = result };
|
||||
}
|
||||
|
||||
pub const rotate = DimensionImpl.rotate;
|
||||
pub const cross = DimensionImpl.cross;
|
||||
|
||||
pub fn swizzle(self: Self, comptime comps: []const u8) SwizzleType(comps.len) {
|
||||
if (comps.len == 1) {
|
||||
return self.data[@intFromEnum(@field(Component, &.{comps[0]}))];
|
||||
}
|
||||
|
||||
var result = GenericVector(comps.len, T).zero();
|
||||
inline for (comps, 0..) |comp, i| {
|
||||
result.data[i] = self.data[@intFromEnum(@field(Component, &.{comp}))];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
fn SwizzleType(comps_len: usize) type {
|
||||
return switch (comps_len) {
|
||||
1 => T,
|
||||
else => GenericVector(comps_len, T),
|
||||
};
|
||||
}
|
||||
|
||||
/// Deprecated; use `swizzle` instead
|
||||
pub inline fn swizzle2(self: Self, comptime vx: Component, comptime vy: Component) GenericVector(2, T) {
|
||||
return GenericVector(2, T).new(self.data[@intFromEnum(vx)], self.data[@intFromEnum(vy)]);
|
||||
return self.swizzle(@tagName(vx) ++ @tagName(vy));
|
||||
}
|
||||
|
||||
/// Deprecated; use `swizzle` instead
|
||||
pub inline fn swizzle3(self: Self, comptime vx: Component, comptime vy: Component, comptime vz: Component) GenericVector(3, T) {
|
||||
return GenericVector(3, T).new(self.data[@intFromEnum(vx)], self.data[@intFromEnum(vy)], self.data[@intFromEnum(vz)]);
|
||||
return self.swizzle(@tagName(vx) ++ @tagName(vy) ++ @tagName(vz));
|
||||
}
|
||||
|
||||
/// Deprecated; use `swizzle` instead
|
||||
pub inline fn swizzle4(self: Self, comptime vx: Component, comptime vy: Component, comptime vz: Component, comptime vw: Component) GenericVector(4, T) {
|
||||
return GenericVector(4, T).new(self.data[@intFromEnum(vx)], self.data[@intFromEnum(vy)], self.data[@intFromEnum(vz)], self.data[@intFromEnum(vw)]);
|
||||
return self.swizzle(@tagName(vx) ++ @tagName(vy) ++ @tagName(vz) ++ @tagName(vw));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -564,7 +626,7 @@ test "zalgebra.Vectors.length" {
|
|||
}
|
||||
}
|
||||
|
||||
test "zalgebra.Vectors.distance" {
|
||||
test "zalgebra.Vectors.distance/Sq" {
|
||||
// Vec2
|
||||
{
|
||||
const a = Vec2.zero();
|
||||
|
|
@ -572,7 +634,9 @@ test "zalgebra.Vectors.distance" {
|
|||
const c = Vec2.new(0, 5);
|
||||
|
||||
try expectEqual(a.distance(b), 1);
|
||||
try expectEqual(a.distanceSq(b), 1);
|
||||
try expectEqual(a.distance(c), 5);
|
||||
try expectEqual(a.distanceSq(c), 25);
|
||||
}
|
||||
|
||||
// Vec3
|
||||
|
|
@ -582,7 +646,9 @@ test "zalgebra.Vectors.distance" {
|
|||
const c = Vec3.new(0, 5, 0);
|
||||
|
||||
try expectEqual(a.distance(b), 1);
|
||||
try expectEqual(a.distanceSq(b), 1);
|
||||
try expectEqual(a.distance(c), 5);
|
||||
try expectEqual(a.distanceSq(c), 25);
|
||||
}
|
||||
|
||||
// Vec4
|
||||
|
|
@ -592,7 +658,9 @@ test "zalgebra.Vectors.distance" {
|
|||
const c = Vec4.new(0, 5, 0, 0);
|
||||
|
||||
try expectEqual(a.distance(b), 1);
|
||||
try expectEqual(a.distanceSq(b), 1);
|
||||
try expectEqual(a.distance(c), 5);
|
||||
try expectEqual(a.distanceSq(c), 25);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -886,50 +954,24 @@ test "vector conversions 4 -> 2" {
|
|||
|
||||
// Just touching every component
|
||||
// not testing every combination cause it's too many
|
||||
test "swizzle2" {
|
||||
test "swizzle" {
|
||||
const v1 = Vec2.new(1, 2);
|
||||
const x = v1.swizzle("x");
|
||||
try expectEqual(1, x);
|
||||
|
||||
const v2 = Vec2.new(1, 2);
|
||||
const yx = v2.swizzle2(.y, .x);
|
||||
const yx = v2.swizzle("yx");
|
||||
try expectEqual(Vec2.new(2, 1), yx);
|
||||
|
||||
const v3 = Vec3.new(1, 2, 3);
|
||||
const zy = v3.swizzle2(.z, .y);
|
||||
const xx = v3.swizzle2(.x, .x);
|
||||
const zy = v3.swizzle("zy");
|
||||
const xx = v3.swizzle("xx");
|
||||
try expectEqual(Vec2.new(3, 2), zy);
|
||||
try expectEqual(Vec2.new(1, 1), xx);
|
||||
|
||||
const v4 = Vec4.new(1, 2, 3, 4);
|
||||
const wz = v4.swizzle2(.w, .z);
|
||||
const xy = v4.swizzle2(.x, .y);
|
||||
const wz = v4.swizzle("wz");
|
||||
const xy = v4.swizzle("xy");
|
||||
try expectEqual(Vec2.new(4, 3), wz);
|
||||
try expectEqual(Vec2.new(1, 2), xy);
|
||||
}
|
||||
|
||||
test "swizzle3" {
|
||||
const v2 = Vec2.new(1, 2);
|
||||
const yxy = v2.swizzle3(.y, .x, .y);
|
||||
try expectEqual(Vec3.new(2, 1, 2), yxy);
|
||||
|
||||
const v3 = Vec3.new(1, 2, 3);
|
||||
const zyx = v3.swizzle3(.z, .y, .x);
|
||||
try expectEqual(Vec3.new(3, 2, 1), zyx);
|
||||
|
||||
const v4 = Vec4.new(1, 2, 3, 4);
|
||||
const wzy = v4.swizzle3(.w, .z, .y);
|
||||
const xxx = v4.swizzle3(.x, .x, .x);
|
||||
try expectEqual(Vec3.new(4, 3, 2), wzy);
|
||||
try expectEqual(Vec3.new(1, 1, 1), xxx);
|
||||
}
|
||||
|
||||
test "swizzle4" {
|
||||
const v2 = Vec2.new(1, 2);
|
||||
const yxyx = v2.swizzle4(.y, .x, .y, .x);
|
||||
try expectEqual(Vec4.new(2, 1, 2, 1), yxyx);
|
||||
|
||||
const v3 = Vec3.new(1, 2, 3);
|
||||
const zyxz = v3.swizzle4(.z, .y, .x, .z);
|
||||
try expectEqual(Vec4.new(3, 2, 1, 3), zyxz);
|
||||
|
||||
const v4 = Vec4.new(1, 2, 3, 4);
|
||||
const wzyx = v4.swizzle4(.w, .z, .y, .x);
|
||||
try expectEqual(Vec4.new(4, 3, 2, 1), wzyx);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,16 +4,55 @@ const std = @import("std");
|
|||
const expectEqual = std.testing.expectEqual;
|
||||
const math = std.math;
|
||||
|
||||
pub usingnamespace @import("generic_vector.zig");
|
||||
pub usingnamespace @import("mat3.zig");
|
||||
pub usingnamespace @import("mat4.zig");
|
||||
pub usingnamespace @import("quaternion.zig");
|
||||
const generic_vector = @import("generic_vector.zig");
|
||||
|
||||
pub const Vec2 = generic_vector.Vec2;
|
||||
pub const Vec2_f64 = generic_vector.Vec2_f64;
|
||||
pub const Vec2_i32 = generic_vector.Vec2_i32;
|
||||
pub const Vec2_usize = generic_vector.Vec2_usize;
|
||||
|
||||
pub const Vec3 = generic_vector.Vec3;
|
||||
pub const Vec3_f64 = generic_vector.Vec3_f64;
|
||||
pub const Vec3_i32 = generic_vector.Vec3_i32;
|
||||
pub const Vec3_usize = generic_vector.Vec3_usize;
|
||||
|
||||
pub const Vec4 = generic_vector.Vec4;
|
||||
pub const Vec4_f64 = generic_vector.Vec4_f64;
|
||||
pub const Vec4_i32 = generic_vector.Vec4_i32;
|
||||
pub const Vec4_usize = generic_vector.Vec4_usize;
|
||||
|
||||
pub const GenericVector = generic_vector.GenericVector;
|
||||
|
||||
const mat3 = @import("mat3.zig");
|
||||
|
||||
pub const Mat3 = mat3.Mat3;
|
||||
pub const Mat3_f64 = mat3.Mat3_f64;
|
||||
|
||||
pub const Mat3x3 = mat3.Mat3x3;
|
||||
|
||||
const mat4 = @import("mat4.zig");
|
||||
|
||||
pub const Mat4 = mat4.Mat4;
|
||||
pub const Mat4_f64 = mat4.Mat4_f64;
|
||||
pub const perspective = mat4.perspective;
|
||||
pub const perspectiveReversedZ = mat4.perspectiveReversedZ;
|
||||
pub const orthographic = mat4.orthographic;
|
||||
pub const lookAt = mat4.lookAt;
|
||||
|
||||
pub const Mat4x4 = mat4.Mat4x4;
|
||||
|
||||
const quat = @import("quaternion.zig");
|
||||
|
||||
pub const Quat = quat.Quat;
|
||||
pub const Quat_f64 = quat.Quaternion;
|
||||
|
||||
pub const Quaternion = quat.Quaternion;
|
||||
|
||||
/// Convert degrees to radians.
|
||||
pub fn toRadians(degrees: anytype) @TypeOf(degrees) {
|
||||
const T = @TypeOf(degrees);
|
||||
|
||||
if (@typeInfo(T) != .Float) {
|
||||
if (@typeInfo(T) != .float) {
|
||||
@compileError("Radians not implemented for " ++ @typeName(T));
|
||||
}
|
||||
|
||||
|
|
@ -24,7 +63,7 @@ pub fn toRadians(degrees: anytype) @TypeOf(degrees) {
|
|||
pub fn toDegrees(radians: anytype) @TypeOf(radians) {
|
||||
const T = @TypeOf(radians);
|
||||
|
||||
if (@typeInfo(T) != .Float) {
|
||||
if (@typeInfo(T) != .float) {
|
||||
@compileError("Radians not implemented for " ++ @typeName(T));
|
||||
}
|
||||
|
||||
|
|
@ -34,7 +73,7 @@ pub fn toDegrees(radians: anytype) @TypeOf(radians) {
|
|||
/// Linear interpolation between two floats.
|
||||
/// `t` is used to interpolate between `from` and `to`.
|
||||
pub fn lerp(comptime T: type, from: T, to: T, t: T) T {
|
||||
if (@typeInfo(T) != .Float) {
|
||||
if (@typeInfo(T) != .float) {
|
||||
@compileError("Lerp not implemented for " ++ @typeName(T));
|
||||
}
|
||||
|
||||
|
|
@ -70,3 +109,10 @@ test "zalgebra.lerp" {
|
|||
try expectEqual(lerp(f32, from, to, 0.5), 5);
|
||||
try expectEqual(lerp(f32, from, to, 1), 10);
|
||||
}
|
||||
|
||||
test {
|
||||
_ = generic_vector;
|
||||
_ = mat3;
|
||||
_ = mat4;
|
||||
_ = quat;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,10 +19,6 @@ pub const Mat3_f64 = Mat3x3(f64);
|
|||
/// A column-major 3x3 matrix
|
||||
/// Note: Column-major means accessing data like m.data[COLUMN][ROW].
|
||||
pub fn Mat3x3(comptime T: type) type {
|
||||
if (@typeInfo(T) != .Float) {
|
||||
@compileError("Mat3x3 not implemented for " ++ @typeName(T));
|
||||
}
|
||||
|
||||
const Vector3 = GenericVector(3, T);
|
||||
|
||||
return extern struct {
|
||||
|
|
@ -85,9 +81,8 @@ pub fn Mat3x3(comptime T: type) type {
|
|||
return result;
|
||||
}
|
||||
|
||||
/// Return a pointer to the inner data of the matrix.
|
||||
pub fn getData(self: *const Self) *const T {
|
||||
return @ptrCast(&self.data);
|
||||
pub fn getSlice(self: *const Self) *const [3][3]T {
|
||||
return self.data[0..3];
|
||||
}
|
||||
|
||||
/// Return true if two matrices are equals.
|
||||
|
|
@ -105,6 +100,10 @@ pub fn Mat3x3(comptime T: type) type {
|
|||
|
||||
/// Construct a 3x3 matrix from given axis and angle (in degrees).
|
||||
pub fn fromRotation(angle_in_degrees: T, axis: Vector3) Self {
|
||||
if (@typeInfo(T) != .float) {
|
||||
@compileError("Mat3x3.fromRotation() not implemented for " ++ @typeName(T));
|
||||
}
|
||||
|
||||
var result = Self.identity();
|
||||
|
||||
const norm_axis = axis.norm();
|
||||
|
|
@ -133,6 +132,10 @@ pub fn Mat3x3(comptime T: type) type {
|
|||
}
|
||||
|
||||
pub fn rotate(self: Self, angle_in_degrees: T, axis: Vector3) Self {
|
||||
if (@typeInfo(T) != .float) {
|
||||
@compileError("Mat3x3.rotate() not implemented for " ++ @typeName(T));
|
||||
}
|
||||
|
||||
const rotation_mat = Self.fromRotation(angle_in_degrees, axis);
|
||||
return Self.mul(self, rotation_mat);
|
||||
}
|
||||
|
|
@ -140,6 +143,10 @@ pub fn Mat3x3(comptime T: type) type {
|
|||
/// Construct a rotation matrix from euler angles (X * Y * Z).
|
||||
/// Order matters because matrix multiplication are NOT commutative.
|
||||
pub fn fromEulerAngles(euler_angle: Vector3) Self {
|
||||
if (@typeInfo(T) != .float) {
|
||||
@compileError("Mat3x3.fromEulerAngles() not implemented for " ++ @typeName(T));
|
||||
}
|
||||
|
||||
const x = Self.fromRotation(euler_angle.x(), Vector3.right());
|
||||
const y = Self.fromRotation(euler_angle.y(), Vector3.up());
|
||||
const z = Self.fromRotation(euler_angle.z(), Vector3.forward());
|
||||
|
|
@ -149,6 +156,10 @@ pub fn Mat3x3(comptime T: type) type {
|
|||
|
||||
/// Ortho normalize given matrix.
|
||||
pub fn orthoNormalize(self: Self) Self {
|
||||
if (@typeInfo(T) != .float) {
|
||||
@compileError("Mat3x3.orthoNormalize() not implemented for " ++ @typeName(T));
|
||||
}
|
||||
|
||||
const column_1 = Vector3.new(self.data[0][0], self.data[0][1], self.data[0][2]).norm();
|
||||
const column_2 = Vector3.new(self.data[1][0], self.data[1][1], self.data[1][2]).norm();
|
||||
const column_3 = Vector3.new(self.data[2][0], self.data[2][1], self.data[2][2]).norm();
|
||||
|
|
@ -174,6 +185,10 @@ pub fn Mat3x3(comptime T: type) type {
|
|||
/// Taken from Mike Day at Insomniac Games (and `glm` as the same function).
|
||||
/// For more details: https://d3cw3dd2w32x2b.cloudfront.net/wp-content/uploads/2012/07/euler-angles1.pdf
|
||||
pub fn extractEulerAngles(self: Self) Vector3 {
|
||||
if (@typeInfo(T) != .float) {
|
||||
@compileError("Mat3x3.extractEulerAngles() not implemented for " ++ @typeName(T));
|
||||
}
|
||||
|
||||
const m = self.orthoNormalize();
|
||||
|
||||
const theta_x = math.atan2(m.data[1][2], m.data[2][2]);
|
||||
|
|
@ -259,35 +274,30 @@ pub fn Mat3x3(comptime T: type) type {
|
|||
return inv_mat;
|
||||
}
|
||||
|
||||
/// Print the 3x3 to stderr.
|
||||
pub fn debugPrint(self: Self) void {
|
||||
const print = std.debug.print;
|
||||
pub fn format(
|
||||
self: Self,
|
||||
comptime fmt: []const u8,
|
||||
options: std.fmt.FormatOptions,
|
||||
writer: anytype,
|
||||
) !void {
|
||||
_ = fmt;
|
||||
_ = options;
|
||||
|
||||
print("({d}, {d}, {d})\n", .{
|
||||
self.data[0][0],
|
||||
self.data[1][0],
|
||||
self.data[2][0],
|
||||
});
|
||||
|
||||
print("({d}, {d}, {d})\n", .{
|
||||
self.data[0][1],
|
||||
self.data[1][1],
|
||||
self.data[2][1],
|
||||
});
|
||||
|
||||
print("({d}, {d}, {d})\n", .{
|
||||
self.data[0][2],
|
||||
self.data[1][2],
|
||||
self.data[2][2],
|
||||
for (0..3) |i| {
|
||||
try writer.print("({d:.2}, {d:.2}, {d:.2})\n", .{
|
||||
self.data[0][i],
|
||||
self.data[1][i],
|
||||
self.data[2][i],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// Cast a type to another type.
|
||||
/// It's like builtins: @intCast, @floatCast, @floatFromInt, @intFromFloat.
|
||||
pub fn cast(self: Self, comptime dest_type: type) Mat3x3(dest_type) {
|
||||
const dest_info = @typeInfo(dest_type);
|
||||
|
||||
if (dest_info != .Float) {
|
||||
if (dest_info != .float) {
|
||||
std.debug.panic("Error, dest type should be float.\n", .{});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ pub const lookAt = Mat4.lookAt;
|
|||
/// A column-major 4x4 matrix
|
||||
/// Note: Column-major means accessing data like m.data[COLUMN][ROW].
|
||||
pub fn Mat4x4(comptime T: type) type {
|
||||
if (@typeInfo(T) != .Float) {
|
||||
if (@typeInfo(T) != .float) {
|
||||
@compileError("Mat4x4 not implemented for " ++ @typeName(T));
|
||||
}
|
||||
|
||||
|
|
@ -92,9 +92,8 @@ pub fn Mat4x4(comptime T: type) type {
|
|||
return result;
|
||||
}
|
||||
|
||||
/// Return a pointer to the inner data of the matrix.
|
||||
pub fn getData(self: *const Self) *const T {
|
||||
return @ptrCast(&self.data);
|
||||
pub fn getSlice(self: *const Self) *const [4][4]T {
|
||||
return self.data[0..4];
|
||||
}
|
||||
|
||||
/// Return true if two matrices are equals.
|
||||
|
|
@ -114,12 +113,14 @@ pub fn Mat4x4(comptime T: type) type {
|
|||
/// Construct 4x4 translation matrix by multiplying identity matrix and
|
||||
/// given translation vector.
|
||||
pub fn fromTranslate(axis: Vector3) Self {
|
||||
var result = Self.identity();
|
||||
result.data[3][0] = axis.data[0];
|
||||
result.data[3][1] = axis.data[1];
|
||||
result.data[3][2] = axis.data[2];
|
||||
|
||||
return result;
|
||||
return .{
|
||||
.data = .{
|
||||
.{ 1, 0, 0, 0 },
|
||||
.{ 0, 1, 0, 0 },
|
||||
.{ 0, 0, 1, 0 },
|
||||
.{ axis.x(), axis.y(), axis.z(), 1 },
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/// Make a translation between the given matrix and the given axis.
|
||||
|
|
@ -217,13 +218,14 @@ pub fn Mat4x4(comptime T: type) type {
|
|||
}
|
||||
|
||||
pub fn fromScale(axis: Vector3) Self {
|
||||
var result = Self.identity();
|
||||
|
||||
result.data[0][0] = axis.x();
|
||||
result.data[1][1] = axis.y();
|
||||
result.data[2][2] = axis.z();
|
||||
|
||||
return result;
|
||||
return .{
|
||||
.data = .{
|
||||
.{ axis.x(), 0, 0, 0 },
|
||||
.{ 0, axis.y(), 0, 0 },
|
||||
.{ 0, 0, axis.z(), 0 },
|
||||
.{ 0, 0, 0, 1 },
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
pub fn scale(self: Self, axis: Vector3) Self {
|
||||
|
|
@ -243,18 +245,17 @@ pub fn Mat4x4(comptime T: type) type {
|
|||
/// Note: Field of view is given in degrees.
|
||||
/// Also for more details https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/gluPerspective.xml.
|
||||
pub fn perspective(fovy_in_degrees: T, aspect_ratio: T, z_near: T, z_far: T) Self {
|
||||
var result = Self.identity();
|
||||
|
||||
const f = 1 / @tan(root.toRadians(fovy_in_degrees) * 0.5);
|
||||
const nf = 1 / (z_near - z_far);
|
||||
|
||||
result.data[0][0] = f / aspect_ratio;
|
||||
result.data[1][1] = f;
|
||||
result.data[2][2] = (z_near + z_far) / (z_near - z_far);
|
||||
result.data[2][3] = -1;
|
||||
result.data[3][2] = 2 * z_far * z_near / (z_near - z_far);
|
||||
result.data[3][3] = 0;
|
||||
|
||||
return result;
|
||||
return .{
|
||||
.data = .{
|
||||
.{ f / aspect_ratio, 0, 0, 0 },
|
||||
.{ 0, f, 0, 0 },
|
||||
.{ 0, 0, (z_near + z_far) * nf, -1 },
|
||||
.{ 0, 0, 2 * z_near * z_far * nf, 0 },
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/// Construct a perspective 4x4 matrix with reverse Z and infinite far plane.
|
||||
|
|
@ -262,18 +263,16 @@ pub fn Mat4x4(comptime T: type) type {
|
|||
/// Also for more details https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/gluPerspective.xml.
|
||||
/// For Reversed-Z details https://nlguillemot.wordpress.com/2016/12/07/reversed-z-in-opengl/
|
||||
pub fn perspectiveReversedZ(fovy_in_degrees: T, aspect_ratio: T, z_near: T) Self {
|
||||
var result = Self.identity();
|
||||
|
||||
const f = 1 / @tan(root.toRadians(fovy_in_degrees) * 0.5);
|
||||
|
||||
result.data[0][0] = f / aspect_ratio;
|
||||
result.data[1][1] = f;
|
||||
result.data[2][2] = 0;
|
||||
result.data[2][3] = -1;
|
||||
result.data[3][2] = z_near;
|
||||
result.data[3][3] = 0;
|
||||
|
||||
return result;
|
||||
return .{
|
||||
.data = .{
|
||||
.{ f / aspect_ratio, 0, 0, 0 },
|
||||
.{ 0, f, 0, 0 },
|
||||
.{ 0, 0, 0, -1 },
|
||||
.{ 0, 0, z_near, 0 },
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/// Construct an orthographic 4x4 matrix.
|
||||
|
|
@ -440,45 +439,31 @@ pub fn Mat4x4(comptime T: type) type {
|
|||
};
|
||||
}
|
||||
|
||||
/// Print the 4x4 to stderr.
|
||||
pub fn debugPrint(self: Self) void {
|
||||
const print = std.debug.print;
|
||||
pub fn format(
|
||||
self: Self,
|
||||
comptime fmt: []const u8,
|
||||
options: std.fmt.FormatOptions,
|
||||
writer: anytype,
|
||||
) !void {
|
||||
_ = fmt;
|
||||
_ = options;
|
||||
|
||||
print("({d}, {d}, {d}, {d})\n", .{
|
||||
self.data[0][0],
|
||||
self.data[1][0],
|
||||
self.data[2][0],
|
||||
self.data[3][0],
|
||||
});
|
||||
|
||||
print("({d}, {d}, {d}, {d})\n", .{
|
||||
self.data[0][1],
|
||||
self.data[1][1],
|
||||
self.data[2][1],
|
||||
self.data[3][1],
|
||||
});
|
||||
|
||||
print("({d}, {d}, {d}, {d})\n", .{
|
||||
self.data[0][2],
|
||||
self.data[1][2],
|
||||
self.data[2][2],
|
||||
self.data[3][2],
|
||||
});
|
||||
|
||||
print("({d}, {d}, {d}, {d})\n", .{
|
||||
self.data[0][3],
|
||||
self.data[1][3],
|
||||
self.data[2][3],
|
||||
self.data[3][3],
|
||||
for (0..4) |i| {
|
||||
try writer.print("({d:.2}, {d:.2}, {d:.2}, {d:.2})\n", .{
|
||||
self.data[0][i],
|
||||
self.data[1][i],
|
||||
self.data[2][i],
|
||||
self.data[3][i],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// Cast a type to another type.
|
||||
/// It's like builtins: @intCast, @floatCast, @floatFromInt, @intFromFloat.
|
||||
pub fn cast(self: Self, comptime dest_type: type) Mat4x4(dest_type) {
|
||||
const dest_info = @typeInfo(dest_type);
|
||||
|
||||
if (dest_info != .Float) {
|
||||
if (dest_info != .float) {
|
||||
std.debug.panic("Error, dest type should be float.\n", .{});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ pub const Quat_f64 = Quaternion(f64);
|
|||
|
||||
/// A Quaternion for 3D rotations.
|
||||
pub fn Quaternion(comptime T: type) type {
|
||||
if (@typeInfo(T) != .Float) {
|
||||
if (@typeInfo(T) != .float) {
|
||||
@compileError("Quaternion not implemented for " ++ @typeName(T));
|
||||
}
|
||||
|
||||
|
|
@ -145,7 +145,7 @@ pub fn Quaternion(comptime T: type) type {
|
|||
}
|
||||
|
||||
/// Convert given quaternion to rotation 3x3 matrix.
|
||||
fn toMat3(self: Self) Mat3x3(T) {
|
||||
pub fn toMat3(self: Self) Mat3x3(T) {
|
||||
var result: Mat3x3(T) = undefined;
|
||||
|
||||
const normalized = self.norm();
|
||||
|
|
@ -378,7 +378,7 @@ pub fn Quaternion(comptime T: type) type {
|
|||
pub fn cast(self: Self, comptime dest_type: type) Quaternion(dest_type) {
|
||||
const dest_info = @typeInfo(dest_type);
|
||||
|
||||
if (dest_info != .Float) {
|
||||
if (dest_info != .float) {
|
||||
std.debug.panic("Error, dest type should be float.\n", .{});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ pub fn windowOpen(entry: *igutils.MenuEntry, dt: f64) void {
|
|||
ig.textSlice(slice);
|
||||
}
|
||||
|
||||
if (core.getEngineObject(core.EcsRegistry)) |ecsReg| {
|
||||
if (core.getEngineObject(core.ecs.EcsRegistry)) |ecsReg| {
|
||||
ig.separator();
|
||||
|
||||
for (ecsReg.containerNames.items, 0..) |*name, i| {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
allocator: std.mem.Allocator,
|
||||
|
||||
lastUpdateFrame: u64 = 0,
|
||||
arena: std.heap.ArenaAllocator,
|
||||
bodyIds: std.ArrayList(physics.BodyId),
|
||||
|
||||
pub var NeonObjectTable = core.EngineObjectVTable.from(@This(), "extras.PhysicsObjectList");
|
||||
|
|
@ -11,8 +10,7 @@ pub fn create(allocator: std.mem.Allocator) !*@This() {
|
|||
|
||||
self.* = .{
|
||||
.allocator = allocator,
|
||||
.arena = std.heap.ArenaAllocator.init(allocator),
|
||||
.bodyIds = std.ArrayList(physics.BodyId).init(allocator),
|
||||
.bodyIds = std.ArrayList(physics.BodyId){},
|
||||
};
|
||||
|
||||
if (core.getEngineObject(igutils.TopBar)) |topbar| {
|
||||
|
|
@ -27,7 +25,7 @@ pub fn windowOpen(entry: *igutils.MenuEntry, dt: f64) void {
|
|||
const self: *@This() = @ptrCast(@alignCast(entry.ctx));
|
||||
self.bodyIds.clearRetainingCapacity();
|
||||
|
||||
physics.context().system.getBodyIds(&self.bodyIds) catch return;
|
||||
physics.context().system.getBodyIds(self.allocator, &self.bodyIds) catch return;
|
||||
|
||||
if (ig.begin("Physics Objects", &entry.open, .{})) {
|
||||
ig.textf("total Physics Objects count: {d}", .{self.bodyIds.items.len});
|
||||
|
|
@ -39,8 +37,7 @@ pub fn windowOpen(entry: *igutils.MenuEntry, dt: f64) void {
|
|||
}
|
||||
|
||||
pub fn destroy(self: *@This()) void {
|
||||
self.arena.deinit();
|
||||
self.bodyIds.deinit();
|
||||
self.bodyIds.deinit(self.allocator);
|
||||
self.allocator.destroy(self);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ pub fn setup(self: *@This()) void {
|
|||
pub fn windowOpen(entry: *igu.MenuEntry, dt: f64) void {
|
||||
const self: *@This() = @ptrCast(@alignCast(entry.ctx));
|
||||
|
||||
core.rollingAverage(&self.dtAverage, dt, 50);
|
||||
core.math.rollingAverage(&self.dtAverage, dt, 50);
|
||||
|
||||
if (ig.begin("renderer debug", null, .{})) {
|
||||
if (self.dtAverage > 0.000001) {
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ pub fn Browser(comptime T: type) type {
|
|||
const self = try allocator.create(@This());
|
||||
|
||||
self.* = .{
|
||||
.browserName = try std.fmt.allocPrintZ(allocator, "Browser", .{}),
|
||||
.browserName = try std.fmt.allocPrintSentinel(allocator, "Browser", .{}, 0),
|
||||
.allocator = allocator,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -57,7 +57,10 @@ pub fn setPosition(self: *@This(), position: core.Vectorf) void {
|
|||
}
|
||||
|
||||
pub fn getPosition(self: *@This()) core.Vectorf {
|
||||
return self.camera.fetch(core.Scene).?.getPosition();
|
||||
if (self.camera.fetch(core.Scene)) |scene| {
|
||||
return scene.getPosition();
|
||||
}
|
||||
return .{};
|
||||
}
|
||||
|
||||
// movement value can be sourced from a mouse binding that has enableMouseRelative() on
|
||||
|
|
|
|||
|
|
@ -555,10 +555,6 @@ pub fn SparseSetAdvanced(comptime T: type, comptime SparseSize: u32) type {
|
|||
self.dense.deinit(self.allocator);
|
||||
}
|
||||
|
||||
pub fn denseList(self: @This()) []const T {
|
||||
return self.dense.items;
|
||||
}
|
||||
|
||||
pub const EcsContainerInterfaceVTable = EcsContainerInterface.Implement(@This());
|
||||
|
||||
pub fn handleExists(self: @This(), handle: SetHandle) bool {
|
||||
|
|
|
|||
|
|
@ -48,8 +48,7 @@ pub fn build(b: *std.Build) void {
|
|||
) orelse true,
|
||||
};
|
||||
|
||||
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
||||
_ = static_build;
|
||||
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse true;
|
||||
|
||||
const user_extensions = b.option(
|
||||
[]const std.Build.LazyPath,
|
||||
|
|
@ -74,14 +73,14 @@ pub fn build(b: *std.Build) void {
|
|||
|
||||
const joltc = b.addLibrary(.{
|
||||
.name = "joltc",
|
||||
.linkage = if (options.shared) .dynamic else .static,
|
||||
.linkage = if (!static_build) .dynamic else .static,
|
||||
.root_module = b.createModule(.{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
}),
|
||||
});
|
||||
|
||||
if (options.shared and target.result.os.tag == .windows)
|
||||
if (!static_build and target.result.os.tag == .windows)
|
||||
joltc.root_module.addCMacro("JPC_API", "extern __declspec(dllexport)");
|
||||
|
||||
b.installArtifact(joltc);
|
||||
|
|
|
|||
BIN
projects/content/meshes/fpsArms_magnum.fbx (Stored with Git LFS)
BIN
projects/content/meshes/fpsArms_magnum.fbx (Stored with Git LFS)
Binary file not shown.
|
|
@ -111,7 +111,7 @@ pub fn testThing(self: *@This()) !void {
|
|||
core.setBarrierCount(workerCount);
|
||||
|
||||
for (0..workerCount) |i| {
|
||||
const name = try std.fmt.allocPrintZ(std.heap.c_allocator, "MultiJob{d}", .{i});
|
||||
const name = try std.fmt.allocPrintSentinel(std.heap.c_allocator, "MultiJob{d}", .{i}, 0);
|
||||
try core.dispatchJob(MultiJob{ .threadName = name, .threadId = @intCast(i) });
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ pub const ExternGameObject = struct {
|
|||
}
|
||||
|
||||
// change this into a parallel for
|
||||
for (0..300) |i| {
|
||||
for (0..1) |i| {
|
||||
_ = try core.get(core.GameObjectSystem).spawnObject(BoxObject, "Box", .{
|
||||
.posRot = .{
|
||||
.position = .{ .x = core.itof32((i % 10)) * 2, .y = 15.0, .z = core.itof32(@divFloor(i, 10) * 2) },
|
||||
|
|
|
|||
|
|
@ -494,7 +494,7 @@ pub fn deinit(self: *@This()) void {
|
|||
|
||||
pub fn main() anyerror!void {
|
||||
var spec = try backlog.getSpec("sampleGame");
|
||||
// try spec.put("useGPA", .{ .boolean = false });
|
||||
try spec.put("useGPA", .{ .boolean = true });
|
||||
_ = backlog.startEngine(&NeonObjectTable, &spec);
|
||||
|
||||
// try backlog.initializeAndRunStandardProgram(@This(), .{
|
||||
|
|
|
|||
|
|
@ -225,7 +225,7 @@ fn loadFileAllocFromCwd(allocator: std.mem.Allocator, dir: std.fs.Dir, path: []c
|
|||
const filesize = (try file.stat()).size + 1; // add null byte
|
||||
const buffer: []u8 = try allocator.alloc(u8, filesize);
|
||||
errdefer allocator.free(buffer);
|
||||
try file.reader().readNoEof(buffer[0 .. buffer.len - 1]);
|
||||
_ = try file.read(buffer[0 .. buffer.len - 1]);
|
||||
buffer[buffer.len - 1] = 0;
|
||||
return buffer;
|
||||
}
|
||||
|
|
@ -295,11 +295,8 @@ fn writeBuildZigFiles(self: *@This()) !void {
|
|||
fn writeBuildZig(self: *@This(), workingDir: *std.fs.Dir) !void {
|
||||
const out_path = "build.zig";
|
||||
|
||||
var content = std.ArrayList(u8).init(self.allocator);
|
||||
defer content.deinit();
|
||||
|
||||
var writer = content.writer();
|
||||
|
||||
var content = std.ArrayList(u8){};
|
||||
defer content.deinit(self.allocator);
|
||||
const template =
|
||||
\\ const std = @import("std");
|
||||
\\ const Backlog = @import("Backlog");
|
||||
|
|
@ -315,7 +312,7 @@ fn writeBuildZig(self: *@This(), workingDir: *std.fs.Dir) !void {
|
|||
\\ }});
|
||||
;
|
||||
|
||||
try writer.print(template, .{self.engineRelative.?});
|
||||
try content.print(self.allocator, template, .{self.engineRelative.?});
|
||||
|
||||
const template2 =
|
||||
\\ const program = blbuild.program(.{{
|
||||
|
|
@ -330,9 +327,9 @@ fn writeBuildZig(self: *@This(), workingDir: *std.fs.Dir) !void {
|
|||
\\ }}
|
||||
;
|
||||
|
||||
try writer.print(template2, .{self.targetName.?});
|
||||
try content.print(self.allocator, template2, .{self.targetName.?});
|
||||
|
||||
try writer.writeByte(0);
|
||||
try content.append(self.allocator, 0);
|
||||
|
||||
try self.writeZigFile(workingDir, out_path, content.items);
|
||||
}
|
||||
|
|
@ -348,13 +345,12 @@ const entries: []const struct { name: []const u8, path: []const u8 } = &.{
|
|||
};
|
||||
|
||||
fn writeBuildZigZon(self: *@This(), workingDir: *std.fs.Dir) !void {
|
||||
var content = std.ArrayList(u8).init(self.allocator);
|
||||
defer content.deinit();
|
||||
var content = std.ArrayList(u8){};
|
||||
defer content.deinit(self.allocator);
|
||||
|
||||
var writer = content.writer();
|
||||
try writer.print(".{{\n", .{});
|
||||
try content.print(self.allocator, ".{{\n", .{});
|
||||
|
||||
try writer.print(
|
||||
try content.print(self.allocator,
|
||||
\\ .name = .{s},
|
||||
\\ .version = "0.0.0",
|
||||
\\ .dependencies = .{{
|
||||
|
|
@ -362,34 +358,35 @@ fn writeBuildZigZon(self: *@This(), workingDir: *std.fs.Dir) !void {
|
|||
, .{ std.fs.path.basename(self.targetDir.?), self.engineRelative.? });
|
||||
|
||||
for (entries) |entry| {
|
||||
try writer.print(" .{s} = .{{ .path = \"{s}/{s}\" }},\n", .{ entry.name, self.engineRelative.?, entry.path });
|
||||
try content.print(self.allocator, " .{s} = .{{ .path = \"{s}/{s}\" }},\n", .{ entry.name, self.engineRelative.?, entry.path });
|
||||
}
|
||||
|
||||
try writer.print(
|
||||
try content.print(self.allocator,
|
||||
\\ }},
|
||||
\\
|
||||
, .{});
|
||||
|
||||
try writer.print(
|
||||
try content.print(self.allocator,
|
||||
\\ .paths = .{{ "" }},
|
||||
\\
|
||||
, .{});
|
||||
|
||||
try writer.print(
|
||||
try content.print(self.allocator,
|
||||
\\ .fingerprint = {s},
|
||||
\\
|
||||
, .{self.fingerprint.?});
|
||||
|
||||
try writer.print("}}", .{});
|
||||
try content.print(self.allocator, "}}", .{});
|
||||
|
||||
const file = try workingDir.createFile("build.zig.zon", .{});
|
||||
defer file.close();
|
||||
try file.writeAll(content.items);
|
||||
var writer = file.writer(&wbuf);
|
||||
try writer.interface.writeAll(content.items);
|
||||
}
|
||||
|
||||
fn writeMainZig(self: *@This(), workingDir: *std.fs.Dir) !void {
|
||||
var content = std.ArrayList(u8).init(self.allocator);
|
||||
defer content.deinit();
|
||||
var content = std.ArrayList(u8){};
|
||||
defer content.deinit(self.allocator);
|
||||
|
||||
const template =
|
||||
\\ pub var NeonObjectTable = core.EngineObjectVTable.from(@This(), "main");
|
||||
|
|
@ -435,10 +432,11 @@ fn writeMainZig(self: *@This(), workingDir: *std.fs.Dir) !void {
|
|||
\\
|
||||
;
|
||||
|
||||
try content.appendSlice(template);
|
||||
try content.appendSlice(self.targetName.?);
|
||||
try content.appendSlice(template2);
|
||||
try content.append(0);
|
||||
const allocator = self.allocator;
|
||||
try content.appendSlice(allocator, template);
|
||||
try content.appendSlice(allocator, self.targetName.?);
|
||||
try content.appendSlice(allocator, template2);
|
||||
try content.append(allocator, 0);
|
||||
|
||||
const out_path = "src/main.zig";
|
||||
|
||||
|
|
@ -447,15 +445,17 @@ fn writeMainZig(self: *@This(), workingDir: *std.fs.Dir) !void {
|
|||
try self.writeZigFile(workingDir, out_path, content.items);
|
||||
}
|
||||
|
||||
var wbuf: [4096]u8 = undefined;
|
||||
fn writeZigFile(self: *@This(), workingDir: *std.fs.Dir, out_path: []const u8, contents: []const u8) !void {
|
||||
var ast = try std.zig.Ast.parse(self.allocator, @as([:0]const u8, @ptrCast(contents[0 .. contents.len - 1])), .zig);
|
||||
|
||||
defer ast.deinit(self.allocator);
|
||||
const out = try ast.render(self.allocator);
|
||||
const out = try ast.renderAlloc(self.allocator);
|
||||
|
||||
const file = try workingDir.createFile(out_path, .{});
|
||||
defer file.close();
|
||||
try file.writeAll(out);
|
||||
var fw = file.writer(&wbuf);
|
||||
try fw.interface.writeAll(out);
|
||||
}
|
||||
|
||||
fn updateFingerPrint(self: *@This(), zonEntry: []const u8) void {
|
||||
|
|
|
|||
|
|
@ -107,8 +107,8 @@ fn findRootDir(allocator: std.mem.Allocator) ![]u8 {
|
|||
var current_dir = std.fs.cwd();
|
||||
|
||||
// Start from current directory and walk up
|
||||
var path_components = std.ArrayList([]const u8).init(allocator);
|
||||
defer path_components.deinit();
|
||||
var path_components = std.ArrayList([]const u8){};
|
||||
defer path_components.deinit(allocator);
|
||||
|
||||
// Try current directory first
|
||||
current_dir.access("content.txt", .{}) catch {
|
||||
|
|
|
|||
Loading…
Reference in New Issue