aboutsummaryrefslogtreecommitdiff
path: root/src/frontend
diff options
context:
space:
mode:
Diffstat (limited to 'src/frontend')
-rw-r--r--src/frontend/ncurses.zig54
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();
}