From ed2445e623a85fad698ab4b38f5ee9a2ff36e330 Mon Sep 17 00:00:00 2001 From: Brandon Dyck Date: Mon, 10 Jan 2022 16:30:58 -0700 Subject: [PATCH] Added setCharInputCallback, and minor cleanup --- lib/minifb/src/minifb.zig | 21 +++++++----- src/main.zig | 69 ++++++++++++++++++++++++++++----------- 2 files changed, 62 insertions(+), 28 deletions(-) diff --git a/lib/minifb/src/minifb.zig b/lib/minifb/src/minifb.zig index dc920ff..43bf479 100644 --- a/lib/minifb/src/minifb.zig +++ b/lib/minifb/src/minifb.zig @@ -145,8 +145,8 @@ pub const KeyMod = packed struct { control: bool = false, alt: bool = false, super: bool = false, - capsLock: bool = false, - numLock: bool = false, + caps_lock: bool = false, + num_lock: bool = false, _reserved: u26 = 0, fn putName(present: bool, name: []const u8, names: *[6][]const u8, index: *usize) void { @@ -168,8 +168,8 @@ pub const KeyMod = packed struct { putName(self.control, "Control", &names, &i); putName(self.alt, "Alt", &names, &i); putName(self.super, "Super", &names, &i); - putName(self.capsLock, "Caps_Lock", &names, &i); - putName(self.numLock, "Num_Lock", &names, &i); + putName(self.caps_lock, "Caps_Lock", &names, &i); + putName(self.num_lock, "Num_Lock", &names, &i); var first = true; for (names[0..i]) |name| { if (!first) { @@ -221,16 +221,14 @@ pub fn Window(comptime TUserData: type) type { pub const OpenFlags = packed struct { resizable: bool = false, fullscreen: bool = false, - fullscreenDesktop: bool = false, + fullscreen_desktop: bool = false, borderless: bool = false, - alwaysOnTop: bool = false, + always_on_top: bool = false, reserved: u27 = 0, }; 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: ?*c.mfb_window = c.mfb_open_ex(cTitle, width, height, intFlags); + const cwin: ?*c.mfb_window = c.mfb_open_ex(title, width, height, @bitCast(u32, flags)); if (cwin) |value| { const win = Window(TUserData){ .cwin = value }; assert(@bitCast(usize, win) == @ptrToInt(win.cwin)); @@ -299,6 +297,11 @@ pub fn Window(comptime TUserData: type) type { c.mfb_set_keyboard_callback(self.cwin, @ptrCast(c.mfb_keyboard_func, callback)); } + pub const CharInputFunc = fn (win: Window(TUserData), code: u32) callconv(.C) void; + pub fn setCharInputCallback(self: Window(TUserData), callback: CharInputFunc) void { + c.mfb_set_char_input_callback(self.cwin, @ptrCast(c.mfb_char_input_func, callback)); + } + pub fn setViewport(self: Window(TUserData), offset_x: u32, offset_y: u32, width: u32, height: u32) bool { return c.mfb_set_viewport(self.cwin, offset_x, offset_y, width, height); } diff --git a/src/main.zig b/src/main.zig index ceef634..9db3d1c 100644 --- a/src/main.zig +++ b/src/main.zig @@ -3,10 +3,10 @@ const std = @import("std"); const min = std.math.min; const max = std.math.max; -const Width = 800; -const Height = 600; -const AspectRatio = @intToFloat(comptime_float, Width) / @intToFloat(comptime_float, Height); -const CursorWidth = 25; +const buffer_width = 800; +const buffer_height = 600; +const aspect_ratio = @intToFloat(comptime_float, buffer_width) / @intToFloat(comptime_float, buffer_height); +const cursor_width = 25; fn grey(value: u8) mfb.Rgb { return mfb.Rgb{ .r = value, .g = value, .b = value }; @@ -36,12 +36,14 @@ const State = struct { alloc: std.mem.Allocator, cursor_pos: Coords = undefined, rectangle_pos: FCoords = FCoords{ - .x = @intToFloat(f32, Width) / 2.0, - .y = @intToFloat(f32, Height) / 2.0, + .x = @intToFloat(f32, buffer_width) / 2.0, + .y = @intToFloat(f32, buffer_height) / 2.0, }, - rectangle_width: f32 = @intToFloat(f32, Width) / 3.0, - rectangle_height: f32 = @intToFloat(f32, Height) / 3.0, + rectangle_width: f32 = @intToFloat(f32, buffer_width) / 3.0, + rectangle_height: f32 = @intToFloat(f32, buffer_height) / 3.0, paused: bool = false, + cheat_code: []const u8 = "rave", + cheat_code_progress: usize = 0, pub fn init(alloc: std.mem.Allocator, period: f64) !State { var timer = try alloc.create(mfb.Timer); @@ -58,15 +60,31 @@ const State = struct { self.alloc.destroy(self.timer); } + pub fn cheatInput(self: *State, char: u32) void { + if (self.isCheating()) { + return; + } + if (char == self.cheat_code[self.cheat_code_progress]) { + self.cheat_code_progress += 1; + } else { + self.cheat_code_progress = 0; + } + } + + fn isCheating(self: State) bool { + return self.cheat_code_progress == self.cheat_code.len; + } + pub fn render(self: State, buf: Buffer) void { - var bgValue = @rem(self.timer.*.now(), self.period) / self.period * 512; + const period = if (!self.isCheating()) self.period else self.period / 10; + var bgValue = @rem(self.timer.*.now(), period) / period * 512; if (bgValue >= 256) { bgValue = 512 - bgValue; } 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 = 0, .y = 0 }, .{ .x = buffer_width, .y = buffer_height }, grey(@floatToInt(u8, bgValue))); buf.drawRectangle( (FCoords{ .x = self.rectangle_pos.x - self.rectangle_width / 2, @@ -81,8 +99,8 @@ const State = struct { // Draw cursor buf.drawRectangle( - .{ .x = self.cursor_pos.x - CursorWidth / 2, .y = self.cursor_pos.y - CursorWidth / 2 }, - .{ .x = self.cursor_pos.x + CursorWidth / 2, .y = self.cursor_pos.y + CursorWidth / 2 }, + .{ .x = self.cursor_pos.x - cursor_width / 2, .y = self.cursor_pos.y - cursor_width / 2 }, + .{ .x = self.cursor_pos.x + cursor_width / 2, .y = self.cursor_pos.y + cursor_width / 2 }, mfb.Rgb{ .r = 61, .g = 97, .b = 170 }, ); } @@ -146,11 +164,11 @@ fn handleResize(win: mfb.Window(State), width: i32, height: i32) callconv(.C) vo var vp_width: i32 = width; var vp_offset_x: i32 = 0; var vp_offset_y: i32 = 0; - if (win_aspect_ratio > AspectRatio) { - vp_width = @floatToInt(i32, @intToFloat(f32, height) * AspectRatio); + if (win_aspect_ratio > aspect_ratio) { + vp_width = @floatToInt(i32, @intToFloat(f32, height) * aspect_ratio); vp_offset_x = @divTrunc(width - vp_width, 2); } else { - vp_height = @floatToInt(i32, @intToFloat(f32, width) / AspectRatio); + vp_height = @floatToInt(i32, @intToFloat(f32, width) / aspect_ratio); vp_offset_y = @divTrunc(height - vp_height, 2); } const did_set = win.setViewport( @@ -205,6 +223,10 @@ fn handleKeyboard(win: mfb.Window(State), key: mfb.Key, _: mfb.KeyMod, is_presse } } +fn handleCharInput(win: mfb.Window(State), char: u32) callconv(.C) void { + win.getUserData().?.cheatInput(char); +} + pub fn main() !void { var gp_allocator = std.heap.GeneralPurposeAllocator(.{}){}; const alloc = gp_allocator.allocator(); @@ -212,20 +234,29 @@ pub fn main() !void { var state = try State.init(alloc, 3); defer state.deinit(); - var win = mfb.Window(State).open("Hello minifb-zig", Width, Height, .{ .resizable = true, .alwaysOnTop = true }) catch unreachable; - const scale = win.getMonitorScale(); - std.log.info("Monitor scale: {d} * {d}", .{ scale.x, scale.y }); + var win = mfb.Window(State).open("Hello minifb-zig", buffer_width, buffer_height, .{ .resizable = true, .always_on_top = true }) catch unreachable; mfb.setTargetFPS(30); win.setUserData(&state); + const scale = win.getMonitorScale(); + try std.io.getStdOut().writer().print( + \\Monitor scale: {d} * {d} + \\ + \\Press spacebar to pause, escape to quit. + \\Try [Ctrl+][Shift+]scroll wheel to change the colored rectangle. + \\Type "{s}" to get crazy. + \\ + , .{ scale.x, scale.y, state.cheat_code }); + win.setActiveCallback(handleActive); win.setResizeCallback(handleResize); win.setMouseButtonCallback(handleMouseButton); win.setMouseMoveCallback(handleMouseMove); win.setMouseScrollCallback(handleMouseScroll); win.setKeyboardCallback(handleKeyboard); + win.setCharInputCallback(handleCharInput); - var buf = try Buffer.init(alloc, Width, Height); + var buf = try Buffer.init(alloc, buffer_width, buffer_height); defer buf.deinit(); state.render(buf);