diff options
Diffstat (limited to 'src/frontend/ncurses.zig')
-rw-r--r-- | src/frontend/ncurses.zig | 54 |
1 files changed, 39 insertions, 15 deletions
diff --git a/src/frontend/ncurses.zig b/src/frontend/ncurses.zig index 76cd750..2a560a8 100644 --- a/src/frontend/ncurses.zig +++ b/src/frontend/ncurses.zig @@ -7,6 +7,8 @@ const locale = @cImport({ @cInclude("locale.h"); }); +const TICK_MS = 33; + const MAIN_PANEL_WIDTH = 100; const MAIN_PANEL_HEIGHT = 41; const INSTRUCTION_PANEL_WIDTH = 32; @@ -27,11 +29,12 @@ const KEY_STAIR_UP: i32 = '<'; const KEY_STAIR_DOWN: i32 = '>'; const KEY_QUIT: i32 = ncurses.KEY_F(1); -pub const Display = struct { +pub const IO = struct { main: ?*ncurses.WINDOW, inst: ?*ncurses.WINDOW, msgs: ?*ncurses.WINDOW, stat: ?*ncurses.WINDOW, + prev_tick_time: i64, fn validTermSize() bool { return ncurses.LINES >= MIN_HEIGHT and @@ -49,7 +52,7 @@ pub const Display = struct { return local_win; } - fn formatInstruction(self: *Display, pos: i32, key: i32, description: [:0]const u8) void { + fn formatInstruction(self: *IO, pos: i32, key: i32, description: [:0]const u8) void { const c_description: ?[*:0]const u8 = description.ptr; if (ncurses.KEY_F0 <= key and key <= ncurses.KEY_F(64)) { @@ -61,7 +64,7 @@ pub const Display = struct { } } - fn handleResize(self: *Display) Action { + fn handleResize(self: *IO) Action { const lines = @as(usize, @intCast(ncurses.LINES)); const cols = @as(usize, @intCast(ncurses.COLS)); for (0..lines) |i| { @@ -90,7 +93,7 @@ pub const Display = struct { return Action.illegal; } - pub fn displayInstructions(self: *Display) void { + pub fn displayInstructions(self: *IO) void { self.formatInstruction(1, KEY_MOVE_LEFT, "move left"); self.formatInstruction(2, KEY_MOVE_DOWN, "move down"); self.formatInstruction(3, KEY_MOVE_UP, "move up"); @@ -101,7 +104,7 @@ pub const Display = struct { _ = ncurses.wrefresh(self.inst); } - pub fn displayMessage(self: *Display, comptime fmt: []const u8, args: anytype) void { + pub fn displayMessage(self: *IO, comptime fmt: []const u8, args: anytype) void { if (self.msgs == null) return; for (1..MESSAGE_PANEL_WIDTH - 1) |i| { @@ -123,7 +126,7 @@ pub const Display = struct { _ = ncurses.wrefresh(self.msgs); } - pub fn displayStatus(self: *Display) void { + pub fn displayStatus(self: *IO) void { for (1..STATUS_PANEL_HEIGHT - 1) |i| { for (1..STATUS_PANEL_WIDTH - 1) |j| { const i_32 = @as(i32, @intCast(i)); @@ -135,8 +138,27 @@ pub const Display = struct { _ = ncurses.wrefresh(self.stat); } - pub fn processInput(self: *Display) Action { + pub fn waitForTick(self: *IO) Action { + var new = std.time.milliTimestamp(); + + while (new - self.prev_tick_time <= TICK_MS) { + const action = self.processInput(); + if (action != Action.illegal) return action; + + new = std.time.milliTimestamp(); + } + + self.prev_tick_time = new; + return Action.tick; + } + + fn processInput(self: *IO) Action { const ch = ncurses.getch(); + + if (!validTermSize()) { + if (ch != KEY_QUIT and ch != ncurses.KEY_RESIZE) return Action.illegal; + } + return switch (ch) { KEY_MOVE_UP => Action.move_up, KEY_MOVE_DOWN => Action.move_down, @@ -186,7 +208,7 @@ pub const Display = struct { ); } - pub fn init() !Display { + pub fn init() !IO { _ = locale.setlocale(locale.LC_ALL, ""); if (ncurses.initscr() == null) { return error.CursesInitFail; @@ -209,30 +231,32 @@ pub const Display = struct { _ = ncurses.wattron(ncurses.stdscr, ncurses.COLOR_PAIR(1)); _ = ncurses.refresh(); - var d: Display = undefined; + var io: IO = undefined; if (!validTermSize()) { _ = ncurses.mvprintw(0, 0, "Terminal must be at least %dx%d", @as(i32, @intCast(MIN_WIDTH)), @as(i32, @intCast(MIN_HEIGHT))); - d = Display{ + io = IO{ .inst = null, .msgs = null, .stat = null, .main = null, + .prev_tick_time = std.time.milliTimestamp(), }; } else { - d = Display{ + io = IO{ .inst = createInstructionPanel(), .msgs = createMessagePanel(), .stat = createStatisticsPanel(), .main = createMainPanel(), + .prev_tick_time = std.time.milliTimestamp(), }; - d.displayInstructions(); + io.displayInstructions(); } - return d; + return io; } - fn deleteWindows(self: *Display) void { + fn deleteWindows(self: *IO) void { _ = ncurses.delwin(self.main); self.main = null; _ = ncurses.delwin(self.inst); @@ -243,7 +267,7 @@ pub const Display = struct { self.stat = null; } - pub fn deinit(self: *Display) void { + pub fn deinit(self: *IO) void { self.deleteWindows(); _ = ncurses.endwin(); } |