Various cleanup
I replaced the rgb function with a packed struct, formatted the code, and updated a couple of allocator things to fit Zig v0.9.0.
This commit is contained in:
		@@ -23,7 +23,7 @@ pub fn link(b: *std.build.Builder, step: *std.build.LibExeObjStep) void {
 | 
			
		||||
    step.linkLibrary(lib);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn fromHere(allocator: *std.mem.Allocator, path: []const u8) []const u8 {
 | 
			
		||||
fn fromHere(allocator: std.mem.Allocator, path: []const u8) []const u8 {
 | 
			
		||||
    const here = std.fs.path.dirname(@src().file) orelse ".";
 | 
			
		||||
    return std.fs.path.join(allocator, &.{here, path}) catch unreachable;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,13 +1,16 @@
 | 
			
		||||
const std = @import("std");
 | 
			
		||||
const minifb_c = @cImport({
 | 
			
		||||
const c = @cImport({
 | 
			
		||||
    @cInclude("MiniFB.h");
 | 
			
		||||
    @cInclude("MiniFB_enums.h");
 | 
			
		||||
});
 | 
			
		||||
const testing = std.testing;
 | 
			
		||||
 | 
			
		||||
pub fn rgb(r: u8, g: u8, b: u8) u32 {
 | 
			
		||||
    return @intCast(u32, r) << 16 | @intCast(u32, g) << 8 | b;
 | 
			
		||||
}
 | 
			
		||||
pub const Rgb = packed struct {
 | 
			
		||||
    r: u8,
 | 
			
		||||
    g: u8,
 | 
			
		||||
    b: u8,
 | 
			
		||||
    _reserved: u8 = 0,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const KeyMod = packed struct {
 | 
			
		||||
    shift: bool = false,
 | 
			
		||||
@@ -16,20 +19,20 @@ pub const KeyMod = packed struct {
 | 
			
		||||
    super: bool = false,
 | 
			
		||||
    capsLock: bool = false,
 | 
			
		||||
    numLock: bool = false,
 | 
			
		||||
    reserved: u26 = 0,
 | 
			
		||||
    _reserved: u26 = 0,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub fn Window(comptime TUserData: type) type {
 | 
			
		||||
    return struct {
 | 
			
		||||
        cwin: *minifb_c.mfb_window,
 | 
			
		||||
    return packed struct {
 | 
			
		||||
        cwin: *c.mfb_window,
 | 
			
		||||
 | 
			
		||||
        pub const UpdateError = error {
 | 
			
		||||
        pub const UpdateError = error{
 | 
			
		||||
            InvalidWindow,
 | 
			
		||||
            InvalidBuffer,
 | 
			
		||||
            InternalError,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        pub const State = enum {ok, exit};
 | 
			
		||||
        pub const State = enum { ok, exit };
 | 
			
		||||
 | 
			
		||||
        pub const OpenFlags = packed struct {
 | 
			
		||||
            resizable: bool = false,
 | 
			
		||||
@@ -43,104 +46,112 @@ pub fn Window(comptime TUserData: type) type {
 | 
			
		||||
        pub fn open(title: [*:0]const u8, width: u32, height: u32, flags: OpenFlags) !Window(TUserData) {
 | 
			
		||||
            const intFlags = @bitCast(u32, flags);
 | 
			
		||||
            const cTitle = @as([*c]const u8, title);
 | 
			
		||||
            const cwin: ?*minifb_c.mfb_window = minifb_c.mfb_open_ex(cTitle, width, height, intFlags);
 | 
			
		||||
            const cwin: ?*c.mfb_window = c.mfb_open_ex(cTitle, width, height, intFlags);
 | 
			
		||||
            if (cwin) |value| {
 | 
			
		||||
                return Window(TUserData) {.cwin=value};
 | 
			
		||||
                return Window(TUserData){ .cwin = value };
 | 
			
		||||
            } else {
 | 
			
		||||
                return error.ItBroke;
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        pub fn waitSync(self: Window(TUserData)) bool {
 | 
			
		||||
            return minifb_c.mfb_wait_sync(self.cwin);
 | 
			
		||||
            return c.mfb_wait_sync(self.cwin);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        pub fn update(self: Window(TUserData), buffer: []u32) UpdateError!State {
 | 
			
		||||
            const rawState = minifb_c.mfb_update(self.cwin, buffer.ptr);
 | 
			
		||||
        pub fn update(self: Window(TUserData), buffer: []Rgb) UpdateError!State {
 | 
			
		||||
            const rawState = c.mfb_update(self.cwin, @ptrCast(*anyopaque, buffer.ptr));
 | 
			
		||||
            switch (rawState) {
 | 
			
		||||
                .STATE_OK => return State.ok,
 | 
			
		||||
                .STATE_EXIT => return State.exit,
 | 
			
		||||
                .STATE_INVALID_WINDOW => return UpdateError.InvalidWindow,
 | 
			
		||||
                .STATE_INVALID_BUFFER => return UpdateError.InvalidBuffer,
 | 
			
		||||
                c.STATE_OK => return State.ok,
 | 
			
		||||
                c.STATE_EXIT => return State.exit,
 | 
			
		||||
                c.STATE_INVALID_WINDOW => return UpdateError.InvalidWindow,
 | 
			
		||||
                c.STATE_INVALID_BUFFER => return UpdateError.InvalidBuffer,
 | 
			
		||||
                else => return UpdateError.InternalError,
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        pub fn setUserData(self: Window(TUserData), data: *TUserData) void {
 | 
			
		||||
            minifb_c.mfb_set_user_data(self.cwin, data);
 | 
			
		||||
            c.mfb_set_user_data(self.cwin, data);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        pub fn getUserData(self: Window(TUserData)) ?*TUserData {
 | 
			
		||||
            return @ptrCast(?*TUserData, @alignCast(@alignOf(?*TUserData), minifb_c.mfb_get_user_data(self.cwin)));
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        test "user data is null if never set" {
 | 
			
		||||
            const win = try Window(u8).open("", 100, 100);
 | 
			
		||||
            const data = win.getUserData();
 | 
			
		||||
            testing.expectEqual(null, data);
 | 
			
		||||
            var cData = c.mfb_get_user_data(self.cwin);
 | 
			
		||||
            std.log.info("@alignOf cwin={d}, addr={x}", .{ @alignOf(@TypeOf(self.cwin)), @ptrToInt(self.cwin) });
 | 
			
		||||
            std.log.info("@alignOf cdata={d}, addr={x}", .{ @alignOf(@TypeOf(cData)), @ptrToInt(cData) });
 | 
			
		||||
            return @ptrCast(?*TUserData, @alignCast(@alignOf(?*TUserData), cData));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        test "user data is not null if previously set" {
 | 
			
		||||
            const win = try Window(u8).open("", 100, 100);
 | 
			
		||||
            var data: u8 = 42;
 | 
			
		||||
            win.setUserData(&data);
 | 
			
		||||
            testing.expectEqual(42, win.getUserData().?.*);
 | 
			
		||||
        pub const ActiveFunc = fn (win: Window(TUserData), isActive: bool) void;
 | 
			
		||||
        pub fn setActiveCallback(self: Window(TUserData), callback: ActiveFunc) void {
 | 
			
		||||
            c.mfb_set_active_callback(self.cwin, @ptrCast(c.mfb_active_func, callback));
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
test "user data is null if never set" {
 | 
			
		||||
    const win = try Window(u64).open("abc", 100, 100, .{});
 | 
			
		||||
    const data = win.getUserData();
 | 
			
		||||
    try testing.expectEqual(@as(?*u64, null), data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// test "user data is not null if previously set" {
 | 
			
		||||
//     const win = try Window(u64).open("abc", 100, 100, .{});
 | 
			
		||||
//     var data: u64 = 42;
 | 
			
		||||
//     win.setUserData(&data);
 | 
			
		||||
//     const expected: u64 = 42;
 | 
			
		||||
//     try testing.expectEqual(expected, win.getUserData().?.*);
 | 
			
		||||
// }
 | 
			
		||||
 | 
			
		||||
pub fn getTargetFPS() u32 {
 | 
			
		||||
    return minifb_c.mfb_get_target_fps();
 | 
			
		||||
    return c.mfb_get_target_fps();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn setTargetFPS(fps: u32) void {
 | 
			
		||||
    minifb_c.mfb_set_target_fps(fps);
 | 
			
		||||
    c.mfb_set_target_fps(fps);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TODO Figure out how to run this once I have Internet access.
 | 
			
		||||
test "set and get target FPS" {
 | 
			
		||||
    const max = 40;
 | 
			
		||||
    var fps: u32 = 30;
 | 
			
		||||
    while (fps < max) {
 | 
			
		||||
        setTargetFPS(fps);
 | 
			
		||||
        try std.testing.expectEqual(fps, getTargetFPS());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
// test "set and get target FPS" {
 | 
			
		||||
//     const max = 40;
 | 
			
		||||
//     var fps: u32 = 30;
 | 
			
		||||
//     while (fps < max) {
 | 
			
		||||
//         setTargetFPS(fps);
 | 
			
		||||
//         try std.testing.expectEqual(fps, getTargetFPS());
 | 
			
		||||
//     }
 | 
			
		||||
// }
 | 
			
		||||
 | 
			
		||||
pub const Timer = struct {
 | 
			
		||||
    ctimer: *minifb_c.mfb_timer,
 | 
			
		||||
pub const Timer = extern struct {
 | 
			
		||||
    ctimer: *c.mfb_timer,
 | 
			
		||||
 | 
			
		||||
    pub fn init() !Timer {
 | 
			
		||||
        const ctimer: ?*minifb_c.mfb_timer = minifb_c.mfb_timer_create();
 | 
			
		||||
        const ctimer: ?*c.mfb_timer = c.mfb_timer_create();
 | 
			
		||||
        if (ctimer) |value| {
 | 
			
		||||
            return Timer {.ctimer=value};
 | 
			
		||||
            return Timer{ .ctimer = value };
 | 
			
		||||
        } else {
 | 
			
		||||
            return error.ItBroke;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn deinit(self: Timer) void {
 | 
			
		||||
        minifb_c.mfb_timer_destroy(self.ctimer);
 | 
			
		||||
        c.mfb_timer_destroy(self.ctimer);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn reset(self: Timer) void {
 | 
			
		||||
        minifb_c.mfb_timer_reset(self.ctimer);
 | 
			
		||||
        c.mfb_timer_reset(self.ctimer);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn now(self: Timer) f64 {
 | 
			
		||||
        return minifb_c.mfb_timer_now(self.ctimer);
 | 
			
		||||
        return c.mfb_timer_now(self.ctimer);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn delta(self: Timer) f64 {
 | 
			
		||||
        return minifb_c.mfb_timer_delta(self.ctimer);
 | 
			
		||||
        return c.mfb_timer_delta(self.ctimer);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn getFrequency() f64 {
 | 
			
		||||
        return minifb_c.mfb_timer_get_frequency();
 | 
			
		||||
        return c.mfb_timer_get_frequency();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn getResolution() f64 {
 | 
			
		||||
        return minifb_c.mfb_timer_get_resolution();
 | 
			
		||||
        return c.mfb_timer_get_resolution();
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										89
									
								
								src/main.zig
									
									
									
									
									
								
							
							
						
						
									
										89
									
								
								src/main.zig
									
									
									
									
									
								
							@@ -6,8 +6,8 @@ const max = std.math.max;
 | 
			
		||||
const Width = 800;
 | 
			
		||||
const Height = 600;
 | 
			
		||||
 | 
			
		||||
fn grey(value: u8) u32 {
 | 
			
		||||
    return mfb.rgb(value, value, value);
 | 
			
		||||
fn grey(value: u8) mfb.Rgb {
 | 
			
		||||
    return mfb.Rgb{ .r = value, .g = value, .b = value };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const Coords = struct {
 | 
			
		||||
@@ -17,45 +17,52 @@ const Coords = struct {
 | 
			
		||||
 | 
			
		||||
const State = struct {
 | 
			
		||||
    period: f64,
 | 
			
		||||
    timer: mfb.Timer,
 | 
			
		||||
    timer: *mfb.Timer,
 | 
			
		||||
    active: bool = true,
 | 
			
		||||
    alloc: std.mem.Allocator,
 | 
			
		||||
 | 
			
		||||
    pub fn init(period: f64) !State {
 | 
			
		||||
        const timer = try mfb.Timer.init();
 | 
			
		||||
    pub fn init(alloc: std.mem.Allocator, period: f64) !State {
 | 
			
		||||
        var timer = try alloc.create(mfb.Timer);
 | 
			
		||||
        timer.* = try mfb.Timer.init();
 | 
			
		||||
        return State{
 | 
			
		||||
            .period=period,
 | 
			
		||||
            .timer=timer,
 | 
			
		||||
            .period = period,
 | 
			
		||||
            .timer = timer,
 | 
			
		||||
            .alloc = alloc,
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn deinit(self: State) void {
 | 
			
		||||
        self.timer.deinit();
 | 
			
		||||
        self.timer.*.deinit();
 | 
			
		||||
        self.alloc.destroy(self.timer);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn render(self: State, buf: Buffer) void {
 | 
			
		||||
        var bgValue = @rem(self.timer.now(), self.period) / self.period * 512;
 | 
			
		||||
        var bgValue = @rem(self.timer.*.now(), self.period) / self.period * 512;
 | 
			
		||||
        if (bgValue >= 256) {
 | 
			
		||||
            bgValue = 512 - bgValue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        buf.drawRectangle(.{.x=0,.y=0}, .{.x=Width, .y=Height}, grey(@floatToInt(u8, bgValue)));
 | 
			
		||||
        buf.drawRectangle(.{.x=Width/3, .y=Height/3}, .{.x=2*Width/3, .y=2*Height/3}, mfb.rgb(255,0,0));
 | 
			
		||||
        buf.drawRectangle(.{.x=0,.y=0}, .{.x=10,.y=10}, mfb.rgb(0,0,255));
 | 
			
		||||
        const rectColor = if (self.active) mfb.Rgb{ .r = 0, .g = 255, .b = 0 } else mfb.Rgb{ .r = 255, .g = 0, .b = 0 };
 | 
			
		||||
 | 
			
		||||
        buf.drawRectangle(.{ .x = 0, .y = 0 }, .{ .x = Width, .y = Height }, grey(@floatToInt(u8, bgValue)));
 | 
			
		||||
        buf.drawRectangle(.{ .x = Width / 3, .y = Height / 3 }, .{ .x = 2 * Width / 3, .y = 2 * Height / 3 }, rectColor);
 | 
			
		||||
        buf.drawRectangle(.{ .x = 0, .y = 0 }, .{ .x = 10, .y = 10 }, mfb.Rgb{ .r = 0, .g = 0, .b = 255 });
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const Buffer = struct {
 | 
			
		||||
    alloc: *std.mem.Allocator,
 | 
			
		||||
    slice: []u32,
 | 
			
		||||
    alloc: std.mem.Allocator,
 | 
			
		||||
    slice: []mfb.Rgb,
 | 
			
		||||
    width: u32,
 | 
			
		||||
    height: u32,
 | 
			
		||||
 | 
			
		||||
    pub fn init(alloc: *std.mem.Allocator, width: u32, height: u32) !Buffer {
 | 
			
		||||
        const slice = try alloc.alloc(u32, width*height);
 | 
			
		||||
        return Buffer {
 | 
			
		||||
            .alloc=alloc,
 | 
			
		||||
            .slice=slice,
 | 
			
		||||
            .width=width,
 | 
			
		||||
            .height=height,
 | 
			
		||||
    pub fn init(alloc: std.mem.Allocator, width: u32, height: u32) !Buffer {
 | 
			
		||||
        const slice = try alloc.alloc(mfb.Rgb, width * height);
 | 
			
		||||
        return Buffer{
 | 
			
		||||
            .alloc = alloc,
 | 
			
		||||
            .slice = slice,
 | 
			
		||||
            .width = width,
 | 
			
		||||
            .height = height,
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -63,27 +70,27 @@ const Buffer = struct {
 | 
			
		||||
        self.alloc.free(self.slice);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn setPixel(self: Buffer, coords: Coords, color: u32) void {
 | 
			
		||||
    pub fn setPixel(self: Buffer, coords: Coords, color: mfb.Rgb) void {
 | 
			
		||||
        const x = @intCast(u32, coords.x);
 | 
			
		||||
        const y = @intCast(u32, coords.y);
 | 
			
		||||
        self.slice[y*self.width + x] = color;
 | 
			
		||||
        self.slice[y * self.width + x] = color;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn drawRectangle(self: Buffer, a: Coords, b: Coords, color: u32) void {
 | 
			
		||||
    pub fn drawRectangle(self: Buffer, a: Coords, b: Coords, color: mfb.Rgb) void {
 | 
			
		||||
        var start = Coords{
 | 
			
		||||
            .x=max(0, min(a.x, b.x)),
 | 
			
		||||
            .y=max(0, min(a.y, b.y)),
 | 
			
		||||
            .x = max(0, min(a.x, b.x)),
 | 
			
		||||
            .y = max(0, min(a.y, b.y)),
 | 
			
		||||
        };
 | 
			
		||||
        var end = Coords{
 | 
			
		||||
            .x=min(@intCast(i32, self.width), max(a.x, b.x)),
 | 
			
		||||
            .y=min(@intCast(i32, self.height), max(a.y, b.y)),
 | 
			
		||||
            .x = min(@intCast(i32, self.width), max(a.x, b.x)),
 | 
			
		||||
            .y = min(@intCast(i32, self.height), max(a.y, b.y)),
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        var y = start.y;
 | 
			
		||||
        while (y < end.y) {
 | 
			
		||||
            var x = start.x;
 | 
			
		||||
            while (x < end.x) {
 | 
			
		||||
                self.setPixel(.{.x=x, .y=y}, color);
 | 
			
		||||
                self.setPixel(.{ .x = x, .y = y }, color);
 | 
			
		||||
                x += 1;
 | 
			
		||||
            }
 | 
			
		||||
            y += 1;
 | 
			
		||||
@@ -91,17 +98,34 @@ const Buffer = struct {
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
fn handleActive(win: mfb.Window(State), isActive: bool) void {
 | 
			
		||||
    // win.getUserData().?.*.active = isActive;
 | 
			
		||||
    var data = win.getUserData();
 | 
			
		||||
    std.log.info("got data", .{});
 | 
			
		||||
    if (data) |value| {
 | 
			
		||||
        // value.*.active = isActive;
 | 
			
		||||
        _ = value;
 | 
			
		||||
    }
 | 
			
		||||
    if (isActive) {
 | 
			
		||||
        std.log.info("activated!!!!!!!!!!!!", .{});
 | 
			
		||||
    } else {
 | 
			
		||||
        std.log.info("deactivated", .{});
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn main() !void {
 | 
			
		||||
    var gp_allocator = std.heap.GeneralPurposeAllocator(.{}){};
 | 
			
		||||
    const alloc = &gp_allocator.allocator;
 | 
			
		||||
    const alloc = gp_allocator.allocator();
 | 
			
		||||
 | 
			
		||||
    var state = try State.init(3);
 | 
			
		||||
    var state = try State.init(alloc, 3);
 | 
			
		||||
    defer state.deinit();
 | 
			
		||||
 | 
			
		||||
    var win = mfb.Window(State).open("Hello minifb-zig", Width, Height, .{.resizable=true}) catch unreachable;
 | 
			
		||||
    var win = mfb.Window(State).open("Hello minifb-zig", Width, Height, .{ .resizable = true, .alwaysOnTop = true }) catch unreachable;
 | 
			
		||||
    mfb.setTargetFPS(7);
 | 
			
		||||
    win.setUserData(&state);
 | 
			
		||||
 | 
			
		||||
    win.setActiveCallback(handleActive);
 | 
			
		||||
 | 
			
		||||
    var buf = try Buffer.init(alloc, Width, Height);
 | 
			
		||||
    defer buf.deinit();
 | 
			
		||||
 | 
			
		||||
@@ -109,6 +133,7 @@ pub fn main() !void {
 | 
			
		||||
    if (aliasedState) |value| {
 | 
			
		||||
        std.log.info("Period: {d}", .{value.*.period});
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    state.render(buf);
 | 
			
		||||
    while (win.waitSync()) {
 | 
			
		||||
        state.render(buf);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user