diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/geom.zig | 36 | ||||
-rw-r--r-- | src/main.zig | 14 | ||||
-rw-r--r-- | src/misc.zig | 56 |
3 files changed, 51 insertions, 55 deletions
diff --git a/src/geom.zig b/src/geom.zig index c84d2aa..af6bd21 100644 --- a/src/geom.zig +++ b/src/geom.zig @@ -30,7 +30,7 @@ fn dot(u: anytype, v: @TypeOf(u)) Child(@TypeOf(u)) { } export fn sqrlen(v: XYZ) f32 { - const u = @bitCast(@Vector(3, f32), v); + const u: @Vector(3, f32) = @bitCast(v); return dot(u, u); } @@ -39,7 +39,7 @@ fn norm(v: anytype) Child(@TypeOf(v)) { } export fn len(v: XYZ) f32 { - const u = @bitCast(@Vector(3, f32), v); + const u: @Vector(3, f32) = @bitCast(v); return norm(u); } @@ -53,16 +53,20 @@ export fn crossProduct(u: XYZ, v: XYZ) XYZ { }; } +inline fn splat(x: f32) @Vector(3, f32) { + return @splat(x); +} + export fn normalize(v: XYZ) XYZ { - const u = @bitCast(@Vector(3, f32), v); + const u: @Vector(3, f32) = @bitCast(v); const d = norm(u); - return if (d == 0) v else @bitCast(XYZ, u / @splat(3, d)); + return if (d == 0) v else @bitCast(u / splat(d)); } export fn reflect(v: XYZ, n: XYZ) XYZ { - const u = @bitCast(@Vector(3, f32), v); - const m = @bitCast(@Vector(3, f32), n); - return @bitCast(XYZ, u - m * @splat(3, dot(u, m) * 2)); + const u: @Vector(3, f32) = @bitCast(v); + const m: @Vector(3, f32) = @bitCast(n); + return @bitCast(u - m * splat(dot(u, m) * 2)); } fn rotate2d(i: *f32, j: *f32, a: f32) void { @@ -84,15 +88,15 @@ export fn rotate(v: XYZ, deg_x: f32, deg_y: f32, deg_z: f32) XYZ { export fn segmentIntersectsSphere(a: XYZ, b: XYZ, i: XYZ, r: f32) bool { // FIXME: call directly with vectors - const p = @bitCast(@Vector(3, f32), a); - const q = @bitCast(@Vector(3, f32), b); - const c = @bitCast(@Vector(3, f32), i); + const p: @Vector(3, f32) = @bitCast(a); + const q: @Vector(3, f32) = @bitCast(b); + const c: @Vector(3, f32) = @bitCast(i); - if (@reduce(.Or, @max(p, q) < c - @splat(3, r))) return false; - if (@reduce(.Or, @min(p, q) > c + @splat(3, r))) return false; + if (@reduce(.Or, @max(p, q) < c - splat(r))) return false; + if (@reduce(.Or, @min(p, q) > c + splat(r))) return false; // https://en.wikipedia.org/wiki/Line–sphere_intersection const d = q - p; // line's direction - const u = d / @splat(3, norm(d)); // unit vector + const u = d / splat(norm(d)); // unit vector return sqr(dot(u, (p - c))) >= @reduce(.Add, sqr(p - c)) - sqr(r); } @@ -242,8 +246,7 @@ export fn setFrustum(frustum: [*][4]f32, p: [*]const f32, export fn cubeInFrustum(frustum: [*][4]f32, x: f32, y: f32, z: f32, size: f32) bool { const delta = [_]f32{ -size, size }; - var i = @as(u8, 0); - loop: while (i < 6) : (i += 1) { + loop: for (0..6) |i| { for (delta) |dx| for (delta) |dy| for (delta) |dz| if (frustum[i][0] * (x + dx) + frustum[i][1] * (y + dy) + frustum[i][2] * (z + dz) + frustum[i][3] > 0) continue :loop; @@ -254,8 +257,7 @@ export fn cubeInFrustum(frustum: [*][4]f32, export fn sphereInFrustum(frustum: [*][4]f32, x: f32, y: f32, z: f32, r: f32) bool { - var i = @as(u8, 0); - while (i < 6) : (i += 1) + for (0..6) |i| if (frustum[i][0] * x + frustum[i][1] * y + frustum[i][2] * z + frustum[i][3] <= -r) return false; diff --git a/src/main.zig b/src/main.zig index 49f2b49..b44b592 100644 --- a/src/main.zig +++ b/src/main.zig @@ -49,7 +49,7 @@ fn handleKey(window: gf.Window, key: gf.Key, scancode: c_int, action: gf.KeyAction, mods: gf.Mods) void { _ = window; _ = scancode; - c.handleKey(game, @enumToInt(key), @enumToInt(action), mods.toInt()); + c.handleKey(game, @intFromEnum(key), @intFromEnum(action), mods.toInt()); } fn look(window: gf.Window, xpos: f64, ypos: f64) void { @@ -60,7 +60,7 @@ fn look(window: gf.Window, xpos: f64, ypos: f64) void { fn click(window: gf.Window, button: gf.MouseButton, action: gf.MouseButton.Action, mods: gf.Mods) void { _ = window; - c.click(game, @enumToInt(button), @enumToInt(action), mods.toInt()); + c.click(game, @intFromEnum(button), @intFromEnum(action), mods.toInt()); } /// Return a floating point value evenly distributed in the range [0, 1). @@ -92,14 +92,14 @@ pub fn main() !void { "Black Shades", .{}, .{}); try window.makeCurrent(); - prng = DefaultPrng.init(@bitCast(u64, try gf.getTime())); - game = c.makeGame(@bitCast(c.Config, config), - @bitCast(c.Scores, try loadScores(loca.user_data))).?; - defer saveScores(loca.user_data, @bitCast(Scores, c.getScores(game))) + prng = DefaultPrng.init(@bitCast(try gf.getTime())); + game = c.makeGame(@bitCast(config), + @bitCast(try loadScores(loca.user_data))).?; + defer saveScores(loca.user_data, @bitCast(c.getScores(game))) catch unreachable; try window.setSizeCallback(resizeWindow); - try gf.swapInterval(@boolToInt(config.vsync)); + try gf.swapInterval(@intFromBool(config.vsync)); c.initGl(game); if (try gf.rawMouseMotionSupported()) diff --git a/src/misc.zig b/src/misc.zig index 6f1d893..ebec4ef 100644 --- a/src/misc.zig +++ b/src/misc.zig @@ -18,7 +18,7 @@ // along with Black Shades. If not, see <https://www.gnu.org/licenses/>. const Dir = std.fs.Dir; -const TokenIterator = std.mem.TokenIterator(u8); +const TokenIterator = std.mem.TokenIterator(u8, .scalar); const allocPrint = std.fmt.allocPrint; const allocator = std.heap.c_allocator; const assert = std.debug.assert; @@ -36,7 +36,7 @@ const sep = std.fs.path.sep; const span = std.mem.span; const startsWith = std.mem.startsWith; const std = @import("std"); -const tokenize = std.mem.tokenize; +const tokenizeScalar = std.mem.tokenizeScalar; const al = @import("zeal"); const gf = @import("gfz"); @@ -49,7 +49,7 @@ const c = @import("cimport.zig"); /// Return whether the given keyboard key is pressed. export fn keyPress(key: c_int) bool { const window = (gf.Window.getCurrent() catch unreachable).?; - return (window.getKey(@intToEnum(gf.Key, key)) catch unreachable) == .press; + return (window.getKey(@enumFromInt(key)) catch unreachable) == .press; } /// Read given file to heap, allocated by C allocator. @@ -80,22 +80,22 @@ export fn loadAnimation(name: [*:0]const u8) extern struct { }) catch unreachable; defer allocator.free(anim_file); const length = count(u8, anim_file, "\t") - 1; - var anim = tokenize(u8, anim_file, "\n"); + var anim = tokenizeScalar(u8, anim_file, '\n'); _ = anim.next().?; // ignore field names const frames = allocator.alloc(Frame, length) catch unreachable; for (frames) |*frame| { - var values = tokenize(u8, anim.next().?, "\t"); + var values = tokenizeScalar(u8, anim.next().?, '\t'); const frame_file = readFile(dir, "{s}{c}frames{c}{s}.tsv", .{ name, sep, sep, values.next().?, // $animation/frames/$frame.tsv }) catch unreachable; defer allocator.free(frame_file); frame.speed = parseFloat(f32, values.next().?) catch unreachable; - var joints = tokenize(u8, frame_file, "\n"); + var joints = tokenizeScalar(u8, frame_file, '\n'); _ = joints.next().?; // ignore field names - for (frame.joints) |*joint| { - var coordinates = tokenize(u8, joints.next().?, "\t"); + for (&frame.joints) |*joint| { + var coordinates = tokenizeScalar(u8, joints.next().?, '\t'); joint.* = .{ .x = parseFloat(f32, coordinates.next().?) catch unreachable, .y = parseFloat(f32, coordinates.next().?) catch unreachable, @@ -126,7 +126,7 @@ const Joint = extern struct { parent: i8, pub fn load(self: *Joint, row: []const u8) !void { - var values = tokenize(u8, row, "\t"); + var values = tokenizeScalar(u8, row, '\t'); self.x = try parseFloat(f32, values.next().?); self.y = try parseFloat(f32, values.next().?); self.z = try parseFloat(f32, values.next().?); @@ -143,7 +143,7 @@ export fn loadJoints(joints: [*]Joint) void { const file = readFile(cwd(), data_dir ++ "joints.tsv", .{}) catch unreachable; defer allocator.free(file); - var tsv = tokenize(u8, file, "\n"); + var tsv = tokenizeScalar(u8, file, '\n'); _ = tsv.next().?; // ignore field names var i = @as(u8, 0); while (tsv.next()) |row| : (i += 1) @@ -164,7 +164,7 @@ const OffIterator = struct { token_iterator: TokenIterator, pub fn init(buffer: []const u8) OffIterator { - var self = .{ .token_iterator = tokenize(u8, buffer, "\n") }; + var self = .{ .token_iterator = tokenizeScalar(u8, buffer, '\n') }; if (!endsWith(u8, self.token_iterator.next().?, "OFF")) self.token_iterator.reset(); return self; @@ -172,7 +172,7 @@ const OffIterator = struct { pub fn next(self: *OffIterator) ?TokenIterator { while (self.token_iterator.next()) |line| { - var words = tokenize(u8, line, " "); + var words = tokenizeScalar(u8, line, ' '); if (words.next()) |word| { // not empty if (!startsWith(u8, word, "#")) { // not comment words.reset(); @@ -247,7 +247,7 @@ const Muscle = extern struct { parent2: i8, pub fn load(self: *Muscle, row: []const u8) !void { - var values = tokenize(u8, row, "\t"); + var values = tokenizeScalar(u8, row, '\t'); self.length = try parseFloat(f32, values.next().?); self.initlen = try parseFloat(f32, values.next().?); self.minlen = try parseFloat(f32, values.next().?); @@ -264,7 +264,7 @@ export fn loadMuscles(muscles: [*]Muscle) void { const file = readFile(cwd(), data_dir ++ "muscles.tsv", .{}) catch unreachable; defer allocator.free(file); - var tsv = tokenize(u8, file, "\n"); + var tsv = tokenizeScalar(u8, file, '\n'); _ = tsv.next().?; // ignore field names var i = @as(u8, 0); while (tsv.next()) |row| : (i += 1) @@ -306,7 +306,7 @@ export fn loadSound(filename: [*:0]const u8) u32 { const path = join(allocator, &.{ data_dir ++ "sounds", span(filename) }) catch unreachable; defer allocator.free(path); - const audio = al.Audio.read(allocator, span(path)) catch unreachable; + const audio = al.Audio.read(allocator, path) catch unreachable; defer audio.free(); const buffer = al.Buffer.init(audio) catch unreachable; return buffer.reference; @@ -315,7 +315,7 @@ export fn loadSound(filename: [*:0]const u8) u32 { fn check(comptime errorString: fn (c_uint) callconv(.C) [*c]const u8, status: anytype) void { if (status != 0) - @panic(span(errorString(@intCast(c_uint, status)))); + @panic(span(errorString(@intCast(status)))); } /// Load PNG file into an OpenGL buffer and return it. @@ -327,7 +327,7 @@ export fn loadTexture(filename: [*:0]const u8) u32 { var image = qoi.decodeBuffer(allocator, file) catch unreachable; defer image.deinit(allocator); - const data = @ptrCast([*c]const u8, image.pixels.ptr); + const data: [*c]const u8 = @ptrCast(image.pixels.ptr); var texture: u32 = undefined; c.glGenTextures(1, &texture); @@ -337,8 +337,8 @@ export fn loadTexture(filename: [*:0]const u8) u32 { c.glTexParameteri(c.GL_TEXTURE_2D, c.GL_TEXTURE_MAG_FILTER, c.GL_LINEAR); c.glTexParameteri(c.GL_TEXTURE_2D, c.GL_TEXTURE_MIN_FILTER, c.GL_LINEAR); - const width = @intCast(i32, image.width); - const height = @intCast(i32, image.height); + const width: i32 = @intCast(image.width); + const height: i32 = @intCast(image.height); c.glPixelStorei(c.GL_UNPACK_ALIGNMENT, 1); c.glTexImage2D(c.GL_TEXTURE_2D, 0, 4, width, height, 0, c.GL_RGBA, c.GL_UNSIGNED_BYTE, data); @@ -356,11 +356,6 @@ export fn playSound(source: u32, x: f32, y: f32, z: f32) void { src.play() catch unreachable; } -// TODO: replace with @maximum from Zig 0.9+ -fn maximum(a: anytype, b: @TypeOf(a)) @TypeOf(a) { - return if (a > b) a else b; -} - /// Write scores to user data directory. pub fn saveScores(base_dir: []const u8, current: Scores) !void { const previous = try loadScores(base_dir); @@ -370,7 +365,7 @@ pub fn saveScores(base_dir: []const u8, current: Scores) !void { defer dir.close(); const format = "[scores]\nhigh score = {}\ncompleted = {}\n"; const data = try allocPrint(allocator, format, .{ - maximum(previous.high_score, current.high_score), + @max(previous.high_score, current.high_score), previous.completed or current.completed, }); defer allocator.free(data); @@ -385,12 +380,11 @@ const Text = struct { export fn buildFont(text: *Text) void { text.base = c.glGenLists(256); c.glBindTexture(c.GL_TEXTURE_2D, text.texture); - var i = @as(u16, 0); - while (i < 256) : (i += 1) { + for (0..256) |i| { // Character coords - const x = @intToFloat(f32, i % 16) / 16.0; - const y = @intToFloat(f32, i / 16) / 16.0; - c.glNewList(text.base + i, c.GL_COMPILE); + const x = @as(f32, @floatFromInt(i % 16)) / 16.0; + const y = @as(f32, @floatFromInt(i / 16)) / 16.0; + c.glNewList(@intCast(text.base + i), c.GL_COMPILE); // Use A Quad For Each Character c.glBegin(c.GL_QUADS); // Bottom left @@ -437,7 +431,7 @@ export fn glPrint(text: *const Text, x: f64, y: f64, str: [*:0]const u8, else c.glListBase(text.base -% 32); // Write to screen - c.glCallLists(@intCast(c_int, len(str)), c.GL_BYTE, str); + c.glCallLists(@intCast(len(str)), c.GL_BYTE, str); // Restore c.glMatrixMode(c.GL_PROJECTION); |