Files
ly/src/animations/Doom.zig
AnErrupTion e0ed1b4eb1 Add animation framework
Signed-off-by: AnErrupTion <anerruption@disroot.org>
2025-03-16 10:54:06 +01:00

93 lines
3.2 KiB
Zig

const std = @import("std");
const Allocator = std.mem.Allocator;
const Animation = @import("../tui/Animation.zig");
const TerminalBuffer = @import("../tui/TerminalBuffer.zig");
const utils = @import("../tui/utils.zig");
const Doom = @This();
pub const STEPS = 12;
allocator: Allocator,
terminal_buffer: *TerminalBuffer,
buffer: []u8,
fire: [STEPS + 1]utils.Cell,
pub fn init(allocator: Allocator, terminal_buffer: *TerminalBuffer, top_color: u32, middle_color: u32, bottom_color: u32) !Doom {
const buffer = try allocator.alloc(u8, terminal_buffer.width * terminal_buffer.height);
initBuffer(buffer, terminal_buffer.width);
return .{
.allocator = allocator,
.terminal_buffer = terminal_buffer,
.buffer = buffer,
.fire = [_]utils.Cell{
utils.initCell(' ', 0x00000000, 0),
utils.initCell(0x2591, top_color, 0),
utils.initCell(0x2592, top_color, 0),
utils.initCell(0x2593, top_color, 0),
utils.initCell(0x2588, top_color, 0),
utils.initCell(0x2591, middle_color, 2),
utils.initCell(0x2592, middle_color, 2),
utils.initCell(0x2593, middle_color, 2),
utils.initCell(0x2588, middle_color, 2),
utils.initCell(0x2591, bottom_color, 4),
utils.initCell(0x2592, bottom_color, 4),
utils.initCell(0x2593, bottom_color, 4),
utils.initCell(0x2588, bottom_color, 4),
},
};
}
pub fn animation(self: *Doom) Animation {
return Animation.init(self, deinit, realloc, draw);
}
fn deinit(self: *Doom) void {
self.allocator.free(self.buffer);
}
fn realloc(self: *Doom) anyerror!void {
const buffer = try self.allocator.realloc(self.buffer, self.terminal_buffer.width * self.terminal_buffer.height);
initBuffer(buffer, self.terminal_buffer.width);
self.buffer = buffer;
}
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 random = (self.terminal_buffer.random.int(u16) % 7) & 3;
var dest = (source - @min(source, random)) + 1;
if (self.terminal_buffer.width > dest) dest = 0 else dest -= self.terminal_buffer.width;
const buffer_source = self.buffer[source];
const buffer_dest_offset = random & 1;
if (buffer_source < buffer_dest_offset) continue;
var buffer_dest = buffer_source - buffer_dest_offset;
if (buffer_dest > STEPS) buffer_dest = 0;
self.buffer[dest] = @intCast(buffer_dest);
const dest_y = dest / self.terminal_buffer.width;
const dest_x = dest % self.terminal_buffer.width;
utils.putCell(dest_x, dest_y, self.fire[buffer_dest]);
const source_y = source / self.terminal_buffer.width;
const source_x = source % self.terminal_buffer.width;
utils.putCell(source_x, source_y, self.fire[buffer_source]);
}
}
}
fn initBuffer(buffer: []u8, width: usize) void {
const length = buffer.len - width;
const slice_start = buffer[0..length];
const slice_end = buffer[length..];
@memset(slice_start, 0);
@memset(slice_end, STEPS);
}