From 020f27b203a39452290537852eb421468e150097 Mon Sep 17 00:00:00 2001 From: peterc-s Date: Tue, 22 Oct 2024 02:03:21 +0100 Subject: [PATCH] added refresh interval in ms for animations --- res/config.ini | 8 +++ src/animations/Doom.zig | 14 +++- src/animations/Matrix.zig | 131 +++++++++++++++++++------------------- src/config/Config.zig | 1 + src/main.zig | 24 ++++++- 5 files changed, 111 insertions(+), 67 deletions(-) diff --git a/res/config.ini b/res/config.ini index 1d28cb8..3738cce 100644 --- a/res/config.ini +++ b/res/config.ini @@ -35,6 +35,14 @@ # matrix -> CMatrix animation = none +# The minimum time between animation frames +# 32 -> ~30fps +# 16 -> ~60fps +# 8 -> ~120fps +# 6 -> ~144fps +# 4 -> ~240fps +animation_refresh_ms = 16 + # Stop the animation after some time # 0 -> Run forever # 1..2e12 -> Stop the animation after this many seconds diff --git a/src/animations/Doom.zig b/src/animations/Doom.zig index 9813122..cff030c 100644 --- a/src/animations/Doom.zig +++ b/src/animations/Doom.zig @@ -50,7 +50,7 @@ pub fn realloc(self: *Doom) !void { self.buffer = buffer; } -pub fn draw(self: Doom) void { +pub fn draw_with_update(self: Doom) void { for (0..self.terminal_buffer.width) |x| { for (1..self.terminal_buffer.height) |y| { const source = y * self.terminal_buffer.width + x; @@ -74,6 +74,18 @@ pub fn draw(self: Doom) void { } } +pub fn draw(self: Doom) void { + for (0..self.terminal_buffer.width) |x| { + for (1..self.terminal_buffer.height) |y| { + const source = y * self.terminal_buffer.width + x; + + const buffer_source = self.buffer[source]; + + self.terminal_buffer.buffer[source] = toTermboxCell(FIRE[buffer_source]); + } + } +} + fn initBuffer(buffer: []u8, width: usize) void { const length = buffer.len - width; const slice_start = buffer[0..length]; diff --git a/src/animations/Matrix.zig b/src/animations/Matrix.zig index ba7e6e1..fa64885 100644 --- a/src/animations/Matrix.zig +++ b/src/animations/Matrix.zig @@ -68,80 +68,83 @@ pub fn realloc(self: *Matrix) !void { self.lines = lines; } -pub fn draw(self: *Matrix) void { +pub fn draw_with_update(self: *Matrix) void { const buf_height = self.terminal_buffer.height; const buf_width = self.terminal_buffer.width; - self.count += 1; - if (self.count > FRAME_DELAY) { - self.frame += 1; - if (self.frame > 4) self.frame = 1; - self.count = 0; - var x: usize = 0; - while (x < self.terminal_buffer.width) : (x += 2) { - var tail: usize = 0; - var line = &self.lines[x]; - if (self.frame <= line.update) continue; + self.frame += 1; + if (self.frame > 4) self.frame = 1; - if (self.dots[x].value == -1 and self.dots[self.terminal_buffer.width + x].value == ' ') { - if (line.space > 0) { - line.space -= 1; - } else { - const randint = self.terminal_buffer.random.int(i16); - const h: isize = @intCast(self.terminal_buffer.height); - line.length = @mod(randint, h - 3) + 3; - self.dots[x].value = @mod(randint, MAX_CODEPOINT) + MIN_CODEPOINT; - line.space = @mod(randint, h + 1); - } - } - - var y: usize = 0; - var first_col = true; - var seg_len: u64 = 0; - height_it: while (y <= buf_height) : (y += 1) { - var dot = &self.dots[buf_width * y + x]; - // Skip over spaces - while (y <= buf_height and (dot.value == ' ' or dot.value == -1)) { - y += 1; - if (y > buf_height) break :height_it; - dot = &self.dots[buf_width * y + x]; - } - - // Find the head of this column - tail = y; - seg_len = 0; - while (y <= buf_height and dot.value != ' ' and dot.value != -1) { - dot.is_head = false; - if (MID_SCROLL_CHANGE) { - const randint = self.terminal_buffer.random.int(i16); - if (@mod(randint, 8) == 0) { - dot.value = @mod(randint, MAX_CODEPOINT) + MIN_CODEPOINT; - } - } - - y += 1; - seg_len += 1; - // Head's down offscreen - if (y > buf_height) { - self.dots[buf_width * tail + x].value = ' '; - break :height_it; - } - dot = &self.dots[buf_width * y + x]; - } + var x: usize = 0; + while (x < self.terminal_buffer.width) : (x += 2) { + var tail: usize = 0; + var line = &self.lines[x]; + if (self.frame <= line.update) continue; + if (self.dots[x].value == -1 and self.dots[self.terminal_buffer.width + x].value == ' ') { + if (line.space > 0) { + line.space -= 1; + } else { const randint = self.terminal_buffer.random.int(i16); - dot.value = @mod(randint, MAX_CODEPOINT) + MIN_CODEPOINT; - dot.is_head = true; - - if (seg_len > line.length or !first_col) { - self.dots[buf_width * tail + x].value = ' '; - self.dots[x].value = -1; - } - first_col = false; + const h: isize = @intCast(self.terminal_buffer.height); + line.length = @mod(randint, h - 3) + 3; + self.dots[x].value = @mod(randint, MAX_CODEPOINT) + MIN_CODEPOINT; + line.space = @mod(randint, h + 1); } } + + var y: usize = 0; + var first_col = true; + var seg_len: u64 = 0; + height_it: while (y <= buf_height) : (y += 1) { + var dot = &self.dots[buf_width * y + x]; + // Skip over spaces + while (y <= buf_height and (dot.value == ' ' or dot.value == -1)) { + y += 1; + if (y > buf_height) break :height_it; + dot = &self.dots[buf_width * y + x]; + } + + // Find the head of this column + tail = y; + seg_len = 0; + while (y <= buf_height and dot.value != ' ' and dot.value != -1) { + dot.is_head = false; + if (MID_SCROLL_CHANGE) { + const randint = self.terminal_buffer.random.int(i16); + if (@mod(randint, 8) == 0) { + dot.value = @mod(randint, MAX_CODEPOINT) + MIN_CODEPOINT; + } + } + + y += 1; + seg_len += 1; + // Head's down offscreen + if (y > buf_height) { + self.dots[buf_width * tail + x].value = ' '; + break :height_it; + } + dot = &self.dots[buf_width * y + x]; + } + + const randint = self.terminal_buffer.random.int(i16); + dot.value = @mod(randint, MAX_CODEPOINT) + MIN_CODEPOINT; + dot.is_head = true; + + if (seg_len > line.length or !first_col) { + self.dots[buf_width * tail + x].value = ' '; + self.dots[x].value = -1; + } + first_col = false; + } } + self.draw(); +} + +pub fn draw(self: *Matrix) void { + const buf_width = self.terminal_buffer.width; + var x: usize = 0; while (x < buf_width) : (x += 2) { var y: usize = 1; diff --git a/src/config/Config.zig b/src/config/Config.zig index 38c8b4c..f35c2d9 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -8,6 +8,7 @@ const Bigclock = enums.Bigclock; animation: Animation = .none, animation_timeout_sec: u12 = 0, +animation_refresh_ms: u16 = 16, asterisk: ?u8 = '*', auth_fails: u64 = 10, bg: u16 = 0, diff --git a/src/main.zig b/src/main.zig index 4afefad..bb52d16 100644 --- a/src/main.zig +++ b/src/main.zig @@ -317,6 +317,11 @@ pub fn main() !void { } } + var animation_timer = switch(config.animation) { + .none => undefined, + else => try std.time.Timer.start() + }; + const animate = config.animation != .none; const shutdown_key = try std.fmt.parseInt(u8, config.shutdown_key[1..], 10); const shutdown_len = try utils.strWidth(lang.shutdown); @@ -340,6 +345,7 @@ pub fn main() !void { try info_line.addMessage(lang.err_console_dev, config.error_bg, config.error_fg); }; + while (run) { // If there's no input or there's an animation, a resolution change needs to be checked if (!update or config.animation != .none) { @@ -380,8 +386,22 @@ pub fn main() !void { if (!animation_timed_out) { switch (config.animation) { .none => {}, - .doom => doom.draw(), - .matrix => matrix.draw(), + .doom => { + if (animation_timer.read() / std.time.ns_per_ms > config.animation_refresh_ms) { + animation_timer.reset(); + doom.draw_with_update(); + } else { + doom.draw(); + } + }, + .matrix => { + if (animation_timer.read() / std.time.ns_per_ms > config.animation_refresh_ms) { + animation_timer.reset(); + matrix.draw_with_update(); + } else { + matrix.draw(); + } + }, } }