From 32fa90eca996f9aed5da3a2f8d216f7cd565efff Mon Sep 17 00:00:00 2001 From: Stephen Gutekanst Date: Sat, 30 Oct 2021 12:04:41 -0700 Subject: [PATCH] glfw: ziggify Joystick hat bitmasks Helps hexops/mach#37 Signed-off-by: Stephen Gutekanst --- glfw/src/Joystick.zig | 39 +++++++++++++++++------------- glfw/src/hat.zig | 56 +++++++++++++++++++++++++++++++++---------- glfw/src/mod.zig | 2 +- 3 files changed, 66 insertions(+), 31 deletions(-) diff --git a/glfw/src/Joystick.zig b/glfw/src/Joystick.zig index 66fe6b80..eb5badd0 100644 --- a/glfw/src/Joystick.zig +++ b/glfw/src/Joystick.zig @@ -12,6 +12,7 @@ const getError = @import("errors.zig").getError; const Action = @import("action.zig").Action; const GamepadAxis = @import("gamepad_axis.zig").GamepadAxis; const GamepadButton = @import("gamepad_button.zig").GamepadButton; +const Hat = @import("hat.zig").Hat; const Joystick = @This(); @@ -153,25 +154,24 @@ pub inline fn getButtons(self: Joystick) Error!?[]const u8 { /// This function returns the state of all hats of the specified joystick. Each element in the array /// is one of the following values: /// -/// | Name | Value | -/// |-----------------------|-------------------------------------| -/// | `glfw.hat.centered` | 0 | -/// | `glfw.hat.u[` | 1 | -/// | `glfw.hat.right` | 2 | -/// | `glfw.hat.down` | 4 | -/// | `glfw.hat.left` | 8 | -/// | `glfw.hat.right_up` | `glfw.hat.right` \| `glfw.hat.up` | -/// | `glfw.hat.right_down` | `glfw.hat.right` \| `glfw.hat.down` | -/// | `glfw.hat.left_up` | `glfw.hat.left` \| `glfw.hat.up` | -/// | `glfw.hat.left_down` | `glfw.hat.left` \| `glfw.hat.down` | +/// | Name | Value | +/// |---------------------------|---------------------------------------------| +/// | `glfw.RawHats.centered` | 0 | +/// | `glfw.RawHats.up` | 1 | +/// | `glfw.RawHats.right` | 2 | +/// | `glfw.RawHats.down` | 4 | +/// | `glfw.RawHats.left` | 8 | +/// | `glfw.RawHats.right_up` | `glfw.RawHats.right` \| `glfw.RawHats.up` | +/// | `glfw.RawHats.right_down` | `glfw.RawHats.right` \| `glfw.RawHats.down` | +/// | `glfw.RawHats.left_up` | `glfw.RawHats.left` \| `glfw.RawHats.up` | +/// | `glfw.RawHats.left_down` | `glfw.RawHats.left` \| `glfw.RawHats.down` | /// /// The diagonal directions are bitwise combinations of the primary (up, right, down and left) -/// directions and you can test for these individually by ANDing it with the corresponding -/// direction. +/// directions, since the Zig GLFW wrapper returns a packed struct it is trivial to test for these: /// /// ``` -/// if (hats[2] & glfw.hat.right) { -/// // State of hat 2 could be right-up, right, or right-down. +/// if (hats.up and hats.right) { +/// // up-right! /// } /// ``` /// @@ -189,12 +189,13 @@ pub inline fn getButtons(self: Joystick) Error!?[]const u8 { /// @thread_safety This function must only be called from the main thread. /// /// see also: joystick_hat -pub inline fn getHats(self: Joystick) Error!?[]const u8 { +pub inline fn getHats(self: Joystick) Error!?[]const Hat { var count: c_int = undefined; const hats = c.glfwGetJoystickHats(self.jid, &count); try getError(); if (hats == null) return null; - return hats[0..@intCast(usize, count)]; + const slice = hats[0..@intCast(usize, count)]; + return @ptrCast(*const []const Hat, &slice).*; } /// Returns the name of the specified joystick. @@ -472,6 +473,10 @@ test "getHats" { const joystick = glfw.Joystick{ .jid = glfw.Joystick.one }; _ = joystick.getHats() catch |err| std.debug.print("failed to get joystick hats, joysticks not supported? error={}\n", .{err}); + const hats = std.mem.zeroes(Hat); + if (hats.down and hats.up) { + // down-up! + } } test "getName" { diff --git a/glfw/src/hat.zig b/glfw/src/hat.zig index e502b82f..069ae1e0 100644 --- a/glfw/src/hat.zig +++ b/glfw/src/hat.zig @@ -1,16 +1,46 @@ -//! Joystick hat states -//! -//! See glfw.getJoystickHats for how these are used. - const c = @import("c.zig").c; -pub const centered = c.GLFW_HAT_CENTERED; -pub const up = c.GLFW_HAT_UP; -pub const right = c.GLFW_HAT_RIGHT; -pub const down = c.GLFW_HAT_DOWN; -pub const left = c.GLFW_HAT_LEFT; +// must be in sync with GLFW C constants in hat state group, search for "@defgroup hat_state Joystick hat states" +/// A bitmask of all Joystick hat states +/// +/// See glfw.Joystick.getHats for how these are used. +pub const Hat = packed struct { + centered: bool align(@alignOf(u8)) = false, + up: bool = false, + right: bool = false, + down: bool = false, + left: bool = false, -pub const right_up = right | up; -pub const right_down = right | down; -pub const left_up = left | up; -pub const left_down = left | down; + inline fn verifyIntType(comptime IntType: type) void { + comptime { + switch (@typeInfo(IntType)) { + .Int => {}, + else => @compileError("Int was not of int type"), + } + } + } + + pub inline fn toInt(comptime IntType: type, self: Hat) IntType { + verifyIntType(IntType); + return @bitCast(IntType, self); + } + + pub inline fn fromInt(flags: anytype) Hat { + verifyIntType(@TypeOf(flags)); + return @bitCast(Hat, flags); + } +}; + +/// Holds all GLFW hat values in their raw form. +pub const RawHats = struct { + pub const centered = c.GLFW_HAT_CENTERED; + pub const up = c.GLFW_HAT_UP; + pub const right = c.GLFW_HAT_RIGHT; + pub const down = c.GLFW_HAT_DOWN; + pub const left = c.GLFW_HAT_LEFT; + + pub const right_up = right | up; + pub const right_down = right | down; + pub const left_up = left | up; + pub const left_down = left | down; +}; diff --git a/glfw/src/mod.zig b/glfw/src/mod.zig index c33bc2f0..1d2091c6 100644 --- a/glfw/src/mod.zig +++ b/glfw/src/mod.zig @@ -4,7 +4,7 @@ const c = @import("c.zig").c; -// must be in sync with https://www.glfw.org/docs/3.3/group__mods.html +// must be in sync with GLFW C constants in modifier group, search for "@defgroup mods Modifier key flags" /// A bitmask of all key modifiers pub const Mods = packed struct { shift: bool align(@alignOf(c_int)) = false,