diff options
Diffstat (limited to 'src/misc.zig')
-rw-r--r-- | src/misc.zig | 98 |
1 files changed, 95 insertions, 3 deletions
diff --git a/src/misc.zig b/src/misc.zig index 353dcac..f4021ac 100644 --- a/src/misc.zig +++ b/src/misc.zig @@ -27,15 +27,98 @@ const al = @import("zeal"); const allocator = std.heap.c_allocator; const cwd = std.fs.cwd; const data_dir = @import("build_options").data_dir ++ [_]u8{ sep }; +const eql = std.mem.eql; const free = std.c.free; const join = std.fs.path.joinZ; const maxInt = std.math.maxInt; +const parseFloat = std.fmt.parseFloat; +const parseInt = std.fmt.parseInt; const sep = std.fs.path.sep; const span = std.mem.span; const std = @import("std"); +const tokenize = std.mem.tokenize; + +/// Parse boolean values. +pub fn parseBool(s: []const u8) !bool { + if (eql(u8, s, "false")) + return false; + if (eql(u8, s, "true")) + return true; + return error.InvalidCharacter; +} + +const Joint = extern struct { + label: i8, + x: f32, + y: f32, + z: f32, + length: f32, + model: u8, + visible: bool, + lower: bool, + parent: i8, + + pub fn load(self: *Joint, row: []const u8) !void { + var values = tokenize(row, "\t"); + self.label = try parseInt(i8, values.next().?, 10); + self.x = try parseFloat(f32, values.next().?); + self.y = try parseFloat(f32, values.next().?); + self.z = try parseFloat(f32, values.next().?); + self.length = try parseFloat(f32, values.next().?); + self.model = try parseInt(u8, values.next().?, 10); + self.visible = try parseBool(values.next().?); + self.lower = try parseBool(values.next().?); + self.parent = try parseInt(i8, values.next().?, 10); + } +}; + +/// Load joints in character's frame +fn loadJoints(joints: [*]Joint) callconv(.C) void { + var tsv = tokenize(@embedFile("joints.tsv"), "\n"); + _ = tsv.next().?; // ignore field names + var i = @as(u8, 0); + while (tsv.next()) |row| { + joints[i].load(row) catch unreachable; + i += 1; + } +} + +const Muscle = extern struct { + length: f32, + initlen: f32, + minlen: f32, + maxlen: f32, + flag: bool, + visible: bool, + parent1: i8, + parent2: i8, + + pub fn load(self: *Muscle, row: []const u8) !void { + var values = tokenize(row, "\t"); + self.length = try parseFloat(f32, values.next().?); + self.initlen = try parseFloat(f32, values.next().?); + self.minlen = try parseFloat(f32, values.next().?); + self.maxlen = try parseFloat(f32, values.next().?); + self.flag = try parseBool(values.next().?); + self.visible = try parseBool(values.next().?); + self.parent1 = try parseInt(i8, values.next().?, 10); + self.parent2 = try parseInt(i8, values.next().?, 10); + } +}; + +/// Load muscles in character's frame +fn loadMuscles(muscles: [*]Muscle) callconv(.C) void { + var tsv = tokenize(@embedFile("muscles.tsv"), "\n"); + _ = tsv.next().?; // ignore field names + var i = @as(u8, 0); + while (tsv.next()) |row| { + muscles[i].load(row) catch unreachable; + i += 1; + } +} /// Load audio file into an OpenAL buffer and return it. -pub fn loadSound(filename: [*:0]const u8) callconv(.C) u32 { +fn loadSound(filename: [*:0]const u8) callconv(.C) u32 { const path = join(allocator, &.{ data_dir ++ "sounds", span(filename) }) catch unreachable; defer allocator.free(path); @@ -52,7 +135,7 @@ fn check(errorString: fn (c_uint) callconv(.C) [*c]const u8, } /// Load PNG file into an OpenGL buffer and return it. -pub fn loadTexture(filename: [*:0]const u8) callconv(.C) GLuint { +fn loadTexture(filename: [*:0]const u8) callconv(.C) GLuint { var dir = cwd().openDir(data_dir ++ "textures", .{}) catch unreachable; defer dir.close(); // Don't judge me, take care of me! @@ -86,9 +169,18 @@ pub fn loadTexture(filename: [*:0]const u8) callconv(.C) GLuint { } /// Move sound source to given position and play it. -pub fn playSound(source: u32, x: f32, y: f32, z: f32) callconv(.C) void { +fn playSound(source: u32, x: f32, y: f32, z: f32) callconv(.C) void { const src = al.Source{ .reference = source }; _ = alGetError(); // TODO: remove when completely migrate to zeal src.setPosition(.{ x / 32, y / 32, z / 32 }) catch unreachable; src.play() catch unreachable; } + +comptime { + // Work around lazy compilation. + @export(loadJoints, .{ .name = "loadJoints" }); + @export(loadMuscles, .{ .name = "loadMuscles" }); + @export(loadSound, .{ .name = "loadSound" }); + @export(loadTexture, .{ .name = "loadTexture" }); + @export(playSound, .{ .name = "playSound" }); +} |