diff options
Diffstat (limited to 'src/main.zig')
-rw-r--r-- | src/main.zig | 96 |
1 files changed, 83 insertions, 13 deletions
diff --git a/src/main.zig b/src/main.zig index add48ae..249d7c7 100644 --- a/src/main.zig +++ b/src/main.zig @@ -16,23 +16,93 @@ // You should have received a copy of the GNU Lesser General Public License // along with zeal. If not, see <https://www.gnu.org/licenses/>. +const al = @import("al.zig"); const alc = @import("alc.zig"); +const expect = std.testing.expect; +const eql = std.meta.eql; +const std = @import("std"); -pub fn init(device_name: [*c]const u8) !void { - const device = try alc.openDevice(device_name); - const context = try alc.createContext(device, null); - try alc.makeContextCurrent(context); +pub const Device = struct { + pimpl: *alc.Device, + + pub fn init(name: ?[]const u8) alc.Error!Device { + return Device{ .pimpl = try alc.openDevice(name) }; + } + + pub fn deinit(self: Device) alc.Error!void { + try alc.closeDevice(self.pimpl); + } +}; + +pub const Context = struct { + pimpl: *alc.Context, + device: Device, + + pub fn init(device: Device, attributes: [:0]const i32) alc.Error!Context { + return Context { + .pimpl = try alc.createContext(device.pimpl, attributes), + .device = device, + }; + } + + pub fn deinit(self: Context) alc.Error!void { + try alc.makeContextCurrent(null); + try alc.destroyContext(self.pimpl); + } +}; + +pub fn useContext(context: ?Context) alc.Error!void { + try alc.makeContextCurrent(if (context == null) null else context.?.pimpl); +} +pub fn currentContext() alc.Error!?Context { + if (alc.getCurrentContext()) |pimpl| + return Context { + .pimpl = pimpl, + .device = Device { .pimpl = try alc.getContextsDevice(pimpl) }, + }; + return null; } -pub fn deinit() !void { - const context = alc.getCurrentContext(); - const device = try alc.getContextsDevice(context); - try alc.makeContextCurrent(null); - try alc.destroyContext(context); - try alc.closeDevice(device); +fn checkContext(context: Context) !void { + if (context.pimpl != alc.getCurrentContext()) + return error.UncurrentContext; } -test { - try init(null); - try deinit(); +pub const Listener = struct { + context: Context, + + pub fn setPosition(self: Listener, position: [3]f32) !void { + try checkContext(self.context); + al.listener.setFloatVector(al.POSITION, &position); + } + + pub fn setOrientation(self: Listener, at: [3]f32, up: [3]f32) !void { + try checkContext(self.context); + al.listener.setFloatVector(al.ORIENTATION, &[_]f32 { + at[0], at[1], at[2], + up[0], up[1], up[2], + }); + } +}; + +test "temporary" { + const device = try Device.init("OpenAL Soft"); + defer device.deinit() catch unreachable; + const context = try Context.init(device, &.{ alc.HRTF, alc.TRUE }); + defer context.deinit() catch unreachable; + + try expect(null == try currentContext()); + if (checkContext(context)) |_| unreachable else |err| switch (err) { + error.UncurrentContext => {}, + } + + try useContext(context); + const current_context = (try currentContext()).?; + try expect(eql(current_context, context)); + try expect(eql(current_context.device, device)); + try checkContext(context); + + const listener = Listener{ .context = context }; + try listener.setPosition(.{ 0, 0, 0 }); + try listener.setOrientation(.{ 0, 0, 0 }, .{ 0, 0, 0 }); } |