glfw: ziggify Joystick hat bitmasks

Helps hexops/mach#37

Signed-off-by: Stephen Gutekanst <stephen@hexops.com>
This commit is contained in:
Stephen Gutekanst 2021-10-30 12:04:41 -07:00 committed by Stephen Gutekanst
parent 210e12a437
commit 32fa90eca9
3 changed files with 66 additions and 31 deletions

View file

@ -12,6 +12,7 @@ const getError = @import("errors.zig").getError;
const Action = @import("action.zig").Action; const Action = @import("action.zig").Action;
const GamepadAxis = @import("gamepad_axis.zig").GamepadAxis; const GamepadAxis = @import("gamepad_axis.zig").GamepadAxis;
const GamepadButton = @import("gamepad_button.zig").GamepadButton; const GamepadButton = @import("gamepad_button.zig").GamepadButton;
const Hat = @import("hat.zig").Hat;
const Joystick = @This(); 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 /// This function returns the state of all hats of the specified joystick. Each element in the array
/// is one of the following values: /// is one of the following values:
/// ///
/// | Name | Value | /// | Name | Value |
/// |-----------------------|-------------------------------------| /// |---------------------------|---------------------------------------------|
/// | `glfw.hat.centered` | 0 | /// | `glfw.RawHats.centered` | 0 |
/// | `glfw.hat.u[` | 1 | /// | `glfw.RawHats.up` | 1 |
/// | `glfw.hat.right` | 2 | /// | `glfw.RawHats.right` | 2 |
/// | `glfw.hat.down` | 4 | /// | `glfw.RawHats.down` | 4 |
/// | `glfw.hat.left` | 8 | /// | `glfw.RawHats.left` | 8 |
/// | `glfw.hat.right_up` | `glfw.hat.right` \| `glfw.hat.up` | /// | `glfw.RawHats.right_up` | `glfw.RawHats.right` \| `glfw.RawHats.up` |
/// | `glfw.hat.right_down` | `glfw.hat.right` \| `glfw.hat.down` | /// | `glfw.RawHats.right_down` | `glfw.RawHats.right` \| `glfw.RawHats.down` |
/// | `glfw.hat.left_up` | `glfw.hat.left` \| `glfw.hat.up` | /// | `glfw.RawHats.left_up` | `glfw.RawHats.left` \| `glfw.RawHats.up` |
/// | `glfw.hat.left_down` | `glfw.hat.left` \| `glfw.hat.down` | /// | `glfw.RawHats.left_down` | `glfw.RawHats.left` \| `glfw.RawHats.down` |
/// ///
/// The diagonal directions are bitwise combinations of the primary (up, right, down and left) /// 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 /// directions, since the Zig GLFW wrapper returns a packed struct it is trivial to test for these:
/// direction.
/// ///
/// ``` /// ```
/// if (hats[2] & glfw.hat.right) { /// if (hats.up and hats.right) {
/// // State of hat 2 could be right-up, right, or right-down. /// // 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. /// @thread_safety This function must only be called from the main thread.
/// ///
/// see also: joystick_hat /// 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; var count: c_int = undefined;
const hats = c.glfwGetJoystickHats(self.jid, &count); const hats = c.glfwGetJoystickHats(self.jid, &count);
try getError(); try getError();
if (hats == null) return null; 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. /// Returns the name of the specified joystick.
@ -472,6 +473,10 @@ test "getHats" {
const joystick = glfw.Joystick{ .jid = glfw.Joystick.one }; 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}); _ = 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" { test "getName" {

View file

@ -1,16 +1,46 @@
//! Joystick hat states
//!
//! See glfw.getJoystickHats for how these are used.
const c = @import("c.zig").c; const c = @import("c.zig").c;
pub const centered = c.GLFW_HAT_CENTERED; // must be in sync with GLFW C constants in hat state group, search for "@defgroup hat_state Joystick hat states"
pub const up = c.GLFW_HAT_UP; /// A bitmask of all Joystick hat states
pub const right = c.GLFW_HAT_RIGHT; ///
pub const down = c.GLFW_HAT_DOWN; /// See glfw.Joystick.getHats for how these are used.
pub const left = c.GLFW_HAT_LEFT; 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; inline fn verifyIntType(comptime IntType: type) void {
pub const right_down = right | down; comptime {
pub const left_up = left | up; switch (@typeInfo(IntType)) {
pub const left_down = left | down; .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;
};

View file

@ -4,7 +4,7 @@
const c = @import("c.zig").c; 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 /// A bitmask of all key modifiers
pub const Mods = packed struct { pub const Mods = packed struct {
shift: bool align(@alignOf(c_int)) = false, shift: bool align(@alignOf(c_int)) = false,