Added setCharInputCallback, and minor cleanup
This commit is contained in:
parent
ed6ab7c92a
commit
ed2445e623
@ -145,8 +145,8 @@ pub const KeyMod = packed struct {
|
|||||||
control: bool = false,
|
control: bool = false,
|
||||||
alt: bool = false,
|
alt: bool = false,
|
||||||
super: bool = false,
|
super: bool = false,
|
||||||
capsLock: bool = false,
|
caps_lock: bool = false,
|
||||||
numLock: bool = false,
|
num_lock: bool = false,
|
||||||
_reserved: u26 = 0,
|
_reserved: u26 = 0,
|
||||||
|
|
||||||
fn putName(present: bool, name: []const u8, names: *[6][]const u8, index: *usize) void {
|
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.control, "Control", &names, &i);
|
||||||
putName(self.alt, "Alt", &names, &i);
|
putName(self.alt, "Alt", &names, &i);
|
||||||
putName(self.super, "Super", &names, &i);
|
putName(self.super, "Super", &names, &i);
|
||||||
putName(self.capsLock, "Caps_Lock", &names, &i);
|
putName(self.caps_lock, "Caps_Lock", &names, &i);
|
||||||
putName(self.numLock, "Num_Lock", &names, &i);
|
putName(self.num_lock, "Num_Lock", &names, &i);
|
||||||
var first = true;
|
var first = true;
|
||||||
for (names[0..i]) |name| {
|
for (names[0..i]) |name| {
|
||||||
if (!first) {
|
if (!first) {
|
||||||
@ -221,16 +221,14 @@ pub fn Window(comptime TUserData: type) type {
|
|||||||
pub const OpenFlags = packed struct {
|
pub const OpenFlags = packed struct {
|
||||||
resizable: bool = false,
|
resizable: bool = false,
|
||||||
fullscreen: bool = false,
|
fullscreen: bool = false,
|
||||||
fullscreenDesktop: bool = false,
|
fullscreen_desktop: bool = false,
|
||||||
borderless: bool = false,
|
borderless: bool = false,
|
||||||
alwaysOnTop: bool = false,
|
always_on_top: bool = false,
|
||||||
reserved: u27 = 0,
|
reserved: u27 = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn open(title: [*:0]const u8, width: u32, height: u32, flags: OpenFlags) !Window(TUserData) {
|
pub fn open(title: [*:0]const u8, width: u32, height: u32, flags: OpenFlags) !Window(TUserData) {
|
||||||
const intFlags = @bitCast(u32, flags);
|
const cwin: ?*c.mfb_window = c.mfb_open_ex(title, width, height, @bitCast(u32, flags));
|
||||||
const cTitle = @as([*c]const u8, title);
|
|
||||||
const cwin: ?*c.mfb_window = c.mfb_open_ex(cTitle, width, height, intFlags);
|
|
||||||
if (cwin) |value| {
|
if (cwin) |value| {
|
||||||
const win = Window(TUserData){ .cwin = value };
|
const win = Window(TUserData){ .cwin = value };
|
||||||
assert(@bitCast(usize, win) == @ptrToInt(win.cwin));
|
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));
|
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 {
|
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);
|
return c.mfb_set_viewport(self.cwin, offset_x, offset_y, width, height);
|
||||||
}
|
}
|
||||||
|
69
src/main.zig
69
src/main.zig
@ -3,10 +3,10 @@ const std = @import("std");
|
|||||||
const min = std.math.min;
|
const min = std.math.min;
|
||||||
const max = std.math.max;
|
const max = std.math.max;
|
||||||
|
|
||||||
const Width = 800;
|
const buffer_width = 800;
|
||||||
const Height = 600;
|
const buffer_height = 600;
|
||||||
const AspectRatio = @intToFloat(comptime_float, Width) / @intToFloat(comptime_float, Height);
|
const aspect_ratio = @intToFloat(comptime_float, buffer_width) / @intToFloat(comptime_float, buffer_height);
|
||||||
const CursorWidth = 25;
|
const cursor_width = 25;
|
||||||
|
|
||||||
fn grey(value: u8) mfb.Rgb {
|
fn grey(value: u8) mfb.Rgb {
|
||||||
return mfb.Rgb{ .r = value, .g = value, .b = value };
|
return mfb.Rgb{ .r = value, .g = value, .b = value };
|
||||||
@ -36,12 +36,14 @@ const State = struct {
|
|||||||
alloc: std.mem.Allocator,
|
alloc: std.mem.Allocator,
|
||||||
cursor_pos: Coords = undefined,
|
cursor_pos: Coords = undefined,
|
||||||
rectangle_pos: FCoords = FCoords{
|
rectangle_pos: FCoords = FCoords{
|
||||||
.x = @intToFloat(f32, Width) / 2.0,
|
.x = @intToFloat(f32, buffer_width) / 2.0,
|
||||||
.y = @intToFloat(f32, Height) / 2.0,
|
.y = @intToFloat(f32, buffer_height) / 2.0,
|
||||||
},
|
},
|
||||||
rectangle_width: f32 = @intToFloat(f32, Width) / 3.0,
|
rectangle_width: f32 = @intToFloat(f32, buffer_width) / 3.0,
|
||||||
rectangle_height: f32 = @intToFloat(f32, Height) / 3.0,
|
rectangle_height: f32 = @intToFloat(f32, buffer_height) / 3.0,
|
||||||
paused: bool = false,
|
paused: bool = false,
|
||||||
|
cheat_code: []const u8 = "rave",
|
||||||
|
cheat_code_progress: usize = 0,
|
||||||
|
|
||||||
pub fn init(alloc: std.mem.Allocator, period: f64) !State {
|
pub fn init(alloc: std.mem.Allocator, period: f64) !State {
|
||||||
var timer = try alloc.create(mfb.Timer);
|
var timer = try alloc.create(mfb.Timer);
|
||||||
@ -58,15 +60,31 @@ const State = struct {
|
|||||||
self.alloc.destroy(self.timer);
|
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 {
|
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) {
|
if (bgValue >= 256) {
|
||||||
bgValue = 512 - bgValue;
|
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 };
|
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(
|
buf.drawRectangle(
|
||||||
(FCoords{
|
(FCoords{
|
||||||
.x = self.rectangle_pos.x - self.rectangle_width / 2,
|
.x = self.rectangle_pos.x - self.rectangle_width / 2,
|
||||||
@ -81,8 +99,8 @@ const State = struct {
|
|||||||
|
|
||||||
// Draw cursor
|
// Draw cursor
|
||||||
buf.drawRectangle(
|
buf.drawRectangle(
|
||||||
.{ .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 + 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 },
|
||||||
mfb.Rgb{ .r = 61, .g = 97, .b = 170 },
|
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_width: i32 = width;
|
||||||
var vp_offset_x: i32 = 0;
|
var vp_offset_x: i32 = 0;
|
||||||
var vp_offset_y: i32 = 0;
|
var vp_offset_y: i32 = 0;
|
||||||
if (win_aspect_ratio > AspectRatio) {
|
if (win_aspect_ratio > aspect_ratio) {
|
||||||
vp_width = @floatToInt(i32, @intToFloat(f32, height) * AspectRatio);
|
vp_width = @floatToInt(i32, @intToFloat(f32, height) * aspect_ratio);
|
||||||
vp_offset_x = @divTrunc(width - vp_width, 2);
|
vp_offset_x = @divTrunc(width - vp_width, 2);
|
||||||
} else {
|
} 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);
|
vp_offset_y = @divTrunc(height - vp_height, 2);
|
||||||
}
|
}
|
||||||
const did_set = win.setViewport(
|
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 {
|
pub fn main() !void {
|
||||||
var gp_allocator = std.heap.GeneralPurposeAllocator(.{}){};
|
var gp_allocator = std.heap.GeneralPurposeAllocator(.{}){};
|
||||||
const alloc = gp_allocator.allocator();
|
const alloc = gp_allocator.allocator();
|
||||||
@ -212,20 +234,29 @@ pub fn main() !void {
|
|||||||
var state = try State.init(alloc, 3);
|
var state = try State.init(alloc, 3);
|
||||||
defer state.deinit();
|
defer state.deinit();
|
||||||
|
|
||||||
var win = mfb.Window(State).open("Hello minifb-zig", Width, Height, .{ .resizable = true, .alwaysOnTop = true }) catch unreachable;
|
var win = mfb.Window(State).open("Hello minifb-zig", buffer_width, buffer_height, .{ .resizable = true, .always_on_top = true }) catch unreachable;
|
||||||
const scale = win.getMonitorScale();
|
|
||||||
std.log.info("Monitor scale: {d} * {d}", .{ scale.x, scale.y });
|
|
||||||
mfb.setTargetFPS(30);
|
mfb.setTargetFPS(30);
|
||||||
win.setUserData(&state);
|
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.setActiveCallback(handleActive);
|
||||||
win.setResizeCallback(handleResize);
|
win.setResizeCallback(handleResize);
|
||||||
win.setMouseButtonCallback(handleMouseButton);
|
win.setMouseButtonCallback(handleMouseButton);
|
||||||
win.setMouseMoveCallback(handleMouseMove);
|
win.setMouseMoveCallback(handleMouseMove);
|
||||||
win.setMouseScrollCallback(handleMouseScroll);
|
win.setMouseScrollCallback(handleMouseScroll);
|
||||||
win.setKeyboardCallback(handleKeyboard);
|
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();
|
defer buf.deinit();
|
||||||
|
|
||||||
state.render(buf);
|
state.render(buf);
|
||||||
|
Loading…
Reference in New Issue
Block a user